linux/drivers/staging/media/imx/imx-media-csi.c
<<
>>
Prefs
   1/*
   2 * V4L2 Capture CSI Subdev for Freescale i.MX5/6 SOC
   3 *
   4 * Copyright (c) 2014-2017 Mentor Graphics Inc.
   5 * Copyright (C) 2017 Pengutronix, Philipp Zabel <kernel@pengutronix.de>
   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 as published by
   9 * the Free Software Foundation; either version 2 of the License, or
  10 * (at your option) any later version.
  11 */
  12#include <linux/delay.h>
  13#include <linux/gcd.h>
  14#include <linux/interrupt.h>
  15#include <linux/module.h>
  16#include <linux/of_graph.h>
  17#include <linux/pinctrl/consumer.h>
  18#include <linux/platform_device.h>
  19#include <media/v4l2-ctrls.h>
  20#include <media/v4l2-device.h>
  21#include <media/v4l2-event.h>
  22#include <media/v4l2-fwnode.h>
  23#include <media/v4l2-mc.h>
  24#include <media/v4l2-subdev.h>
  25#include <media/videobuf2-dma-contig.h>
  26#include <video/imx-ipu-v3.h>
  27#include <media/imx.h>
  28#include "imx-media.h"
  29
  30/*
  31 * Min/Max supported width and heights.
  32 *
  33 * We allow planar output, so we have to align width by 16 pixels
  34 * to meet IDMAC alignment requirements.
  35 *
  36 * TODO: move this into pad format negotiation, if capture device
  37 * has not requested planar formats, we should allow 8 pixel
  38 * alignment.
  39 */
  40#define MIN_W       176
  41#define MIN_H       144
  42#define MAX_W      4096
  43#define MAX_H      4096
  44#define W_ALIGN    4 /* multiple of 16 pixels */
  45#define H_ALIGN    1 /* multiple of 2 lines */
  46#define S_ALIGN    1 /* multiple of 2 */
  47
  48/*
  49 * struct csi_skip_desc - CSI frame skipping descriptor
  50 * @keep - number of frames kept per max_ratio frames
  51 * @max_ratio - width of skip_smfc, written to MAX_RATIO bitfield
  52 * @skip_smfc - skip pattern written to the SKIP_SMFC bitfield
  53 */
  54struct csi_skip_desc {
  55        u8 keep;
  56        u8 max_ratio;
  57        u8 skip_smfc;
  58};
  59
  60struct csi_priv {
  61        struct device *dev;
  62        struct ipu_soc *ipu;
  63        struct imx_media_dev *md;
  64        struct v4l2_subdev sd;
  65        struct media_pad pad[CSI_NUM_PADS];
  66        /* the video device at IDMAC output pad */
  67        struct imx_media_video_dev *vdev;
  68        struct imx_media_fim *fim;
  69        int csi_id;
  70        int smfc_id;
  71
  72        /* lock to protect all members below */
  73        struct mutex lock;
  74
  75        int active_output_pad;
  76
  77        struct ipuv3_channel *idmac_ch;
  78        struct ipu_smfc *smfc;
  79        struct ipu_csi *csi;
  80
  81        struct v4l2_mbus_framefmt format_mbus[CSI_NUM_PADS];
  82        const struct imx_media_pixfmt *cc[CSI_NUM_PADS];
  83        struct v4l2_fract frame_interval[CSI_NUM_PADS];
  84        struct v4l2_rect crop;
  85        struct v4l2_rect compose;
  86        const struct csi_skip_desc *skip;
  87
  88        /* active vb2 buffers to send to video dev sink */
  89        struct imx_media_buffer *active_vb2_buf[2];
  90        struct imx_media_dma_buf underrun_buf;
  91
  92        int ipu_buf_num;  /* ipu double buffer index: 0-1 */
  93
  94        /* the sink for the captured frames */
  95        struct media_entity *sink;
  96        enum ipu_csi_dest dest;
  97        /* the source subdev */
  98        struct v4l2_subdev *src_sd;
  99
 100        /* the mipi virtual channel number at link validate */
 101        int vc_num;
 102
 103        /* the upstream endpoint CSI is receiving from */
 104        struct v4l2_fwnode_endpoint upstream_ep;
 105
 106        spinlock_t irqlock; /* protect eof_irq handler */
 107        struct timer_list eof_timeout_timer;
 108        int eof_irq;
 109        int nfb4eof_irq;
 110
 111        struct v4l2_ctrl_handler ctrl_hdlr;
 112
 113        int stream_count; /* streaming counter */
 114        bool last_eof;   /* waiting for last EOF at stream off */
 115        bool nfb4eof;    /* NFB4EOF encountered during streaming */
 116        struct completion last_eof_comp;
 117};
 118
 119static inline struct csi_priv *sd_to_dev(struct v4l2_subdev *sdev)
 120{
 121        return container_of(sdev, struct csi_priv, sd);
 122}
 123
 124static inline bool is_parallel_16bit_bus(struct v4l2_fwnode_endpoint *ep)
 125{
 126        return ep->bus_type != V4L2_MBUS_CSI2 &&
 127                ep->bus.parallel.bus_width >= 16;
 128}
 129
 130/*
 131 * Parses the fwnode endpoint from the source pad of the entity
 132 * connected to this CSI. This will either be the entity directly
 133 * upstream from the CSI-2 receiver, or directly upstream from the
 134 * video mux. The endpoint is needed to determine the bus type and
 135 * bus config coming into the CSI.
 136 */
 137static int csi_get_upstream_endpoint(struct csi_priv *priv,
 138                                     struct v4l2_fwnode_endpoint *ep)
 139{
 140        struct device_node *endpoint, *port;
 141        struct media_entity *src;
 142        struct v4l2_subdev *sd;
 143        struct media_pad *pad;
 144
 145        if (!priv->src_sd)
 146                return -EPIPE;
 147
 148        src = &priv->src_sd->entity;
 149
 150        if (src->function == MEDIA_ENT_F_VID_MUX) {
 151                /*
 152                 * CSI is connected directly to video mux, skip up to
 153                 * CSI-2 receiver if it is in the path, otherwise stay
 154                 * with video mux.
 155                 */
 156                sd = imx_media_find_upstream_subdev(priv->md, src,
 157                                                    IMX_MEDIA_GRP_ID_CSI2);
 158                if (!IS_ERR(sd))
 159                        src = &sd->entity;
 160        }
 161
 162        /* get source pad of entity directly upstream from src */
 163        pad = imx_media_find_upstream_pad(priv->md, src, 0);
 164        if (IS_ERR(pad))
 165                return PTR_ERR(pad);
 166
 167        sd = media_entity_to_v4l2_subdev(pad->entity);
 168
 169        /*
 170         * NOTE: this assumes an OF-graph port id is the same as a
 171         * media pad index.
 172         */
 173        port = of_graph_get_port_by_id(sd->dev->of_node, pad->index);
 174        if (!port)
 175                return -ENODEV;
 176
 177        endpoint = of_get_next_child(port, NULL);
 178        of_node_put(port);
 179        if (!endpoint)
 180                return -ENODEV;
 181
 182        v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint), ep);
 183        of_node_put(endpoint);
 184
 185        return 0;
 186}
 187
 188static void csi_idmac_put_ipu_resources(struct csi_priv *priv)
 189{
 190        if (priv->idmac_ch)
 191                ipu_idmac_put(priv->idmac_ch);
 192        priv->idmac_ch = NULL;
 193
 194        if (priv->smfc)
 195                ipu_smfc_put(priv->smfc);
 196        priv->smfc = NULL;
 197}
 198
 199static int csi_idmac_get_ipu_resources(struct csi_priv *priv)
 200{
 201        int ch_num, ret;
 202        struct ipu_smfc *smfc;
 203        struct ipuv3_channel *idmac_ch;
 204
 205        ch_num = IPUV3_CHANNEL_CSI0 + priv->smfc_id;
 206
 207        smfc = ipu_smfc_get(priv->ipu, ch_num);
 208        if (IS_ERR(smfc)) {
 209                v4l2_err(&priv->sd, "failed to get SMFC\n");
 210                ret = PTR_ERR(smfc);
 211                goto out;
 212        }
 213        priv->smfc = smfc;
 214
 215        idmac_ch = ipu_idmac_get(priv->ipu, ch_num);
 216        if (IS_ERR(idmac_ch)) {
 217                v4l2_err(&priv->sd, "could not get IDMAC channel %u\n",
 218                         ch_num);
 219                ret = PTR_ERR(idmac_ch);
 220                goto out;
 221        }
 222        priv->idmac_ch = idmac_ch;
 223
 224        return 0;
 225out:
 226        csi_idmac_put_ipu_resources(priv);
 227        return ret;
 228}
 229
 230static void csi_vb2_buf_done(struct csi_priv *priv)
 231{
 232        struct imx_media_video_dev *vdev = priv->vdev;
 233        struct imx_media_buffer *done, *next;
 234        struct vb2_buffer *vb;
 235        dma_addr_t phys;
 236
 237        done = priv->active_vb2_buf[priv->ipu_buf_num];
 238        if (done) {
 239                vb = &done->vbuf.vb2_buf;
 240                vb->timestamp = ktime_get_ns();
 241                vb2_buffer_done(vb, priv->nfb4eof ?
 242                                VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
 243        }
 244
 245        priv->nfb4eof = false;
 246
 247        /* get next queued buffer */
 248        next = imx_media_capture_device_next_buf(vdev);
 249        if (next) {
 250                phys = vb2_dma_contig_plane_dma_addr(&next->vbuf.vb2_buf, 0);
 251                priv->active_vb2_buf[priv->ipu_buf_num] = next;
 252        } else {
 253                phys = priv->underrun_buf.phys;
 254                priv->active_vb2_buf[priv->ipu_buf_num] = NULL;
 255        }
 256
 257        if (ipu_idmac_buffer_is_ready(priv->idmac_ch, priv->ipu_buf_num))
 258                ipu_idmac_clear_buffer(priv->idmac_ch, priv->ipu_buf_num);
 259
 260        ipu_cpmem_set_buffer(priv->idmac_ch, priv->ipu_buf_num, phys);
 261}
 262
 263static irqreturn_t csi_idmac_eof_interrupt(int irq, void *dev_id)
 264{
 265        struct csi_priv *priv = dev_id;
 266
 267        spin_lock(&priv->irqlock);
 268
 269        if (priv->last_eof) {
 270                complete(&priv->last_eof_comp);
 271                priv->last_eof = false;
 272                goto unlock;
 273        }
 274
 275        if (priv->fim)
 276                /* call frame interval monitor */
 277                imx_media_fim_eof_monitor(priv->fim, ktime_get());
 278
 279        csi_vb2_buf_done(priv);
 280
 281        /* select new IPU buf */
 282        ipu_idmac_select_buffer(priv->idmac_ch, priv->ipu_buf_num);
 283        /* toggle IPU double-buffer index */
 284        priv->ipu_buf_num ^= 1;
 285
 286        /* bump the EOF timeout timer */
 287        mod_timer(&priv->eof_timeout_timer,
 288                  jiffies + msecs_to_jiffies(IMX_MEDIA_EOF_TIMEOUT));
 289
 290unlock:
 291        spin_unlock(&priv->irqlock);
 292        return IRQ_HANDLED;
 293}
 294
 295static irqreturn_t csi_idmac_nfb4eof_interrupt(int irq, void *dev_id)
 296{
 297        struct csi_priv *priv = dev_id;
 298
 299        spin_lock(&priv->irqlock);
 300
 301        /*
 302         * this is not an unrecoverable error, just mark
 303         * the next captured frame with vb2 error flag.
 304         */
 305        priv->nfb4eof = true;
 306
 307        v4l2_err(&priv->sd, "NFB4EOF\n");
 308
 309        spin_unlock(&priv->irqlock);
 310
 311        return IRQ_HANDLED;
 312}
 313
 314/*
 315 * EOF timeout timer function. This is an unrecoverable condition
 316 * without a stream restart.
 317 */
 318static void csi_idmac_eof_timeout(struct timer_list *t)
 319{
 320        struct csi_priv *priv = from_timer(priv, t, eof_timeout_timer);
 321        struct imx_media_video_dev *vdev = priv->vdev;
 322
 323        v4l2_err(&priv->sd, "EOF timeout\n");
 324
 325        /* signal a fatal error to capture device */
 326        imx_media_capture_device_error(vdev);
 327}
 328
 329static void csi_idmac_setup_vb2_buf(struct csi_priv *priv, dma_addr_t *phys)
 330{
 331        struct imx_media_video_dev *vdev = priv->vdev;
 332        struct imx_media_buffer *buf;
 333        int i;
 334
 335        for (i = 0; i < 2; i++) {
 336                buf = imx_media_capture_device_next_buf(vdev);
 337                if (buf) {
 338                        priv->active_vb2_buf[i] = buf;
 339                        phys[i] = vb2_dma_contig_plane_dma_addr(
 340                                &buf->vbuf.vb2_buf, 0);
 341                } else {
 342                        priv->active_vb2_buf[i] = NULL;
 343                        phys[i] = priv->underrun_buf.phys;
 344                }
 345        }
 346}
 347
 348static void csi_idmac_unsetup_vb2_buf(struct csi_priv *priv,
 349                                      enum vb2_buffer_state return_status)
 350{
 351        struct imx_media_buffer *buf;
 352        int i;
 353
 354        /* return any remaining active frames with return_status */
 355        for (i = 0; i < 2; i++) {
 356                buf = priv->active_vb2_buf[i];
 357                if (buf) {
 358                        struct vb2_buffer *vb = &buf->vbuf.vb2_buf;
 359
 360                        vb->timestamp = ktime_get_ns();
 361                        vb2_buffer_done(vb, return_status);
 362                }
 363        }
 364}
 365
 366/* init the SMFC IDMAC channel */
 367static int csi_idmac_setup_channel(struct csi_priv *priv)
 368{
 369        struct imx_media_video_dev *vdev = priv->vdev;
 370        struct v4l2_mbus_framefmt *infmt;
 371        struct ipu_image image;
 372        u32 passthrough_bits;
 373        dma_addr_t phys[2];
 374        bool passthrough;
 375        u32 burst_size;
 376        int ret;
 377
 378        infmt = &priv->format_mbus[CSI_SINK_PAD];
 379
 380        ipu_cpmem_zero(priv->idmac_ch);
 381
 382        memset(&image, 0, sizeof(image));
 383        image.pix = vdev->fmt.fmt.pix;
 384        image.rect.width = image.pix.width;
 385        image.rect.height = image.pix.height;
 386
 387        csi_idmac_setup_vb2_buf(priv, phys);
 388
 389        image.phys0 = phys[0];
 390        image.phys1 = phys[1];
 391
 392        /*
 393         * Check for conditions that require the IPU to handle the
 394         * data internally as generic data, aka passthrough mode:
 395         * - raw bayer formats
 396         * - the CSI is receiving from a 16-bit parallel bus
 397         */
 398        switch (image.pix.pixelformat) {
 399        case V4L2_PIX_FMT_SBGGR8:
 400        case V4L2_PIX_FMT_SGBRG8:
 401        case V4L2_PIX_FMT_SGRBG8:
 402        case V4L2_PIX_FMT_SRGGB8:
 403        case V4L2_PIX_FMT_GREY:
 404                burst_size = 16;
 405                passthrough = true;
 406                passthrough_bits = 8;
 407                break;
 408        case V4L2_PIX_FMT_SBGGR16:
 409        case V4L2_PIX_FMT_SGBRG16:
 410        case V4L2_PIX_FMT_SGRBG16:
 411        case V4L2_PIX_FMT_SRGGB16:
 412        case V4L2_PIX_FMT_Y16:
 413                burst_size = 8;
 414                passthrough = true;
 415                passthrough_bits = 16;
 416                break;
 417        case V4L2_PIX_FMT_YUV420:
 418        case V4L2_PIX_FMT_NV12:
 419                burst_size = (image.pix.width & 0x3f) ?
 420                             ((image.pix.width & 0x1f) ?
 421                              ((image.pix.width & 0xf) ? 8 : 16) : 32) : 64;
 422                passthrough = is_parallel_16bit_bus(&priv->upstream_ep);
 423                passthrough_bits = 16;
 424                /* Skip writing U and V components to odd rows */
 425                ipu_cpmem_skip_odd_chroma_rows(priv->idmac_ch);
 426                break;
 427        case V4L2_PIX_FMT_YUYV:
 428        case V4L2_PIX_FMT_UYVY:
 429                burst_size = (image.pix.width & 0x1f) ?
 430                             ((image.pix.width & 0xf) ? 8 : 16) : 32;
 431                passthrough = is_parallel_16bit_bus(&priv->upstream_ep);
 432                passthrough_bits = 16;
 433                break;
 434        default:
 435                burst_size = (image.pix.width & 0xf) ? 8 : 16;
 436                passthrough = is_parallel_16bit_bus(&priv->upstream_ep);
 437                passthrough_bits = 16;
 438                break;
 439        }
 440
 441        if (passthrough) {
 442                ipu_cpmem_set_resolution(priv->idmac_ch, image.rect.width,
 443                                         image.rect.height);
 444                ipu_cpmem_set_stride(priv->idmac_ch, image.pix.bytesperline);
 445                ipu_cpmem_set_buffer(priv->idmac_ch, 0, image.phys0);
 446                ipu_cpmem_set_buffer(priv->idmac_ch, 1, image.phys1);
 447                ipu_cpmem_set_format_passthrough(priv->idmac_ch,
 448                                                 passthrough_bits);
 449        } else {
 450                ret = ipu_cpmem_set_image(priv->idmac_ch, &image);
 451                if (ret)
 452                        goto unsetup_vb2;
 453        }
 454
 455        ipu_cpmem_set_burstsize(priv->idmac_ch, burst_size);
 456
 457        /*
 458         * Set the channel for the direct CSI-->memory via SMFC
 459         * use-case to very high priority, by enabling the watermark
 460         * signal in the SMFC, enabling WM in the channel, and setting
 461         * the channel priority to high.
 462         *
 463         * Refer to the i.mx6 rev. D TRM Table 36-8: Calculated priority
 464         * value.
 465         *
 466         * The WM's are set very low by intention here to ensure that
 467         * the SMFC FIFOs do not overflow.
 468         */
 469        ipu_smfc_set_watermark(priv->smfc, 0x02, 0x01);
 470        ipu_cpmem_set_high_priority(priv->idmac_ch);
 471        ipu_idmac_enable_watermark(priv->idmac_ch, true);
 472        ipu_cpmem_set_axi_id(priv->idmac_ch, 0);
 473
 474        burst_size = passthrough ?
 475                (burst_size >> 3) - 1 : (burst_size >> 2) - 1;
 476
 477        ipu_smfc_set_burstsize(priv->smfc, burst_size);
 478
 479        if (image.pix.field == V4L2_FIELD_NONE &&
 480            V4L2_FIELD_HAS_BOTH(infmt->field))
 481                ipu_cpmem_interlaced_scan(priv->idmac_ch,
 482                                          image.pix.bytesperline);
 483
 484        ipu_idmac_set_double_buffer(priv->idmac_ch, true);
 485
 486        return 0;
 487
 488unsetup_vb2:
 489        csi_idmac_unsetup_vb2_buf(priv, VB2_BUF_STATE_QUEUED);
 490        return ret;
 491}
 492
 493static void csi_idmac_unsetup(struct csi_priv *priv,
 494                              enum vb2_buffer_state state)
 495{
 496        ipu_idmac_disable_channel(priv->idmac_ch);
 497        ipu_smfc_disable(priv->smfc);
 498
 499        csi_idmac_unsetup_vb2_buf(priv, state);
 500}
 501
 502static int csi_idmac_setup(struct csi_priv *priv)
 503{
 504        int ret;
 505
 506        ret = csi_idmac_setup_channel(priv);
 507        if (ret)
 508                return ret;
 509
 510        ipu_cpmem_dump(priv->idmac_ch);
 511        ipu_dump(priv->ipu);
 512
 513        ipu_smfc_enable(priv->smfc);
 514
 515        /* set buffers ready */
 516        ipu_idmac_select_buffer(priv->idmac_ch, 0);
 517        ipu_idmac_select_buffer(priv->idmac_ch, 1);
 518
 519        /* enable the channels */
 520        ipu_idmac_enable_channel(priv->idmac_ch);
 521
 522        return 0;
 523}
 524
 525static int csi_idmac_start(struct csi_priv *priv)
 526{
 527        struct imx_media_video_dev *vdev = priv->vdev;
 528        struct v4l2_pix_format *outfmt;
 529        int ret;
 530
 531        ret = csi_idmac_get_ipu_resources(priv);
 532        if (ret)
 533                return ret;
 534
 535        ipu_smfc_map_channel(priv->smfc, priv->csi_id, priv->vc_num);
 536
 537        outfmt = &vdev->fmt.fmt.pix;
 538
 539        ret = imx_media_alloc_dma_buf(priv->md, &priv->underrun_buf,
 540                                      outfmt->sizeimage);
 541        if (ret)
 542                goto out_put_ipu;
 543
 544        priv->ipu_buf_num = 0;
 545
 546        /* init EOF completion waitq */
 547        init_completion(&priv->last_eof_comp);
 548        priv->last_eof = false;
 549        priv->nfb4eof = false;
 550
 551        ret = csi_idmac_setup(priv);
 552        if (ret) {
 553                v4l2_err(&priv->sd, "csi_idmac_setup failed: %d\n", ret);
 554                goto out_free_dma_buf;
 555        }
 556
 557        priv->nfb4eof_irq = ipu_idmac_channel_irq(priv->ipu,
 558                                                 priv->idmac_ch,
 559                                                 IPU_IRQ_NFB4EOF);
 560        ret = devm_request_irq(priv->dev, priv->nfb4eof_irq,
 561                               csi_idmac_nfb4eof_interrupt, 0,
 562                               "imx-smfc-nfb4eof", priv);
 563        if (ret) {
 564                v4l2_err(&priv->sd,
 565                         "Error registering NFB4EOF irq: %d\n", ret);
 566                goto out_unsetup;
 567        }
 568
 569        priv->eof_irq = ipu_idmac_channel_irq(priv->ipu, priv->idmac_ch,
 570                                              IPU_IRQ_EOF);
 571
 572        ret = devm_request_irq(priv->dev, priv->eof_irq,
 573                               csi_idmac_eof_interrupt, 0,
 574                               "imx-smfc-eof", priv);
 575        if (ret) {
 576                v4l2_err(&priv->sd,
 577                         "Error registering eof irq: %d\n", ret);
 578                goto out_free_nfb4eof_irq;
 579        }
 580
 581        /* start the EOF timeout timer */
 582        mod_timer(&priv->eof_timeout_timer,
 583                  jiffies + msecs_to_jiffies(IMX_MEDIA_EOF_TIMEOUT));
 584
 585        return 0;
 586
 587out_free_nfb4eof_irq:
 588        devm_free_irq(priv->dev, priv->nfb4eof_irq, priv);
 589out_unsetup:
 590        csi_idmac_unsetup(priv, VB2_BUF_STATE_QUEUED);
 591out_free_dma_buf:
 592        imx_media_free_dma_buf(priv->md, &priv->underrun_buf);
 593out_put_ipu:
 594        csi_idmac_put_ipu_resources(priv);
 595        return ret;
 596}
 597
 598static void csi_idmac_stop(struct csi_priv *priv)
 599{
 600        unsigned long flags;
 601        int ret;
 602
 603        /* mark next EOF interrupt as the last before stream off */
 604        spin_lock_irqsave(&priv->irqlock, flags);
 605        priv->last_eof = true;
 606        spin_unlock_irqrestore(&priv->irqlock, flags);
 607
 608        /*
 609         * and then wait for interrupt handler to mark completion.
 610         */
 611        ret = wait_for_completion_timeout(
 612                &priv->last_eof_comp, msecs_to_jiffies(IMX_MEDIA_EOF_TIMEOUT));
 613        if (ret == 0)
 614                v4l2_warn(&priv->sd, "wait last EOF timeout\n");
 615
 616        devm_free_irq(priv->dev, priv->eof_irq, priv);
 617        devm_free_irq(priv->dev, priv->nfb4eof_irq, priv);
 618
 619        csi_idmac_unsetup(priv, VB2_BUF_STATE_ERROR);
 620
 621        imx_media_free_dma_buf(priv->md, &priv->underrun_buf);
 622
 623        /* cancel the EOF timeout timer */
 624        del_timer_sync(&priv->eof_timeout_timer);
 625
 626        csi_idmac_put_ipu_resources(priv);
 627}
 628
 629/* Update the CSI whole sensor and active windows */
 630static int csi_setup(struct csi_priv *priv)
 631{
 632        struct v4l2_mbus_framefmt *infmt, *outfmt;
 633        struct v4l2_mbus_config mbus_cfg;
 634        struct v4l2_mbus_framefmt if_fmt;
 635
 636        infmt = &priv->format_mbus[CSI_SINK_PAD];
 637        outfmt = &priv->format_mbus[priv->active_output_pad];
 638
 639        /* compose mbus_config from the upstream endpoint */
 640        mbus_cfg.type = priv->upstream_ep.bus_type;
 641        mbus_cfg.flags = (priv->upstream_ep.bus_type == V4L2_MBUS_CSI2) ?
 642                priv->upstream_ep.bus.mipi_csi2.flags :
 643                priv->upstream_ep.bus.parallel.flags;
 644
 645        /*
 646         * we need to pass input frame to CSI interface, but
 647         * with translated field type from output format
 648         */
 649        if_fmt = *infmt;
 650        if_fmt.field = outfmt->field;
 651
 652        ipu_csi_set_window(priv->csi, &priv->crop);
 653
 654        ipu_csi_set_downsize(priv->csi,
 655                             priv->crop.width == 2 * priv->compose.width,
 656                             priv->crop.height == 2 * priv->compose.height);
 657
 658        ipu_csi_init_interface(priv->csi, &mbus_cfg, &if_fmt);
 659
 660        ipu_csi_set_dest(priv->csi, priv->dest);
 661
 662        if (priv->dest == IPU_CSI_DEST_IDMAC)
 663                ipu_csi_set_skip_smfc(priv->csi, priv->skip->skip_smfc,
 664                                      priv->skip->max_ratio - 1, 0);
 665
 666        ipu_csi_dump(priv->csi);
 667
 668        return 0;
 669}
 670
 671static int csi_start(struct csi_priv *priv)
 672{
 673        struct v4l2_fract *output_fi;
 674        int ret;
 675
 676        output_fi = &priv->frame_interval[priv->active_output_pad];
 677
 678        if (priv->dest == IPU_CSI_DEST_IDMAC) {
 679                ret = csi_idmac_start(priv);
 680                if (ret)
 681                        return ret;
 682        }
 683
 684        ret = csi_setup(priv);
 685        if (ret)
 686                goto idmac_stop;
 687
 688        /* start the frame interval monitor */
 689        if (priv->fim && priv->dest == IPU_CSI_DEST_IDMAC) {
 690                ret = imx_media_fim_set_stream(priv->fim, output_fi, true);
 691                if (ret)
 692                        goto idmac_stop;
 693        }
 694
 695        ret = ipu_csi_enable(priv->csi);
 696        if (ret) {
 697                v4l2_err(&priv->sd, "CSI enable error: %d\n", ret);
 698                goto fim_off;
 699        }
 700
 701        return 0;
 702
 703fim_off:
 704        if (priv->fim && priv->dest == IPU_CSI_DEST_IDMAC)
 705                imx_media_fim_set_stream(priv->fim, NULL, false);
 706idmac_stop:
 707        if (priv->dest == IPU_CSI_DEST_IDMAC)
 708                csi_idmac_stop(priv);
 709        return ret;
 710}
 711
 712static void csi_stop(struct csi_priv *priv)
 713{
 714        if (priv->dest == IPU_CSI_DEST_IDMAC) {
 715                csi_idmac_stop(priv);
 716
 717                /* stop the frame interval monitor */
 718                if (priv->fim)
 719                        imx_media_fim_set_stream(priv->fim, NULL, false);
 720        }
 721
 722        ipu_csi_disable(priv->csi);
 723}
 724
 725static const struct csi_skip_desc csi_skip[12] = {
 726        { 1, 1, 0x00 }, /* Keep all frames */
 727        { 5, 6, 0x10 }, /* Skip every sixth frame */
 728        { 4, 5, 0x08 }, /* Skip every fifth frame */
 729        { 3, 4, 0x04 }, /* Skip every fourth frame */
 730        { 2, 3, 0x02 }, /* Skip every third frame */
 731        { 3, 5, 0x0a }, /* Skip frames 1 and 3 of every 5 */
 732        { 1, 2, 0x01 }, /* Skip every second frame */
 733        { 2, 5, 0x0b }, /* Keep frames 1 and 4 of every 5 */
 734        { 1, 3, 0x03 }, /* Keep one in three frames */
 735        { 1, 4, 0x07 }, /* Keep one in four frames */
 736        { 1, 5, 0x0f }, /* Keep one in five frames */
 737        { 1, 6, 0x1f }, /* Keep one in six frames */
 738};
 739
 740static void csi_apply_skip_interval(const struct csi_skip_desc *skip,
 741                                    struct v4l2_fract *interval)
 742{
 743        unsigned int div;
 744
 745        interval->numerator *= skip->max_ratio;
 746        interval->denominator *= skip->keep;
 747
 748        /* Reduce fraction to lowest terms */
 749        div = gcd(interval->numerator, interval->denominator);
 750        if (div > 1) {
 751                interval->numerator /= div;
 752                interval->denominator /= div;
 753        }
 754}
 755
 756/*
 757 * Find the skip pattern to produce the output frame interval closest to the
 758 * requested one, for the given input frame interval. Updates the output frame
 759 * interval to the exact value.
 760 */
 761static const struct csi_skip_desc *csi_find_best_skip(struct v4l2_fract *in,
 762                                                      struct v4l2_fract *out)
 763{
 764        const struct csi_skip_desc *skip = &csi_skip[0], *best_skip = skip;
 765        u32 min_err = UINT_MAX;
 766        u64 want_us;
 767        int i;
 768
 769        /* Default to 1:1 ratio */
 770        if (out->numerator == 0 || out->denominator == 0 ||
 771            in->numerator == 0 || in->denominator == 0) {
 772                *out = *in;
 773                return best_skip;
 774        }
 775
 776        want_us = div_u64((u64)USEC_PER_SEC * out->numerator, out->denominator);
 777
 778        /* Find the reduction closest to the requested time per frame */
 779        for (i = 0; i < ARRAY_SIZE(csi_skip); i++, skip++) {
 780                u64 tmp, err;
 781
 782                tmp = div_u64((u64)USEC_PER_SEC * in->numerator *
 783                              skip->max_ratio, in->denominator * skip->keep);
 784
 785                err = abs((s64)tmp - want_us);
 786                if (err < min_err) {
 787                        min_err = err;
 788                        best_skip = skip;
 789                }
 790        }
 791
 792        *out = *in;
 793        csi_apply_skip_interval(best_skip, out);
 794
 795        return best_skip;
 796}
 797
 798/*
 799 * V4L2 subdev operations.
 800 */
 801
 802static int csi_g_frame_interval(struct v4l2_subdev *sd,
 803                                struct v4l2_subdev_frame_interval *fi)
 804{
 805        struct csi_priv *priv = v4l2_get_subdevdata(sd);
 806
 807        if (fi->pad >= CSI_NUM_PADS)
 808                return -EINVAL;
 809
 810        mutex_lock(&priv->lock);
 811
 812        fi->interval = priv->frame_interval[fi->pad];
 813
 814        mutex_unlock(&priv->lock);
 815
 816        return 0;
 817}
 818
 819static int csi_s_frame_interval(struct v4l2_subdev *sd,
 820                                struct v4l2_subdev_frame_interval *fi)
 821{
 822        struct csi_priv *priv = v4l2_get_subdevdata(sd);
 823        struct v4l2_fract *input_fi;
 824        int ret = 0;
 825
 826        mutex_lock(&priv->lock);
 827
 828        input_fi = &priv->frame_interval[CSI_SINK_PAD];
 829
 830        switch (fi->pad) {
 831        case CSI_SINK_PAD:
 832                /* No limits on input frame interval */
 833                /* Reset output intervals and frame skipping ratio to 1:1 */
 834                priv->frame_interval[CSI_SRC_PAD_IDMAC] = fi->interval;
 835                priv->frame_interval[CSI_SRC_PAD_DIRECT] = fi->interval;
 836                priv->skip = &csi_skip[0];
 837                break;
 838        case CSI_SRC_PAD_IDMAC:
 839                /*
 840                 * frame interval at IDMAC output pad depends on input
 841                 * interval, modified by frame skipping.
 842                 */
 843                priv->skip = csi_find_best_skip(input_fi, &fi->interval);
 844                break;
 845        case CSI_SRC_PAD_DIRECT:
 846                /*
 847                 * frame interval at DIRECT output pad is same as input
 848                 * interval.
 849                 */
 850                fi->interval = *input_fi;
 851                break;
 852        default:
 853                ret = -EINVAL;
 854                goto out;
 855        }
 856
 857        priv->frame_interval[fi->pad] = fi->interval;
 858out:
 859        mutex_unlock(&priv->lock);
 860        return ret;
 861}
 862
 863static int csi_s_stream(struct v4l2_subdev *sd, int enable)
 864{
 865        struct csi_priv *priv = v4l2_get_subdevdata(sd);
 866        int ret = 0;
 867
 868        mutex_lock(&priv->lock);
 869
 870        if (!priv->src_sd || !priv->sink) {
 871                ret = -EPIPE;
 872                goto out;
 873        }
 874
 875        /*
 876         * enable/disable streaming only if stream_count is
 877         * going from 0 to 1 / 1 to 0.
 878         */
 879        if (priv->stream_count != !enable)
 880                goto update_count;
 881
 882        if (enable) {
 883                /* upstream must be started first, before starting CSI */
 884                ret = v4l2_subdev_call(priv->src_sd, video, s_stream, 1);
 885                ret = (ret && ret != -ENOIOCTLCMD) ? ret : 0;
 886                if (ret)
 887                        goto out;
 888
 889                dev_dbg(priv->dev, "stream ON\n");
 890                ret = csi_start(priv);
 891                if (ret) {
 892                        v4l2_subdev_call(priv->src_sd, video, s_stream, 0);
 893                        goto out;
 894                }
 895        } else {
 896                dev_dbg(priv->dev, "stream OFF\n");
 897                /* CSI must be stopped first, then stop upstream */
 898                csi_stop(priv);
 899                v4l2_subdev_call(priv->src_sd, video, s_stream, 0);
 900        }
 901
 902update_count:
 903        priv->stream_count += enable ? 1 : -1;
 904        if (priv->stream_count < 0)
 905                priv->stream_count = 0;
 906out:
 907        mutex_unlock(&priv->lock);
 908        return ret;
 909}
 910
 911static int csi_link_setup(struct media_entity *entity,
 912                          const struct media_pad *local,
 913                          const struct media_pad *remote, u32 flags)
 914{
 915        struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
 916        struct csi_priv *priv = v4l2_get_subdevdata(sd);
 917        struct v4l2_subdev *remote_sd;
 918        int ret = 0;
 919
 920        dev_dbg(priv->dev, "link setup %s -> %s\n", remote->entity->name,
 921                local->entity->name);
 922
 923        mutex_lock(&priv->lock);
 924
 925        if (local->flags & MEDIA_PAD_FL_SINK) {
 926                if (!is_media_entity_v4l2_subdev(remote->entity)) {
 927                        ret = -EINVAL;
 928                        goto out;
 929                }
 930
 931                remote_sd = media_entity_to_v4l2_subdev(remote->entity);
 932
 933                if (flags & MEDIA_LNK_FL_ENABLED) {
 934                        if (priv->src_sd) {
 935                                ret = -EBUSY;
 936                                goto out;
 937                        }
 938                        priv->src_sd = remote_sd;
 939                } else {
 940                        priv->src_sd = NULL;
 941                }
 942
 943                goto out;
 944        }
 945
 946        /* this is a source pad */
 947
 948        if (flags & MEDIA_LNK_FL_ENABLED) {
 949                if (priv->sink) {
 950                        ret = -EBUSY;
 951                        goto out;
 952                }
 953        } else {
 954                v4l2_ctrl_handler_free(&priv->ctrl_hdlr);
 955                v4l2_ctrl_handler_init(&priv->ctrl_hdlr, 0);
 956                priv->sink = NULL;
 957                goto out;
 958        }
 959
 960        /* record which output pad is now active */
 961        priv->active_output_pad = local->index;
 962
 963        /* set CSI destination */
 964        if (local->index == CSI_SRC_PAD_IDMAC) {
 965                if (!is_media_entity_v4l2_video_device(remote->entity)) {
 966                        ret = -EINVAL;
 967                        goto out;
 968                }
 969
 970                if (priv->fim) {
 971                        ret = imx_media_fim_add_controls(priv->fim);
 972                        if (ret)
 973                                goto out;
 974                }
 975
 976                priv->dest = IPU_CSI_DEST_IDMAC;
 977        } else {
 978                if (!is_media_entity_v4l2_subdev(remote->entity)) {
 979                        ret = -EINVAL;
 980                        goto out;
 981                }
 982
 983                remote_sd = media_entity_to_v4l2_subdev(remote->entity);
 984                switch (remote_sd->grp_id) {
 985                case IMX_MEDIA_GRP_ID_VDIC:
 986                        priv->dest = IPU_CSI_DEST_VDIC;
 987                        break;
 988                case IMX_MEDIA_GRP_ID_IC_PRP:
 989                        priv->dest = IPU_CSI_DEST_IC;
 990                        break;
 991                default:
 992                        ret = -EINVAL;
 993                        goto out;
 994                }
 995        }
 996
 997        priv->sink = remote->entity;
 998out:
 999        mutex_unlock(&priv->lock);
1000        return ret;
1001}
1002
1003static int csi_link_validate(struct v4l2_subdev *sd,
1004                             struct media_link *link,
1005                             struct v4l2_subdev_format *source_fmt,
1006                             struct v4l2_subdev_format *sink_fmt)
1007{
1008        struct csi_priv *priv = v4l2_get_subdevdata(sd);
1009        struct v4l2_fwnode_endpoint upstream_ep = {};
1010        const struct imx_media_pixfmt *incc;
1011        bool is_csi2;
1012        int ret;
1013
1014        ret = v4l2_subdev_link_validate_default(sd, link,
1015                                                source_fmt, sink_fmt);
1016        if (ret)
1017                return ret;
1018
1019        ret = csi_get_upstream_endpoint(priv, &upstream_ep);
1020        if (ret) {
1021                v4l2_err(&priv->sd, "failed to find upstream endpoint\n");
1022                return ret;
1023        }
1024
1025        mutex_lock(&priv->lock);
1026
1027        priv->upstream_ep = upstream_ep;
1028        is_csi2 = (upstream_ep.bus_type == V4L2_MBUS_CSI2);
1029        incc = priv->cc[CSI_SINK_PAD];
1030
1031        if (priv->dest != IPU_CSI_DEST_IDMAC &&
1032            (incc->bayer || is_parallel_16bit_bus(&upstream_ep))) {
1033                v4l2_err(&priv->sd,
1034                         "bayer/16-bit parallel buses must go to IDMAC pad\n");
1035                ret = -EINVAL;
1036                goto out;
1037        }
1038
1039        if (is_csi2) {
1040                int vc_num = 0;
1041                /*
1042                 * NOTE! It seems the virtual channels from the mipi csi-2
1043                 * receiver are used only for routing by the video mux's,
1044                 * or for hard-wired routing to the CSI's. Once the stream
1045                 * enters the CSI's however, they are treated internally
1046                 * in the IPU as virtual channel 0.
1047                 */
1048#if 0
1049                mutex_unlock(&priv->lock);
1050                vc_num = imx_media_find_mipi_csi2_channel(priv->md,
1051                                                          &priv->sd.entity);
1052                if (vc_num < 0)
1053                        return vc_num;
1054                mutex_lock(&priv->lock);
1055#endif
1056                ipu_csi_set_mipi_datatype(priv->csi, vc_num,
1057                                          &priv->format_mbus[CSI_SINK_PAD]);
1058        }
1059
1060        /* select either parallel or MIPI-CSI2 as input to CSI */
1061        ipu_set_csi_src_mux(priv->ipu, priv->csi_id, is_csi2);
1062out:
1063        mutex_unlock(&priv->lock);
1064        return ret;
1065}
1066
1067static struct v4l2_mbus_framefmt *
1068__csi_get_fmt(struct csi_priv *priv, struct v4l2_subdev_pad_config *cfg,
1069              unsigned int pad, enum v4l2_subdev_format_whence which)
1070{
1071        if (which == V4L2_SUBDEV_FORMAT_TRY)
1072                return v4l2_subdev_get_try_format(&priv->sd, cfg, pad);
1073        else
1074                return &priv->format_mbus[pad];
1075}
1076
1077static struct v4l2_rect *
1078__csi_get_crop(struct csi_priv *priv, struct v4l2_subdev_pad_config *cfg,
1079               enum v4l2_subdev_format_whence which)
1080{
1081        if (which == V4L2_SUBDEV_FORMAT_TRY)
1082                return v4l2_subdev_get_try_crop(&priv->sd, cfg, CSI_SINK_PAD);
1083        else
1084                return &priv->crop;
1085}
1086
1087static struct v4l2_rect *
1088__csi_get_compose(struct csi_priv *priv, struct v4l2_subdev_pad_config *cfg,
1089                  enum v4l2_subdev_format_whence which)
1090{
1091        if (which == V4L2_SUBDEV_FORMAT_TRY)
1092                return v4l2_subdev_get_try_compose(&priv->sd, cfg,
1093                                                   CSI_SINK_PAD);
1094        else
1095                return &priv->compose;
1096}
1097
1098static void csi_try_crop(struct csi_priv *priv,
1099                         struct v4l2_rect *crop,
1100                         struct v4l2_subdev_pad_config *cfg,
1101                         struct v4l2_mbus_framefmt *infmt,
1102                         struct v4l2_fwnode_endpoint *upstream_ep)
1103{
1104        crop->width = min_t(__u32, infmt->width, crop->width);
1105        if (crop->left + crop->width > infmt->width)
1106                crop->left = infmt->width - crop->width;
1107        /* adjust crop left/width to h/w alignment restrictions */
1108        crop->left &= ~0x3;
1109        crop->width &= ~0x7;
1110
1111        /*
1112         * FIXME: not sure why yet, but on interlaced bt.656,
1113         * changing the vertical cropping causes loss of vertical
1114         * sync, so fix it to NTSC/PAL active lines. NTSC contains
1115         * 2 extra lines of active video that need to be cropped.
1116         */
1117        if (upstream_ep->bus_type == V4L2_MBUS_BT656 &&
1118            (V4L2_FIELD_HAS_BOTH(infmt->field) ||
1119             infmt->field == V4L2_FIELD_ALTERNATE)) {
1120                crop->height = infmt->height;
1121                crop->top = (infmt->height == 480) ? 2 : 0;
1122        } else {
1123                crop->height = min_t(__u32, infmt->height, crop->height);
1124                if (crop->top + crop->height > infmt->height)
1125                        crop->top = infmt->height - crop->height;
1126        }
1127}
1128
1129static int csi_enum_mbus_code(struct v4l2_subdev *sd,
1130                              struct v4l2_subdev_pad_config *cfg,
1131                              struct v4l2_subdev_mbus_code_enum *code)
1132{
1133        struct csi_priv *priv = v4l2_get_subdevdata(sd);
1134        const struct imx_media_pixfmt *incc;
1135        struct v4l2_mbus_framefmt *infmt;
1136        int ret = 0;
1137
1138        mutex_lock(&priv->lock);
1139
1140        infmt = __csi_get_fmt(priv, cfg, CSI_SINK_PAD, code->which);
1141        incc = imx_media_find_mbus_format(infmt->code, CS_SEL_ANY, true);
1142
1143        switch (code->pad) {
1144        case CSI_SINK_PAD:
1145                ret = imx_media_enum_mbus_format(&code->code, code->index,
1146                                                 CS_SEL_ANY, true);
1147                break;
1148        case CSI_SRC_PAD_DIRECT:
1149        case CSI_SRC_PAD_IDMAC:
1150                if (incc->bayer) {
1151                        if (code->index != 0) {
1152                                ret = -EINVAL;
1153                                goto out;
1154                        }
1155                        code->code = infmt->code;
1156                } else {
1157                        u32 cs_sel = (incc->cs == IPUV3_COLORSPACE_YUV) ?
1158                                CS_SEL_YUV : CS_SEL_RGB;
1159                        ret = imx_media_enum_ipu_format(&code->code,
1160                                                        code->index,
1161                                                        cs_sel);
1162                }
1163                break;
1164        default:
1165                ret = -EINVAL;
1166        }
1167
1168out:
1169        mutex_unlock(&priv->lock);
1170        return ret;
1171}
1172
1173static int csi_enum_frame_size(struct v4l2_subdev *sd,
1174                               struct v4l2_subdev_pad_config *cfg,
1175                               struct v4l2_subdev_frame_size_enum *fse)
1176{
1177        struct csi_priv *priv = v4l2_get_subdevdata(sd);
1178        struct v4l2_rect *crop;
1179        int ret = 0;
1180
1181        if (fse->pad >= CSI_NUM_PADS ||
1182            fse->index > (fse->pad == CSI_SINK_PAD ? 0 : 3))
1183                return -EINVAL;
1184
1185        mutex_lock(&priv->lock);
1186
1187        if (fse->pad == CSI_SINK_PAD) {
1188                fse->min_width = MIN_W;
1189                fse->max_width = MAX_W;
1190                fse->min_height = MIN_H;
1191                fse->max_height = MAX_H;
1192        } else {
1193                crop = __csi_get_crop(priv, cfg, fse->which);
1194
1195                fse->min_width = fse->max_width = fse->index & 1 ?
1196                        crop->width / 2 : crop->width;
1197                fse->min_height = fse->max_height = fse->index & 2 ?
1198                        crop->height / 2 : crop->height;
1199        }
1200
1201        mutex_unlock(&priv->lock);
1202        return ret;
1203}
1204
1205static int csi_enum_frame_interval(struct v4l2_subdev *sd,
1206                                   struct v4l2_subdev_pad_config *cfg,
1207                                   struct v4l2_subdev_frame_interval_enum *fie)
1208{
1209        struct csi_priv *priv = v4l2_get_subdevdata(sd);
1210        struct v4l2_fract *input_fi;
1211        struct v4l2_rect *crop;
1212        int ret = 0;
1213
1214        if (fie->pad >= CSI_NUM_PADS ||
1215            fie->index >= (fie->pad != CSI_SRC_PAD_IDMAC ?
1216                           1 : ARRAY_SIZE(csi_skip)))
1217                return -EINVAL;
1218
1219        mutex_lock(&priv->lock);
1220
1221        input_fi = &priv->frame_interval[CSI_SINK_PAD];
1222        crop = __csi_get_crop(priv, cfg, fie->which);
1223
1224        if ((fie->width != crop->width && fie->width != crop->width / 2) ||
1225            (fie->height != crop->height && fie->height != crop->height / 2)) {
1226                ret = -EINVAL;
1227                goto out;
1228        }
1229
1230        fie->interval = *input_fi;
1231
1232        if (fie->pad == CSI_SRC_PAD_IDMAC)
1233                csi_apply_skip_interval(&csi_skip[fie->index],
1234                                        &fie->interval);
1235
1236out:
1237        mutex_unlock(&priv->lock);
1238        return ret;
1239}
1240
1241static int csi_get_fmt(struct v4l2_subdev *sd,
1242                       struct v4l2_subdev_pad_config *cfg,
1243                       struct v4l2_subdev_format *sdformat)
1244{
1245        struct csi_priv *priv = v4l2_get_subdevdata(sd);
1246        struct v4l2_mbus_framefmt *fmt;
1247        int ret = 0;
1248
1249        if (sdformat->pad >= CSI_NUM_PADS)
1250                return -EINVAL;
1251
1252        mutex_lock(&priv->lock);
1253
1254        fmt = __csi_get_fmt(priv, cfg, sdformat->pad, sdformat->which);
1255        if (!fmt) {
1256                ret = -EINVAL;
1257                goto out;
1258        }
1259
1260        sdformat->format = *fmt;
1261out:
1262        mutex_unlock(&priv->lock);
1263        return ret;
1264}
1265
1266static void csi_try_fmt(struct csi_priv *priv,
1267                        struct v4l2_fwnode_endpoint *upstream_ep,
1268                        struct v4l2_subdev_pad_config *cfg,
1269                        struct v4l2_subdev_format *sdformat,
1270                        struct v4l2_rect *crop,
1271                        struct v4l2_rect *compose,
1272                        const struct imx_media_pixfmt **cc)
1273{
1274        const struct imx_media_pixfmt *incc;
1275        struct v4l2_mbus_framefmt *infmt;
1276        u32 code;
1277
1278        infmt = __csi_get_fmt(priv, cfg, CSI_SINK_PAD, sdformat->which);
1279
1280        switch (sdformat->pad) {
1281        case CSI_SRC_PAD_DIRECT:
1282        case CSI_SRC_PAD_IDMAC:
1283                incc = imx_media_find_mbus_format(infmt->code,
1284                                                  CS_SEL_ANY, true);
1285
1286                sdformat->format.width = compose->width;
1287                sdformat->format.height = compose->height;
1288
1289                if (incc->bayer) {
1290                        sdformat->format.code = infmt->code;
1291                        *cc = incc;
1292                } else {
1293                        u32 cs_sel = (incc->cs == IPUV3_COLORSPACE_YUV) ?
1294                                CS_SEL_YUV : CS_SEL_RGB;
1295
1296                        *cc = imx_media_find_ipu_format(sdformat->format.code,
1297                                                        cs_sel);
1298                        if (!*cc) {
1299                                imx_media_enum_ipu_format(&code, 0, cs_sel);
1300                                *cc = imx_media_find_ipu_format(code, cs_sel);
1301                                sdformat->format.code = (*cc)->codes[0];
1302                        }
1303                }
1304
1305                if (sdformat->pad == CSI_SRC_PAD_DIRECT ||
1306                    sdformat->format.field != V4L2_FIELD_NONE)
1307                        sdformat->format.field = infmt->field;
1308
1309                /*
1310                 * translate V4L2_FIELD_ALTERNATE to SEQ_TB or SEQ_BT
1311                 * depending on input height (assume NTSC top-bottom
1312                 * order if 480 lines, otherwise PAL bottom-top order).
1313                 */
1314                if (sdformat->format.field == V4L2_FIELD_ALTERNATE) {
1315                        sdformat->format.field =  (infmt->height == 480) ?
1316                                V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT;
1317                }
1318
1319                /* propagate colorimetry from sink */
1320                sdformat->format.colorspace = infmt->colorspace;
1321                sdformat->format.xfer_func = infmt->xfer_func;
1322                sdformat->format.quantization = infmt->quantization;
1323                sdformat->format.ycbcr_enc = infmt->ycbcr_enc;
1324                break;
1325        case CSI_SINK_PAD:
1326                v4l_bound_align_image(&sdformat->format.width, MIN_W, MAX_W,
1327                                      W_ALIGN, &sdformat->format.height,
1328                                      MIN_H, MAX_H, H_ALIGN, S_ALIGN);
1329
1330                /* Reset crop and compose rectangles */
1331                crop->left = 0;
1332                crop->top = 0;
1333                crop->width = sdformat->format.width;
1334                crop->height = sdformat->format.height;
1335                csi_try_crop(priv, crop, cfg, &sdformat->format, upstream_ep);
1336                compose->left = 0;
1337                compose->top = 0;
1338                compose->width = crop->width;
1339                compose->height = crop->height;
1340
1341                *cc = imx_media_find_mbus_format(sdformat->format.code,
1342                                                 CS_SEL_ANY, true);
1343                if (!*cc) {
1344                        imx_media_enum_mbus_format(&code, 0,
1345                                                   CS_SEL_ANY, false);
1346                        *cc = imx_media_find_mbus_format(code,
1347                                                        CS_SEL_ANY, false);
1348                        sdformat->format.code = (*cc)->codes[0];
1349                }
1350
1351                imx_media_fill_default_mbus_fields(
1352                        &sdformat->format, infmt,
1353                        priv->active_output_pad == CSI_SRC_PAD_DIRECT);
1354                break;
1355        }
1356}
1357
1358static int csi_set_fmt(struct v4l2_subdev *sd,
1359                       struct v4l2_subdev_pad_config *cfg,
1360                       struct v4l2_subdev_format *sdformat)
1361{
1362        struct csi_priv *priv = v4l2_get_subdevdata(sd);
1363        struct imx_media_video_dev *vdev = priv->vdev;
1364        struct v4l2_fwnode_endpoint upstream_ep;
1365        const struct imx_media_pixfmt *cc;
1366        struct v4l2_pix_format vdev_fmt;
1367        struct v4l2_mbus_framefmt *fmt;
1368        struct v4l2_rect *crop, *compose;
1369        int ret;
1370
1371        if (sdformat->pad >= CSI_NUM_PADS)
1372                return -EINVAL;
1373
1374        ret = csi_get_upstream_endpoint(priv, &upstream_ep);
1375        if (ret) {
1376                v4l2_err(&priv->sd, "failed to find upstream endpoint\n");
1377                return ret;
1378        }
1379
1380        mutex_lock(&priv->lock);
1381
1382        if (priv->stream_count > 0) {
1383                ret = -EBUSY;
1384                goto out;
1385        }
1386
1387        crop = __csi_get_crop(priv, cfg, sdformat->which);
1388        compose = __csi_get_compose(priv, cfg, sdformat->which);
1389
1390        csi_try_fmt(priv, &upstream_ep, cfg, sdformat, crop, compose, &cc);
1391
1392        fmt = __csi_get_fmt(priv, cfg, sdformat->pad, sdformat->which);
1393        *fmt = sdformat->format;
1394
1395        if (sdformat->pad == CSI_SINK_PAD) {
1396                int pad;
1397
1398                /* propagate format to source pads */
1399                for (pad = CSI_SINK_PAD + 1; pad < CSI_NUM_PADS; pad++) {
1400                        const struct imx_media_pixfmt *outcc;
1401                        struct v4l2_mbus_framefmt *outfmt;
1402                        struct v4l2_subdev_format format;
1403
1404                        format.pad = pad;
1405                        format.which = sdformat->which;
1406                        format.format = sdformat->format;
1407                        csi_try_fmt(priv, &upstream_ep, cfg, &format,
1408                                    NULL, compose, &outcc);
1409
1410                        outfmt = __csi_get_fmt(priv, cfg, pad, sdformat->which);
1411                        *outfmt = format.format;
1412
1413                        if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE)
1414                                priv->cc[pad] = outcc;
1415                }
1416        }
1417
1418        if (sdformat->which == V4L2_SUBDEV_FORMAT_TRY)
1419                goto out;
1420
1421        priv->cc[sdformat->pad] = cc;
1422
1423        /* propagate IDMAC output pad format to capture device */
1424        imx_media_mbus_fmt_to_pix_fmt(&vdev_fmt,
1425                                      &priv->format_mbus[CSI_SRC_PAD_IDMAC],
1426                                      priv->cc[CSI_SRC_PAD_IDMAC]);
1427        mutex_unlock(&priv->lock);
1428        imx_media_capture_device_set_format(vdev, &vdev_fmt);
1429
1430        return 0;
1431out:
1432        mutex_unlock(&priv->lock);
1433        return ret;
1434}
1435
1436static int csi_get_selection(struct v4l2_subdev *sd,
1437                             struct v4l2_subdev_pad_config *cfg,
1438                             struct v4l2_subdev_selection *sel)
1439{
1440        struct csi_priv *priv = v4l2_get_subdevdata(sd);
1441        struct v4l2_mbus_framefmt *infmt;
1442        struct v4l2_rect *crop, *compose;
1443        int ret = 0;
1444
1445        if (sel->pad != CSI_SINK_PAD)
1446                return -EINVAL;
1447
1448        mutex_lock(&priv->lock);
1449
1450        infmt = __csi_get_fmt(priv, cfg, CSI_SINK_PAD, sel->which);
1451        crop = __csi_get_crop(priv, cfg, sel->which);
1452        compose = __csi_get_compose(priv, cfg, sel->which);
1453
1454        switch (sel->target) {
1455        case V4L2_SEL_TGT_CROP_BOUNDS:
1456                sel->r.left = 0;
1457                sel->r.top = 0;
1458                sel->r.width = infmt->width;
1459                sel->r.height = infmt->height;
1460                break;
1461        case V4L2_SEL_TGT_CROP:
1462                sel->r = *crop;
1463                break;
1464        case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1465                sel->r.left = 0;
1466                sel->r.top = 0;
1467                sel->r.width = crop->width;
1468                sel->r.height = crop->height;
1469                break;
1470        case V4L2_SEL_TGT_COMPOSE:
1471                sel->r = *compose;
1472                break;
1473        default:
1474                ret = -EINVAL;
1475        }
1476
1477        mutex_unlock(&priv->lock);
1478        return ret;
1479}
1480
1481static int csi_set_scale(u32 *compose, u32 crop, u32 flags)
1482{
1483        if ((flags & (V4L2_SEL_FLAG_LE | V4L2_SEL_FLAG_GE)) ==
1484                     (V4L2_SEL_FLAG_LE | V4L2_SEL_FLAG_GE) &&
1485            *compose != crop && *compose != crop / 2)
1486                return -ERANGE;
1487
1488        if (*compose <= crop / 2 ||
1489            (*compose < crop * 3 / 4 && !(flags & V4L2_SEL_FLAG_GE)) ||
1490            (*compose < crop && (flags & V4L2_SEL_FLAG_LE)))
1491                *compose = crop / 2;
1492        else
1493                *compose = crop;
1494
1495        return 0;
1496}
1497
1498static int csi_set_selection(struct v4l2_subdev *sd,
1499                             struct v4l2_subdev_pad_config *cfg,
1500                             struct v4l2_subdev_selection *sel)
1501{
1502        struct csi_priv *priv = v4l2_get_subdevdata(sd);
1503        struct v4l2_fwnode_endpoint upstream_ep;
1504        struct v4l2_mbus_framefmt *infmt;
1505        struct v4l2_rect *crop, *compose;
1506        int pad, ret;
1507
1508        if (sel->pad != CSI_SINK_PAD)
1509                return -EINVAL;
1510
1511        ret = csi_get_upstream_endpoint(priv, &upstream_ep);
1512        if (ret) {
1513                v4l2_err(&priv->sd, "failed to find upstream endpoint\n");
1514                return ret;
1515        }
1516
1517        mutex_lock(&priv->lock);
1518
1519        if (priv->stream_count > 0) {
1520                ret = -EBUSY;
1521                goto out;
1522        }
1523
1524        infmt = __csi_get_fmt(priv, cfg, CSI_SINK_PAD, sel->which);
1525        crop = __csi_get_crop(priv, cfg, sel->which);
1526        compose = __csi_get_compose(priv, cfg, sel->which);
1527
1528        switch (sel->target) {
1529        case V4L2_SEL_TGT_CROP:
1530                /*
1531                 * Modifying the crop rectangle always changes the format on
1532                 * the source pads. If the KEEP_CONFIG flag is set, just return
1533                 * the current crop rectangle.
1534                 */
1535                if (sel->flags & V4L2_SEL_FLAG_KEEP_CONFIG) {
1536                        sel->r = priv->crop;
1537                        if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
1538                                *crop = sel->r;
1539                        goto out;
1540                }
1541
1542                csi_try_crop(priv, &sel->r, cfg, infmt, &upstream_ep);
1543
1544                *crop = sel->r;
1545
1546                /* Reset scaling to 1:1 */
1547                compose->width = crop->width;
1548                compose->height = crop->height;
1549                break;
1550        case V4L2_SEL_TGT_COMPOSE:
1551                /*
1552                 * Modifying the compose rectangle always changes the format on
1553                 * the source pads. If the KEEP_CONFIG flag is set, just return
1554                 * the current compose rectangle.
1555                 */
1556                if (sel->flags & V4L2_SEL_FLAG_KEEP_CONFIG) {
1557                        sel->r = priv->compose;
1558                        if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
1559                                *compose = sel->r;
1560                        goto out;
1561                }
1562
1563                sel->r.left = 0;
1564                sel->r.top = 0;
1565                ret = csi_set_scale(&sel->r.width, crop->width, sel->flags);
1566                if (ret)
1567                        goto out;
1568                ret = csi_set_scale(&sel->r.height, crop->height, sel->flags);
1569                if (ret)
1570                        goto out;
1571
1572                *compose = sel->r;
1573                break;
1574        default:
1575                ret = -EINVAL;
1576                goto out;
1577        }
1578
1579        /* Reset source pads to sink compose rectangle */
1580        for (pad = CSI_SINK_PAD + 1; pad < CSI_NUM_PADS; pad++) {
1581                struct v4l2_mbus_framefmt *outfmt;
1582
1583                outfmt = __csi_get_fmt(priv, cfg, pad, sel->which);
1584                outfmt->width = compose->width;
1585                outfmt->height = compose->height;
1586        }
1587
1588out:
1589        mutex_unlock(&priv->lock);
1590        return ret;
1591}
1592
1593static int csi_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
1594                               struct v4l2_event_subscription *sub)
1595{
1596        if (sub->type != V4L2_EVENT_IMX_FRAME_INTERVAL_ERROR)
1597                return -EINVAL;
1598        if (sub->id != 0)
1599                return -EINVAL;
1600
1601        return v4l2_event_subscribe(fh, sub, 0, NULL);
1602}
1603
1604static int csi_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
1605                                 struct v4l2_event_subscription *sub)
1606{
1607        return v4l2_event_unsubscribe(fh, sub);
1608}
1609
1610/*
1611 * retrieve our pads parsed from the OF graph by the media device
1612 */
1613static int csi_registered(struct v4l2_subdev *sd)
1614{
1615        struct csi_priv *priv = v4l2_get_subdevdata(sd);
1616        struct ipu_csi *csi;
1617        int i, ret;
1618        u32 code;
1619
1620        /* get media device */
1621        priv->md = dev_get_drvdata(sd->v4l2_dev->dev);
1622
1623        /* get handle to IPU CSI */
1624        csi = ipu_csi_get(priv->ipu, priv->csi_id);
1625        if (IS_ERR(csi)) {
1626                v4l2_err(&priv->sd, "failed to get CSI%d\n", priv->csi_id);
1627                return PTR_ERR(csi);
1628        }
1629        priv->csi = csi;
1630
1631        for (i = 0; i < CSI_NUM_PADS; i++) {
1632                priv->pad[i].flags = (i == CSI_SINK_PAD) ?
1633                        MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
1634
1635                code = 0;
1636                if (i != CSI_SINK_PAD)
1637                        imx_media_enum_ipu_format(&code, 0, CS_SEL_YUV);
1638
1639                /* set a default mbus format  */
1640                ret = imx_media_init_mbus_fmt(&priv->format_mbus[i],
1641                                              640, 480, code, V4L2_FIELD_NONE,
1642                                              &priv->cc[i]);
1643                if (ret)
1644                        goto put_csi;
1645
1646                /* init default frame interval */
1647                priv->frame_interval[i].numerator = 1;
1648                priv->frame_interval[i].denominator = 30;
1649        }
1650
1651        /* disable frame skipping */
1652        priv->skip = &csi_skip[0];
1653
1654        /* init default crop and compose rectangle sizes */
1655        priv->crop.width = 640;
1656        priv->crop.height = 480;
1657        priv->compose.width = 640;
1658        priv->compose.height = 480;
1659
1660        priv->fim = imx_media_fim_init(&priv->sd);
1661        if (IS_ERR(priv->fim)) {
1662                ret = PTR_ERR(priv->fim);
1663                goto put_csi;
1664        }
1665
1666        ret = media_entity_pads_init(&sd->entity, CSI_NUM_PADS, priv->pad);
1667        if (ret)
1668                goto free_fim;
1669
1670        ret = imx_media_capture_device_register(priv->vdev);
1671        if (ret)
1672                goto free_fim;
1673
1674        ret = imx_media_add_video_device(priv->md, priv->vdev);
1675        if (ret)
1676                goto unreg;
1677
1678        return 0;
1679unreg:
1680        imx_media_capture_device_unregister(priv->vdev);
1681free_fim:
1682        if (priv->fim)
1683                imx_media_fim_free(priv->fim);
1684put_csi:
1685        ipu_csi_put(priv->csi);
1686        return ret;
1687}
1688
1689static void csi_unregistered(struct v4l2_subdev *sd)
1690{
1691        struct csi_priv *priv = v4l2_get_subdevdata(sd);
1692
1693        imx_media_capture_device_unregister(priv->vdev);
1694
1695        if (priv->fim)
1696                imx_media_fim_free(priv->fim);
1697
1698        if (priv->csi)
1699                ipu_csi_put(priv->csi);
1700}
1701
1702static const struct media_entity_operations csi_entity_ops = {
1703        .link_setup = csi_link_setup,
1704        .link_validate = v4l2_subdev_link_validate,
1705};
1706
1707static const struct v4l2_subdev_core_ops csi_core_ops = {
1708        .subscribe_event = csi_subscribe_event,
1709        .unsubscribe_event = csi_unsubscribe_event,
1710};
1711
1712static const struct v4l2_subdev_video_ops csi_video_ops = {
1713        .g_frame_interval = csi_g_frame_interval,
1714        .s_frame_interval = csi_s_frame_interval,
1715        .s_stream = csi_s_stream,
1716};
1717
1718static const struct v4l2_subdev_pad_ops csi_pad_ops = {
1719        .init_cfg = imx_media_init_cfg,
1720        .enum_mbus_code = csi_enum_mbus_code,
1721        .enum_frame_size = csi_enum_frame_size,
1722        .enum_frame_interval = csi_enum_frame_interval,
1723        .get_fmt = csi_get_fmt,
1724        .set_fmt = csi_set_fmt,
1725        .get_selection = csi_get_selection,
1726        .set_selection = csi_set_selection,
1727        .link_validate = csi_link_validate,
1728};
1729
1730static const struct v4l2_subdev_ops csi_subdev_ops = {
1731        .core = &csi_core_ops,
1732        .video = &csi_video_ops,
1733        .pad = &csi_pad_ops,
1734};
1735
1736static const struct v4l2_subdev_internal_ops csi_internal_ops = {
1737        .registered = csi_registered,
1738        .unregistered = csi_unregistered,
1739};
1740
1741static int imx_csi_probe(struct platform_device *pdev)
1742{
1743        struct ipu_client_platformdata *pdata;
1744        struct pinctrl *pinctrl;
1745        struct csi_priv *priv;
1746        int ret;
1747
1748        priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
1749        if (!priv)
1750                return -ENOMEM;
1751
1752        platform_set_drvdata(pdev, &priv->sd);
1753        priv->dev = &pdev->dev;
1754
1755        ret = dma_set_coherent_mask(priv->dev, DMA_BIT_MASK(32));
1756        if (ret)
1757                return ret;
1758
1759        /* get parent IPU */
1760        priv->ipu = dev_get_drvdata(priv->dev->parent);
1761
1762        /* get our CSI id */
1763        pdata = priv->dev->platform_data;
1764        priv->csi_id = pdata->csi;
1765        priv->smfc_id = (priv->csi_id == 0) ? 0 : 2;
1766
1767        timer_setup(&priv->eof_timeout_timer, csi_idmac_eof_timeout, 0);
1768        spin_lock_init(&priv->irqlock);
1769
1770        v4l2_subdev_init(&priv->sd, &csi_subdev_ops);
1771        v4l2_set_subdevdata(&priv->sd, priv);
1772        priv->sd.internal_ops = &csi_internal_ops;
1773        priv->sd.entity.ops = &csi_entity_ops;
1774        priv->sd.entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
1775        priv->sd.dev = &pdev->dev;
1776        priv->sd.fwnode = of_fwnode_handle(pdata->of_node);
1777        priv->sd.owner = THIS_MODULE;
1778        priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
1779        priv->sd.grp_id = priv->csi_id ?
1780                IMX_MEDIA_GRP_ID_CSI1 : IMX_MEDIA_GRP_ID_CSI0;
1781        imx_media_grp_id_to_sd_name(priv->sd.name, sizeof(priv->sd.name),
1782                                    priv->sd.grp_id, ipu_get_num(priv->ipu));
1783
1784        priv->vdev = imx_media_capture_device_init(&priv->sd,
1785                                                   CSI_SRC_PAD_IDMAC);
1786        if (IS_ERR(priv->vdev))
1787                return PTR_ERR(priv->vdev);
1788
1789        mutex_init(&priv->lock);
1790
1791        v4l2_ctrl_handler_init(&priv->ctrl_hdlr, 0);
1792        priv->sd.ctrl_handler = &priv->ctrl_hdlr;
1793
1794        /*
1795         * The IPUv3 driver did not assign an of_node to this
1796         * device. As a result, pinctrl does not automatically
1797         * configure our pin groups, so we need to do that manually
1798         * here, after setting this device's of_node.
1799         */
1800        priv->dev->of_node = pdata->of_node;
1801        pinctrl = devm_pinctrl_get_select_default(priv->dev);
1802        if (IS_ERR(pinctrl)) {
1803                ret = PTR_ERR(pinctrl);
1804                dev_dbg(priv->dev,
1805                        "devm_pinctrl_get_select_default() failed: %d\n", ret);
1806                if (ret != -ENODEV)
1807                        goto free;
1808        }
1809
1810        ret = v4l2_async_register_subdev(&priv->sd);
1811        if (ret)
1812                goto free;
1813
1814        return 0;
1815free:
1816        v4l2_ctrl_handler_free(&priv->ctrl_hdlr);
1817        mutex_destroy(&priv->lock);
1818        imx_media_capture_device_remove(priv->vdev);
1819        return ret;
1820}
1821
1822static int imx_csi_remove(struct platform_device *pdev)
1823{
1824        struct v4l2_subdev *sd = platform_get_drvdata(pdev);
1825        struct csi_priv *priv = sd_to_dev(sd);
1826
1827        v4l2_ctrl_handler_free(&priv->ctrl_hdlr);
1828        mutex_destroy(&priv->lock);
1829        imx_media_capture_device_remove(priv->vdev);
1830        v4l2_async_unregister_subdev(sd);
1831        media_entity_cleanup(&sd->entity);
1832
1833        return 0;
1834}
1835
1836static const struct platform_device_id imx_csi_ids[] = {
1837        { .name = "imx-ipuv3-csi" },
1838        { },
1839};
1840MODULE_DEVICE_TABLE(platform, imx_csi_ids);
1841
1842static struct platform_driver imx_csi_driver = {
1843        .probe = imx_csi_probe,
1844        .remove = imx_csi_remove,
1845        .id_table = imx_csi_ids,
1846        .driver = {
1847                .name = "imx-ipuv3-csi",
1848        },
1849};
1850module_platform_driver(imx_csi_driver);
1851
1852MODULE_DESCRIPTION("i.MX CSI subdev driver");
1853MODULE_AUTHOR("Steve Longerbeam <steve_longerbeam@mentor.com>");
1854MODULE_LICENSE("GPL");
1855MODULE_ALIAS("platform:imx-ipuv3-csi");
1856