sh_mobile_ceu_camera.c 61.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*
 * V4L2 Driver for SuperH Mobile CEU interface
 *
 * Copyright (C) 2008 Magnus Damm
 *
 * Based on V4L2 Driver for PXA camera host - "pxa_camera.c",
 *
 * Copyright (C) 2006, Sascha Hauer, Pengutronix
 * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/io.h>
20
#include <linux/completion.h>
21 22 23 24 25 26 27 28 29
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/moduleparam.h>
#include <linux/time.h>
30
#include <linux/slab.h>
31 32 33
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/videodev2.h>
34
#include <linux/pm_runtime.h>
35
#include <linux/sched.h>
36 37 38 39 40

#include <media/v4l2-common.h>
#include <media/v4l2-dev.h>
#include <media/soc_camera.h>
#include <media/sh_mobile_ceu.h>
41
#include <media/sh_mobile_csi2.h>
42
#include <media/videobuf2-dma-contig.h>
43 44
#include <media/v4l2-mediabus.h>
#include <media/soc_mediabus.h>
45 46 47

/* register offsets for sh7722 / sh7723 */

48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
#define CAPSR  0x00 /* Capture start register */
#define CAPCR  0x04 /* Capture control register */
#define CAMCR  0x08 /* Capture interface control register */
#define CMCYR  0x0c /* Capture interface cycle  register */
#define CAMOR  0x10 /* Capture interface offset register */
#define CAPWR  0x14 /* Capture interface width register */
#define CAIFR  0x18 /* Capture interface input format register */
#define CSTCR  0x20 /* Camera strobe control register (<= sh7722) */
#define CSECR  0x24 /* Camera strobe emission count register (<= sh7722) */
#define CRCNTR 0x28 /* CEU register control register */
#define CRCMPR 0x2c /* CEU register forcible control register */
#define CFLCR  0x30 /* Capture filter control register */
#define CFSZR  0x34 /* Capture filter size clip register */
#define CDWDR  0x38 /* Capture destination width register */
#define CDAYR  0x3c /* Capture data address Y register */
#define CDACR  0x40 /* Capture data address C register */
#define CDBYR  0x44 /* Capture data bottom-field address Y register */
#define CDBCR  0x48 /* Capture data bottom-field address C register */
#define CBDSR  0x4c /* Capture bundle destination size register */
#define CFWCR  0x5c /* Firewall operation control register */
#define CLFCR  0x60 /* Capture low-pass filter control register */
#define CDOCR  0x64 /* Capture data output control register */
#define CDDCR  0x68 /* Capture data complexity level register */
#define CDDAR  0x6c /* Capture data complexity level address register */
#define CEIER  0x70 /* Capture event interrupt enable register */
#define CETCR  0x74 /* Capture event flag clear register */
#define CSTSR  0x7c /* Capture status register */
#define CSRTR  0x80 /* Capture software reset register */
#define CDSSR  0x84 /* Capture data size register */
#define CDAYR2 0x90 /* Capture data address Y register 2 */
#define CDACR2 0x94 /* Capture data address C register 2 */
#define CDBYR2 0x98 /* Capture data bottom-field address Y register 2 */
#define CDBCR2 0x9c /* Capture data bottom-field address C register 2 */
81

82 83 84 85 86 87 88
#undef DEBUG_GEOMETRY
#ifdef DEBUG_GEOMETRY
#define dev_geo	dev_info
#else
#define dev_geo	dev_dbg
#endif

89 90
/* per video frame buffer */
struct sh_mobile_ceu_buffer {
91 92
	struct vb2_buffer vb; /* v4l buffer must be first */
	struct list_head queue;
93 94 95 96 97
};

struct sh_mobile_ceu_dev {
	struct soc_camera_host ici;
	struct soc_camera_device *icd;
98
	struct platform_device *csi2_pdev;
99 100 101

	unsigned int irq;
	void __iomem *base;
102 103
	size_t video_limit;
	size_t buf_total;
104

105
	spinlock_t lock;		/* Protects video buffer lists */
106
	struct list_head capture;
107 108
	struct vb2_buffer *active;
	struct vb2_alloc_ctx *alloc_ctx;
109 110

	struct sh_mobile_ceu_info *pdata;
111
	struct completion complete;
112

113 114
	u32 cflcr;

115
	enum v4l2_field field;
116
	int sequence;
117

118 119
	unsigned int image_mode:1;
	unsigned int is_16bit:1;
120
	unsigned int frozen:1;
121 122 123
};

struct sh_mobile_ceu_cam {
124
	/* CEU offsets within the camera output, before the CEU scaler */
125 126 127 128 129 130 131 132 133 134 135 136 137
	unsigned int ceu_left;
	unsigned int ceu_top;
	/* Client output, as seen by the CEU */
	unsigned int width;
	unsigned int height;
	/*
	 * User window from S_CROP / G_CROP, produced by client cropping and
	 * scaling, CEU scaling and CEU cropping, mapped back onto the client
	 * input window
	 */
	struct v4l2_rect subrect;
	/* Camera cropping rectangle */
	struct v4l2_rect rect;
138 139
	const struct soc_mbus_pixelfmt *extra_fmt;
	enum v4l2_mbus_pixelcode code;
140 141
};

142 143 144 145 146
static struct sh_mobile_ceu_buffer *to_ceu_vb(struct vb2_buffer *vb)
{
	return container_of(vb, struct sh_mobile_ceu_buffer, vb);
}

147
static void ceu_write(struct sh_mobile_ceu_dev *priv,
148
		      unsigned long reg_offs, u32 data)
149 150 151 152
{
	iowrite32(data, priv->base + reg_offs);
}

153
static u32 ceu_read(struct sh_mobile_ceu_dev *priv, unsigned long reg_offs)
154 155 156 157
{
	return ioread32(priv->base + reg_offs);
}

158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
static int sh_mobile_ceu_soft_reset(struct sh_mobile_ceu_dev *pcdev)
{
	int i, success = 0;
	struct soc_camera_device *icd = pcdev->icd;

	ceu_write(pcdev, CAPSR, 1 << 16); /* reset */

	/* wait CSTSR.CPTON bit */
	for (i = 0; i < 1000; i++) {
		if (!(ceu_read(pcdev, CSTSR) & 1)) {
			success++;
			break;
		}
		udelay(1);
	}

	/* wait CAPSR.CPKIL bit */
	for (i = 0; i < 1000; i++) {
		if (!(ceu_read(pcdev, CAPSR) & (1 << 16))) {
			success++;
			break;
		}
		udelay(1);
	}


	if (2 != success) {
185
		dev_warn(icd->pdev, "soft reset time out\n");
186 187 188 189 190 191
		return -EIO;
	}

	return 0;
}

192 193 194
/*
 *  Videobuf operations
 */
195 196 197 198 199 200

/*
 * .queue_setup() is called to check, whether the driver can accept the
 *		  requested number of buffers and to fill in plane sizes
 *		  for the current frame format if required
 */
201
static int sh_mobile_ceu_videobuf_setup(struct vb2_queue *vq,
202
			const struct v4l2_format *fmt,
203
			unsigned int *count, unsigned int *num_planes,
204
			unsigned int sizes[], void *alloc_ctxs[])
205
{
206
	struct soc_camera_device *icd = container_of(vq, struct soc_camera_device, vb2_vidq);
207
	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
208
	struct sh_mobile_ceu_dev *pcdev = ici->priv;
209 210
	int bytes_per_line;
	unsigned int height;
211

212 213 214 215 216 217 218 219 220 221 222 223 224 225
	if (fmt) {
		const struct soc_camera_format_xlate *xlate = soc_camera_xlate_by_fourcc(icd,
								fmt->fmt.pix.pixelformat);
		if (!xlate)
			return -EINVAL;
		bytes_per_line = soc_mbus_bytes_per_line(fmt->fmt.pix.width,
							 xlate->host_fmt);
		height = fmt->fmt.pix.height;
	} else {
		/* Called from VIDIOC_REQBUFS or in compatibility mode */
		bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
						icd->current_fmt->host_fmt);
		height = icd->user_height;
	}
226 227 228
	if (bytes_per_line < 0)
		return bytes_per_line;

229
	sizes[0] = bytes_per_line * height;
230 231

	alloc_ctxs[0] = pcdev->alloc_ctx;
232

233 234 235
	if (!vq->num_buffers)
		pcdev->sequence = 0;

236
	if (!*count)
237 238
		*count = 2;

239 240 241 242 243 244 245
	/* If *num_planes != 0, we have already verified *count. */
	if (pcdev->video_limit && !*num_planes) {
		size_t size = PAGE_ALIGN(sizes[0]) * *count;

		if (size + pcdev->buf_total > pcdev->video_limit)
			*count = (pcdev->video_limit - pcdev->buf_total) /
				PAGE_ALIGN(sizes[0]);
246 247
	}

248 249
	*num_planes = 1;

250
	dev_dbg(icd->parent, "count=%d, size=%u\n", *count, sizes[0]);
251 252 253 254

	return 0;
}

255 256 257
#define CEU_CETCR_MAGIC 0x0317f313 /* acknowledge magical interrupt sources */
#define CEU_CETCR_IGRW (1 << 4) /* prohibited register access interrupt bit */
#define CEU_CEIER_CPEIE (1 << 0) /* one-frame capture end interrupt */
258
#define CEU_CEIER_VBP   (1 << 20) /* vbp error */
259
#define CEU_CAPCR_CTNCP (1 << 16) /* continuous capture mode (if set) */
260
#define CEU_CEIER_MASK (CEU_CEIER_CPEIE | CEU_CEIER_VBP)
261 262


263 264 265 266 267
/*
 * return value doesn't reflex the success/failure to queue the new buffer,
 * but rather the status of the previous buffer.
 */
static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
268
{
269
	struct soc_camera_device *icd = pcdev->icd;
270
	dma_addr_t phys_addr_top, phys_addr_bottom;
271 272
	unsigned long top1, top2;
	unsigned long bottom1, bottom2;
273
	u32 status;
274
	bool planar;
275
	int ret = 0;
276

277 278
	/*
	 * The hardware is _very_ picky about this sequence. Especially
279 280 281
	 * the CEU_CETCR_MAGIC value. It seems like we need to acknowledge
	 * several not-so-well documented interrupt sources in CETCR.
	 */
282 283 284
	ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) & ~CEU_CEIER_MASK);
	status = ceu_read(pcdev, CETCR);
	ceu_write(pcdev, CETCR, ~status & CEU_CETCR_MAGIC);
285 286
	if (!pcdev->frozen)
		ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) | CEU_CEIER_MASK);
287 288
	ceu_write(pcdev, CAPCR, ceu_read(pcdev, CAPCR) & ~CEU_CAPCR_CTNCP);
	ceu_write(pcdev, CETCR, CEU_CETCR_MAGIC ^ CEU_CETCR_IGRW);
289

290 291 292 293 294 295 296 297 298 299
	/*
	 * When a VBP interrupt occurs, a capture end interrupt does not occur
	 * and the image of that frame is not captured correctly. So, soft reset
	 * is needed here.
	 */
	if (status & CEU_CEIER_VBP) {
		sh_mobile_ceu_soft_reset(pcdev);
		ret = -EIO;
	}

300 301 302 303 304
	if (pcdev->frozen) {
		complete(&pcdev->complete);
		return ret;
	}

305
	if (!pcdev->active)
306
		return ret;
307

308 309 310 311 312 313 314 315 316 317 318 319
	if (V4L2_FIELD_INTERLACED_BT == pcdev->field) {
		top1	= CDBYR;
		top2	= CDBCR;
		bottom1	= CDAYR;
		bottom2	= CDACR;
	} else {
		top1	= CDAYR;
		top2	= CDACR;
		bottom1	= CDBYR;
		bottom2	= CDBCR;
	}

320
	phys_addr_top = vb2_dma_contig_plane_dma_addr(pcdev->active, 0);
321

322
	switch (icd->current_fmt->host_fmt->fourcc) {
323 324
	case V4L2_PIX_FMT_NV12:
	case V4L2_PIX_FMT_NV21:
325 326
	case V4L2_PIX_FMT_NV16:
	case V4L2_PIX_FMT_NV61:
327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344
		planar = true;
		break;
	default:
		planar = false;
	}

	ceu_write(pcdev, top1, phys_addr_top);
	if (V4L2_FIELD_NONE != pcdev->field) {
		if (planar)
			phys_addr_bottom = phys_addr_top + icd->user_width;
		else
			phys_addr_bottom = phys_addr_top +
				soc_mbus_bytes_per_line(icd->user_width,
							icd->current_fmt->host_fmt);
		ceu_write(pcdev, bottom1, phys_addr_bottom);
	}

	if (planar) {
345 346
		phys_addr_top += icd->user_width *
			icd->user_height;
347 348 349 350
		ceu_write(pcdev, top2, phys_addr_top);
		if (V4L2_FIELD_NONE != pcdev->field) {
			phys_addr_bottom = phys_addr_top + icd->user_width;
			ceu_write(pcdev, bottom2, phys_addr_bottom);
351
		}
352
	}
353 354

	ceu_write(pcdev, CAPSR, 0x1); /* start capture */
355 356

	return ret;
357 358
}

359
static int sh_mobile_ceu_videobuf_prepare(struct vb2_buffer *vb)
360 361 362 363 364 365 366 367 368 369
{
	struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);

	/* Added list head initialization on alloc */
	WARN(!list_empty(&buf->queue), "Buffer %p on queue!\n", vb);

	return 0;
}

static void sh_mobile_ceu_videobuf_queue(struct vb2_buffer *vb)
370
{
371
	struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
372 373 374 375
	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
	struct sh_mobile_ceu_dev *pcdev = ici->priv;
	struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
	unsigned long size;
376 377
	int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
						icd->current_fmt->host_fmt);
378

379
	if (bytes_per_line < 0)
380
		goto error;
381

382 383 384 385 386 387 388 389 390
	size = icd->user_height * bytes_per_line;

	if (vb2_plane_size(vb, 0) < size) {
		dev_err(icd->parent, "Buffer #%d too small (%lu < %lu)\n",
			vb->v4l2_buf.index, vb2_plane_size(vb, 0), size);
		goto error;
	}

	vb2_set_plane_payload(vb, 0, size);
391

392
	dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
393
		vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
394 395

#ifdef DEBUG
396 397 398 399
	/*
	 * This can be useful if you want to see if we actually fill
	 * the buffer with something
	 */
400 401
	if (vb2_plane_vaddr(vb, 0))
		memset(vb2_plane_vaddr(vb, 0), 0xaa, vb2_get_plane_payload(vb, 0));
402 403
#endif

404
	spin_lock_irq(&pcdev->lock);
405
	list_add_tail(&buf->queue, &pcdev->capture);
406 407

	if (!pcdev->active) {
408 409 410 411 412
		/*
		 * Because there were no active buffer at this moment,
		 * we are not interested in the return value of
		 * sh_mobile_ceu_capture here.
		 */
413 414 415
		pcdev->active = vb;
		sh_mobile_ceu_capture(pcdev);
	}
416
	spin_unlock_irq(&pcdev->lock);
417 418 419 420 421

	return;

error:
	vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
422 423
}

424
static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb)
425
{
426
	struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
427
	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
428
	struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
429 430
	struct sh_mobile_ceu_dev *pcdev = ici->priv;

431
	spin_lock_irq(&pcdev->lock);
432 433 434 435 436 437 438

	if (pcdev->active == vb) {
		/* disable capture (release DMA buffer), reset */
		ceu_write(pcdev, CAPSR, 1 << 16);
		pcdev->active = NULL;
	}

439 440 441 442 443 444
	/*
	 * Doesn't hurt also if the list is empty, but it hurts, if queuing the
	 * buffer failed, and .buf_init() hasn't been called
	 */
	if (buf->queue.next)
		list_del_init(&buf->queue);
445

446 447 448 449
	pcdev->buf_total -= PAGE_ALIGN(vb2_plane_size(vb, 0));
	dev_dbg(icd->parent, "%s() %zu bytes buffers\n", __func__,
		pcdev->buf_total);

450
	spin_unlock_irq(&pcdev->lock);
451
}
452

453 454
static int sh_mobile_ceu_videobuf_init(struct vb2_buffer *vb)
{
455 456 457 458 459 460 461 462
	struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
	struct sh_mobile_ceu_dev *pcdev = ici->priv;

	pcdev->buf_total += PAGE_ALIGN(vb2_plane_size(vb, 0));
	dev_dbg(icd->parent, "%s() %zu bytes buffers\n", __func__,
		pcdev->buf_total);

463 464 465
	/* This is for locking debugging only */
	INIT_LIST_HEAD(&to_ceu_vb(vb)->queue);
	return 0;
466 467
}

468 469 470
static int sh_mobile_ceu_stop_streaming(struct vb2_queue *q)
{
	struct soc_camera_device *icd = container_of(q, struct soc_camera_device, vb2_vidq);
471
	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
472 473 474
	struct sh_mobile_ceu_dev *pcdev = ici->priv;
	struct list_head *buf_head, *tmp;

475
	spin_lock_irq(&pcdev->lock);
476 477 478 479 480 481

	pcdev->active = NULL;

	list_for_each_safe(buf_head, tmp, &pcdev->capture)
		list_del_init(buf_head);

482
	spin_unlock_irq(&pcdev->lock);
483 484 485 486

	return sh_mobile_ceu_soft_reset(pcdev);
}

487 488 489 490 491 492 493 494
static struct vb2_ops sh_mobile_ceu_videobuf_ops = {
	.queue_setup	= sh_mobile_ceu_videobuf_setup,
	.buf_prepare	= sh_mobile_ceu_videobuf_prepare,
	.buf_queue	= sh_mobile_ceu_videobuf_queue,
	.buf_cleanup	= sh_mobile_ceu_videobuf_release,
	.buf_init	= sh_mobile_ceu_videobuf_init,
	.wait_prepare	= soc_camera_unlock,
	.wait_finish	= soc_camera_lock,
495
	.stop_streaming	= sh_mobile_ceu_stop_streaming,
496 497 498 499 500
};

static irqreturn_t sh_mobile_ceu_irq(int irq, void *data)
{
	struct sh_mobile_ceu_dev *pcdev = data;
501 502
	struct vb2_buffer *vb;
	int ret;
503

504
	spin_lock(&pcdev->lock);
505 506

	vb = pcdev->active;
507 508 509 510
	if (!vb)
		/* Stale interrupt from a released buffer */
		goto out;

511
	list_del_init(&to_ceu_vb(vb)->queue);
512 513

	if (!list_empty(&pcdev->capture))
514 515
		pcdev->active = &list_entry(pcdev->capture.next,
					    struct sh_mobile_ceu_buffer, queue)->vb;
516 517 518
	else
		pcdev->active = NULL;

519 520 521 522 523 524 525
	ret = sh_mobile_ceu_capture(pcdev);
	do_gettimeofday(&vb->v4l2_buf.timestamp);
	if (!ret) {
		vb->v4l2_buf.field = pcdev->field;
		vb->v4l2_buf.sequence = pcdev->sequence++;
	}
	vb2_buffer_done(vb, ret < 0 ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
526 527

out:
528
	spin_unlock(&pcdev->lock);
529 530 531 532

	return IRQ_HANDLED;
}

533 534 535 536 537 538 539 540 541 542 543 544 545 546
static struct v4l2_subdev *find_csi2(struct sh_mobile_ceu_dev *pcdev)
{
	struct v4l2_subdev *sd;

	if (!pcdev->csi2_pdev)
		return NULL;

	v4l2_device_for_each_subdev(sd, &pcdev->ici.v4l2_dev)
		if (&pcdev->csi2_pdev->dev == v4l2_get_subdevdata(sd))
			return sd;

	return NULL;
}

547
/* Called with .video_lock held */
548 549
static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
{
550
	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
551
	struct sh_mobile_ceu_dev *pcdev = ici->priv;
552
	struct v4l2_subdev *csi2_sd;
553
	int ret;
554 555

	if (pcdev->icd)
556
		return -EBUSY;
557

558
	dev_info(icd->parent,
559 560 561
		 "SuperH Mobile CEU driver attached to camera %d\n",
		 icd->devnum);

562
	pm_runtime_get_sync(ici->v4l2_dev.dev);
563

564 565
	pcdev->buf_total = 0;

566
	ret = sh_mobile_ceu_soft_reset(pcdev);
567 568

	csi2_sd = find_csi2(pcdev);
569 570 571 572
	if (csi2_sd) {
		csi2_sd->grp_id = soc_camera_grp_id(icd);
		v4l2_set_subdev_hostdata(csi2_sd, icd);
	}
573 574

	ret = v4l2_subdev_call(csi2_sd, core, s_power, 1);
575
	if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) {
576
		pm_runtime_put_sync(ici->v4l2_dev.dev);
577
		return ret;
578
	}
579

580 581 582 583 584 585 586 587 588
	/*
	 * -ENODEV is special: either csi2_sd == NULL or the CSI-2 driver
	 * has not found this soc-camera device among its clients
	 */
	if (ret == -ENODEV && csi2_sd)
		csi2_sd->grp_id = 0;
	pcdev->icd = icd;

	return 0;
589 590
}

591
/* Called with .video_lock held */
592 593
static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
{
594
	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
595
	struct sh_mobile_ceu_dev *pcdev = ici->priv;
596
	struct v4l2_subdev *csi2_sd = find_csi2(pcdev);
597 598 599

	BUG_ON(icd != pcdev->icd);

600
	v4l2_subdev_call(csi2_sd, core, s_power, 0);
601 602
	if (csi2_sd)
		csi2_sd->grp_id = 0;
603 604
	/* disable capture, disable interrupts */
	ceu_write(pcdev, CEIER, 0);
605
	sh_mobile_ceu_soft_reset(pcdev);
606 607

	/* make sure active buffer is canceled */
608
	spin_lock_irq(&pcdev->lock);
609
	if (pcdev->active) {
610 611
		list_del_init(&to_ceu_vb(pcdev->active)->queue);
		vb2_buffer_done(pcdev->active, VB2_BUF_STATE_ERROR);
612 613
		pcdev->active = NULL;
	}
614
	spin_unlock_irq(&pcdev->lock);
615

616
	pm_runtime_put_sync(ici->v4l2_dev.dev);
617

618
	dev_info(icd->parent,
619 620 621 622 623 624
		 "SuperH Mobile CEU driver detached from camera %d\n",
		 icd->devnum);

	pcdev->icd = NULL;
}

625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655
/*
 * See chapter 29.4.12 "Capture Filter Control Register (CFLCR)"
 * in SH7722 Hardware Manual
 */
static unsigned int size_dst(unsigned int src, unsigned int scale)
{
	unsigned int mant_pre = scale >> 12;
	if (!src || !scale)
		return src;
	return ((mant_pre + 2 * (src - 1)) / (2 * mant_pre) - 1) *
		mant_pre * 4096 / scale + 1;
}

static u16 calc_scale(unsigned int src, unsigned int *dst)
{
	u16 scale;

	if (src == *dst)
		return 0;

	scale = (src * 4096 / *dst) & ~7;

	while (scale > 4096 && size_dst(src, scale) < *dst)
		scale -= 8;

	*dst = size_dst(src, scale);

	return scale;
}

/* rect is guaranteed to not exceed the scaled camera rectangle */
656
static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd)
657
{
658
	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
659 660
	struct sh_mobile_ceu_cam *cam = icd->host_priv;
	struct sh_mobile_ceu_dev *pcdev = ici->priv;
661 662
	unsigned int height, width, cdwdr_width, in_width, in_height;
	unsigned int left_offset, top_offset;
663 664
	u32 camor;

665
	dev_geo(icd->parent, "Crop %ux%u@%u:%u\n",
666
		icd->user_width, icd->user_height, cam->ceu_left, cam->ceu_top);
667

668 669
	left_offset	= cam->ceu_left;
	top_offset	= cam->ceu_top;
670

671 672 673 674
	WARN_ON(icd->user_width & 3 || icd->user_height & 3);

	width = icd->user_width;

675
	if (pcdev->image_mode) {
676
		in_width = cam->width;
677 678 679 680
		if (!pcdev->is_16bit) {
			in_width *= 2;
			left_offset *= 2;
		}
681
		cdwdr_width = width;
682
	} else {
683
		int bytes_per_line = soc_mbus_bytes_per_line(width,
684 685
						icd->current_fmt->host_fmt);
		unsigned int w_factor;
686

687 688 689 690 691 692 693
		switch (icd->current_fmt->host_fmt->packing) {
		case SOC_MBUS_PACKING_2X8_PADHI:
			w_factor = 2;
			break;
		default:
			w_factor = 1;
		}
694

695
		in_width = cam->width * w_factor;
696
		left_offset *= w_factor;
697

698
		if (bytes_per_line < 0)
699
			cdwdr_width = width;
700 701
		else
			cdwdr_width = bytes_per_line;
702 703
	}

704 705
	height = icd->user_height;
	in_height = cam->height;
706
	if (V4L2_FIELD_NONE != pcdev->field) {
707
		height = (height / 2) & ~3;
708 709
		in_height /= 2;
		top_offset /= 2;
710 711 712
		cdwdr_width *= 2;
	}

713
	/* CSI2 special configuration */
714
	if (pcdev->pdata->csi2) {
715 716 717 718
		in_width = ((in_width - 2) * 2);
		left_offset *= 2;
	}

719
	/* Set CAMOR, CAPWR, CFSZR, take care of CDWDR */
720
	camor = left_offset | (top_offset << 16);
721

722
	dev_geo(icd->parent,
723 724 725 726
		"CAMOR 0x%x, CAPWR 0x%x, CFSZR 0x%x, CDWDR 0x%x\n", camor,
		(in_height << 16) | in_width, (height << 16) | width,
		cdwdr_width);

727
	ceu_write(pcdev, CAMOR, camor);
728
	ceu_write(pcdev, CAPWR, (in_height << 16) | in_width);
729
	/* CFSZR clipping is applied _after_ the scaling filter (CFLCR) */
730
	ceu_write(pcdev, CFSZR, (height << 16) | width);
731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766
	ceu_write(pcdev, CDWDR, cdwdr_width);
}

static u32 capture_save_reset(struct sh_mobile_ceu_dev *pcdev)
{
	u32 capsr = ceu_read(pcdev, CAPSR);
	ceu_write(pcdev, CAPSR, 1 << 16); /* reset, stop capture */
	return capsr;
}

static void capture_restore(struct sh_mobile_ceu_dev *pcdev, u32 capsr)
{
	unsigned long timeout = jiffies + 10 * HZ;

	/*
	 * Wait until the end of the current frame. It can take a long time,
	 * but if it has been aborted by a CAPSR reset, it shoule exit sooner.
	 */
	while ((ceu_read(pcdev, CSTSR) & 1) && time_before(jiffies, timeout))
		msleep(1);

	if (time_after(jiffies, timeout)) {
		dev_err(pcdev->ici.v4l2_dev.dev,
			"Timeout waiting for frame end! Interface problem?\n");
		return;
	}

	/* Wait until reset clears, this shall not hang... */
	while (ceu_read(pcdev, CAPSR) & (1 << 16))
		udelay(10);

	/* Anything to restore? */
	if (capsr & ~(1 << 16))
		ceu_write(pcdev, CAPSR, capsr);
}

767 768 769 770
/* Find the bus subdevice driver, e.g., CSI2 */
static struct v4l2_subdev *find_bus_subdev(struct sh_mobile_ceu_dev *pcdev,
					   struct soc_camera_device *icd)
{
771 772
	if (pcdev->csi2_pdev) {
		struct v4l2_subdev *csi2_sd = find_csi2(pcdev);
773
		if (csi2_sd && csi2_sd->grp_id == soc_camera_grp_id(icd))
774 775
			return csi2_sd;
	}
776

777
	return soc_camera_to_subdev(icd);
778 779 780 781 782 783 784 785 786 787
}

#define CEU_BUS_FLAGS (V4L2_MBUS_MASTER |	\
		V4L2_MBUS_PCLK_SAMPLE_RISING |	\
		V4L2_MBUS_HSYNC_ACTIVE_HIGH |	\
		V4L2_MBUS_HSYNC_ACTIVE_LOW |	\
		V4L2_MBUS_VSYNC_ACTIVE_HIGH |	\
		V4L2_MBUS_VSYNC_ACTIVE_LOW |	\
		V4L2_MBUS_DATA_ACTIVE_HIGH)

788
/* Capture is not running, no interrupts, no locking needed */
789 790 791
static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
				       __u32 pixfmt)
{
792
	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
793
	struct sh_mobile_ceu_dev *pcdev = ici->priv;
794
	struct v4l2_subdev *sd = find_bus_subdev(pcdev, icd);
795
	struct sh_mobile_ceu_cam *cam = icd->host_priv;
796 797
	struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
	unsigned long value, common_flags = CEU_BUS_FLAGS;
798
	u32 capsr = capture_save_reset(pcdev);
799 800
	unsigned int yuv_lineskip;
	int ret;
801

802 803 804 805 806 807 808 809 810 811 812 813 814
	/*
	 * If the client doesn't implement g_mbus_config, we just use our
	 * platform data
	 */
	ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
	if (!ret) {
		common_flags = soc_mbus_config_compatible(&cfg,
							  common_flags);
		if (!common_flags)
			return -EINVAL;
	} else if (ret != -ENOIOCTLCMD) {
		return ret;
	}
815

816
	/* Make choises, based on platform preferences */
817 818
	if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
	    (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
819
		if (pcdev->pdata->flags & SH_CEU_FLAG_HSYNC_LOW)
820
			common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
821
		else
822
			common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
823 824
	}

825 826
	if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
	    (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
827
		if (pcdev->pdata->flags & SH_CEU_FLAG_VSYNC_LOW)
828
			common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
829
		else
830
			common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
831 832
	}

833 834 835
	cfg.flags = common_flags;
	ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
	if (ret < 0 && ret != -ENOIOCTLCMD)
836 837
		return ret;

838
	if (icd->current_fmt->host_fmt->bits_per_sample > 8)
839
		pcdev->is_16bit = 1;
840 841
	else
		pcdev->is_16bit = 0;
842 843 844 845

	ceu_write(pcdev, CRCNTR, 0);
	ceu_write(pcdev, CRCMPR, 0);

846
	value = 0x00000010; /* data fetch by default */
847
	yuv_lineskip = 0x10;
848

849
	switch (icd->current_fmt->host_fmt->fourcc) {
850 851
	case V4L2_PIX_FMT_NV12:
	case V4L2_PIX_FMT_NV21:
852 853
		/* convert 4:2:2 -> 4:2:0 */
		yuv_lineskip = 0; /* skip for NV12/21, no skip for NV16/61 */
854 855 856
		/* fall-through */
	case V4L2_PIX_FMT_NV16:
	case V4L2_PIX_FMT_NV61:
857
		switch (cam->code) {
858
		case V4L2_MBUS_FMT_UYVY8_2X8:
859 860
			value = 0x00000000; /* Cb0, Y0, Cr0, Y1 */
			break;
861
		case V4L2_MBUS_FMT_VYUY8_2X8:
862 863
			value = 0x00000100; /* Cr0, Y0, Cb0, Y1 */
			break;
864
		case V4L2_MBUS_FMT_YUYV8_2X8:
865 866
			value = 0x00000200; /* Y0, Cb0, Y1, Cr0 */
			break;
867
		case V4L2_MBUS_FMT_YVYU8_2X8:
868 869 870 871 872 873 874
			value = 0x00000300; /* Y0, Cr0, Y1, Cb0 */
			break;
		default:
			BUG();
		}
	}

875 876
	if (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV21 ||
	    icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV61)
877
		value ^= 0x00000100; /* swap U, V to change from NV1x->NVx1 */
878

879 880
	value |= common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? 1 << 1 : 0;
	value |= common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? 1 << 0 : 0;
881
	value |= pcdev->is_16bit ? 1 << 12 : 0;
882 883

	/* CSI2 mode */
884
	if (pcdev->pdata->csi2)
885 886
		value |= 3 << 12;

887 888 889
	ceu_write(pcdev, CAMCR, value);

	ceu_write(pcdev, CAPCR, 0x00300000);
890 891 892 893 894 895 896 897 898 899 900 901 902

	switch (pcdev->field) {
	case V4L2_FIELD_INTERLACED_TB:
		value = 0x101;
		break;
	case V4L2_FIELD_INTERLACED_BT:
		value = 0x102;
		break;
	default:
		value = 0;
		break;
	}
	ceu_write(pcdev, CAIFR, value);
903

904
	sh_mobile_ceu_set_rect(icd);
905 906
	mdelay(1);

907
	dev_geo(icd->parent, "CFLCR 0x%x\n", pcdev->cflcr);
908
	ceu_write(pcdev, CFLCR, pcdev->cflcr);
909

910 911
	/*
	 * A few words about byte order (observed in Big Endian mode)
912 913 914 915 916 917 918 919
	 *
	 * In data fetch mode bytes are received in chunks of 8 bytes.
	 * D0, D1, D2, D3, D4, D5, D6, D7 (D0 received first)
	 *
	 * The data is however by default written to memory in reverse order:
	 * D7, D6, D5, D4, D3, D2, D1, D0 (D7 written to lowest byte)
	 *
	 * The lowest three bits of CDOCR allows us to do swapping,
920 921
	 * using 7 we swap the data bytes to match the incoming order:
	 * D0, D1, D2, D3, D4, D5, D6, D7
922
	 */
923
	value = 0x00000007 | yuv_lineskip;
924 925

	ceu_write(pcdev, CDOCR, value);
926 927
	ceu_write(pcdev, CFWCR, 0); /* keep "datafetch firewall" disabled */

928
	dev_dbg(icd->parent, "S_FMT successful for %c%c%c%c %ux%u\n",
929 930
		pixfmt & 0xff, (pixfmt >> 8) & 0xff,
		(pixfmt >> 16) & 0xff, (pixfmt >> 24) & 0xff,
931
		icd->user_width, icd->user_height);
932 933 934

	capture_restore(pcdev, capsr);

935 936 937 938
	/* not in bundle mode: skip CBDSR, CDAYR2, CDACR2, CDBYR2, CDBCR2 */
	return 0;
}

939 940
static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd,
				       unsigned char buswidth)
941
{
942
	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
943
	struct sh_mobile_ceu_dev *pcdev = ici->priv;
944 945 946 947
	struct v4l2_subdev *sd = find_bus_subdev(pcdev, icd);
	unsigned long common_flags = CEU_BUS_FLAGS;
	struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
	int ret;
948

949 950 951 952 953 954 955 956
	ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
	if (!ret)
		common_flags = soc_mbus_config_compatible(&cfg,
							  common_flags);
	else if (ret != -ENOIOCTLCMD)
		return ret;

	if (!common_flags || buswidth > 16)
957 958 959 960 961
		return -EINVAL;

	return 0;
}

962
static const struct soc_mbus_pixelfmt sh_mobile_ceu_formats[] = {
963
	{
964 965
		.fourcc			= V4L2_PIX_FMT_NV12,
		.name			= "NV12",
966 967
		.bits_per_sample	= 8,
		.packing		= SOC_MBUS_PACKING_1_5X8,
968 969 970 971
		.order			= SOC_MBUS_ORDER_LE,
	}, {
		.fourcc			= V4L2_PIX_FMT_NV21,
		.name			= "NV21",
972 973
		.bits_per_sample	= 8,
		.packing		= SOC_MBUS_PACKING_1_5X8,
974 975 976 977
		.order			= SOC_MBUS_ORDER_LE,
	}, {
		.fourcc			= V4L2_PIX_FMT_NV16,
		.name			= "NV16",
978 979
		.bits_per_sample	= 8,
		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
980 981 982 983
		.order			= SOC_MBUS_ORDER_LE,
	}, {
		.fourcc			= V4L2_PIX_FMT_NV61,
		.name			= "NV61",
984 985
		.bits_per_sample	= 8,
		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
986
		.order			= SOC_MBUS_ORDER_LE,
987
	},
988 989
};

990 991 992 993
/* This will be corrected as we get more formats */
static bool sh_mobile_ceu_packing_supported(const struct soc_mbus_pixelfmt *fmt)
{
	return	fmt->packing == SOC_MBUS_PACKING_NONE ||
994 995
		(fmt->bits_per_sample == 8 &&
		 fmt->packing == SOC_MBUS_PACKING_1_5X8) ||
996 997 998 999 1000 1001
		(fmt->bits_per_sample == 8 &&
		 fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) ||
		(fmt->bits_per_sample > 8 &&
		 fmt->packing == SOC_MBUS_PACKING_EXTEND16);
}

1002 1003
static int client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect);

1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035
static struct soc_camera_device *ctrl_to_icd(struct v4l2_ctrl *ctrl)
{
	return container_of(ctrl->handler, struct soc_camera_device,
							ctrl_handler);
}

static int sh_mobile_ceu_s_ctrl(struct v4l2_ctrl *ctrl)
{
	struct soc_camera_device *icd = ctrl_to_icd(ctrl);
	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
	struct sh_mobile_ceu_dev *pcdev = ici->priv;

	switch (ctrl->id) {
	case V4L2_CID_SHARPNESS:
		switch (icd->current_fmt->host_fmt->fourcc) {
		case V4L2_PIX_FMT_NV12:
		case V4L2_PIX_FMT_NV21:
		case V4L2_PIX_FMT_NV16:
		case V4L2_PIX_FMT_NV61:
			ceu_write(pcdev, CLFCR, !ctrl->val);
			return 0;
		}
		break;
	}

	return -EINVAL;
}

static const struct v4l2_ctrl_ops sh_mobile_ceu_ctrl_ops = {
	.s_ctrl = sh_mobile_ceu_s_ctrl,
};

1036
static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int idx,
1037 1038
				     struct soc_camera_format_xlate *xlate)
{
1039
	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1040
	struct device *dev = icd->parent;
1041 1042
	struct soc_camera_host *ici = to_soc_camera_host(dev);
	struct sh_mobile_ceu_dev *pcdev = ici->priv;
1043
	int ret, k, n;
1044
	int formats = 0;
1045
	struct sh_mobile_ceu_cam *cam;
1046 1047
	enum v4l2_mbus_pixelcode code;
	const struct soc_mbus_pixelfmt *fmt;
1048

1049 1050 1051 1052 1053 1054 1055
	ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
	if (ret < 0)
		/* No more formats */
		return 0;

	fmt = soc_mbus_get_fmtdesc(code);
	if (!fmt) {
1056 1057
		dev_warn(dev, "unsupported format code #%u: %d\n", idx, code);
		return 0;
1058 1059
	}

1060
	if (!pcdev->pdata->csi2) {
1061
		/* Are there any restrictions in the CSI-2 case? */
1062 1063 1064 1065
		ret = sh_mobile_ceu_try_bus_param(icd, fmt->bits_per_sample);
		if (ret < 0)
			return 0;
	}
1066

1067
	if (!icd->host_priv) {
1068 1069 1070 1071
		struct v4l2_mbus_framefmt mf;
		struct v4l2_rect rect;
		int shift = 0;

1072 1073 1074 1075 1076 1077
		/* Add our control */
		v4l2_ctrl_new_std(&icd->ctrl_handler, &sh_mobile_ceu_ctrl_ops,
				  V4L2_CID_SHARPNESS, 0, 1, 1, 0);
		if (icd->ctrl_handler.error)
			return icd->ctrl_handler.error;

1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093
		/* FIXME: subwindow is lost between close / open */

		/* Cache current client geometry */
		ret = client_g_rect(sd, &rect);
		if (ret < 0)
			return ret;

		/* First time */
		ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
		if (ret < 0)
			return ret;

		while ((mf.width > 2560 || mf.height > 1920) && shift < 4) {
			/* Try 2560x1920, 1280x960, 640x480, 320x240 */
			mf.width	= 2560 >> shift;
			mf.height	= 1920 >> shift;
1094 1095 1096
			ret = v4l2_device_call_until_err(sd->v4l2_dev,
					soc_camera_grp_id(icd), video,
					s_mbus_fmt, &mf);
1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109
			if (ret < 0)
				return ret;
			shift++;
		}

		if (shift == 4) {
			dev_err(dev, "Failed to configure the client below %ux%x\n",
				mf.width, mf.height);
			return -EIO;
		}

		dev_geo(dev, "camera fmt %ux%u\n", mf.width, mf.height);

1110 1111 1112 1113
		cam = kzalloc(sizeof(*cam), GFP_KERNEL);
		if (!cam)
			return -ENOMEM;

1114 1115 1116 1117 1118 1119 1120
		/* We are called with current camera crop, initialise subrect with it */
		cam->rect	= rect;
		cam->subrect	= rect;

		cam->width	= mf.width;
		cam->height	= mf.height;

1121 1122 1123 1124 1125
		icd->host_priv = cam;
	} else {
		cam = icd->host_priv;
	}

1126 1127
	/* Beginning of a pass */
	if (!idx)
1128
		cam->extra_fmt = NULL;
1129

1130
	switch (code) {
1131 1132 1133 1134
	case V4L2_MBUS_FMT_UYVY8_2X8:
	case V4L2_MBUS_FMT_VYUY8_2X8:
	case V4L2_MBUS_FMT_YUYV8_2X8:
	case V4L2_MBUS_FMT_YVYU8_2X8:
1135
		if (cam->extra_fmt)
1136
			break;
1137 1138 1139 1140 1141 1142 1143 1144 1145 1146

		/*
		 * Our case is simple so far: for any of the above four camera
		 * formats we add all our four synthesized NV* formats, so,
		 * just marking the device with a single flag suffices. If
		 * the format generation rules are more complex, you would have
		 * to actually hang your already added / counted formats onto
		 * the host_priv pointer and check whether the format you're
		 * going to add now is already there.
		 */
1147
		cam->extra_fmt = sh_mobile_ceu_formats;
1148

1149 1150 1151
		n = ARRAY_SIZE(sh_mobile_ceu_formats);
		formats += n;
		for (k = 0; xlate && k < n; k++) {
1152 1153
			xlate->host_fmt	= &sh_mobile_ceu_formats[k];
			xlate->code	= code;
1154
			xlate++;
1155 1156
			dev_dbg(dev, "Providing format %s using code %d\n",
				sh_mobile_ceu_formats[k].name, code);
1157
		}
1158
		break;
1159
	default:
1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170
		if (!sh_mobile_ceu_packing_supported(fmt))
			return 0;
	}

	/* Generic pass-through */
	formats++;
	if (xlate) {
		xlate->host_fmt	= fmt;
		xlate->code	= code;
		xlate++;
		dev_dbg(dev, "Providing format %s in pass-through mode\n",
1171
			fmt->name);
1172 1173 1174 1175 1176
	}

	return formats;
}

1177 1178 1179 1180 1181 1182
static void sh_mobile_ceu_put_formats(struct soc_camera_device *icd)
{
	kfree(icd->host_priv);
	icd->host_priv = NULL;
}

1183
/* Check if any dimension of r1 is smaller than respective one of r2 */
1184 1185 1186 1187 1188
static bool is_smaller(struct v4l2_rect *r1, struct v4l2_rect *r2)
{
	return r1->width < r2->width || r1->height < r2->height;
}

1189 1190 1191 1192 1193 1194 1195 1196
/* Check if r1 fails to cover r2 */
static bool is_inside(struct v4l2_rect *r1, struct v4l2_rect *r2)
{
	return r1->left > r2->left || r1->top > r2->top ||
		r1->left + r1->width < r2->left + r2->width ||
		r1->top + r1->height < r2->top + r2->height;
}

1197 1198 1199 1200 1201 1202 1203 1204 1205 1206
static unsigned int scale_down(unsigned int size, unsigned int scale)
{
	return (size * 4096 + scale / 2) / scale;
}

static unsigned int calc_generic_scale(unsigned int input, unsigned int output)
{
	return (input * 4096 + output / 2) / output;
}

1207
/* Get and store current client crop */
1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225
static int client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect)
{
	struct v4l2_crop crop;
	struct v4l2_cropcap cap;
	int ret;

	crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

	ret = v4l2_subdev_call(sd, video, g_crop, &crop);
	if (!ret) {
		*rect = crop.c;
		return ret;
	}

	/* Camera driver doesn't support .g_crop(), assume default rectangle */
	cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

	ret = v4l2_subdev_call(sd, video, cropcap, &cap);
1226 1227
	if (!ret)
		*rect = cap.defrect;
1228 1229 1230 1231

	return ret;
}

1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257
/* Client crop has changed, update our sub-rectangle to remain within the area */
static void update_subrect(struct sh_mobile_ceu_cam *cam)
{
	struct v4l2_rect *rect = &cam->rect, *subrect = &cam->subrect;

	if (rect->width < subrect->width)
		subrect->width = rect->width;

	if (rect->height < subrect->height)
		subrect->height = rect->height;

	if (rect->left > subrect->left)
		subrect->left = rect->left;
	else if (rect->left + rect->width >
		 subrect->left + subrect->width)
		subrect->left = rect->left + rect->width -
			subrect->width;

	if (rect->top > subrect->top)
		subrect->top = rect->top;
	else if (rect->top + rect->height >
		 subrect->top + subrect->height)
		subrect->top = rect->top + rect->height -
			subrect->height;
}

1258
/*
1259
 * The common for both scaling and cropping iterative approach is:
1260 1261 1262 1263
 * 1. try if the client can produce exactly what requested by the user
 * 2. if (1) failed, try to double the client image until we get one big enough
 * 3. if (2) failed, try to request the maximum image
 */
1264
static int client_s_crop(struct soc_camera_device *icd, struct v4l2_crop *crop,
1265
			 struct v4l2_crop *cam_crop)
1266
{
1267
	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1268 1269
	struct v4l2_rect *rect = &crop->c, *cam_rect = &cam_crop->c;
	struct device *dev = sd->v4l2_dev->dev;
1270
	struct sh_mobile_ceu_cam *cam = icd->host_priv;
1271
	struct v4l2_cropcap cap;
1272
	int ret;
1273
	unsigned int width, height;
1274

1275 1276 1277 1278
	v4l2_subdev_call(sd, video, s_crop, crop);
	ret = client_g_rect(sd, cam_rect);
	if (ret < 0)
		return ret;
1279

1280 1281 1282 1283 1284 1285
	/*
	 * Now cam_crop contains the current camera input rectangle, and it must
	 * be within camera cropcap bounds
	 */
	if (!memcmp(rect, cam_rect, sizeof(*rect))) {
		/* Even if camera S_CROP failed, but camera rectangle matches */
1286
		dev_dbg(dev, "Camera S_CROP successful for %dx%d@%d:%d\n",
1287
			rect->width, rect->height, rect->left, rect->top);
1288
		cam->rect = *cam_rect;
1289
		return 0;
1290 1291
	}

1292
	/* Try to fix cropping, that camera hasn't managed to set */
1293
	dev_geo(dev, "Fix camera S_CROP for %dx%d@%d:%d to %dx%d@%d:%d\n",
1294
		cam_rect->width, cam_rect->height,
1295
		cam_rect->left, cam_rect->top,
1296 1297 1298 1299 1300 1301 1302
		rect->width, rect->height, rect->left, rect->top);

	/* We need sensor maximum rectangle */
	ret = v4l2_subdev_call(sd, video, cropcap, &cap);
	if (ret < 0)
		return ret;

1303
	/* Put user requested rectangle within sensor bounds */
1304 1305 1306 1307
	soc_camera_limit_side(&rect->left, &rect->width, cap.bounds.left, 2,
			      cap.bounds.width);
	soc_camera_limit_side(&rect->top, &rect->height, cap.bounds.top, 4,
			      cap.bounds.height);
1308 1309 1310 1311 1312

	/*
	 * Popular special case - some cameras can only handle fixed sizes like
	 * QVGA, VGA,... Take care to avoid infinite loop.
	 */
1313 1314 1315
	width = max(cam_rect->width, 2);
	height = max(cam_rect->height, 2);

1316 1317 1318 1319
	/*
	 * Loop as long as sensor is not covering the requested rectangle and
	 * is still within its bounds
	 */
1320 1321 1322
	while (!ret && (is_smaller(cam_rect, rect) ||
			is_inside(cam_rect, rect)) &&
	       (cap.bounds.width > width || cap.bounds.height > height)) {
1323 1324 1325

		width *= 2;
		height *= 2;
1326

1327 1328
		cam_rect->width = width;
		cam_rect->height = height;
1329

1330 1331 1332 1333 1334 1335 1336
		/*
		 * We do not know what capabilities the camera has to set up
		 * left and top borders. We could try to be smarter in iterating
		 * them, e.g., if camera current left is to the right of the
		 * target left, set it to the middle point between the current
		 * left and minimum left. But that would add too much
		 * complexity: we would have to iterate each border separately.
1337
		 * Instead we just drop to the left and top bounds.
1338 1339 1340
		 */
		if (cam_rect->left > rect->left)
			cam_rect->left = cap.bounds.left;
1341

1342 1343
		if (cam_rect->left + cam_rect->width < rect->left + rect->width)
			cam_rect->width = rect->left + rect->width -
1344
				cam_rect->left;
1345

1346 1347
		if (cam_rect->top > rect->top)
			cam_rect->top = cap.bounds.top;
1348

1349 1350
		if (cam_rect->top + cam_rect->height < rect->top + rect->height)
			cam_rect->height = rect->top + rect->height -
1351
				cam_rect->top;
1352

1353 1354
		v4l2_subdev_call(sd, video, s_crop, cam_crop);
		ret = client_g_rect(sd, cam_rect);
1355
		dev_geo(dev, "Camera S_CROP %d for %dx%d@%d:%d\n", ret,
1356
			cam_rect->width, cam_rect->height,
1357
			cam_rect->left, cam_rect->top);
1358 1359
	}

1360 1361
	/* S_CROP must not modify the rectangle */
	if (is_smaller(cam_rect, rect) || is_inside(cam_rect, rect)) {
1362 1363 1364 1365
		/*
		 * The camera failed to configure a suitable cropping,
		 * we cannot use the current rectangle, set to max
		 */
1366 1367 1368
		*cam_rect = cap.bounds;
		v4l2_subdev_call(sd, video, s_crop, cam_crop);
		ret = client_g_rect(sd, cam_rect);
1369
		dev_geo(dev, "Camera S_CROP %d for max %dx%d@%d:%d\n", ret,
1370
			cam_rect->width, cam_rect->height,
1371
			cam_rect->left, cam_rect->top);
1372 1373
	}

1374 1375 1376
	if (!ret) {
		cam->rect = *cam_rect;
		update_subrect(cam);
1377 1378
	}

1379
	return ret;
1380 1381
}

1382
/* Iterative s_mbus_fmt, also updates cached client crop on success */
1383 1384
static int client_s_fmt(struct soc_camera_device *icd,
			struct v4l2_mbus_framefmt *mf, bool ceu_can_scale)
1385
{
1386
	struct sh_mobile_ceu_cam *cam = icd->host_priv;
1387
	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1388
	struct device *dev = icd->parent;
1389
	unsigned int width = mf->width, height = mf->height, tmp_w, tmp_h;
1390 1391
	unsigned int max_width, max_height;
	struct v4l2_cropcap cap;
1392
	bool ceu_1to1;
1393 1394
	int ret;

1395 1396
	ret = v4l2_device_call_until_err(sd->v4l2_dev,
					 soc_camera_grp_id(icd), video,
1397
					 s_mbus_fmt, mf);
1398 1399 1400 1401 1402
	if (ret < 0)
		return ret;

	dev_geo(dev, "camera scaled to %ux%u\n", mf->width, mf->height);

1403 1404 1405 1406 1407 1408 1409 1410
	if (width == mf->width && height == mf->height) {
		/* Perfect! The client has done it all. */
		ceu_1to1 = true;
		goto update_cache;
	}

	ceu_1to1 = false;
	if (!ceu_can_scale)
1411 1412
		goto update_cache;

1413 1414 1415 1416 1417 1418 1419 1420 1421 1422
	cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

	ret = v4l2_subdev_call(sd, video, cropcap, &cap);
	if (ret < 0)
		return ret;

	max_width = min(cap.bounds.width, 2560);
	max_height = min(cap.bounds.height, 1920);

	/* Camera set a format, but geometry is not precise, try to improve */
1423 1424
	tmp_w = mf->width;
	tmp_h = mf->height;
1425 1426 1427 1428 1429 1430

	/* width <= max_width && height <= max_height - guaranteed by try_fmt */
	while ((width > tmp_w || height > tmp_h) &&
	       tmp_w < max_width && tmp_h < max_height) {
		tmp_w = min(2 * tmp_w, max_width);
		tmp_h = min(2 * tmp_h, max_height);
1431 1432
		mf->width = tmp_w;
		mf->height = tmp_h;
1433 1434 1435
		ret = v4l2_device_call_until_err(sd->v4l2_dev,
					soc_camera_grp_id(icd), video,
					s_mbus_fmt, mf);
1436
		dev_geo(dev, "Camera scaled to %ux%u\n",
1437
			mf->width, mf->height);
1438 1439 1440 1441 1442 1443 1444
		if (ret < 0) {
			/* This shouldn't happen */
			dev_err(dev, "Client failed to set format: %d\n", ret);
			return ret;
		}
	}

1445 1446 1447 1448 1449 1450
update_cache:
	/* Update cache */
	ret = client_g_rect(sd, &cam->rect);
	if (ret < 0)
		return ret;

1451 1452 1453 1454
	if (ceu_1to1)
		cam->subrect = cam->rect;
	else
		update_subrect(cam);
1455

1456 1457 1458 1459
	return 0;
}

/**
1460 1461 1462
 * @width	- on output: user width, mapped back to input
 * @height	- on output: user height, mapped back to input
 * @mf		- in- / output camera output window
1463
 */
1464 1465 1466 1467
static int client_scale(struct soc_camera_device *icd,
			struct v4l2_mbus_framefmt *mf,
			unsigned int *width, unsigned int *height,
			bool ceu_can_scale)
1468 1469
{
	struct sh_mobile_ceu_cam *cam = icd->host_priv;
1470
	struct device *dev = icd->parent;
1471
	struct v4l2_mbus_framefmt mf_tmp = *mf;
1472 1473 1474
	unsigned int scale_h, scale_v;
	int ret;

1475 1476 1477 1478
	/*
	 * 5. Apply iterative camera S_FMT for camera user window (also updates
	 *    client crop cache and the imaginary sub-rectangle).
	 */
1479
	ret = client_s_fmt(icd, &mf_tmp, ceu_can_scale);
1480 1481 1482 1483
	if (ret < 0)
		return ret;

	dev_geo(dev, "5: camera scaled to %ux%u\n",
1484
		mf_tmp.width, mf_tmp.height);
1485 1486 1487

	/* 6. Retrieve camera output window (g_fmt) */

1488
	/* unneeded - it is already in "mf_tmp" */
1489

1490 1491 1492
	/* 7. Calculate new client scales. */
	scale_h = calc_generic_scale(cam->rect.width, mf_tmp.width);
	scale_v = calc_generic_scale(cam->rect.height, mf_tmp.height);
1493

1494 1495 1496
	mf->width	= mf_tmp.width;
	mf->height	= mf_tmp.height;
	mf->colorspace	= mf_tmp.colorspace;
1497 1498

	/*
1499
	 * 8. Calculate new CEU crop - apply camera scales to previously
1500
	 *    updated "effective" crop.
1501
	 */
1502 1503
	*width = scale_down(cam->subrect.width, scale_h);
	*height = scale_down(cam->subrect.height, scale_v);
1504

1505
	dev_geo(dev, "8: new client sub-window %ux%u\n", *width, *height);
1506 1507 1508 1509 1510 1511 1512

	return 0;
}

/*
 * CEU can scale and crop, but we don't want to waste bandwidth and kill the
 * framerate by always requesting the maximum image from the client. See
1513
 * Documentation/video4linux/sh_mobile_ceu_camera.txt for a description of
1514 1515 1516 1517 1518 1519
 * scaling and cropping algorithms and for the meaning of referenced here steps.
 */
static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
				  struct v4l2_crop *a)
{
	struct v4l2_rect *rect = &a->c;
1520 1521
	struct device *dev = icd->parent;
	struct soc_camera_host *ici = to_soc_camera_host(dev);
1522 1523 1524
	struct sh_mobile_ceu_dev *pcdev = ici->priv;
	struct v4l2_crop cam_crop;
	struct sh_mobile_ceu_cam *cam = icd->host_priv;
1525
	struct v4l2_rect *cam_rect = &cam_crop.c;
1526
	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1527
	struct v4l2_mbus_framefmt mf;
1528
	unsigned int scale_cam_h, scale_cam_v, scale_ceu_h, scale_ceu_v,
1529
		out_width, out_height;
1530
	int interm_width, interm_height;
1531 1532 1533
	u32 capsr, cflcr;
	int ret;

1534 1535
	dev_geo(dev, "S_CROP(%ux%u@%u:%u)\n", rect->width, rect->height,
		rect->left, rect->top);
1536

1537 1538 1539
	/* During camera cropping its output window can change too, stop CEU */
	capsr = capture_save_reset(pcdev);
	dev_dbg(dev, "CAPSR 0x%x, CFLCR 0x%x\n", capsr, pcdev->cflcr);
1540

1541 1542 1543 1544
	/*
	 * 1. - 2. Apply iterative camera S_CROP for new input window, read back
	 * actual camera rectangle.
	 */
1545
	ret = client_s_crop(icd, a, &cam_crop);
1546 1547 1548
	if (ret < 0)
		return ret;

1549
	dev_geo(dev, "1-2: camera cropped to %ux%u@%u:%u\n",
1550 1551 1552 1553 1554
		cam_rect->width, cam_rect->height,
		cam_rect->left, cam_rect->top);

	/* On success cam_crop contains current camera crop */

1555 1556 1557 1558
	/* 3. Retrieve camera output window */
	ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
	if (ret < 0)
		return ret;
1559

1560 1561
	if (mf.width > 2560 || mf.height > 1920)
		return -EINVAL;
1562

1563 1564 1565
	/* 4. Calculate camera scales */
	scale_cam_h	= calc_generic_scale(cam_rect->width, mf.width);
	scale_cam_v	= calc_generic_scale(cam_rect->height, mf.height);
1566

1567 1568 1569
	/* Calculate intermediate window */
	interm_width	= scale_down(rect->width, scale_cam_h);
	interm_height	= scale_down(rect->height, scale_cam_v);
1570

1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587
	if (interm_width < icd->user_width) {
		u32 new_scale_h;

		new_scale_h = calc_generic_scale(rect->width, icd->user_width);

		mf.width = scale_down(cam_rect->width, new_scale_h);
	}

	if (interm_height < icd->user_height) {
		u32 new_scale_v;

		new_scale_v = calc_generic_scale(rect->height, icd->user_height);

		mf.height = scale_down(cam_rect->height, new_scale_v);
	}

	if (interm_width < icd->user_width || interm_height < icd->user_height) {
1588 1589 1590
		ret = v4l2_device_call_until_err(sd->v4l2_dev,
					soc_camera_grp_id(icd), video,
					s_mbus_fmt, &mf);
1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604
		if (ret < 0)
			return ret;

		dev_geo(dev, "New camera output %ux%u\n", mf.width, mf.height);
		scale_cam_h	= calc_generic_scale(cam_rect->width, mf.width);
		scale_cam_v	= calc_generic_scale(cam_rect->height, mf.height);
		interm_width	= scale_down(rect->width, scale_cam_h);
		interm_height	= scale_down(rect->height, scale_cam_v);
	}

	/* Cache camera output window */
	cam->width	= mf.width;
	cam->height	= mf.height;

1605 1606 1607 1608 1609 1610 1611
	if (pcdev->image_mode) {
		out_width	= min(interm_width, icd->user_width);
		out_height	= min(interm_height, icd->user_height);
	} else {
		out_width	= interm_width;
		out_height	= interm_height;
	}
1612 1613

	/*
1614 1615
	 * 5. Calculate CEU scales from camera scales from results of (5) and
	 *    the user window
1616
	 */
1617 1618
	scale_ceu_h	= calc_scale(interm_width, &out_width);
	scale_ceu_v	= calc_scale(interm_height, &out_height);
1619

1620 1621 1622
	dev_geo(dev, "5: CEU scales %u:%u\n", scale_ceu_h, scale_ceu_v);

	/* Apply CEU scales. */
1623 1624 1625 1626 1627 1628
	cflcr = scale_ceu_h | (scale_ceu_v << 16);
	if (cflcr != pcdev->cflcr) {
		pcdev->cflcr = cflcr;
		ceu_write(pcdev, CFLCR, cflcr);
	}

1629 1630 1631
	icd->user_width	 = out_width & ~3;
	icd->user_height = out_height & ~3;
	/* Offsets are applied at the CEU scaling filter input */
1632 1633
	cam->ceu_left	 = scale_down(rect->left - cam_rect->left, scale_cam_h) & ~1;
	cam->ceu_top	 = scale_down(rect->top - cam_rect->top, scale_cam_v) & ~1;
1634 1635 1636 1637 1638 1639 1640 1641 1642 1643

	/* 6. Use CEU cropping to crop to the new window. */
	sh_mobile_ceu_set_rect(icd);

	cam->subrect = *rect;

	dev_geo(dev, "6: CEU cropped to %ux%u@%u:%u\n",
		icd->user_width, icd->user_height,
		cam->ceu_left, cam->ceu_top);

1644
	/* Restore capture. The CE bit can be cleared by the hardware */
1645 1646 1647 1648 1649 1650
	if (pcdev->active)
		capsr |= 1;
	capture_restore(pcdev, capsr);

	/* Even if only camera cropping succeeded */
	return ret;
1651 1652
}

1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669
static int sh_mobile_ceu_get_crop(struct soc_camera_device *icd,
				  struct v4l2_crop *a)
{
	struct sh_mobile_ceu_cam *cam = icd->host_priv;

	a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	a->c = cam->subrect;

	return 0;
}

/*
 * Calculate real client output window by applying new scales to the current
 * client crop. New scales are calculated from the requested output format and
 * CEU crop, mapped backed onto the client input (subrect).
 */
static void calculate_client_output(struct soc_camera_device *icd,
1670
		const struct v4l2_pix_format *pix, struct v4l2_mbus_framefmt *mf)
1671 1672
{
	struct sh_mobile_ceu_cam *cam = icd->host_priv;
1673
	struct device *dev = icd->parent;
1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705
	struct v4l2_rect *cam_subrect = &cam->subrect;
	unsigned int scale_v, scale_h;

	if (cam_subrect->width == cam->rect.width &&
	    cam_subrect->height == cam->rect.height) {
		/* No sub-cropping */
		mf->width	= pix->width;
		mf->height	= pix->height;
		return;
	}

	/* 1.-2. Current camera scales and subwin - cached. */

	dev_geo(dev, "2: subwin %ux%u@%u:%u\n",
		cam_subrect->width, cam_subrect->height,
		cam_subrect->left, cam_subrect->top);

	/*
	 * 3. Calculate new combined scales from input sub-window to requested
	 *    user window.
	 */

	/*
	 * TODO: CEU cannot scale images larger than VGA to smaller than SubQCIF
	 * (128x96) or larger than VGA
	 */
	scale_h = calc_generic_scale(cam_subrect->width, pix->width);
	scale_v = calc_generic_scale(cam_subrect->height, pix->height);

	dev_geo(dev, "3: scales %u:%u\n", scale_h, scale_v);

	/*
1706 1707
	 * 4. Calculate desired client output window by applying combined scales
	 *    to client (real) input window.
1708 1709 1710 1711 1712
	 */
	mf->width	= scale_down(cam->rect.width, scale_h);
	mf->height	= scale_down(cam->rect.height, scale_v);
}

1713
/* Similar to set_crop multistage iterative algorithm */
1714
static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
1715
				 struct v4l2_format *f)
1716
{
1717 1718
	struct device *dev = icd->parent;
	struct soc_camera_host *ici = to_soc_camera_host(dev);
1719
	struct sh_mobile_ceu_dev *pcdev = ici->priv;
1720 1721
	struct sh_mobile_ceu_cam *cam = icd->host_priv;
	struct v4l2_pix_format *pix = &f->fmt.pix;
1722
	struct v4l2_mbus_framefmt mf;
1723
	__u32 pixfmt = pix->pixelformat;
1724
	const struct soc_camera_format_xlate *xlate;
1725 1726
	/* Keep Compiler Happy */
	unsigned int ceu_sub_width = 0, ceu_sub_height = 0;
1727 1728
	u16 scale_v, scale_h;
	int ret;
1729 1730
	bool image_mode;
	enum v4l2_field field;
1731 1732 1733 1734 1735

	switch (pix->field) {
	default:
		pix->field = V4L2_FIELD_NONE;
		/* fall-through */
1736 1737
	case V4L2_FIELD_INTERLACED_TB:
	case V4L2_FIELD_INTERLACED_BT:
1738
	case V4L2_FIELD_NONE:
1739 1740 1741 1742
		field = pix->field;
		break;
	case V4L2_FIELD_INTERLACED:
		field = V4L2_FIELD_INTERLACED_TB;
1743 1744
		break;
	}
1745

1746 1747
	xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
	if (!xlate) {
1748
		dev_warn(dev, "Format %x not found\n", pixfmt);
1749
		return -EINVAL;
1750 1751
	}

1752
	/* 1.-4. Calculate desired client output geometry */
1753
	calculate_client_output(icd, pix, &mf);
1754 1755 1756
	mf.field	= pix->field;
	mf.colorspace	= pix->colorspace;
	mf.code		= xlate->code;
1757

1758 1759 1760 1761 1762
	switch (pixfmt) {
	case V4L2_PIX_FMT_NV12:
	case V4L2_PIX_FMT_NV21:
	case V4L2_PIX_FMT_NV16:
	case V4L2_PIX_FMT_NV61:
1763
		image_mode = true;
1764 1765
		break;
	default:
1766
		image_mode = false;
1767
	}
1768

1769
	dev_geo(dev, "S_FMT(pix=0x%x, fld 0x%x, code 0x%x, %ux%u)\n", pixfmt, mf.field, mf.code,
1770 1771
		pix->width, pix->height);

1772
	dev_geo(dev, "4: request camera output %ux%u\n", mf.width, mf.height);
1773

1774
	/* 5. - 9. */
1775
	ret = client_scale(icd, &mf, &ceu_sub_width, &ceu_sub_height,
1776
			   image_mode && V4L2_FIELD_NONE == field);
1777

1778
	dev_geo(dev, "5-9: client scale return %d\n", ret);
1779 1780 1781

	/* Done with the camera. Now see if we can improve the result */

1782 1783
	dev_geo(dev, "fmt %ux%u, requested %ux%u\n",
		mf.width, mf.height, pix->width, pix->height);
1784 1785 1786
	if (ret < 0)
		return ret;

1787 1788 1789
	if (mf.code != xlate->code)
		return -EINVAL;

1790 1791 1792 1793
	/* 9. Prepare CEU crop */
	cam->width = mf.width;
	cam->height = mf.height;

1794
	/* 10. Use CEU scaling to scale to the requested user window. */
1795 1796

	/* We cannot scale up */
1797 1798
	if (pix->width > ceu_sub_width)
		ceu_sub_width = pix->width;
1799

1800 1801
	if (pix->height > ceu_sub_height)
		ceu_sub_height = pix->height;
1802

1803 1804 1805 1806
	pix->colorspace = mf.colorspace;

	if (image_mode) {
		/* Scale pix->{width x height} down to width x height */
1807 1808
		scale_h		= calc_scale(ceu_sub_width, &pix->width);
		scale_v		= calc_scale(ceu_sub_height, &pix->height);
1809
	} else {
1810 1811 1812 1813
		pix->width	= ceu_sub_width;
		pix->height	= ceu_sub_height;
		scale_h		= 0;
		scale_v		= 0;
1814
	}
1815

1816 1817 1818 1819 1820 1821 1822
	pcdev->cflcr = scale_h | (scale_v << 16);

	/*
	 * We have calculated CFLCR, the actual configuration will be performed
	 * in sh_mobile_ceu_set_bus_param()
	 */

1823
	dev_geo(dev, "10: W: %u : 0x%x = %u, H: %u : 0x%x = %u\n",
1824 1825
		ceu_sub_width, scale_h, pix->width,
		ceu_sub_height, scale_v, pix->height);
1826

1827 1828
	cam->code		= xlate->code;
	icd->current_fmt	= xlate;
1829

1830
	pcdev->field = field;
1831
	pcdev->image_mode = image_mode;
1832

1833 1834 1835 1836
	/* CFSZR requirement */
	pix->width	&= ~3;
	pix->height	&= ~3;

1837
	return 0;
1838 1839
}

1840 1841
static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
				 struct v4l2_format *f)
1842
{
1843
	const struct soc_camera_format_xlate *xlate;
1844
	struct v4l2_pix_format *pix = &f->fmt.pix;
1845
	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1846
	struct v4l2_mbus_framefmt mf;
1847
	__u32 pixfmt = pix->pixelformat;
1848
	int width, height;
1849
	int ret;
1850

1851
	dev_geo(icd->parent, "TRY_FMT(pix=0x%x, %ux%u)\n",
1852 1853
		 pixfmt, pix->width, pix->height);

1854 1855
	xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
	if (!xlate) {
1856
		dev_warn(icd->parent, "Format %x not found\n", pixfmt);
1857
		return -EINVAL;
1858
	}
1859

1860 1861
	/* FIXME: calculate using depth and bus width */

1862 1863
	/* CFSZR requires height and width to be 4-pixel aligned */
	v4l_bound_align_image(&pix->width, 2, 2560, 2,
1864
			      &pix->height, 4, 1920, 2, 0);
1865

1866 1867 1868
	width = pix->width;
	height = pix->height;

1869
	/* limit to sensor capabilities */
1870 1871 1872 1873 1874 1875
	mf.width	= pix->width;
	mf.height	= pix->height;
	mf.field	= pix->field;
	mf.code		= xlate->code;
	mf.colorspace	= pix->colorspace;

1876 1877
	ret = v4l2_device_call_until_err(sd->v4l2_dev, soc_camera_grp_id(icd),
					 video, try_mbus_fmt, &mf);
1878 1879 1880
	if (ret < 0)
		return ret;

1881 1882 1883 1884 1885
	pix->width	= mf.width;
	pix->height	= mf.height;
	pix->field	= mf.field;
	pix->colorspace	= mf.colorspace;

1886 1887 1888 1889 1890 1891 1892 1893
	switch (pixfmt) {
	case V4L2_PIX_FMT_NV12:
	case V4L2_PIX_FMT_NV21:
	case V4L2_PIX_FMT_NV16:
	case V4L2_PIX_FMT_NV61:
		/* FIXME: check against rect_max after converting soc-camera */
		/* We can scale precisely, need a bigger image from camera */
		if (pix->width < width || pix->height < height) {
1894 1895 1896 1897 1898 1899 1900
			/*
			 * We presume, the sensor behaves sanely, i.e., if
			 * requested a bigger rectangle, it will not return a
			 * smaller one.
			 */
			mf.width = 2560;
			mf.height = 1920;
1901 1902 1903
			ret = v4l2_device_call_until_err(sd->v4l2_dev,
					soc_camera_grp_id(icd), video,
					try_mbus_fmt, &mf);
1904 1905
			if (ret < 0) {
				/* Shouldn't actually happen... */
1906
				dev_err(icd->parent,
1907 1908
					"FIXME: client try_fmt() = %d\n", ret);
				return ret;
1909 1910
			}
		}
1911 1912
		/* We will scale exactly */
		if (mf.width > width)
1913
			pix->width = width;
1914
		if (mf.height > height)
1915
			pix->height = height;
1916 1917
	}

1918 1919 1920
	pix->width	&= ~3;
	pix->height	&= ~3;

1921
	dev_geo(icd->parent, "%s(): return %d, fmt 0x%x, %ux%u\n",
1922 1923
		__func__, ret, pix->pixelformat, pix->width, pix->height);

1924
	return ret;
1925 1926
}

1927 1928 1929 1930
static int sh_mobile_ceu_set_livecrop(struct soc_camera_device *icd,
				      struct v4l2_crop *a)
{
	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1931
	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942
	struct sh_mobile_ceu_dev *pcdev = ici->priv;
	u32 out_width = icd->user_width, out_height = icd->user_height;
	int ret;

	/* Freeze queue */
	pcdev->frozen = 1;
	/* Wait for frame */
	ret = wait_for_completion_interruptible(&pcdev->complete);
	/* Stop the client */
	ret = v4l2_subdev_call(sd, video, s_stream, 0);
	if (ret < 0)
1943
		dev_warn(icd->parent,
1944 1945 1946 1947 1948
			 "Client failed to stop the stream: %d\n", ret);
	else
		/* Do the crop, if it fails, there's nothing more we can do */
		sh_mobile_ceu_set_crop(icd, a);

1949
	dev_geo(icd->parent, "Output after crop: %ux%u\n", icd->user_width, icd->user_height);
1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966

	if (icd->user_width != out_width || icd->user_height != out_height) {
		struct v4l2_format f = {
			.type	= V4L2_BUF_TYPE_VIDEO_CAPTURE,
			.fmt.pix	= {
				.width		= out_width,
				.height		= out_height,
				.pixelformat	= icd->current_fmt->host_fmt->fourcc,
				.field		= pcdev->field,
				.colorspace	= icd->colorspace,
			},
		};
		ret = sh_mobile_ceu_set_fmt(icd, &f);
		if (!ret && (out_width != f.fmt.pix.width ||
			     out_height != f.fmt.pix.height))
			ret = -EINVAL;
		if (!ret) {
1967 1968
			icd->user_width		= out_width & ~3;
			icd->user_height	= out_height & ~3;
1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983
			ret = sh_mobile_ceu_set_bus_param(icd,
					icd->current_fmt->host_fmt->fourcc);
		}
	}

	/* Thaw the queue */
	pcdev->frozen = 0;
	spin_lock_irq(&pcdev->lock);
	sh_mobile_ceu_capture(pcdev);
	spin_unlock_irq(&pcdev->lock);
	/* Start the client */
	ret = v4l2_subdev_call(sd, video, s_stream, 1);
	return ret;
}

1984 1985
static unsigned int sh_mobile_ceu_poll(struct file *file, poll_table *pt)
{
1986
	struct soc_camera_device *icd = file->private_data;
1987

1988
	return vb2_poll(&icd->vb2_vidq, file, pt);
1989 1990 1991 1992 1993 1994 1995 1996 1997 1998
}

static int sh_mobile_ceu_querycap(struct soc_camera_host *ici,
				  struct v4l2_capability *cap)
{
	strlcpy(cap->card, "SuperH_Mobile_CEU", sizeof(cap->card));
	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
	return 0;
}

1999 2000
static int sh_mobile_ceu_init_videobuf(struct vb2_queue *q,
				       struct soc_camera_device *icd)
2001
{
2002 2003 2004 2005 2006 2007 2008 2009
	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	q->io_modes = VB2_MMAP | VB2_USERPTR;
	q->drv_priv = icd;
	q->ops = &sh_mobile_ceu_videobuf_ops;
	q->mem_ops = &vb2_dma_contig_memops;
	q->buf_struct_size = sizeof(struct sh_mobile_ceu_buffer);

	return vb2_queue_init(q);
2010 2011 2012 2013 2014 2015
}

static struct soc_camera_host_ops sh_mobile_ceu_host_ops = {
	.owner		= THIS_MODULE,
	.add		= sh_mobile_ceu_add_device,
	.remove		= sh_mobile_ceu_remove_device,
2016
	.get_formats	= sh_mobile_ceu_get_formats,
2017
	.put_formats	= sh_mobile_ceu_put_formats,
2018
	.get_crop	= sh_mobile_ceu_get_crop,
2019
	.set_crop	= sh_mobile_ceu_set_crop,
2020
	.set_livecrop	= sh_mobile_ceu_set_livecrop,
2021 2022
	.set_fmt	= sh_mobile_ceu_set_fmt,
	.try_fmt	= sh_mobile_ceu_try_fmt,
2023 2024 2025
	.poll		= sh_mobile_ceu_poll,
	.querycap	= sh_mobile_ceu_querycap,
	.set_bus_param	= sh_mobile_ceu_set_bus_param,
2026
	.init_videobuf2	= sh_mobile_ceu_init_videobuf,
2027 2028
};

2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052
struct bus_wait {
	struct notifier_block	notifier;
	struct completion	completion;
	struct device		*dev;
};

static int bus_notify(struct notifier_block *nb,
		      unsigned long action, void *data)
{
	struct device *dev = data;
	struct bus_wait *wait = container_of(nb, struct bus_wait, notifier);

	if (wait->dev != dev)
		return NOTIFY_DONE;

	switch (action) {
	case BUS_NOTIFY_UNBOUND_DRIVER:
		/* Protect from module unloading */
		wait_for_completion(&wait->completion);
		return NOTIFY_OK;
	}
	return NOTIFY_DONE;
}

2053
static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
2054 2055 2056 2057 2058 2059
{
	struct sh_mobile_ceu_dev *pcdev;
	struct resource *res;
	void __iomem *base;
	unsigned int irq;
	int err = 0;
2060 2061 2062 2063
	struct bus_wait wait = {
		.completion = COMPLETION_INITIALIZER_ONSTACK(wait.completion),
		.notifier.notifier_call = bus_notify,
	};
2064
	struct sh_mobile_ceu_companion *csi2;
2065 2066 2067

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	irq = platform_get_irq(pdev, 0);
2068
	if (!res || (int)irq <= 0) {
2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082
		dev_err(&pdev->dev, "Not enough CEU platform resources.\n");
		err = -ENODEV;
		goto exit;
	}

	pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
	if (!pcdev) {
		dev_err(&pdev->dev, "Could not allocate pcdev\n");
		err = -ENOMEM;
		goto exit;
	}

	INIT_LIST_HEAD(&pcdev->capture);
	spin_lock_init(&pcdev->lock);
2083
	init_completion(&pcdev->complete);
2084 2085 2086 2087 2088 2089 2090 2091

	pcdev->pdata = pdev->dev.platform_data;
	if (!pcdev->pdata) {
		err = -EINVAL;
		dev_err(&pdev->dev, "CEU platform data not set.\n");
		goto exit_kfree;
	}

2092
	base = ioremap_nocache(res->start, resource_size(res));
2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106
	if (!base) {
		err = -ENXIO;
		dev_err(&pdev->dev, "Unable to ioremap CEU registers.\n");
		goto exit_kfree;
	}

	pcdev->irq = irq;
	pcdev->base = base;
	pcdev->video_limit = 0; /* only enabled if second resource exists */

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if (res) {
		err = dma_declare_coherent_memory(&pdev->dev, res->start,
						  res->start,
2107
						  resource_size(res),
2108 2109 2110 2111 2112 2113 2114 2115
						  DMA_MEMORY_MAP |
						  DMA_MEMORY_EXCLUSIVE);
		if (!err) {
			dev_err(&pdev->dev, "Unable to declare CEU memory.\n");
			err = -ENXIO;
			goto exit_iounmap;
		}

2116
		pcdev->video_limit = resource_size(res);
2117 2118 2119 2120
	}

	/* request irq */
	err = request_irq(pcdev->irq, sh_mobile_ceu_irq, IRQF_DISABLED,
2121
			  dev_name(&pdev->dev), pcdev);
2122 2123 2124 2125 2126
	if (err) {
		dev_err(&pdev->dev, "Unable to register CEU interrupt.\n");
		goto exit_release_mem;
	}

2127 2128 2129
	pm_suspend_ignore_children(&pdev->dev, true);
	pm_runtime_enable(&pdev->dev);
	pm_runtime_resume(&pdev->dev);
2130

2131
	pcdev->ici.priv = pcdev;
2132
	pcdev->ici.v4l2_dev.dev = &pdev->dev;
2133
	pcdev->ici.nr = pdev->id;
2134 2135
	pcdev->ici.drv_name = dev_name(&pdev->dev);
	pcdev->ici.ops = &sh_mobile_ceu_host_ops;
2136

2137 2138 2139 2140 2141 2142 2143 2144 2145 2146
	pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
	if (IS_ERR(pcdev->alloc_ctx)) {
		err = PTR_ERR(pcdev->alloc_ctx);
		goto exit_free_clk;
	}

	err = soc_camera_host_register(&pcdev->ici);
	if (err)
		goto exit_free_ctx;

2147
	/* CSI2 interfacing */
2148
	csi2 = pcdev->pdata->csi2;
2149
	if (csi2) {
2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175
		struct platform_device *csi2_pdev =
			platform_device_alloc("sh-mobile-csi2", csi2->id);
		struct sh_csi2_pdata *csi2_pdata = csi2->platform_data;

		if (!csi2_pdev) {
			err = -ENOMEM;
			goto exit_host_unregister;
		}

		pcdev->csi2_pdev		= csi2_pdev;

		err = platform_device_add_data(csi2_pdev, csi2_pdata, sizeof(*csi2_pdata));
		if (err < 0)
			goto exit_pdev_put;

		csi2_pdata			= csi2_pdev->dev.platform_data;
		csi2_pdata->v4l2_dev		= &pcdev->ici.v4l2_dev;

		csi2_pdev->resource		= csi2->resource;
		csi2_pdev->num_resources	= csi2->num_resources;

		err = platform_device_add(csi2_pdev);
		if (err < 0)
			goto exit_pdev_put;

		wait.dev = &csi2_pdev->dev;
2176 2177 2178

		err = bus_register_notifier(&platform_bus_type, &wait.notifier);
		if (err < 0)
2179
			goto exit_pdev_unregister;
2180 2181 2182 2183 2184 2185

		/*
		 * From this point the driver module will not unload, until
		 * we complete the completion.
		 */

2186
		if (!csi2_pdev->dev.driver) {
2187 2188 2189 2190
			complete(&wait.completion);
			/* Either too late, or probing failed */
			bus_unregister_notifier(&platform_bus_type, &wait.notifier);
			err = -ENXIO;
2191
			goto exit_pdev_unregister;
2192 2193 2194 2195 2196 2197 2198 2199
		}

		/*
		 * The module is still loaded, in the worst case it is hanging
		 * in device release on our completion. So, _now_ dereferencing
		 * the "owner" is safe!
		 */

2200
		err = try_module_get(csi2_pdev->dev.driver->owner);
2201 2202 2203 2204 2205 2206

		/* Let notifier complete, if it has been locked */
		complete(&wait.completion);
		bus_unregister_notifier(&platform_bus_type, &wait.notifier);
		if (!err) {
			err = -ENODEV;
2207
			goto exit_pdev_unregister;
2208 2209 2210
		}
	}

2211 2212
	return 0;

2213 2214 2215 2216 2217 2218 2219
exit_pdev_unregister:
	platform_device_del(pcdev->csi2_pdev);
exit_pdev_put:
	pcdev->csi2_pdev->resource = NULL;
	platform_device_put(pcdev->csi2_pdev);
exit_host_unregister:
	soc_camera_host_unregister(&pcdev->ici);
2220 2221
exit_free_ctx:
	vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
2222 2223
exit_free_clk:
	pm_runtime_disable(&pdev->dev);
2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235
	free_irq(pcdev->irq, pcdev);
exit_release_mem:
	if (platform_get_resource(pdev, IORESOURCE_MEM, 1))
		dma_release_declared_memory(&pdev->dev);
exit_iounmap:
	iounmap(base);
exit_kfree:
	kfree(pcdev);
exit:
	return err;
}

2236
static int __devexit sh_mobile_ceu_remove(struct platform_device *pdev)
2237
{
2238 2239 2240
	struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
	struct sh_mobile_ceu_dev *pcdev = container_of(soc_host,
					struct sh_mobile_ceu_dev, ici);
2241
	struct platform_device *csi2_pdev = pcdev->csi2_pdev;
2242

2243
	soc_camera_host_unregister(soc_host);
2244
	pm_runtime_disable(&pdev->dev);
2245 2246 2247 2248
	free_irq(pcdev->irq, pcdev);
	if (platform_get_resource(pdev, IORESOURCE_MEM, 1))
		dma_release_declared_memory(&pdev->dev);
	iounmap(pcdev->base);
2249
	vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
2250 2251 2252 2253 2254 2255 2256
	if (csi2_pdev && csi2_pdev->dev.driver) {
		struct module *csi2_drv = csi2_pdev->dev.driver->owner;
		platform_device_del(csi2_pdev);
		csi2_pdev->resource = NULL;
		platform_device_put(csi2_pdev);
		module_put(csi2_drv);
	}
2257
	kfree(pcdev);
2258

2259 2260 2261
	return 0;
}

2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273
static int sh_mobile_ceu_runtime_nop(struct device *dev)
{
	/* Runtime PM callback shared between ->runtime_suspend()
	 * and ->runtime_resume(). Simply returns success.
	 *
	 * This driver re-initializes all registers after
	 * pm_runtime_get_sync() anyway so there is no need
	 * to save and restore registers here.
	 */
	return 0;
}

2274
static const struct dev_pm_ops sh_mobile_ceu_dev_pm_ops = {
2275 2276 2277 2278
	.runtime_suspend = sh_mobile_ceu_runtime_nop,
	.runtime_resume = sh_mobile_ceu_runtime_nop,
};

2279 2280 2281
static struct platform_driver sh_mobile_ceu_driver = {
	.driver 	= {
		.name	= "sh_mobile_ceu",
2282
		.pm	= &sh_mobile_ceu_dev_pm_ops,
2283 2284
	},
	.probe		= sh_mobile_ceu_probe,
2285
	.remove		= __devexit_p(sh_mobile_ceu_remove),
2286 2287 2288 2289
};

static int __init sh_mobile_ceu_init(void)
{
2290 2291
	/* Whatever return code */
	request_module("sh_mobile_csi2");
2292 2293 2294 2295 2296
	return platform_driver_register(&sh_mobile_ceu_driver);
}

static void __exit sh_mobile_ceu_exit(void)
{
2297
	platform_driver_unregister(&sh_mobile_ceu_driver);
2298 2299 2300 2301 2302 2303 2304 2305
}

module_init(sh_mobile_ceu_init);
module_exit(sh_mobile_ceu_exit);

MODULE_DESCRIPTION("SuperH Mobile CEU driver");
MODULE_AUTHOR("Magnus Damm");
MODULE_LICENSE("GPL");
2306
MODULE_VERSION("0.0.6");
2307
MODULE_ALIAS("platform:sh_mobile_ceu");