xref: /linux/drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c (revision 7f71507851fc7764b36a3221839607d3a45c2025)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Allwinner sun8i DE2 rotation driver
4  *
5  * Copyright (C) 2020 Jernej Skrabec <jernej.skrabec@siol.net>
6  */
7 
8 #include <linux/clk.h>
9 #include <linux/interrupt.h>
10 #include <linux/io.h>
11 #include <linux/iopoll.h>
12 #include <linux/mod_devicetable.h>
13 #include <linux/module.h>
14 #include <linux/platform_device.h>
15 #include <linux/pm_runtime.h>
16 #include <linux/reset.h>
17 
18 #include <media/v4l2-device.h>
19 #include <media/v4l2-event.h>
20 #include <media/v4l2-ioctl.h>
21 #include <media/v4l2-mem2mem.h>
22 
23 #include "sun8i-formats.h"
24 #include "sun8i-rotate.h"
25 
26 static inline u32 rotate_read(struct rotate_dev *dev, u32 reg)
27 {
28 	return readl(dev->base + reg);
29 }
30 
31 static inline void rotate_write(struct rotate_dev *dev, u32 reg, u32 value)
32 {
33 	writel(value, dev->base + reg);
34 }
35 
36 static inline void rotate_set_bits(struct rotate_dev *dev, u32 reg, u32 bits)
37 {
38 	writel(readl(dev->base + reg) | bits, dev->base + reg);
39 }
40 
41 static void rotate_calc_addr_pitch(dma_addr_t buffer,
42 				   u32 bytesperline, u32 height,
43 				   const struct rotate_format *fmt,
44 				   dma_addr_t *addr, u32 *pitch)
45 {
46 	u32 size;
47 	int i;
48 
49 	for (i = 0; i < fmt->planes; i++) {
50 		pitch[i] = bytesperline;
51 		addr[i] = buffer;
52 		if (i > 0)
53 			pitch[i] /= fmt->hsub / fmt->bpp[i];
54 		size = pitch[i] * height;
55 		if (i > 0)
56 			size /= fmt->vsub;
57 		buffer += size;
58 	}
59 }
60 
61 static void rotate_device_run(void *priv)
62 {
63 	struct rotate_ctx *ctx = priv;
64 	struct rotate_dev *dev = ctx->dev;
65 	struct vb2_v4l2_buffer *src, *dst;
66 	const struct rotate_format *fmt;
67 	dma_addr_t addr[3];
68 	u32 val, pitch[3];
69 
70 	src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
71 	dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
72 
73 	v4l2_m2m_buf_copy_metadata(src, dst, true);
74 
75 	val = ROTATE_GLB_CTL_MODE(ROTATE_MODE_COPY_ROTATE);
76 	if (ctx->hflip)
77 		val |= ROTATE_GLB_CTL_HFLIP;
78 	if (ctx->vflip)
79 		val |= ROTATE_GLB_CTL_VFLIP;
80 	val |= ROTATE_GLB_CTL_ROTATION(ctx->rotate / 90);
81 	if (ctx->rotate != 90 && ctx->rotate != 270)
82 		val |= ROTATE_GLB_CTL_BURST_LEN(ROTATE_BURST_64);
83 	else
84 		val |= ROTATE_GLB_CTL_BURST_LEN(ROTATE_BURST_8);
85 	rotate_write(dev, ROTATE_GLB_CTL, val);
86 
87 	fmt = rotate_find_format(ctx->src_fmt.pixelformat);
88 	if (!fmt)
89 		return;
90 
91 	rotate_write(dev, ROTATE_IN_FMT, ROTATE_IN_FMT_FORMAT(fmt->hw_format));
92 
93 	rotate_calc_addr_pitch(vb2_dma_contig_plane_dma_addr(&src->vb2_buf, 0),
94 			       ctx->src_fmt.bytesperline, ctx->src_fmt.height,
95 			       fmt, addr, pitch);
96 
97 	rotate_write(dev, ROTATE_IN_SIZE,
98 		     ROTATE_SIZE(ctx->src_fmt.width, ctx->src_fmt.height));
99 
100 	rotate_write(dev, ROTATE_IN_PITCH0, pitch[0]);
101 	rotate_write(dev, ROTATE_IN_PITCH1, pitch[1]);
102 	rotate_write(dev, ROTATE_IN_PITCH2, pitch[2]);
103 
104 	rotate_write(dev, ROTATE_IN_ADDRL0, addr[0]);
105 	rotate_write(dev, ROTATE_IN_ADDRL1, addr[1]);
106 	rotate_write(dev, ROTATE_IN_ADDRL2, addr[2]);
107 
108 	rotate_write(dev, ROTATE_IN_ADDRH0, 0);
109 	rotate_write(dev, ROTATE_IN_ADDRH1, 0);
110 	rotate_write(dev, ROTATE_IN_ADDRH2, 0);
111 
112 	fmt = rotate_find_format(ctx->dst_fmt.pixelformat);
113 	if (!fmt)
114 		return;
115 
116 	rotate_calc_addr_pitch(vb2_dma_contig_plane_dma_addr(&dst->vb2_buf, 0),
117 			       ctx->dst_fmt.bytesperline, ctx->dst_fmt.height,
118 			       fmt, addr, pitch);
119 
120 	rotate_write(dev, ROTATE_OUT_SIZE,
121 		     ROTATE_SIZE(ctx->dst_fmt.width, ctx->dst_fmt.height));
122 
123 	rotate_write(dev, ROTATE_OUT_PITCH0, pitch[0]);
124 	rotate_write(dev, ROTATE_OUT_PITCH1, pitch[1]);
125 	rotate_write(dev, ROTATE_OUT_PITCH2, pitch[2]);
126 
127 	rotate_write(dev, ROTATE_OUT_ADDRL0, addr[0]);
128 	rotate_write(dev, ROTATE_OUT_ADDRL1, addr[1]);
129 	rotate_write(dev, ROTATE_OUT_ADDRL2, addr[2]);
130 
131 	rotate_write(dev, ROTATE_OUT_ADDRH0, 0);
132 	rotate_write(dev, ROTATE_OUT_ADDRH1, 0);
133 	rotate_write(dev, ROTATE_OUT_ADDRH2, 0);
134 
135 	rotate_set_bits(dev, ROTATE_INT, ROTATE_INT_FINISH_IRQ_EN);
136 	rotate_set_bits(dev, ROTATE_GLB_CTL, ROTATE_GLB_CTL_START);
137 }
138 
139 static irqreturn_t rotate_irq(int irq, void *data)
140 {
141 	struct vb2_v4l2_buffer *buffer;
142 	struct rotate_dev *dev = data;
143 	struct rotate_ctx *ctx;
144 	unsigned int val;
145 
146 	ctx = v4l2_m2m_get_curr_priv(dev->m2m_dev);
147 	if (!ctx) {
148 		v4l2_err(&dev->v4l2_dev,
149 			 "Instance released before the end of transaction\n");
150 		return IRQ_NONE;
151 	}
152 
153 	val = rotate_read(dev, ROTATE_INT);
154 	if (!(val & ROTATE_INT_FINISH_IRQ))
155 		return IRQ_NONE;
156 
157 	/* clear flag and disable irq */
158 	rotate_write(dev, ROTATE_INT, ROTATE_INT_FINISH_IRQ);
159 
160 	buffer = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
161 	v4l2_m2m_buf_done(buffer, VB2_BUF_STATE_DONE);
162 
163 	buffer = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
164 	v4l2_m2m_buf_done(buffer, VB2_BUF_STATE_DONE);
165 
166 	v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx);
167 
168 	return IRQ_HANDLED;
169 }
170 
171 static inline struct rotate_ctx *rotate_file2ctx(struct file *file)
172 {
173 	return container_of(file->private_data, struct rotate_ctx, fh);
174 }
175 
176 static void rotate_prepare_format(struct v4l2_pix_format *pix_fmt)
177 {
178 	unsigned int height, width, alignment, sizeimage, size, bpl;
179 	const struct rotate_format *fmt;
180 	int i;
181 
182 	fmt = rotate_find_format(pix_fmt->pixelformat);
183 	if (!fmt)
184 		return;
185 
186 	width = ALIGN(pix_fmt->width, fmt->hsub);
187 	height = ALIGN(pix_fmt->height, fmt->vsub);
188 
189 	/* all pitches have to be 16 byte aligned */
190 	alignment = 16;
191 	if (fmt->planes > 1)
192 		alignment *= fmt->hsub / fmt->bpp[1];
193 	bpl = ALIGN(width * fmt->bpp[0], alignment);
194 
195 	sizeimage = 0;
196 	for (i = 0; i < fmt->planes; i++) {
197 		size = bpl * height;
198 		if (i > 0) {
199 			size *= fmt->bpp[i];
200 			size /= fmt->hsub;
201 			size /= fmt->vsub;
202 		}
203 		sizeimage += size;
204 	}
205 
206 	pix_fmt->width = width;
207 	pix_fmt->height = height;
208 	pix_fmt->bytesperline = bpl;
209 	pix_fmt->sizeimage = sizeimage;
210 }
211 
212 static int rotate_querycap(struct file *file, void *priv,
213 			   struct v4l2_capability *cap)
214 {
215 	strscpy(cap->driver, ROTATE_NAME, sizeof(cap->driver));
216 	strscpy(cap->card, ROTATE_NAME, sizeof(cap->card));
217 	snprintf(cap->bus_info, sizeof(cap->bus_info),
218 		 "platform:%s", ROTATE_NAME);
219 
220 	return 0;
221 }
222 
223 static int rotate_enum_fmt_vid_cap(struct file *file, void *priv,
224 				   struct v4l2_fmtdesc *f)
225 {
226 	return rotate_enum_fmt(f, true);
227 }
228 
229 static int rotate_enum_fmt_vid_out(struct file *file, void *priv,
230 				   struct v4l2_fmtdesc *f)
231 {
232 	return rotate_enum_fmt(f, false);
233 }
234 
235 static int rotate_enum_framesizes(struct file *file, void *priv,
236 				  struct v4l2_frmsizeenum *fsize)
237 {
238 	const struct rotate_format *fmt;
239 
240 	if (fsize->index != 0)
241 		return -EINVAL;
242 
243 	fmt = rotate_find_format(fsize->pixel_format);
244 	if (!fmt)
245 		return -EINVAL;
246 
247 	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
248 	fsize->stepwise.min_width = ROTATE_MIN_WIDTH;
249 	fsize->stepwise.min_height = ROTATE_MIN_HEIGHT;
250 	fsize->stepwise.max_width = ROTATE_MAX_WIDTH;
251 	fsize->stepwise.max_height = ROTATE_MAX_HEIGHT;
252 	fsize->stepwise.step_width = fmt->hsub;
253 	fsize->stepwise.step_height = fmt->vsub;
254 
255 	return 0;
256 }
257 
258 static int rotate_set_cap_format(struct rotate_ctx *ctx,
259 				 struct v4l2_pix_format *f,
260 				 u32 rotate)
261 {
262 	const struct rotate_format *fmt;
263 
264 	fmt = rotate_find_format(ctx->src_fmt.pixelformat);
265 	if (!fmt)
266 		return -EINVAL;
267 
268 	if (fmt->flags & ROTATE_FLAG_YUV)
269 		f->pixelformat = V4L2_PIX_FMT_YUV420;
270 	else
271 		f->pixelformat = ctx->src_fmt.pixelformat;
272 
273 	f->field = V4L2_FIELD_NONE;
274 
275 	if (rotate == 90 || rotate == 270) {
276 		f->width = ctx->src_fmt.height;
277 		f->height = ctx->src_fmt.width;
278 	} else {
279 		f->width = ctx->src_fmt.width;
280 		f->height = ctx->src_fmt.height;
281 	}
282 
283 	rotate_prepare_format(f);
284 
285 	return 0;
286 }
287 
288 static int rotate_g_fmt_vid_cap(struct file *file, void *priv,
289 				struct v4l2_format *f)
290 {
291 	struct rotate_ctx *ctx = rotate_file2ctx(file);
292 
293 	f->fmt.pix = ctx->dst_fmt;
294 
295 	return 0;
296 }
297 
298 static int rotate_g_fmt_vid_out(struct file *file, void *priv,
299 				struct v4l2_format *f)
300 {
301 	struct rotate_ctx *ctx = rotate_file2ctx(file);
302 
303 	f->fmt.pix = ctx->src_fmt;
304 
305 	return 0;
306 }
307 
308 static int rotate_try_fmt_vid_cap(struct file *file, void *priv,
309 				  struct v4l2_format *f)
310 {
311 	struct rotate_ctx *ctx = rotate_file2ctx(file);
312 
313 	return rotate_set_cap_format(ctx, &f->fmt.pix, ctx->rotate);
314 }
315 
316 static int rotate_try_fmt_vid_out(struct file *file, void *priv,
317 				  struct v4l2_format *f)
318 {
319 	if (!rotate_find_format(f->fmt.pix.pixelformat))
320 		f->fmt.pix.pixelformat = V4L2_PIX_FMT_ARGB32;
321 
322 	if (f->fmt.pix.width < ROTATE_MIN_WIDTH)
323 		f->fmt.pix.width = ROTATE_MIN_WIDTH;
324 	if (f->fmt.pix.height < ROTATE_MIN_HEIGHT)
325 		f->fmt.pix.height = ROTATE_MIN_HEIGHT;
326 
327 	if (f->fmt.pix.width > ROTATE_MAX_WIDTH)
328 		f->fmt.pix.width = ROTATE_MAX_WIDTH;
329 	if (f->fmt.pix.height > ROTATE_MAX_HEIGHT)
330 		f->fmt.pix.height = ROTATE_MAX_HEIGHT;
331 
332 	f->fmt.pix.field = V4L2_FIELD_NONE;
333 
334 	rotate_prepare_format(&f->fmt.pix);
335 
336 	return 0;
337 }
338 
339 static int rotate_s_fmt_vid_cap(struct file *file, void *priv,
340 				struct v4l2_format *f)
341 {
342 	struct rotate_ctx *ctx = rotate_file2ctx(file);
343 	struct vb2_queue *vq;
344 	int ret;
345 
346 	ret = rotate_try_fmt_vid_cap(file, priv, f);
347 	if (ret)
348 		return ret;
349 
350 	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
351 	if (vb2_is_busy(vq))
352 		return -EBUSY;
353 
354 	ctx->dst_fmt = f->fmt.pix;
355 
356 	return 0;
357 }
358 
359 static int rotate_s_fmt_vid_out(struct file *file, void *priv,
360 				struct v4l2_format *f)
361 {
362 	struct rotate_ctx *ctx = rotate_file2ctx(file);
363 	struct vb2_queue *vq;
364 	int ret;
365 
366 	ret = rotate_try_fmt_vid_out(file, priv, f);
367 	if (ret)
368 		return ret;
369 
370 	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
371 	if (vb2_is_busy(vq))
372 		return -EBUSY;
373 
374 	/*
375 	 * Capture queue has to be also checked, because format and size
376 	 * depends on output format and size.
377 	 */
378 	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
379 	if (vb2_is_busy(vq))
380 		return -EBUSY;
381 
382 	ctx->src_fmt = f->fmt.pix;
383 
384 	/* Propagate colorspace information to capture. */
385 	ctx->dst_fmt.colorspace = f->fmt.pix.colorspace;
386 	ctx->dst_fmt.xfer_func = f->fmt.pix.xfer_func;
387 	ctx->dst_fmt.ycbcr_enc = f->fmt.pix.ycbcr_enc;
388 	ctx->dst_fmt.quantization = f->fmt.pix.quantization;
389 
390 	return rotate_set_cap_format(ctx, &ctx->dst_fmt, ctx->rotate);
391 }
392 
393 static const struct v4l2_ioctl_ops rotate_ioctl_ops = {
394 	.vidioc_querycap		= rotate_querycap,
395 
396 	.vidioc_enum_framesizes		= rotate_enum_framesizes,
397 
398 	.vidioc_enum_fmt_vid_cap	= rotate_enum_fmt_vid_cap,
399 	.vidioc_g_fmt_vid_cap		= rotate_g_fmt_vid_cap,
400 	.vidioc_try_fmt_vid_cap		= rotate_try_fmt_vid_cap,
401 	.vidioc_s_fmt_vid_cap		= rotate_s_fmt_vid_cap,
402 
403 	.vidioc_enum_fmt_vid_out	= rotate_enum_fmt_vid_out,
404 	.vidioc_g_fmt_vid_out		= rotate_g_fmt_vid_out,
405 	.vidioc_try_fmt_vid_out		= rotate_try_fmt_vid_out,
406 	.vidioc_s_fmt_vid_out		= rotate_s_fmt_vid_out,
407 
408 	.vidioc_reqbufs			= v4l2_m2m_ioctl_reqbufs,
409 	.vidioc_querybuf		= v4l2_m2m_ioctl_querybuf,
410 	.vidioc_qbuf			= v4l2_m2m_ioctl_qbuf,
411 	.vidioc_dqbuf			= v4l2_m2m_ioctl_dqbuf,
412 	.vidioc_prepare_buf		= v4l2_m2m_ioctl_prepare_buf,
413 	.vidioc_create_bufs		= v4l2_m2m_ioctl_create_bufs,
414 	.vidioc_expbuf			= v4l2_m2m_ioctl_expbuf,
415 
416 	.vidioc_streamon		= v4l2_m2m_ioctl_streamon,
417 	.vidioc_streamoff		= v4l2_m2m_ioctl_streamoff,
418 
419 	.vidioc_log_status		= v4l2_ctrl_log_status,
420 	.vidioc_subscribe_event		= v4l2_ctrl_subscribe_event,
421 	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,
422 };
423 
424 static int rotate_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
425 			      unsigned int *nplanes, unsigned int sizes[],
426 			      struct device *alloc_devs[])
427 {
428 	struct rotate_ctx *ctx = vb2_get_drv_priv(vq);
429 	struct v4l2_pix_format *pix_fmt;
430 
431 	if (V4L2_TYPE_IS_OUTPUT(vq->type))
432 		pix_fmt = &ctx->src_fmt;
433 	else
434 		pix_fmt = &ctx->dst_fmt;
435 
436 	if (*nplanes) {
437 		if (sizes[0] < pix_fmt->sizeimage)
438 			return -EINVAL;
439 	} else {
440 		sizes[0] = pix_fmt->sizeimage;
441 		*nplanes = 1;
442 	}
443 
444 	return 0;
445 }
446 
447 static int rotate_buf_prepare(struct vb2_buffer *vb)
448 {
449 	struct vb2_queue *vq = vb->vb2_queue;
450 	struct rotate_ctx *ctx = vb2_get_drv_priv(vq);
451 	struct v4l2_pix_format *pix_fmt;
452 
453 	if (V4L2_TYPE_IS_OUTPUT(vq->type))
454 		pix_fmt = &ctx->src_fmt;
455 	else
456 		pix_fmt = &ctx->dst_fmt;
457 
458 	if (vb2_plane_size(vb, 0) < pix_fmt->sizeimage)
459 		return -EINVAL;
460 
461 	vb2_set_plane_payload(vb, 0, pix_fmt->sizeimage);
462 
463 	return 0;
464 }
465 
466 static void rotate_buf_queue(struct vb2_buffer *vb)
467 {
468 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
469 	struct rotate_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
470 
471 	v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
472 }
473 
474 static void rotate_queue_cleanup(struct vb2_queue *vq, u32 state)
475 {
476 	struct rotate_ctx *ctx = vb2_get_drv_priv(vq);
477 	struct vb2_v4l2_buffer *vbuf;
478 
479 	do {
480 		if (V4L2_TYPE_IS_OUTPUT(vq->type))
481 			vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
482 		else
483 			vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
484 
485 		if (vbuf)
486 			v4l2_m2m_buf_done(vbuf, state);
487 	} while (vbuf);
488 }
489 
490 static int rotate_start_streaming(struct vb2_queue *vq, unsigned int count)
491 {
492 	if (V4L2_TYPE_IS_OUTPUT(vq->type)) {
493 		struct rotate_ctx *ctx = vb2_get_drv_priv(vq);
494 		struct device *dev = ctx->dev->dev;
495 		int ret;
496 
497 		ret = pm_runtime_resume_and_get(dev);
498 		if (ret < 0) {
499 			dev_err(dev, "Failed to enable module\n");
500 
501 			return ret;
502 		}
503 	}
504 
505 	return 0;
506 }
507 
508 static void rotate_stop_streaming(struct vb2_queue *vq)
509 {
510 	if (V4L2_TYPE_IS_OUTPUT(vq->type)) {
511 		struct rotate_ctx *ctx = vb2_get_drv_priv(vq);
512 
513 		pm_runtime_put(ctx->dev->dev);
514 	}
515 
516 	rotate_queue_cleanup(vq, VB2_BUF_STATE_ERROR);
517 }
518 
519 static const struct vb2_ops rotate_qops = {
520 	.queue_setup		= rotate_queue_setup,
521 	.buf_prepare		= rotate_buf_prepare,
522 	.buf_queue		= rotate_buf_queue,
523 	.start_streaming	= rotate_start_streaming,
524 	.stop_streaming		= rotate_stop_streaming,
525 };
526 
527 static int rotate_queue_init(void *priv, struct vb2_queue *src_vq,
528 			     struct vb2_queue *dst_vq)
529 {
530 	struct rotate_ctx *ctx = priv;
531 	int ret;
532 
533 	src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
534 	src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
535 	src_vq->drv_priv = ctx;
536 	src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
537 	src_vq->min_queued_buffers = 1;
538 	src_vq->ops = &rotate_qops;
539 	src_vq->mem_ops = &vb2_dma_contig_memops;
540 	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
541 	src_vq->lock = &ctx->dev->dev_mutex;
542 	src_vq->dev = ctx->dev->dev;
543 
544 	ret = vb2_queue_init(src_vq);
545 	if (ret)
546 		return ret;
547 
548 	dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
549 	dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
550 	dst_vq->drv_priv = ctx;
551 	dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
552 	dst_vq->min_queued_buffers = 2;
553 	dst_vq->ops = &rotate_qops;
554 	dst_vq->mem_ops = &vb2_dma_contig_memops;
555 	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
556 	dst_vq->lock = &ctx->dev->dev_mutex;
557 	dst_vq->dev = ctx->dev->dev;
558 
559 	ret = vb2_queue_init(dst_vq);
560 	if (ret)
561 		return ret;
562 
563 	return 0;
564 }
565 
566 static int rotate_s_ctrl(struct v4l2_ctrl *ctrl)
567 {
568 	struct rotate_ctx *ctx = container_of(ctrl->handler,
569 					      struct rotate_ctx,
570 					      ctrl_handler);
571 	struct v4l2_pix_format fmt;
572 
573 	switch (ctrl->id) {
574 	case V4L2_CID_HFLIP:
575 		ctx->hflip = ctrl->val;
576 		break;
577 	case V4L2_CID_VFLIP:
578 		ctx->vflip = ctrl->val;
579 		break;
580 	case V4L2_CID_ROTATE:
581 		rotate_set_cap_format(ctx, &fmt, ctrl->val);
582 
583 		/* Check if capture format needs to be changed */
584 		if (fmt.width != ctx->dst_fmt.width ||
585 		    fmt.height != ctx->dst_fmt.height ||
586 		    fmt.bytesperline != ctx->dst_fmt.bytesperline ||
587 		    fmt.sizeimage != ctx->dst_fmt.sizeimage) {
588 			struct vb2_queue *vq;
589 
590 			vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
591 					     V4L2_BUF_TYPE_VIDEO_CAPTURE);
592 			if (vb2_is_busy(vq))
593 				return -EBUSY;
594 
595 			rotate_set_cap_format(ctx, &ctx->dst_fmt, ctrl->val);
596 		}
597 
598 		ctx->rotate = ctrl->val;
599 		break;
600 	default:
601 		return -EINVAL;
602 	}
603 
604 	return 0;
605 }
606 
607 static const struct v4l2_ctrl_ops rotate_ctrl_ops = {
608 	.s_ctrl = rotate_s_ctrl,
609 };
610 
611 static int rotate_setup_ctrls(struct rotate_ctx *ctx)
612 {
613 	v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
614 
615 	v4l2_ctrl_new_std(&ctx->ctrl_handler, &rotate_ctrl_ops,
616 			  V4L2_CID_HFLIP, 0, 1, 1, 0);
617 
618 	v4l2_ctrl_new_std(&ctx->ctrl_handler, &rotate_ctrl_ops,
619 			  V4L2_CID_VFLIP, 0, 1, 1, 0);
620 
621 	v4l2_ctrl_new_std(&ctx->ctrl_handler, &rotate_ctrl_ops,
622 			  V4L2_CID_ROTATE, 0, 270, 90, 0);
623 
624 	if (ctx->ctrl_handler.error) {
625 		int err = ctx->ctrl_handler.error;
626 
627 		v4l2_err(&ctx->dev->v4l2_dev, "control setup failed!\n");
628 		v4l2_ctrl_handler_free(&ctx->ctrl_handler);
629 
630 		return err;
631 	}
632 
633 	return v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
634 }
635 
636 static int rotate_open(struct file *file)
637 {
638 	struct rotate_dev *dev = video_drvdata(file);
639 	struct rotate_ctx *ctx = NULL;
640 	int ret;
641 
642 	if (mutex_lock_interruptible(&dev->dev_mutex))
643 		return -ERESTARTSYS;
644 
645 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
646 	if (!ctx) {
647 		mutex_unlock(&dev->dev_mutex);
648 		return -ENOMEM;
649 	}
650 
651 	/* default output format */
652 	ctx->src_fmt.pixelformat = V4L2_PIX_FMT_ARGB32;
653 	ctx->src_fmt.field = V4L2_FIELD_NONE;
654 	ctx->src_fmt.width = 640;
655 	ctx->src_fmt.height = 480;
656 	rotate_prepare_format(&ctx->src_fmt);
657 
658 	/* default capture format */
659 	rotate_set_cap_format(ctx, &ctx->dst_fmt, ctx->rotate);
660 
661 	v4l2_fh_init(&ctx->fh, video_devdata(file));
662 	file->private_data = &ctx->fh;
663 	ctx->dev = dev;
664 
665 	ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx,
666 					    &rotate_queue_init);
667 	if (IS_ERR(ctx->fh.m2m_ctx)) {
668 		ret = PTR_ERR(ctx->fh.m2m_ctx);
669 		goto err_free;
670 	}
671 
672 	v4l2_fh_add(&ctx->fh);
673 
674 	ret = rotate_setup_ctrls(ctx);
675 	if (ret)
676 		goto err_free;
677 
678 	ctx->fh.ctrl_handler = &ctx->ctrl_handler;
679 
680 	mutex_unlock(&dev->dev_mutex);
681 
682 	return 0;
683 
684 err_free:
685 	kfree(ctx);
686 	mutex_unlock(&dev->dev_mutex);
687 
688 	return ret;
689 }
690 
691 static int rotate_release(struct file *file)
692 {
693 	struct rotate_dev *dev = video_drvdata(file);
694 	struct rotate_ctx *ctx = container_of(file->private_data,
695 						   struct rotate_ctx, fh);
696 
697 	mutex_lock(&dev->dev_mutex);
698 
699 	v4l2_ctrl_handler_free(&ctx->ctrl_handler);
700 	v4l2_fh_del(&ctx->fh);
701 	v4l2_fh_exit(&ctx->fh);
702 	v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
703 
704 	kfree(ctx);
705 
706 	mutex_unlock(&dev->dev_mutex);
707 
708 	return 0;
709 }
710 
711 static const struct v4l2_file_operations rotate_fops = {
712 	.owner		= THIS_MODULE,
713 	.open		= rotate_open,
714 	.release	= rotate_release,
715 	.poll		= v4l2_m2m_fop_poll,
716 	.unlocked_ioctl	= video_ioctl2,
717 	.mmap		= v4l2_m2m_fop_mmap,
718 };
719 
720 static const struct video_device rotate_video_device = {
721 	.name		= ROTATE_NAME,
722 	.vfl_dir	= VFL_DIR_M2M,
723 	.fops		= &rotate_fops,
724 	.ioctl_ops	= &rotate_ioctl_ops,
725 	.minor		= -1,
726 	.release	= video_device_release_empty,
727 	.device_caps	= V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING,
728 };
729 
730 static const struct v4l2_m2m_ops rotate_m2m_ops = {
731 	.device_run	= rotate_device_run,
732 };
733 
734 static int rotate_probe(struct platform_device *pdev)
735 {
736 	struct rotate_dev *dev;
737 	struct video_device *vfd;
738 	int irq, ret;
739 
740 	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
741 	if (!dev)
742 		return -ENOMEM;
743 
744 	dev->vfd = rotate_video_device;
745 	dev->dev = &pdev->dev;
746 
747 	irq = platform_get_irq(pdev, 0);
748 	if (irq <= 0)
749 		return irq;
750 
751 	ret = devm_request_irq(dev->dev, irq, rotate_irq,
752 			       0, dev_name(dev->dev), dev);
753 	if (ret) {
754 		dev_err(dev->dev, "Failed to request IRQ\n");
755 
756 		return ret;
757 	}
758 
759 	dev->base = devm_platform_ioremap_resource(pdev, 0);
760 	if (IS_ERR(dev->base))
761 		return PTR_ERR(dev->base);
762 
763 	dev->bus_clk = devm_clk_get(dev->dev, "bus");
764 	if (IS_ERR(dev->bus_clk)) {
765 		dev_err(dev->dev, "Failed to get bus clock\n");
766 
767 		return PTR_ERR(dev->bus_clk);
768 	}
769 
770 	dev->mod_clk = devm_clk_get(dev->dev, "mod");
771 	if (IS_ERR(dev->mod_clk)) {
772 		dev_err(dev->dev, "Failed to get mod clock\n");
773 
774 		return PTR_ERR(dev->mod_clk);
775 	}
776 
777 	dev->rstc = devm_reset_control_get(dev->dev, NULL);
778 	if (IS_ERR(dev->rstc)) {
779 		dev_err(dev->dev, "Failed to get reset control\n");
780 
781 		return PTR_ERR(dev->rstc);
782 	}
783 
784 	mutex_init(&dev->dev_mutex);
785 
786 	ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
787 	if (ret) {
788 		dev_err(dev->dev, "Failed to register V4L2 device\n");
789 
790 		return ret;
791 	}
792 
793 	vfd = &dev->vfd;
794 	vfd->lock = &dev->dev_mutex;
795 	vfd->v4l2_dev = &dev->v4l2_dev;
796 
797 	snprintf(vfd->name, sizeof(vfd->name), "%s",
798 		 rotate_video_device.name);
799 	video_set_drvdata(vfd, dev);
800 
801 	ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
802 	if (ret) {
803 		v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
804 
805 		goto err_v4l2;
806 	}
807 
808 	v4l2_info(&dev->v4l2_dev,
809 		  "Device registered as /dev/video%d\n", vfd->num);
810 
811 	dev->m2m_dev = v4l2_m2m_init(&rotate_m2m_ops);
812 	if (IS_ERR(dev->m2m_dev)) {
813 		v4l2_err(&dev->v4l2_dev,
814 			 "Failed to initialize V4L2 M2M device\n");
815 		ret = PTR_ERR(dev->m2m_dev);
816 
817 		goto err_video;
818 	}
819 
820 	platform_set_drvdata(pdev, dev);
821 
822 	pm_runtime_enable(dev->dev);
823 
824 	return 0;
825 
826 err_video:
827 	video_unregister_device(&dev->vfd);
828 err_v4l2:
829 	v4l2_device_unregister(&dev->v4l2_dev);
830 
831 	return ret;
832 }
833 
834 static void rotate_remove(struct platform_device *pdev)
835 {
836 	struct rotate_dev *dev = platform_get_drvdata(pdev);
837 
838 	v4l2_m2m_release(dev->m2m_dev);
839 	video_unregister_device(&dev->vfd);
840 	v4l2_device_unregister(&dev->v4l2_dev);
841 
842 	pm_runtime_force_suspend(&pdev->dev);
843 }
844 
845 static int rotate_runtime_resume(struct device *device)
846 {
847 	struct rotate_dev *dev = dev_get_drvdata(device);
848 	int ret;
849 
850 	ret = clk_prepare_enable(dev->bus_clk);
851 	if (ret) {
852 		dev_err(dev->dev, "Failed to enable bus clock\n");
853 
854 		return ret;
855 	}
856 
857 	ret = clk_prepare_enable(dev->mod_clk);
858 	if (ret) {
859 		dev_err(dev->dev, "Failed to enable mod clock\n");
860 
861 		goto err_bus_clk;
862 	}
863 
864 	ret = reset_control_deassert(dev->rstc);
865 	if (ret) {
866 		dev_err(dev->dev, "Failed to apply reset\n");
867 
868 		goto err_mod_clk;
869 	}
870 
871 	return 0;
872 
873 err_mod_clk:
874 	clk_disable_unprepare(dev->mod_clk);
875 err_bus_clk:
876 	clk_disable_unprepare(dev->bus_clk);
877 
878 	return ret;
879 }
880 
881 static int rotate_runtime_suspend(struct device *device)
882 {
883 	struct rotate_dev *dev = dev_get_drvdata(device);
884 
885 	reset_control_assert(dev->rstc);
886 
887 	clk_disable_unprepare(dev->mod_clk);
888 	clk_disable_unprepare(dev->bus_clk);
889 
890 	return 0;
891 }
892 
893 static const struct of_device_id rotate_dt_match[] = {
894 	{ .compatible = "allwinner,sun8i-a83t-de2-rotate" },
895 	{ /* sentinel */ }
896 };
897 MODULE_DEVICE_TABLE(of, rotate_dt_match);
898 
899 static const struct dev_pm_ops rotate_pm_ops = {
900 	.runtime_resume		= rotate_runtime_resume,
901 	.runtime_suspend	= rotate_runtime_suspend,
902 };
903 
904 static struct platform_driver rotate_driver = {
905 	.probe		= rotate_probe,
906 	.remove		= rotate_remove,
907 	.driver		= {
908 		.name		= ROTATE_NAME,
909 		.of_match_table	= rotate_dt_match,
910 		.pm		= &rotate_pm_ops,
911 	},
912 };
913 module_platform_driver(rotate_driver);
914 
915 MODULE_LICENSE("GPL v2");
916 MODULE_AUTHOR("Jernej Skrabec <jernej.skrabec@siol.net>");
917 MODULE_DESCRIPTION("Allwinner DE2 rotate driver");
918