1// SPDX-License-Identifier: GPL-2.0
2/*
3 * camss-vfe.c
4 *
5 * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module
6 *
7 * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
8 * Copyright (C) 2015-2018 Linaro Ltd.
9 */
10#include <linux/clk.h>
11#include <linux/completion.h>
12#include <linux/interrupt.h>
13#include <linux/iommu.h>
14#include <linux/mutex.h>
15#include <linux/of.h>
16#include <linux/platform_device.h>
17#include <linux/pm_domain.h>
18#include <linux/pm_runtime.h>
19#include <linux/spinlock_types.h>
20#include <linux/spinlock.h>
21#include <media/media-entity.h>
22#include <media/v4l2-device.h>
23#include <media/v4l2-subdev.h>
24
25#include "camss-vfe.h"
26#include "camss.h"
27
28#define MSM_VFE_NAME "msm_vfe"
29
30/* VFE reset timeout */
31#define VFE_RESET_TIMEOUT_MS 50
32
33#define SCALER_RATIO_MAX 16
34
35struct vfe_format {
36	u32 code;
37	u8 bpp;
38};
39
40static const struct vfe_format formats_rdi_8x16[] = {
41	{ MEDIA_BUS_FMT_UYVY8_1X16, 8 },
42	{ MEDIA_BUS_FMT_VYUY8_1X16, 8 },
43	{ MEDIA_BUS_FMT_YUYV8_1X16, 8 },
44	{ MEDIA_BUS_FMT_YVYU8_1X16, 8 },
45	{ MEDIA_BUS_FMT_SBGGR8_1X8, 8 },
46	{ MEDIA_BUS_FMT_SGBRG8_1X8, 8 },
47	{ MEDIA_BUS_FMT_SGRBG8_1X8, 8 },
48	{ MEDIA_BUS_FMT_SRGGB8_1X8, 8 },
49	{ MEDIA_BUS_FMT_SBGGR10_1X10, 10 },
50	{ MEDIA_BUS_FMT_SGBRG10_1X10, 10 },
51	{ MEDIA_BUS_FMT_SGRBG10_1X10, 10 },
52	{ MEDIA_BUS_FMT_SRGGB10_1X10, 10 },
53	{ MEDIA_BUS_FMT_SBGGR12_1X12, 12 },
54	{ MEDIA_BUS_FMT_SGBRG12_1X12, 12 },
55	{ MEDIA_BUS_FMT_SGRBG12_1X12, 12 },
56	{ MEDIA_BUS_FMT_SRGGB12_1X12, 12 },
57	{ MEDIA_BUS_FMT_Y10_1X10, 10 },
58};
59
60static const struct vfe_format formats_pix_8x16[] = {
61	{ MEDIA_BUS_FMT_UYVY8_1X16, 8 },
62	{ MEDIA_BUS_FMT_VYUY8_1X16, 8 },
63	{ MEDIA_BUS_FMT_YUYV8_1X16, 8 },
64	{ MEDIA_BUS_FMT_YVYU8_1X16, 8 },
65};
66
67static const struct vfe_format formats_rdi_8x96[] = {
68	{ MEDIA_BUS_FMT_UYVY8_1X16, 8 },
69	{ MEDIA_BUS_FMT_VYUY8_1X16, 8 },
70	{ MEDIA_BUS_FMT_YUYV8_1X16, 8 },
71	{ MEDIA_BUS_FMT_YVYU8_1X16, 8 },
72	{ MEDIA_BUS_FMT_SBGGR8_1X8, 8 },
73	{ MEDIA_BUS_FMT_SGBRG8_1X8, 8 },
74	{ MEDIA_BUS_FMT_SGRBG8_1X8, 8 },
75	{ MEDIA_BUS_FMT_SRGGB8_1X8, 8 },
76	{ MEDIA_BUS_FMT_SBGGR10_1X10, 10 },
77	{ MEDIA_BUS_FMT_SGBRG10_1X10, 10 },
78	{ MEDIA_BUS_FMT_SGRBG10_1X10, 10 },
79	{ MEDIA_BUS_FMT_SRGGB10_1X10, 10 },
80	{ MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, 16 },
81	{ MEDIA_BUS_FMT_SBGGR12_1X12, 12 },
82	{ MEDIA_BUS_FMT_SGBRG12_1X12, 12 },
83	{ MEDIA_BUS_FMT_SGRBG12_1X12, 12 },
84	{ MEDIA_BUS_FMT_SRGGB12_1X12, 12 },
85	{ MEDIA_BUS_FMT_SBGGR14_1X14, 14 },
86	{ MEDIA_BUS_FMT_SGBRG14_1X14, 14 },
87	{ MEDIA_BUS_FMT_SGRBG14_1X14, 14 },
88	{ MEDIA_BUS_FMT_SRGGB14_1X14, 14 },
89	{ MEDIA_BUS_FMT_Y10_1X10, 10 },
90	{ MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, 16 },
91};
92
93static const struct vfe_format formats_pix_8x96[] = {
94	{ MEDIA_BUS_FMT_UYVY8_1X16, 8 },
95	{ MEDIA_BUS_FMT_VYUY8_1X16, 8 },
96	{ MEDIA_BUS_FMT_YUYV8_1X16, 8 },
97	{ MEDIA_BUS_FMT_YVYU8_1X16, 8 },
98};
99
100static const struct vfe_format formats_rdi_845[] = {
101	{ MEDIA_BUS_FMT_UYVY8_1X16, 8 },
102	{ MEDIA_BUS_FMT_VYUY8_1X16, 8 },
103	{ MEDIA_BUS_FMT_YUYV8_1X16, 8 },
104	{ MEDIA_BUS_FMT_YVYU8_1X16, 8 },
105	{ MEDIA_BUS_FMT_SBGGR8_1X8, 8 },
106	{ MEDIA_BUS_FMT_SGBRG8_1X8, 8 },
107	{ MEDIA_BUS_FMT_SGRBG8_1X8, 8 },
108	{ MEDIA_BUS_FMT_SRGGB8_1X8, 8 },
109	{ MEDIA_BUS_FMT_SBGGR10_1X10, 10 },
110	{ MEDIA_BUS_FMT_SGBRG10_1X10, 10 },
111	{ MEDIA_BUS_FMT_SGRBG10_1X10, 10 },
112	{ MEDIA_BUS_FMT_SRGGB10_1X10, 10 },
113	{ MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, 16 },
114	{ MEDIA_BUS_FMT_SBGGR12_1X12, 12 },
115	{ MEDIA_BUS_FMT_SGBRG12_1X12, 12 },
116	{ MEDIA_BUS_FMT_SGRBG12_1X12, 12 },
117	{ MEDIA_BUS_FMT_SRGGB12_1X12, 12 },
118	{ MEDIA_BUS_FMT_SBGGR14_1X14, 14 },
119	{ MEDIA_BUS_FMT_SGBRG14_1X14, 14 },
120	{ MEDIA_BUS_FMT_SGRBG14_1X14, 14 },
121	{ MEDIA_BUS_FMT_SRGGB14_1X14, 14 },
122	{ MEDIA_BUS_FMT_Y8_1X8, 8 },
123	{ MEDIA_BUS_FMT_Y10_1X10, 10 },
124	{ MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, 16 },
125};
126
127/*
128 * vfe_get_bpp - map media bus format to bits per pixel
129 * @formats: supported media bus formats array
130 * @nformats: size of @formats array
131 * @code: media bus format code
132 *
133 * Return number of bits per pixel
134 */
135static u8 vfe_get_bpp(const struct vfe_format *formats,
136		      unsigned int nformats, u32 code)
137{
138	unsigned int i;
139
140	for (i = 0; i < nformats; i++)
141		if (code == formats[i].code)
142			return formats[i].bpp;
143
144	WARN(1, "Unknown format\n");
145
146	return formats[0].bpp;
147}
148
149static u32 vfe_find_code(u32 *code, unsigned int n_code,
150			 unsigned int index, u32 req_code)
151{
152	int i;
153
154	if (!req_code && (index >= n_code))
155		return 0;
156
157	for (i = 0; i < n_code; i++)
158		if (req_code) {
159			if (req_code == code[i])
160				return req_code;
161		} else {
162			if (i == index)
163				return code[i];
164		}
165
166	return code[0];
167}
168
169static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
170			    unsigned int index, u32 src_req_code)
171{
172	struct vfe_device *vfe = to_vfe(line);
173
174	switch (vfe->camss->res->version) {
175	case CAMSS_8x16:
176		switch (sink_code) {
177		case MEDIA_BUS_FMT_YUYV8_1X16:
178		{
179			u32 src_code[] = {
180				MEDIA_BUS_FMT_YUYV8_1X16,
181				MEDIA_BUS_FMT_YUYV8_1_5X8,
182			};
183
184			return vfe_find_code(src_code, ARRAY_SIZE(src_code),
185					     index, src_req_code);
186		}
187		case MEDIA_BUS_FMT_YVYU8_1X16:
188		{
189			u32 src_code[] = {
190				MEDIA_BUS_FMT_YVYU8_1X16,
191				MEDIA_BUS_FMT_YVYU8_1_5X8,
192			};
193
194			return vfe_find_code(src_code, ARRAY_SIZE(src_code),
195					     index, src_req_code);
196		}
197		case MEDIA_BUS_FMT_UYVY8_1X16:
198		{
199			u32 src_code[] = {
200				MEDIA_BUS_FMT_UYVY8_1X16,
201				MEDIA_BUS_FMT_UYVY8_1_5X8,
202			};
203
204			return vfe_find_code(src_code, ARRAY_SIZE(src_code),
205					     index, src_req_code);
206		}
207		case MEDIA_BUS_FMT_VYUY8_1X16:
208		{
209			u32 src_code[] = {
210				MEDIA_BUS_FMT_VYUY8_1X16,
211				MEDIA_BUS_FMT_VYUY8_1_5X8,
212			};
213
214			return vfe_find_code(src_code, ARRAY_SIZE(src_code),
215					     index, src_req_code);
216		}
217		default:
218			if (index > 0)
219				return 0;
220
221			return sink_code;
222		}
223		break;
224	case CAMSS_8x96:
225	case CAMSS_660:
226	case CAMSS_845:
227	case CAMSS_8250:
228		switch (sink_code) {
229		case MEDIA_BUS_FMT_YUYV8_1X16:
230		{
231			u32 src_code[] = {
232				MEDIA_BUS_FMT_YUYV8_1X16,
233				MEDIA_BUS_FMT_YVYU8_1X16,
234				MEDIA_BUS_FMT_UYVY8_1X16,
235				MEDIA_BUS_FMT_VYUY8_1X16,
236				MEDIA_BUS_FMT_YUYV8_1_5X8,
237			};
238
239			return vfe_find_code(src_code, ARRAY_SIZE(src_code),
240					     index, src_req_code);
241		}
242		case MEDIA_BUS_FMT_YVYU8_1X16:
243		{
244			u32 src_code[] = {
245				MEDIA_BUS_FMT_YVYU8_1X16,
246				MEDIA_BUS_FMT_YUYV8_1X16,
247				MEDIA_BUS_FMT_UYVY8_1X16,
248				MEDIA_BUS_FMT_VYUY8_1X16,
249				MEDIA_BUS_FMT_YVYU8_1_5X8,
250			};
251
252			return vfe_find_code(src_code, ARRAY_SIZE(src_code),
253					     index, src_req_code);
254		}
255		case MEDIA_BUS_FMT_UYVY8_1X16:
256		{
257			u32 src_code[] = {
258				MEDIA_BUS_FMT_UYVY8_1X16,
259				MEDIA_BUS_FMT_YUYV8_1X16,
260				MEDIA_BUS_FMT_YVYU8_1X16,
261				MEDIA_BUS_FMT_VYUY8_1X16,
262				MEDIA_BUS_FMT_UYVY8_1_5X8,
263			};
264
265			return vfe_find_code(src_code, ARRAY_SIZE(src_code),
266					     index, src_req_code);
267		}
268		case MEDIA_BUS_FMT_VYUY8_1X16:
269		{
270			u32 src_code[] = {
271				MEDIA_BUS_FMT_VYUY8_1X16,
272				MEDIA_BUS_FMT_YUYV8_1X16,
273				MEDIA_BUS_FMT_YVYU8_1X16,
274				MEDIA_BUS_FMT_UYVY8_1X16,
275				MEDIA_BUS_FMT_VYUY8_1_5X8,
276			};
277
278			return vfe_find_code(src_code, ARRAY_SIZE(src_code),
279					     index, src_req_code);
280		}
281		default:
282			if (index > 0)
283				return 0;
284
285			return sink_code;
286		}
287		break;
288	}
289	return 0;
290}
291
292int vfe_reset(struct vfe_device *vfe)
293{
294	unsigned long time;
295
296	reinit_completion(&vfe->reset_complete);
297
298	vfe->ops->global_reset(vfe);
299
300	time = wait_for_completion_timeout(&vfe->reset_complete,
301		msecs_to_jiffies(VFE_RESET_TIMEOUT_MS));
302	if (!time) {
303		dev_err(vfe->camss->dev, "VFE reset timeout\n");
304		return -EIO;
305	}
306
307	return 0;
308}
309
310static void vfe_init_outputs(struct vfe_device *vfe)
311{
312	int i;
313
314	for (i = 0; i < vfe->line_num; i++) {
315		struct vfe_output *output = &vfe->line[i].output;
316
317		output->state = VFE_OUTPUT_OFF;
318		output->buf[0] = NULL;
319		output->buf[1] = NULL;
320		INIT_LIST_HEAD(&output->pending_bufs);
321	}
322}
323
324static void vfe_reset_output_maps(struct vfe_device *vfe)
325{
326	int i;
327
328	for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++)
329		vfe->wm_output_map[i] = VFE_LINE_NONE;
330}
331
332int vfe_reserve_wm(struct vfe_device *vfe, enum vfe_line_id line_id)
333{
334	int ret = -EBUSY;
335	int i;
336
337	for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++) {
338		if (vfe->wm_output_map[i] == VFE_LINE_NONE) {
339			vfe->wm_output_map[i] = line_id;
340			ret = i;
341			break;
342		}
343	}
344
345	return ret;
346}
347
348int vfe_release_wm(struct vfe_device *vfe, u8 wm)
349{
350	if (wm >= ARRAY_SIZE(vfe->wm_output_map))
351		return -EINVAL;
352
353	vfe->wm_output_map[wm] = VFE_LINE_NONE;
354
355	return 0;
356}
357
358struct camss_buffer *vfe_buf_get_pending(struct vfe_output *output)
359{
360	struct camss_buffer *buffer = NULL;
361
362	if (!list_empty(&output->pending_bufs)) {
363		buffer = list_first_entry(&output->pending_bufs,
364					  struct camss_buffer,
365					  queue);
366		list_del(&buffer->queue);
367	}
368
369	return buffer;
370}
371
372void vfe_buf_add_pending(struct vfe_output *output,
373			 struct camss_buffer *buffer)
374{
375	INIT_LIST_HEAD(&buffer->queue);
376	list_add_tail(&buffer->queue, &output->pending_bufs);
377}
378
379/*
380 * vfe_buf_flush_pending - Flush all pending buffers.
381 * @output: VFE output
382 * @state: vb2 buffer state
383 */
384static void vfe_buf_flush_pending(struct vfe_output *output,
385				  enum vb2_buffer_state state)
386{
387	struct camss_buffer *buf;
388	struct camss_buffer *t;
389
390	list_for_each_entry_safe(buf, t, &output->pending_bufs, queue) {
391		vb2_buffer_done(&buf->vb.vb2_buf, state);
392		list_del(&buf->queue);
393	}
394}
395
396int vfe_put_output(struct vfe_line *line)
397{
398	struct vfe_device *vfe = to_vfe(line);
399	struct vfe_output *output = &line->output;
400	unsigned long flags;
401	unsigned int i;
402
403	spin_lock_irqsave(&vfe->output_lock, flags);
404
405	for (i = 0; i < output->wm_num; i++)
406		vfe_release_wm(vfe, output->wm_idx[i]);
407
408	output->state = VFE_OUTPUT_OFF;
409
410	spin_unlock_irqrestore(&vfe->output_lock, flags);
411	return 0;
412}
413
414static int vfe_disable_output(struct vfe_line *line)
415{
416	struct vfe_device *vfe = to_vfe(line);
417	struct vfe_output *output = &line->output;
418	unsigned long flags;
419	unsigned int i;
420
421	spin_lock_irqsave(&vfe->output_lock, flags);
422	for (i = 0; i < output->wm_num; i++)
423		vfe->ops->vfe_wm_stop(vfe, output->wm_idx[i]);
424	output->gen2.active_num = 0;
425	spin_unlock_irqrestore(&vfe->output_lock, flags);
426
427	return vfe_reset(vfe);
428}
429
430/*
431 * vfe_disable - Disable streaming on VFE line
432 * @line: VFE line
433 *
434 * Return 0 on success or a negative error code otherwise
435 */
436int vfe_disable(struct vfe_line *line)
437{
438	struct vfe_device *vfe = to_vfe(line);
439	int ret;
440
441	ret = vfe_disable_output(line);
442	if (ret)
443		goto error;
444
445	vfe_put_output(line);
446
447	mutex_lock(&vfe->stream_lock);
448
449	vfe->stream_count--;
450
451	mutex_unlock(&vfe->stream_lock);
452
453error:
454	return ret;
455}
456
457/**
458 * vfe_isr_comp_done() - Process composite image done interrupt
459 * @vfe: VFE Device
460 * @comp: Composite image id
461 */
462void vfe_isr_comp_done(struct vfe_device *vfe, u8 comp)
463{
464	unsigned int i;
465
466	for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++)
467		if (vfe->wm_output_map[i] == VFE_LINE_PIX) {
468			vfe->isr_ops.wm_done(vfe, i);
469			break;
470		}
471}
472
473void vfe_isr_reset_ack(struct vfe_device *vfe)
474{
475	complete(&vfe->reset_complete);
476}
477
478/*
479 * vfe_pm_domain_off - Disable power domains specific to this VFE.
480 * @vfe: VFE Device
481 */
482void vfe_pm_domain_off(struct vfe_device *vfe)
483{
484	if (!vfe->genpd)
485		return;
486
487	device_link_del(vfe->genpd_link);
488	vfe->genpd_link = NULL;
489}
490
491/*
492 * vfe_pm_domain_on - Enable power domains specific to this VFE.
493 * @vfe: VFE Device
494 */
495int vfe_pm_domain_on(struct vfe_device *vfe)
496{
497	struct camss *camss = vfe->camss;
498
499	if (!vfe->genpd)
500		return 0;
501
502	vfe->genpd_link = device_link_add(camss->dev, vfe->genpd,
503					  DL_FLAG_STATELESS |
504					  DL_FLAG_PM_RUNTIME |
505					  DL_FLAG_RPM_ACTIVE);
506	if (!vfe->genpd_link)
507		return -EINVAL;
508
509	return 0;
510}
511
512static int vfe_match_clock_names(struct vfe_device *vfe,
513				 struct camss_clock *clock)
514{
515	char vfe_name[7]; /* vfeXXX\0 */
516	char vfe_lite_name[12]; /* vfe_liteXXX\0 */
517
518	snprintf(vfe_name, sizeof(vfe_name), "vfe%d", vfe->id);
519	snprintf(vfe_lite_name, sizeof(vfe_lite_name), "vfe_lite%d", vfe->id);
520
521	return (!strcmp(clock->name, vfe_name) ||
522		!strcmp(clock->name, vfe_lite_name) ||
523		!strcmp(clock->name, "vfe_lite"));
524}
525
526/*
527 * vfe_set_clock_rates - Calculate and set clock rates on VFE module
528 * @vfe: VFE device
529 *
530 * Return 0 on success or a negative error code otherwise
531 */
532static int vfe_set_clock_rates(struct vfe_device *vfe)
533{
534	struct device *dev = vfe->camss->dev;
535	u64 pixel_clock[VFE_LINE_NUM_MAX];
536	int i, j;
537	int ret;
538
539	for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) {
540		ret = camss_get_pixel_clock(&vfe->line[i].subdev.entity,
541					    &pixel_clock[i]);
542		if (ret)
543			pixel_clock[i] = 0;
544	}
545
546	for (i = 0; i < vfe->nclocks; i++) {
547		struct camss_clock *clock = &vfe->clock[i];
548
549		if (vfe_match_clock_names(vfe, clock)) {
550			u64 min_rate = 0;
551			long rate;
552
553			for (j = VFE_LINE_RDI0; j < vfe->line_num; j++) {
554				u32 tmp;
555				u8 bpp;
556
557				if (j == VFE_LINE_PIX) {
558					tmp = pixel_clock[j];
559				} else {
560					struct vfe_line *l = &vfe->line[j];
561
562					bpp = vfe_get_bpp(l->formats,
563						l->nformats,
564						l->fmt[MSM_VFE_PAD_SINK].code);
565					tmp = pixel_clock[j] * bpp / 64;
566				}
567
568				if (min_rate < tmp)
569					min_rate = tmp;
570			}
571
572			camss_add_clock_margin(&min_rate);
573
574			for (j = 0; j < clock->nfreqs; j++)
575				if (min_rate < clock->freq[j])
576					break;
577
578			if (j == clock->nfreqs) {
579				dev_err(dev,
580					"Pixel clock is too high for VFE");
581				return -EINVAL;
582			}
583
584			/* if sensor pixel clock is not available */
585			/* set highest possible VFE clock rate */
586			if (min_rate == 0)
587				j = clock->nfreqs - 1;
588
589			rate = clk_round_rate(clock->clk, clock->freq[j]);
590			if (rate < 0) {
591				dev_err(dev, "clk round rate failed: %ld\n",
592					rate);
593				return -EINVAL;
594			}
595
596			ret = clk_set_rate(clock->clk, rate);
597			if (ret < 0) {
598				dev_err(dev, "clk set rate failed: %d\n", ret);
599				return ret;
600			}
601		}
602	}
603
604	return 0;
605}
606
607/*
608 * vfe_check_clock_rates - Check current clock rates on VFE module
609 * @vfe: VFE device
610 *
611 * Return 0 if current clock rates are suitable for a new pipeline
612 * or a negative error code otherwise
613 */
614static int vfe_check_clock_rates(struct vfe_device *vfe)
615{
616	u64 pixel_clock[VFE_LINE_NUM_MAX];
617	int i, j;
618	int ret;
619
620	for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) {
621		ret = camss_get_pixel_clock(&vfe->line[i].subdev.entity,
622					    &pixel_clock[i]);
623		if (ret)
624			pixel_clock[i] = 0;
625	}
626
627	for (i = 0; i < vfe->nclocks; i++) {
628		struct camss_clock *clock = &vfe->clock[i];
629
630		if (vfe_match_clock_names(vfe, clock)) {
631			u64 min_rate = 0;
632			unsigned long rate;
633
634			for (j = VFE_LINE_RDI0; j < vfe->line_num; j++) {
635				u32 tmp;
636				u8 bpp;
637
638				if (j == VFE_LINE_PIX) {
639					tmp = pixel_clock[j];
640				} else {
641					struct vfe_line *l = &vfe->line[j];
642
643					bpp = vfe_get_bpp(l->formats,
644						l->nformats,
645						l->fmt[MSM_VFE_PAD_SINK].code);
646					tmp = pixel_clock[j] * bpp / 64;
647				}
648
649				if (min_rate < tmp)
650					min_rate = tmp;
651			}
652
653			camss_add_clock_margin(&min_rate);
654
655			rate = clk_get_rate(clock->clk);
656			if (rate < min_rate)
657				return -EBUSY;
658		}
659	}
660
661	return 0;
662}
663
664/*
665 * vfe_get - Power up and reset VFE module
666 * @vfe: VFE Device
667 *
668 * Return 0 on success or a negative error code otherwise
669 */
670int vfe_get(struct vfe_device *vfe)
671{
672	int ret;
673
674	mutex_lock(&vfe->power_lock);
675
676	if (vfe->power_count == 0) {
677		ret = vfe->ops->pm_domain_on(vfe);
678		if (ret < 0)
679			goto error_pm_domain;
680
681		ret = pm_runtime_resume_and_get(vfe->camss->dev);
682		if (ret < 0)
683			goto error_domain_off;
684
685		ret = vfe_set_clock_rates(vfe);
686		if (ret < 0)
687			goto error_pm_runtime_get;
688
689		ret = camss_enable_clocks(vfe->nclocks, vfe->clock,
690					  vfe->camss->dev);
691		if (ret < 0)
692			goto error_pm_runtime_get;
693
694		ret = vfe_reset(vfe);
695		if (ret < 0)
696			goto error_reset;
697
698		vfe_reset_output_maps(vfe);
699
700		vfe_init_outputs(vfe);
701
702		vfe->ops->hw_version(vfe);
703	} else {
704		ret = vfe_check_clock_rates(vfe);
705		if (ret < 0)
706			goto error_pm_domain;
707	}
708	vfe->power_count++;
709
710	mutex_unlock(&vfe->power_lock);
711
712	return 0;
713
714error_reset:
715	camss_disable_clocks(vfe->nclocks, vfe->clock);
716
717error_pm_runtime_get:
718	pm_runtime_put_sync(vfe->camss->dev);
719error_domain_off:
720	vfe->ops->pm_domain_off(vfe);
721
722error_pm_domain:
723	mutex_unlock(&vfe->power_lock);
724
725	return ret;
726}
727
728/*
729 * vfe_put - Power down VFE module
730 * @vfe: VFE Device
731 */
732void vfe_put(struct vfe_device *vfe)
733{
734	mutex_lock(&vfe->power_lock);
735
736	if (vfe->power_count == 0) {
737		dev_err(vfe->camss->dev, "vfe power off on power_count == 0\n");
738		goto exit;
739	} else if (vfe->power_count == 1) {
740		if (vfe->was_streaming) {
741			vfe->was_streaming = 0;
742			vfe->ops->vfe_halt(vfe);
743		}
744		camss_disable_clocks(vfe->nclocks, vfe->clock);
745		pm_runtime_put_sync(vfe->camss->dev);
746		vfe->ops->pm_domain_off(vfe);
747	}
748
749	vfe->power_count--;
750
751exit:
752	mutex_unlock(&vfe->power_lock);
753}
754
755/*
756 * vfe_flush_buffers - Return all vb2 buffers
757 * @vid: Video device structure
758 * @state: vb2 buffer state of the returned buffers
759 *
760 * Return all buffers to vb2. This includes queued pending buffers (still
761 * unused) and any buffers given to the hardware but again still not used.
762 *
763 * Return 0 on success or a negative error code otherwise
764 */
765int vfe_flush_buffers(struct camss_video *vid,
766		      enum vb2_buffer_state state)
767{
768	struct vfe_line *line = container_of(vid, struct vfe_line, video_out);
769	struct vfe_device *vfe = to_vfe(line);
770	struct vfe_output *output;
771	unsigned long flags;
772
773	output = &line->output;
774
775	spin_lock_irqsave(&vfe->output_lock, flags);
776
777	vfe_buf_flush_pending(output, state);
778
779	if (output->buf[0])
780		vb2_buffer_done(&output->buf[0]->vb.vb2_buf, state);
781
782	if (output->buf[1])
783		vb2_buffer_done(&output->buf[1]->vb.vb2_buf, state);
784
785	if (output->last_buffer) {
786		vb2_buffer_done(&output->last_buffer->vb.vb2_buf, state);
787		output->last_buffer = NULL;
788	}
789
790	spin_unlock_irqrestore(&vfe->output_lock, flags);
791
792	return 0;
793}
794
795/*
796 * vfe_set_power - Power on/off VFE module
797 * @sd: VFE V4L2 subdevice
798 * @on: Requested power state
799 *
800 * Return 0 on success or a negative error code otherwise
801 */
802static int vfe_set_power(struct v4l2_subdev *sd, int on)
803{
804	struct vfe_line *line = v4l2_get_subdevdata(sd);
805	struct vfe_device *vfe = to_vfe(line);
806	int ret;
807
808	if (on) {
809		ret = vfe_get(vfe);
810		if (ret < 0)
811			return ret;
812	} else {
813		vfe_put(vfe);
814	}
815
816	return 0;
817}
818
819/*
820 * vfe_set_stream - Enable/disable streaming on VFE module
821 * @sd: VFE V4L2 subdevice
822 * @enable: Requested streaming state
823 *
824 * Main configuration of VFE module is triggered here.
825 *
826 * Return 0 on success or a negative error code otherwise
827 */
828static int vfe_set_stream(struct v4l2_subdev *sd, int enable)
829{
830	struct vfe_line *line = v4l2_get_subdevdata(sd);
831	struct vfe_device *vfe = to_vfe(line);
832	int ret;
833
834	if (enable) {
835		line->output.state = VFE_OUTPUT_RESERVED;
836		ret = vfe->ops->vfe_enable(line);
837		if (ret < 0)
838			dev_err(vfe->camss->dev,
839				"Failed to enable vfe outputs\n");
840	} else {
841		ret = vfe->ops->vfe_disable(line);
842		if (ret < 0)
843			dev_err(vfe->camss->dev,
844				"Failed to disable vfe outputs\n");
845	}
846
847	return ret;
848}
849
850/*
851 * __vfe_get_format - Get pointer to format structure
852 * @line: VFE line
853 * @sd_state: V4L2 subdev state
854 * @pad: pad from which format is requested
855 * @which: TRY or ACTIVE format
856 *
857 * Return pointer to TRY or ACTIVE format structure
858 */
859static struct v4l2_mbus_framefmt *
860__vfe_get_format(struct vfe_line *line,
861		 struct v4l2_subdev_state *sd_state,
862		 unsigned int pad,
863		 enum v4l2_subdev_format_whence which)
864{
865	if (which == V4L2_SUBDEV_FORMAT_TRY)
866		return v4l2_subdev_state_get_format(sd_state, pad);
867
868	return &line->fmt[pad];
869}
870
871/*
872 * __vfe_get_compose - Get pointer to compose selection structure
873 * @line: VFE line
874 * @sd_state: V4L2 subdev state
875 * @which: TRY or ACTIVE format
876 *
877 * Return pointer to TRY or ACTIVE compose rectangle structure
878 */
879static struct v4l2_rect *
880__vfe_get_compose(struct vfe_line *line,
881		  struct v4l2_subdev_state *sd_state,
882		  enum v4l2_subdev_format_whence which)
883{
884	if (which == V4L2_SUBDEV_FORMAT_TRY)
885		return v4l2_subdev_state_get_compose(sd_state,
886						     MSM_VFE_PAD_SINK);
887
888	return &line->compose;
889}
890
891/*
892 * __vfe_get_crop - Get pointer to crop selection structure
893 * @line: VFE line
894 * @sd_state: V4L2 subdev state
895 * @which: TRY or ACTIVE format
896 *
897 * Return pointer to TRY or ACTIVE crop rectangle structure
898 */
899static struct v4l2_rect *
900__vfe_get_crop(struct vfe_line *line,
901	       struct v4l2_subdev_state *sd_state,
902	       enum v4l2_subdev_format_whence which)
903{
904	if (which == V4L2_SUBDEV_FORMAT_TRY)
905		return v4l2_subdev_state_get_crop(sd_state, MSM_VFE_PAD_SRC);
906
907	return &line->crop;
908}
909
910/*
911 * vfe_try_format - Handle try format by pad subdev method
912 * @line: VFE line
913 * @sd_state: V4L2 subdev state
914 * @pad: pad on which format is requested
915 * @fmt: pointer to v4l2 format structure
916 * @which: wanted subdev format
917 */
918static void vfe_try_format(struct vfe_line *line,
919			   struct v4l2_subdev_state *sd_state,
920			   unsigned int pad,
921			   struct v4l2_mbus_framefmt *fmt,
922			   enum v4l2_subdev_format_whence which)
923{
924	unsigned int i;
925	u32 code;
926
927	switch (pad) {
928	case MSM_VFE_PAD_SINK:
929		/* Set format on sink pad */
930
931		for (i = 0; i < line->nformats; i++)
932			if (fmt->code == line->formats[i].code)
933				break;
934
935		/* If not found, use UYVY as default */
936		if (i >= line->nformats)
937			fmt->code = MEDIA_BUS_FMT_UYVY8_1X16;
938
939		fmt->width = clamp_t(u32, fmt->width, 1, 8191);
940		fmt->height = clamp_t(u32, fmt->height, 1, 8191);
941
942		fmt->field = V4L2_FIELD_NONE;
943		fmt->colorspace = V4L2_COLORSPACE_SRGB;
944
945		break;
946
947	case MSM_VFE_PAD_SRC:
948		/* Set and return a format same as sink pad */
949		code = fmt->code;
950
951		*fmt = *__vfe_get_format(line, sd_state, MSM_VFE_PAD_SINK,
952					 which);
953
954		fmt->code = vfe_src_pad_code(line, fmt->code, 0, code);
955
956		if (line->id == VFE_LINE_PIX) {
957			struct v4l2_rect *rect;
958
959			rect = __vfe_get_crop(line, sd_state, which);
960
961			fmt->width = rect->width;
962			fmt->height = rect->height;
963		}
964
965		break;
966	}
967
968	fmt->colorspace = V4L2_COLORSPACE_SRGB;
969}
970
971/*
972 * vfe_try_compose - Handle try compose selection by pad subdev method
973 * @line: VFE line
974 * @sd_state: V4L2 subdev state
975 * @rect: pointer to v4l2 rect structure
976 * @which: wanted subdev format
977 */
978static void vfe_try_compose(struct vfe_line *line,
979			    struct v4l2_subdev_state *sd_state,
980			    struct v4l2_rect *rect,
981			    enum v4l2_subdev_format_whence which)
982{
983	struct v4l2_mbus_framefmt *fmt;
984
985	fmt = __vfe_get_format(line, sd_state, MSM_VFE_PAD_SINK, which);
986
987	if (rect->width > fmt->width)
988		rect->width = fmt->width;
989
990	if (rect->height > fmt->height)
991		rect->height = fmt->height;
992
993	if (fmt->width > rect->width * SCALER_RATIO_MAX)
994		rect->width = (fmt->width + SCALER_RATIO_MAX - 1) /
995							SCALER_RATIO_MAX;
996
997	rect->width &= ~0x1;
998
999	if (fmt->height > rect->height * SCALER_RATIO_MAX)
1000		rect->height = (fmt->height + SCALER_RATIO_MAX - 1) /
1001							SCALER_RATIO_MAX;
1002
1003	if (rect->width < 16)
1004		rect->width = 16;
1005
1006	if (rect->height < 4)
1007		rect->height = 4;
1008}
1009
1010/*
1011 * vfe_try_crop - Handle try crop selection by pad subdev method
1012 * @line: VFE line
1013 * @sd_state: V4L2 subdev state
1014 * @rect: pointer to v4l2 rect structure
1015 * @which: wanted subdev format
1016 */
1017static void vfe_try_crop(struct vfe_line *line,
1018			 struct v4l2_subdev_state *sd_state,
1019			 struct v4l2_rect *rect,
1020			 enum v4l2_subdev_format_whence which)
1021{
1022	struct v4l2_rect *compose;
1023
1024	compose = __vfe_get_compose(line, sd_state, which);
1025
1026	if (rect->width > compose->width)
1027		rect->width = compose->width;
1028
1029	if (rect->width + rect->left > compose->width)
1030		rect->left = compose->width - rect->width;
1031
1032	if (rect->height > compose->height)
1033		rect->height = compose->height;
1034
1035	if (rect->height + rect->top > compose->height)
1036		rect->top = compose->height - rect->height;
1037
1038	/* wm in line based mode writes multiple of 16 horizontally */
1039	rect->left += (rect->width & 0xf) >> 1;
1040	rect->width &= ~0xf;
1041
1042	if (rect->width < 16) {
1043		rect->left = 0;
1044		rect->width = 16;
1045	}
1046
1047	if (rect->height < 4) {
1048		rect->top = 0;
1049		rect->height = 4;
1050	}
1051}
1052
1053/*
1054 * vfe_enum_mbus_code - Handle pixel format enumeration
1055 * @sd: VFE V4L2 subdevice
1056 * @sd_state: V4L2 subdev state
1057 * @code: pointer to v4l2_subdev_mbus_code_enum structure
1058 *
1059 * return -EINVAL or zero on success
1060 */
1061static int vfe_enum_mbus_code(struct v4l2_subdev *sd,
1062			      struct v4l2_subdev_state *sd_state,
1063			      struct v4l2_subdev_mbus_code_enum *code)
1064{
1065	struct vfe_line *line = v4l2_get_subdevdata(sd);
1066
1067	if (code->pad == MSM_VFE_PAD_SINK) {
1068		if (code->index >= line->nformats)
1069			return -EINVAL;
1070
1071		code->code = line->formats[code->index].code;
1072	} else {
1073		struct v4l2_mbus_framefmt *sink_fmt;
1074
1075		sink_fmt = __vfe_get_format(line, sd_state, MSM_VFE_PAD_SINK,
1076					    code->which);
1077
1078		code->code = vfe_src_pad_code(line, sink_fmt->code,
1079					      code->index, 0);
1080		if (!code->code)
1081			return -EINVAL;
1082	}
1083
1084	return 0;
1085}
1086
1087/*
1088 * vfe_enum_frame_size - Handle frame size enumeration
1089 * @sd: VFE V4L2 subdevice
1090 * @sd_state: V4L2 subdev state
1091 * @fse: pointer to v4l2_subdev_frame_size_enum structure
1092 *
1093 * Return -EINVAL or zero on success
1094 */
1095static int vfe_enum_frame_size(struct v4l2_subdev *sd,
1096			       struct v4l2_subdev_state *sd_state,
1097			       struct v4l2_subdev_frame_size_enum *fse)
1098{
1099	struct vfe_line *line = v4l2_get_subdevdata(sd);
1100	struct v4l2_mbus_framefmt format;
1101
1102	if (fse->index != 0)
1103		return -EINVAL;
1104
1105	format.code = fse->code;
1106	format.width = 1;
1107	format.height = 1;
1108	vfe_try_format(line, sd_state, fse->pad, &format, fse->which);
1109	fse->min_width = format.width;
1110	fse->min_height = format.height;
1111
1112	if (format.code != fse->code)
1113		return -EINVAL;
1114
1115	format.code = fse->code;
1116	format.width = -1;
1117	format.height = -1;
1118	vfe_try_format(line, sd_state, fse->pad, &format, fse->which);
1119	fse->max_width = format.width;
1120	fse->max_height = format.height;
1121
1122	return 0;
1123}
1124
1125/*
1126 * vfe_get_format - Handle get format by pads subdev method
1127 * @sd: VFE V4L2 subdevice
1128 * @sd_state: V4L2 subdev state
1129 * @fmt: pointer to v4l2 subdev format structure
1130 *
1131 * Return -EINVAL or zero on success
1132 */
1133static int vfe_get_format(struct v4l2_subdev *sd,
1134			  struct v4l2_subdev_state *sd_state,
1135			  struct v4l2_subdev_format *fmt)
1136{
1137	struct vfe_line *line = v4l2_get_subdevdata(sd);
1138	struct v4l2_mbus_framefmt *format;
1139
1140	format = __vfe_get_format(line, sd_state, fmt->pad, fmt->which);
1141	if (format == NULL)
1142		return -EINVAL;
1143
1144	fmt->format = *format;
1145
1146	return 0;
1147}
1148
1149static int vfe_set_selection(struct v4l2_subdev *sd,
1150			     struct v4l2_subdev_state *sd_state,
1151			     struct v4l2_subdev_selection *sel);
1152
1153/*
1154 * vfe_set_format - Handle set format by pads subdev method
1155 * @sd: VFE V4L2 subdevice
1156 * @sd_state: V4L2 subdev state
1157 * @fmt: pointer to v4l2 subdev format structure
1158 *
1159 * Return -EINVAL or zero on success
1160 */
1161static int vfe_set_format(struct v4l2_subdev *sd,
1162			  struct v4l2_subdev_state *sd_state,
1163			  struct v4l2_subdev_format *fmt)
1164{
1165	struct vfe_line *line = v4l2_get_subdevdata(sd);
1166	struct v4l2_mbus_framefmt *format;
1167
1168	format = __vfe_get_format(line, sd_state, fmt->pad, fmt->which);
1169	if (format == NULL)
1170		return -EINVAL;
1171
1172	vfe_try_format(line, sd_state, fmt->pad, &fmt->format, fmt->which);
1173	*format = fmt->format;
1174
1175	if (fmt->pad == MSM_VFE_PAD_SINK) {
1176		struct v4l2_subdev_selection sel = { 0 };
1177		int ret;
1178
1179		/* Propagate the format from sink to source */
1180		format = __vfe_get_format(line, sd_state, MSM_VFE_PAD_SRC,
1181					  fmt->which);
1182
1183		*format = fmt->format;
1184		vfe_try_format(line, sd_state, MSM_VFE_PAD_SRC, format,
1185			       fmt->which);
1186
1187		if (line->id != VFE_LINE_PIX)
1188			return 0;
1189
1190		/* Reset sink pad compose selection */
1191		sel.which = fmt->which;
1192		sel.pad = MSM_VFE_PAD_SINK;
1193		sel.target = V4L2_SEL_TGT_COMPOSE;
1194		sel.r.width = fmt->format.width;
1195		sel.r.height = fmt->format.height;
1196		ret = vfe_set_selection(sd, sd_state, &sel);
1197		if (ret < 0)
1198			return ret;
1199	}
1200
1201	return 0;
1202}
1203
1204/*
1205 * vfe_get_selection - Handle get selection by pads subdev method
1206 * @sd: VFE V4L2 subdevice
1207 * @sd_state: V4L2 subdev state
1208 * @sel: pointer to v4l2 subdev selection structure
1209 *
1210 * Return -EINVAL or zero on success
1211 */
1212static int vfe_get_selection(struct v4l2_subdev *sd,
1213			     struct v4l2_subdev_state *sd_state,
1214			     struct v4l2_subdev_selection *sel)
1215{
1216	struct vfe_line *line = v4l2_get_subdevdata(sd);
1217	struct v4l2_subdev_format fmt = { 0 };
1218	struct v4l2_rect *rect;
1219	int ret;
1220
1221	if (line->id != VFE_LINE_PIX)
1222		return -EINVAL;
1223
1224	if (sel->pad == MSM_VFE_PAD_SINK)
1225		switch (sel->target) {
1226		case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1227			fmt.pad = sel->pad;
1228			fmt.which = sel->which;
1229			ret = vfe_get_format(sd, sd_state, &fmt);
1230			if (ret < 0)
1231				return ret;
1232
1233			sel->r.left = 0;
1234			sel->r.top = 0;
1235			sel->r.width = fmt.format.width;
1236			sel->r.height = fmt.format.height;
1237			break;
1238		case V4L2_SEL_TGT_COMPOSE:
1239			rect = __vfe_get_compose(line, sd_state, sel->which);
1240			if (rect == NULL)
1241				return -EINVAL;
1242
1243			sel->r = *rect;
1244			break;
1245		default:
1246			return -EINVAL;
1247		}
1248	else if (sel->pad == MSM_VFE_PAD_SRC)
1249		switch (sel->target) {
1250		case V4L2_SEL_TGT_CROP_BOUNDS:
1251			rect = __vfe_get_compose(line, sd_state, sel->which);
1252			if (rect == NULL)
1253				return -EINVAL;
1254
1255			sel->r.left = rect->left;
1256			sel->r.top = rect->top;
1257			sel->r.width = rect->width;
1258			sel->r.height = rect->height;
1259			break;
1260		case V4L2_SEL_TGT_CROP:
1261			rect = __vfe_get_crop(line, sd_state, sel->which);
1262			if (rect == NULL)
1263				return -EINVAL;
1264
1265			sel->r = *rect;
1266			break;
1267		default:
1268			return -EINVAL;
1269		}
1270
1271	return 0;
1272}
1273
1274/*
1275 * vfe_set_selection - Handle set selection by pads subdev method
1276 * @sd: VFE V4L2 subdevice
1277 * @sd_state: V4L2 subdev state
1278 * @sel: pointer to v4l2 subdev selection structure
1279 *
1280 * Return -EINVAL or zero on success
1281 */
1282static int vfe_set_selection(struct v4l2_subdev *sd,
1283			     struct v4l2_subdev_state *sd_state,
1284			     struct v4l2_subdev_selection *sel)
1285{
1286	struct vfe_line *line = v4l2_get_subdevdata(sd);
1287	struct v4l2_rect *rect;
1288	int ret;
1289
1290	if (line->id != VFE_LINE_PIX)
1291		return -EINVAL;
1292
1293	if (sel->target == V4L2_SEL_TGT_COMPOSE &&
1294		sel->pad == MSM_VFE_PAD_SINK) {
1295		struct v4l2_subdev_selection crop = { 0 };
1296
1297		rect = __vfe_get_compose(line, sd_state, sel->which);
1298		if (rect == NULL)
1299			return -EINVAL;
1300
1301		vfe_try_compose(line, sd_state, &sel->r, sel->which);
1302		*rect = sel->r;
1303
1304		/* Reset source crop selection */
1305		crop.which = sel->which;
1306		crop.pad = MSM_VFE_PAD_SRC;
1307		crop.target = V4L2_SEL_TGT_CROP;
1308		crop.r = *rect;
1309		ret = vfe_set_selection(sd, sd_state, &crop);
1310	} else if (sel->target == V4L2_SEL_TGT_CROP &&
1311		sel->pad == MSM_VFE_PAD_SRC) {
1312		struct v4l2_subdev_format fmt = { 0 };
1313
1314		rect = __vfe_get_crop(line, sd_state, sel->which);
1315		if (rect == NULL)
1316			return -EINVAL;
1317
1318		vfe_try_crop(line, sd_state, &sel->r, sel->which);
1319		*rect = sel->r;
1320
1321		/* Reset source pad format width and height */
1322		fmt.which = sel->which;
1323		fmt.pad = MSM_VFE_PAD_SRC;
1324		ret = vfe_get_format(sd, sd_state, &fmt);
1325		if (ret < 0)
1326			return ret;
1327
1328		fmt.format.width = rect->width;
1329		fmt.format.height = rect->height;
1330		ret = vfe_set_format(sd, sd_state, &fmt);
1331	} else {
1332		ret = -EINVAL;
1333	}
1334
1335	return ret;
1336}
1337
1338/*
1339 * vfe_init_formats - Initialize formats on all pads
1340 * @sd: VFE V4L2 subdevice
1341 * @fh: V4L2 subdev file handle
1342 *
1343 * Initialize all pad formats with default values.
1344 *
1345 * Return 0 on success or a negative error code otherwise
1346 */
1347static int vfe_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1348{
1349	struct v4l2_subdev_format format = {
1350		.pad = MSM_VFE_PAD_SINK,
1351		.which = fh ? V4L2_SUBDEV_FORMAT_TRY :
1352			      V4L2_SUBDEV_FORMAT_ACTIVE,
1353		.format = {
1354			.code = MEDIA_BUS_FMT_UYVY8_1X16,
1355			.width = 1920,
1356			.height = 1080
1357		}
1358	};
1359
1360	return vfe_set_format(sd, fh ? fh->state : NULL, &format);
1361}
1362
1363/*
1364 * msm_vfe_subdev_init - Initialize VFE device structure and resources
1365 * @vfe: VFE device
1366 * @res: VFE module resources table
1367 *
1368 * Return 0 on success or a negative error code otherwise
1369 */
1370int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
1371			const struct camss_subdev_resources *res, u8 id)
1372{
1373	struct device *dev = camss->dev;
1374	struct platform_device *pdev = to_platform_device(dev);
1375	int i, j;
1376	int ret;
1377
1378	vfe->ops = res->ops;
1379
1380	if (!res->line_num)
1381		return -EINVAL;
1382
1383	/* Power domain */
1384
1385	if (res->pd_name) {
1386		vfe->genpd = dev_pm_domain_attach_by_name(camss->dev,
1387							  res->pd_name);
1388		if (IS_ERR(vfe->genpd)) {
1389			ret = PTR_ERR(vfe->genpd);
1390			return ret;
1391		}
1392	}
1393
1394	if (!vfe->genpd && res->has_pd) {
1395		/*
1396		 * Legacy magic index.
1397		 * Requires
1398		 * power-domain = <VFE_X>,
1399		 *                <VFE_Y>,
1400		 *                <TITAN_TOP>
1401		 * id must correspondng to the index of the VFE which must
1402		 * come before the TOP GDSC. VFE Lite has no individually
1403		 * collapasible domain which is why id < vfe_num is a valid
1404		 * check.
1405		 */
1406		vfe->genpd = dev_pm_domain_attach_by_id(camss->dev, id);
1407		if (IS_ERR(vfe->genpd))
1408			return PTR_ERR(vfe->genpd);
1409	}
1410
1411	vfe->line_num = res->line_num;
1412	vfe->ops->subdev_init(dev, vfe);
1413
1414	/* Memory */
1415
1416	vfe->base = devm_platform_ioremap_resource_byname(pdev, res->reg[0]);
1417	if (IS_ERR(vfe->base)) {
1418		dev_err(dev, "could not map memory\n");
1419		return PTR_ERR(vfe->base);
1420	}
1421
1422	/* Interrupt */
1423
1424	ret = platform_get_irq_byname(pdev, res->interrupt[0]);
1425	if (ret < 0)
1426		return ret;
1427
1428	vfe->irq = ret;
1429	snprintf(vfe->irq_name, sizeof(vfe->irq_name), "%s_%s%d",
1430		 dev_name(dev), MSM_VFE_NAME, id);
1431	ret = devm_request_irq(dev, vfe->irq, vfe->ops->isr,
1432			       IRQF_TRIGGER_RISING, vfe->irq_name, vfe);
1433	if (ret < 0) {
1434		dev_err(dev, "request_irq failed: %d\n", ret);
1435		return ret;
1436	}
1437
1438	/* Clocks */
1439
1440	vfe->nclocks = 0;
1441	while (res->clock[vfe->nclocks])
1442		vfe->nclocks++;
1443
1444	vfe->clock = devm_kcalloc(dev, vfe->nclocks, sizeof(*vfe->clock),
1445				  GFP_KERNEL);
1446	if (!vfe->clock)
1447		return -ENOMEM;
1448
1449	for (i = 0; i < vfe->nclocks; i++) {
1450		struct camss_clock *clock = &vfe->clock[i];
1451
1452		clock->clk = devm_clk_get(dev, res->clock[i]);
1453		if (IS_ERR(clock->clk))
1454			return PTR_ERR(clock->clk);
1455
1456		clock->name = res->clock[i];
1457
1458		clock->nfreqs = 0;
1459		while (res->clock_rate[i][clock->nfreqs])
1460			clock->nfreqs++;
1461
1462		if (!clock->nfreqs) {
1463			clock->freq = NULL;
1464			continue;
1465		}
1466
1467		clock->freq = devm_kcalloc(dev,
1468					   clock->nfreqs,
1469					   sizeof(*clock->freq),
1470					   GFP_KERNEL);
1471		if (!clock->freq)
1472			return -ENOMEM;
1473
1474		for (j = 0; j < clock->nfreqs; j++)
1475			clock->freq[j] = res->clock_rate[i][j];
1476	}
1477
1478	mutex_init(&vfe->power_lock);
1479	vfe->power_count = 0;
1480
1481	mutex_init(&vfe->stream_lock);
1482	vfe->stream_count = 0;
1483
1484	spin_lock_init(&vfe->output_lock);
1485
1486	vfe->camss = camss;
1487	vfe->id = id;
1488	vfe->reg_update = 0;
1489
1490	for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) {
1491		struct vfe_line *l = &vfe->line[i];
1492
1493		l->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1494		l->video_out.camss = camss;
1495		l->id = i;
1496		init_completion(&l->output.sof);
1497		init_completion(&l->output.reg_update);
1498
1499		switch (camss->res->version) {
1500		case CAMSS_8x16:
1501			if (i == VFE_LINE_PIX) {
1502				l->formats = formats_pix_8x16;
1503				l->nformats = ARRAY_SIZE(formats_pix_8x16);
1504			} else {
1505				l->formats = formats_rdi_8x16;
1506				l->nformats = ARRAY_SIZE(formats_rdi_8x16);
1507			}
1508			break;
1509		case CAMSS_8x96:
1510		case CAMSS_660:
1511			if (i == VFE_LINE_PIX) {
1512				l->formats = formats_pix_8x96;
1513				l->nformats = ARRAY_SIZE(formats_pix_8x96);
1514			} else {
1515				l->formats = formats_rdi_8x96;
1516				l->nformats = ARRAY_SIZE(formats_rdi_8x96);
1517			}
1518			break;
1519		case CAMSS_845:
1520		case CAMSS_8250:
1521			l->formats = formats_rdi_845;
1522			l->nformats = ARRAY_SIZE(formats_rdi_845);
1523			break;
1524		}
1525	}
1526
1527	init_completion(&vfe->reset_complete);
1528	init_completion(&vfe->halt_complete);
1529
1530	return 0;
1531}
1532
1533/*
1534 * msm_vfe_genpd_cleanup - Cleanup VFE genpd linkages
1535 * @vfe: VFE device
1536 */
1537void msm_vfe_genpd_cleanup(struct vfe_device *vfe)
1538{
1539	if (vfe->genpd_link)
1540		device_link_del(vfe->genpd_link);
1541
1542	if (vfe->genpd)
1543		dev_pm_domain_detach(vfe->genpd, true);
1544}
1545
1546/*
1547 * vfe_link_setup - Setup VFE connections
1548 * @entity: Pointer to media entity structure
1549 * @local: Pointer to local pad
1550 * @remote: Pointer to remote pad
1551 * @flags: Link flags
1552 *
1553 * Return 0 on success
1554 */
1555static int vfe_link_setup(struct media_entity *entity,
1556			  const struct media_pad *local,
1557			  const struct media_pad *remote, u32 flags)
1558{
1559	if (flags & MEDIA_LNK_FL_ENABLED)
1560		if (media_pad_remote_pad_first(local))
1561			return -EBUSY;
1562
1563	return 0;
1564}
1565
1566static const struct v4l2_subdev_core_ops vfe_core_ops = {
1567	.s_power = vfe_set_power,
1568};
1569
1570static const struct v4l2_subdev_video_ops vfe_video_ops = {
1571	.s_stream = vfe_set_stream,
1572};
1573
1574static const struct v4l2_subdev_pad_ops vfe_pad_ops = {
1575	.enum_mbus_code = vfe_enum_mbus_code,
1576	.enum_frame_size = vfe_enum_frame_size,
1577	.get_fmt = vfe_get_format,
1578	.set_fmt = vfe_set_format,
1579	.get_selection = vfe_get_selection,
1580	.set_selection = vfe_set_selection,
1581};
1582
1583static const struct v4l2_subdev_ops vfe_v4l2_ops = {
1584	.core = &vfe_core_ops,
1585	.video = &vfe_video_ops,
1586	.pad = &vfe_pad_ops,
1587};
1588
1589static const struct v4l2_subdev_internal_ops vfe_v4l2_internal_ops = {
1590	.open = vfe_init_formats,
1591};
1592
1593static const struct media_entity_operations vfe_media_ops = {
1594	.link_setup = vfe_link_setup,
1595	.link_validate = v4l2_subdev_link_validate,
1596};
1597
1598/*
1599 * msm_vfe_register_entities - Register subdev node for VFE module
1600 * @vfe: VFE device
1601 * @v4l2_dev: V4L2 device
1602 *
1603 * Initialize and register a subdev node for the VFE module. Then
1604 * call msm_video_register() to register the video device node which
1605 * will be connected to this subdev node. Then actually create the
1606 * media link between them.
1607 *
1608 * Return 0 on success or a negative error code otherwise
1609 */
1610int msm_vfe_register_entities(struct vfe_device *vfe,
1611			      struct v4l2_device *v4l2_dev)
1612{
1613	struct device *dev = vfe->camss->dev;
1614	struct v4l2_subdev *sd;
1615	struct media_pad *pads;
1616	struct camss_video *video_out;
1617	int ret;
1618	int i;
1619
1620	for (i = 0; i < vfe->line_num; i++) {
1621		char name[32];
1622
1623		sd = &vfe->line[i].subdev;
1624		pads = vfe->line[i].pads;
1625		video_out = &vfe->line[i].video_out;
1626
1627		v4l2_subdev_init(sd, &vfe_v4l2_ops);
1628		sd->internal_ops = &vfe_v4l2_internal_ops;
1629		sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1630		if (i == VFE_LINE_PIX)
1631			snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d_%s",
1632				 MSM_VFE_NAME, vfe->id, "pix");
1633		else
1634			snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d_%s%d",
1635				 MSM_VFE_NAME, vfe->id, "rdi", i);
1636
1637		v4l2_set_subdevdata(sd, &vfe->line[i]);
1638
1639		ret = vfe_init_formats(sd, NULL);
1640		if (ret < 0) {
1641			dev_err(dev, "Failed to init format: %d\n", ret);
1642			goto error_init;
1643		}
1644
1645		pads[MSM_VFE_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
1646		pads[MSM_VFE_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;
1647
1648		sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
1649		sd->entity.ops = &vfe_media_ops;
1650		ret = media_entity_pads_init(&sd->entity, MSM_VFE_PADS_NUM,
1651					     pads);
1652		if (ret < 0) {
1653			dev_err(dev, "Failed to init media entity: %d\n", ret);
1654			goto error_init;
1655		}
1656
1657		ret = v4l2_device_register_subdev(v4l2_dev, sd);
1658		if (ret < 0) {
1659			dev_err(dev, "Failed to register subdev: %d\n", ret);
1660			goto error_reg_subdev;
1661		}
1662
1663		video_out->ops = &vfe->video_ops;
1664		if (vfe->camss->res->version == CAMSS_845 ||
1665		    vfe->camss->res->version == CAMSS_8250)
1666			video_out->bpl_alignment = 16;
1667		else
1668			video_out->bpl_alignment = 8;
1669		video_out->line_based = 0;
1670		if (i == VFE_LINE_PIX) {
1671			video_out->bpl_alignment = 16;
1672			video_out->line_based = 1;
1673		}
1674		snprintf(name, ARRAY_SIZE(name), "%s%d_%s%d",
1675			 MSM_VFE_NAME, vfe->id, "video", i);
1676		ret = msm_video_register(video_out, v4l2_dev, name,
1677					 i == VFE_LINE_PIX ? 1 : 0);
1678		if (ret < 0) {
1679			dev_err(dev, "Failed to register video node: %d\n",
1680				ret);
1681			goto error_reg_video;
1682		}
1683
1684		ret = media_create_pad_link(
1685				&sd->entity, MSM_VFE_PAD_SRC,
1686				&video_out->vdev.entity, 0,
1687				MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
1688		if (ret < 0) {
1689			dev_err(dev, "Failed to link %s->%s entities: %d\n",
1690				sd->entity.name, video_out->vdev.entity.name,
1691				ret);
1692			goto error_link;
1693		}
1694	}
1695
1696	return 0;
1697
1698error_link:
1699	msm_video_unregister(video_out);
1700
1701error_reg_video:
1702	v4l2_device_unregister_subdev(sd);
1703
1704error_reg_subdev:
1705	media_entity_cleanup(&sd->entity);
1706
1707error_init:
1708	for (i--; i >= 0; i--) {
1709		sd = &vfe->line[i].subdev;
1710		video_out = &vfe->line[i].video_out;
1711
1712		msm_video_unregister(video_out);
1713		v4l2_device_unregister_subdev(sd);
1714		media_entity_cleanup(&sd->entity);
1715	}
1716
1717	return ret;
1718}
1719
1720/*
1721 * msm_vfe_unregister_entities - Unregister VFE module subdev node
1722 * @vfe: VFE device
1723 */
1724void msm_vfe_unregister_entities(struct vfe_device *vfe)
1725{
1726	int i;
1727
1728	mutex_destroy(&vfe->power_lock);
1729	mutex_destroy(&vfe->stream_lock);
1730
1731	for (i = 0; i < vfe->line_num; i++) {
1732		struct v4l2_subdev *sd = &vfe->line[i].subdev;
1733		struct camss_video *video_out = &vfe->line[i].video_out;
1734
1735		msm_video_unregister(video_out);
1736		v4l2_device_unregister_subdev(sd);
1737		media_entity_cleanup(&sd->entity);
1738	}
1739}
1740
1741bool vfe_is_lite(struct vfe_device *vfe)
1742{
1743	return vfe->camss->res->vfe_res[vfe->id].is_lite;
1744}
1745