Linux Audio

Check our new training course

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