xref: /linux/drivers/media/platform/qcom/camss/camss-vfe.c (revision 68a052239fc4b351e961f698b824f7654a346091)
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 
35 #define VFE_HW_VERSION		0x0
36 #define		HW_VERSION_STEPPING	0
37 #define		HW_VERSION_REVISION	16
38 #define		HW_VERSION_GENERATION	28
39 
40 static const struct camss_format_info formats_rdi_8x16[] = {
41 	{ MEDIA_BUS_FMT_UYVY8_1X16, 8, V4L2_PIX_FMT_UYVY, 1,
42 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
43 	{ MEDIA_BUS_FMT_VYUY8_1X16, 8, V4L2_PIX_FMT_VYUY, 1,
44 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
45 	{ MEDIA_BUS_FMT_YUYV8_1X16, 8, V4L2_PIX_FMT_YUYV, 1,
46 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
47 	{ MEDIA_BUS_FMT_YVYU8_1X16, 8, V4L2_PIX_FMT_YVYU, 1,
48 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
49 	{ MEDIA_BUS_FMT_SBGGR8_1X8, 8, V4L2_PIX_FMT_SBGGR8, 1,
50 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 8) },
51 	{ MEDIA_BUS_FMT_SGBRG8_1X8, 8, V4L2_PIX_FMT_SGBRG8, 1,
52 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 8) },
53 	{ MEDIA_BUS_FMT_SGRBG8_1X8, 8, V4L2_PIX_FMT_SGRBG8, 1,
54 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 8) },
55 	{ MEDIA_BUS_FMT_SRGGB8_1X8, 8, V4L2_PIX_FMT_SRGGB8, 1,
56 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 8) },
57 	{ MEDIA_BUS_FMT_SBGGR10_1X10, 10, V4L2_PIX_FMT_SBGGR10P, 1,
58 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 10) },
59 	{ MEDIA_BUS_FMT_SGBRG10_1X10, 10, V4L2_PIX_FMT_SGBRG10P, 1,
60 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 10) },
61 	{ MEDIA_BUS_FMT_SGRBG10_1X10, 10, V4L2_PIX_FMT_SGRBG10P, 1,
62 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 10) },
63 	{ MEDIA_BUS_FMT_SRGGB10_1X10, 10, V4L2_PIX_FMT_SRGGB10P, 1,
64 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 10) },
65 	{ MEDIA_BUS_FMT_SBGGR12_1X12, 12, V4L2_PIX_FMT_SBGGR12P, 1,
66 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 12) },
67 	{ MEDIA_BUS_FMT_SGBRG12_1X12, 12, V4L2_PIX_FMT_SGBRG12P, 1,
68 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 12) },
69 	{ MEDIA_BUS_FMT_SGRBG12_1X12, 12, V4L2_PIX_FMT_SGRBG12P, 1,
70 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 12) },
71 	{ MEDIA_BUS_FMT_SRGGB12_1X12, 12, V4L2_PIX_FMT_SRGGB12P, 1,
72 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 12) },
73 	{ MEDIA_BUS_FMT_Y10_1X10, 10, V4L2_PIX_FMT_Y10P, 1,
74 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 10) },
75 };
76 
77 static const struct camss_format_info formats_rdi_8x96[] = {
78 	{ MEDIA_BUS_FMT_UYVY8_1X16, 8, V4L2_PIX_FMT_UYVY, 1,
79 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
80 	{ MEDIA_BUS_FMT_VYUY8_1X16, 8, V4L2_PIX_FMT_VYUY, 1,
81 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
82 	{ MEDIA_BUS_FMT_YUYV8_1X16, 8, V4L2_PIX_FMT_YUYV, 1,
83 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
84 	{ MEDIA_BUS_FMT_YVYU8_1X16, 8, V4L2_PIX_FMT_YVYU, 1,
85 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
86 	{ MEDIA_BUS_FMT_SBGGR8_1X8, 8, V4L2_PIX_FMT_SBGGR8, 1,
87 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 8) },
88 	{ MEDIA_BUS_FMT_SGBRG8_1X8, 8, V4L2_PIX_FMT_SGBRG8, 1,
89 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 8) },
90 	{ MEDIA_BUS_FMT_SGRBG8_1X8, 8, V4L2_PIX_FMT_SGRBG8, 1,
91 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 8) },
92 	{ MEDIA_BUS_FMT_SRGGB8_1X8, 8, V4L2_PIX_FMT_SRGGB8, 1,
93 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 8) },
94 	{ MEDIA_BUS_FMT_SBGGR10_1X10, 10, V4L2_PIX_FMT_SBGGR10P, 1,
95 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 10) },
96 	{ MEDIA_BUS_FMT_SGBRG10_1X10, 10, V4L2_PIX_FMT_SGBRG10P, 1,
97 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 10) },
98 	{ MEDIA_BUS_FMT_SGRBG10_1X10, 10, V4L2_PIX_FMT_SGRBG10P, 1,
99 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 10) },
100 	{ MEDIA_BUS_FMT_SRGGB10_1X10, 10, V4L2_PIX_FMT_SRGGB10P, 1,
101 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 10) },
102 	{ MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, 16, V4L2_PIX_FMT_SBGGR10, 1,
103 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
104 	{ MEDIA_BUS_FMT_SBGGR12_1X12, 12, V4L2_PIX_FMT_SBGGR12P, 1,
105 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 12) },
106 	{ MEDIA_BUS_FMT_SGBRG12_1X12, 12, V4L2_PIX_FMT_SGBRG12P, 1,
107 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 12) },
108 	{ MEDIA_BUS_FMT_SGRBG12_1X12, 12, V4L2_PIX_FMT_SGRBG12P, 1,
109 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 12) },
110 	{ MEDIA_BUS_FMT_SRGGB12_1X12, 12, V4L2_PIX_FMT_SRGGB12P, 1,
111 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 12) },
112 	{ MEDIA_BUS_FMT_SBGGR14_1X14, 14, V4L2_PIX_FMT_SBGGR14P, 1,
113 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 14) },
114 	{ MEDIA_BUS_FMT_SGBRG14_1X14, 14, V4L2_PIX_FMT_SGBRG14P, 1,
115 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 14) },
116 	{ MEDIA_BUS_FMT_SGRBG14_1X14, 14, V4L2_PIX_FMT_SGRBG14P, 1,
117 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 14) },
118 	{ MEDIA_BUS_FMT_SRGGB14_1X14, 14, V4L2_PIX_FMT_SRGGB14P, 1,
119 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 14) },
120 	{ MEDIA_BUS_FMT_Y10_1X10, 10, V4L2_PIX_FMT_Y10P, 1,
121 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 10) },
122 	{ MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, 16, V4L2_PIX_FMT_Y10, 1,
123 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
124 };
125 
126 static const struct camss_format_info formats_rdi_845[] = {
127 	{ MEDIA_BUS_FMT_UYVY8_1X16, 8, V4L2_PIX_FMT_UYVY, 1,
128 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
129 	{ MEDIA_BUS_FMT_VYUY8_1X16, 8, V4L2_PIX_FMT_VYUY, 1,
130 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
131 	{ MEDIA_BUS_FMT_YUYV8_1X16, 8, V4L2_PIX_FMT_YUYV, 1,
132 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
133 	{ MEDIA_BUS_FMT_YVYU8_1X16, 8, V4L2_PIX_FMT_YVYU, 1,
134 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
135 	{ MEDIA_BUS_FMT_SBGGR8_1X8, 8, V4L2_PIX_FMT_SBGGR8, 1,
136 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 8) },
137 	{ MEDIA_BUS_FMT_SGBRG8_1X8, 8, V4L2_PIX_FMT_SGBRG8, 1,
138 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 8) },
139 	{ MEDIA_BUS_FMT_SGRBG8_1X8, 8, V4L2_PIX_FMT_SGRBG8, 1,
140 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 8) },
141 	{ MEDIA_BUS_FMT_SRGGB8_1X8, 8, V4L2_PIX_FMT_SRGGB8, 1,
142 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 8) },
143 	{ MEDIA_BUS_FMT_SBGGR10_1X10, 10, V4L2_PIX_FMT_SBGGR10P, 1,
144 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 10) },
145 	{ MEDIA_BUS_FMT_SGBRG10_1X10, 10, V4L2_PIX_FMT_SGBRG10P, 1,
146 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 10) },
147 	{ MEDIA_BUS_FMT_SGRBG10_1X10, 10, V4L2_PIX_FMT_SGRBG10P, 1,
148 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 10) },
149 	{ MEDIA_BUS_FMT_SRGGB10_1X10, 10, V4L2_PIX_FMT_SRGGB10P, 1,
150 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 10) },
151 	{ MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, 16, V4L2_PIX_FMT_SBGGR10, 1,
152 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
153 	{ MEDIA_BUS_FMT_SBGGR12_1X12, 12, V4L2_PIX_FMT_SBGGR12P, 1,
154 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 12) },
155 	{ MEDIA_BUS_FMT_SGBRG12_1X12, 12, V4L2_PIX_FMT_SGBRG12P, 1,
156 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 12) },
157 	{ MEDIA_BUS_FMT_SGRBG12_1X12, 12, V4L2_PIX_FMT_SGRBG12P, 1,
158 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 12) },
159 	{ MEDIA_BUS_FMT_SRGGB12_1X12, 12, V4L2_PIX_FMT_SRGGB12P, 1,
160 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 12) },
161 	{ MEDIA_BUS_FMT_SBGGR14_1X14, 14, V4L2_PIX_FMT_SBGGR14P, 1,
162 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 14) },
163 	{ MEDIA_BUS_FMT_SGBRG14_1X14, 14, V4L2_PIX_FMT_SGBRG14P, 1,
164 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 14) },
165 	{ MEDIA_BUS_FMT_SGRBG14_1X14, 14, V4L2_PIX_FMT_SGRBG14P, 1,
166 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 14) },
167 	{ MEDIA_BUS_FMT_SRGGB14_1X14, 14, V4L2_PIX_FMT_SRGGB14P, 1,
168 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 14) },
169 	{ MEDIA_BUS_FMT_Y8_1X8, 8, V4L2_PIX_FMT_GREY, 1,
170 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 8) },
171 	{ MEDIA_BUS_FMT_Y10_1X10, 10, V4L2_PIX_FMT_Y10P, 1,
172 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 10) },
173 	{ MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, 16, V4L2_PIX_FMT_Y10, 1,
174 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
175 };
176 
177 static const struct camss_format_info formats_pix_8x16[] = {
178 	{ MEDIA_BUS_FMT_YUYV8_1_5X8, 8, V4L2_PIX_FMT_NV12, 1,
179 	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
180 	{ MEDIA_BUS_FMT_YVYU8_1_5X8, 8, V4L2_PIX_FMT_NV12, 1,
181 	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
182 	{ MEDIA_BUS_FMT_UYVY8_1_5X8, 8, V4L2_PIX_FMT_NV12, 1,
183 	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
184 	{ MEDIA_BUS_FMT_VYUY8_1_5X8, 8, V4L2_PIX_FMT_NV12, 1,
185 	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
186 	{ MEDIA_BUS_FMT_YUYV8_1_5X8, 8, V4L2_PIX_FMT_NV21, 1,
187 	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
188 	{ MEDIA_BUS_FMT_YVYU8_1_5X8, 8, V4L2_PIX_FMT_NV21, 1,
189 	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
190 	{ MEDIA_BUS_FMT_UYVY8_1_5X8, 8, V4L2_PIX_FMT_NV21, 1,
191 	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
192 	{ MEDIA_BUS_FMT_VYUY8_1_5X8, 8, V4L2_PIX_FMT_NV21, 1,
193 	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
194 	{ MEDIA_BUS_FMT_YUYV8_1X16, 8, V4L2_PIX_FMT_NV16, 1,
195 	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
196 	{ MEDIA_BUS_FMT_YVYU8_1X16, 8, V4L2_PIX_FMT_NV16, 1,
197 	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
198 	{ MEDIA_BUS_FMT_UYVY8_1X16, 8, V4L2_PIX_FMT_NV16, 1,
199 	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
200 	{ MEDIA_BUS_FMT_VYUY8_1X16, 8, V4L2_PIX_FMT_NV16, 1,
201 	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
202 	{ MEDIA_BUS_FMT_YUYV8_1X16, 8, V4L2_PIX_FMT_NV61, 1,
203 	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
204 	{ MEDIA_BUS_FMT_YVYU8_1X16, 8, V4L2_PIX_FMT_NV61, 1,
205 	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
206 	{ MEDIA_BUS_FMT_UYVY8_1X16, 8, V4L2_PIX_FMT_NV61, 1,
207 	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
208 	{ MEDIA_BUS_FMT_VYUY8_1X16, 8, V4L2_PIX_FMT_NV61, 1,
209 	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
210 };
211 
212 static const struct camss_format_info formats_pix_8x96[] = {
213 	{ MEDIA_BUS_FMT_YUYV8_1_5X8, 8, V4L2_PIX_FMT_NV12, 1,
214 	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
215 	{ MEDIA_BUS_FMT_YVYU8_1_5X8, 8, V4L2_PIX_FMT_NV12, 1,
216 	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
217 	{ MEDIA_BUS_FMT_UYVY8_1_5X8, 8, V4L2_PIX_FMT_NV12, 1,
218 	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
219 	{ MEDIA_BUS_FMT_VYUY8_1_5X8, 8, V4L2_PIX_FMT_NV12, 1,
220 	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
221 	{ MEDIA_BUS_FMT_YUYV8_1_5X8, 8, V4L2_PIX_FMT_NV21, 1,
222 	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
223 	{ MEDIA_BUS_FMT_YVYU8_1_5X8, 8, V4L2_PIX_FMT_NV21, 1,
224 	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
225 	{ MEDIA_BUS_FMT_UYVY8_1_5X8, 8, V4L2_PIX_FMT_NV21, 1,
226 	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
227 	{ MEDIA_BUS_FMT_VYUY8_1_5X8, 8, V4L2_PIX_FMT_NV21, 1,
228 	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
229 	{ MEDIA_BUS_FMT_YUYV8_1X16, 8, V4L2_PIX_FMT_NV16, 1,
230 	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
231 	{ MEDIA_BUS_FMT_YVYU8_1X16, 8, V4L2_PIX_FMT_NV16, 1,
232 	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
233 	{ MEDIA_BUS_FMT_UYVY8_1X16, 8, V4L2_PIX_FMT_NV16, 1,
234 	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
235 	{ MEDIA_BUS_FMT_VYUY8_1X16, 8, V4L2_PIX_FMT_NV16, 1,
236 	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
237 	{ MEDIA_BUS_FMT_YUYV8_1X16, 8, V4L2_PIX_FMT_NV61, 1,
238 	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
239 	{ MEDIA_BUS_FMT_YVYU8_1X16, 8, V4L2_PIX_FMT_NV61, 1,
240 	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
241 	{ MEDIA_BUS_FMT_UYVY8_1X16, 8, V4L2_PIX_FMT_NV61, 1,
242 	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
243 	{ MEDIA_BUS_FMT_VYUY8_1X16, 8, V4L2_PIX_FMT_NV61, 1,
244 	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
245 	{ MEDIA_BUS_FMT_UYVY8_1X16, 8, V4L2_PIX_FMT_UYVY, 1,
246 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
247 	{ MEDIA_BUS_FMT_VYUY8_1X16, 8, V4L2_PIX_FMT_VYUY, 1,
248 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
249 	{ MEDIA_BUS_FMT_YUYV8_1X16, 8, V4L2_PIX_FMT_YUYV, 1,
250 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
251 	{ MEDIA_BUS_FMT_YVYU8_1X16, 8, V4L2_PIX_FMT_YVYU, 1,
252 	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
253 };
254 
255 const struct camss_formats vfe_formats_rdi_8x16 = {
256 	.nformats = ARRAY_SIZE(formats_rdi_8x16),
257 	.formats = formats_rdi_8x16
258 };
259 
260 const struct camss_formats vfe_formats_pix_8x16 = {
261 	.nformats = ARRAY_SIZE(formats_pix_8x16),
262 	.formats = formats_pix_8x16
263 };
264 
265 const struct camss_formats vfe_formats_rdi_8x96 = {
266 	.nformats = ARRAY_SIZE(formats_rdi_8x96),
267 	.formats = formats_rdi_8x96
268 };
269 
270 const struct camss_formats vfe_formats_pix_8x96 = {
271 	.nformats = ARRAY_SIZE(formats_pix_8x96),
272 	.formats = formats_pix_8x96
273 };
274 
275 const struct camss_formats vfe_formats_rdi_845 = {
276 	.nformats = ARRAY_SIZE(formats_rdi_845),
277 	.formats = formats_rdi_845
278 };
279 
280 /* TODO: Replace with pix formats */
281 const struct camss_formats vfe_formats_pix_845 = {
282 	.nformats = ARRAY_SIZE(formats_rdi_845),
283 	.formats = formats_rdi_845
284 };
285 
286 static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
287 			    unsigned int index, u32 src_req_code)
288 {
289 	struct vfe_device *vfe = to_vfe(line);
290 
291 	switch (vfe->camss->res->version) {
292 	case CAMSS_8x16:
293 	case CAMSS_8x53:
294 		switch (sink_code) {
295 		case MEDIA_BUS_FMT_YUYV8_1X16:
296 		{
297 			u32 src_code[] = {
298 				MEDIA_BUS_FMT_YUYV8_1X16,
299 				MEDIA_BUS_FMT_YUYV8_1_5X8,
300 			};
301 
302 			return camss_format_find_code(src_code, ARRAY_SIZE(src_code),
303 						      index, src_req_code);
304 		}
305 		case MEDIA_BUS_FMT_YVYU8_1X16:
306 		{
307 			u32 src_code[] = {
308 				MEDIA_BUS_FMT_YVYU8_1X16,
309 				MEDIA_BUS_FMT_YVYU8_1_5X8,
310 			};
311 
312 			return camss_format_find_code(src_code, ARRAY_SIZE(src_code),
313 						      index, src_req_code);
314 		}
315 		case MEDIA_BUS_FMT_UYVY8_1X16:
316 		{
317 			u32 src_code[] = {
318 				MEDIA_BUS_FMT_UYVY8_1X16,
319 				MEDIA_BUS_FMT_UYVY8_1_5X8,
320 			};
321 
322 			return camss_format_find_code(src_code, ARRAY_SIZE(src_code),
323 						      index, src_req_code);
324 		}
325 		case MEDIA_BUS_FMT_VYUY8_1X16:
326 		{
327 			u32 src_code[] = {
328 				MEDIA_BUS_FMT_VYUY8_1X16,
329 				MEDIA_BUS_FMT_VYUY8_1_5X8,
330 			};
331 
332 			return camss_format_find_code(src_code, ARRAY_SIZE(src_code),
333 						      index, src_req_code);
334 		}
335 		default:
336 			if (index > 0)
337 				return 0;
338 
339 			return sink_code;
340 		}
341 		break;
342 	case CAMSS_660:
343 	case CAMSS_2290:
344 	case CAMSS_7280:
345 	case CAMSS_8x96:
346 	case CAMSS_8250:
347 	case CAMSS_8280XP:
348 	case CAMSS_8300:
349 	case CAMSS_845:
350 	case CAMSS_8550:
351 	case CAMSS_8775P:
352 	case CAMSS_X1E80100:
353 		switch (sink_code) {
354 		case MEDIA_BUS_FMT_YUYV8_1X16:
355 		{
356 			u32 src_code[] = {
357 				MEDIA_BUS_FMT_YUYV8_1X16,
358 				MEDIA_BUS_FMT_YVYU8_1X16,
359 				MEDIA_BUS_FMT_UYVY8_1X16,
360 				MEDIA_BUS_FMT_VYUY8_1X16,
361 				MEDIA_BUS_FMT_YUYV8_1_5X8,
362 			};
363 
364 			return camss_format_find_code(src_code, ARRAY_SIZE(src_code),
365 						      index, src_req_code);
366 		}
367 		case MEDIA_BUS_FMT_YVYU8_1X16:
368 		{
369 			u32 src_code[] = {
370 				MEDIA_BUS_FMT_YVYU8_1X16,
371 				MEDIA_BUS_FMT_YUYV8_1X16,
372 				MEDIA_BUS_FMT_UYVY8_1X16,
373 				MEDIA_BUS_FMT_VYUY8_1X16,
374 				MEDIA_BUS_FMT_YVYU8_1_5X8,
375 			};
376 
377 			return camss_format_find_code(src_code, ARRAY_SIZE(src_code),
378 						      index, src_req_code);
379 		}
380 		case MEDIA_BUS_FMT_UYVY8_1X16:
381 		{
382 			u32 src_code[] = {
383 				MEDIA_BUS_FMT_UYVY8_1X16,
384 				MEDIA_BUS_FMT_YUYV8_1X16,
385 				MEDIA_BUS_FMT_YVYU8_1X16,
386 				MEDIA_BUS_FMT_VYUY8_1X16,
387 				MEDIA_BUS_FMT_UYVY8_1_5X8,
388 			};
389 
390 			return camss_format_find_code(src_code, ARRAY_SIZE(src_code),
391 						      index, src_req_code);
392 		}
393 		case MEDIA_BUS_FMT_VYUY8_1X16:
394 		{
395 			u32 src_code[] = {
396 				MEDIA_BUS_FMT_VYUY8_1X16,
397 				MEDIA_BUS_FMT_YUYV8_1X16,
398 				MEDIA_BUS_FMT_YVYU8_1X16,
399 				MEDIA_BUS_FMT_UYVY8_1X16,
400 				MEDIA_BUS_FMT_VYUY8_1_5X8,
401 			};
402 
403 			return camss_format_find_code(src_code, ARRAY_SIZE(src_code),
404 						      index, src_req_code);
405 		}
406 		default:
407 			if (index > 0)
408 				return 0;
409 
410 			return sink_code;
411 		}
412 		break;
413 	default:
414 		WARN(1, "Unsupported HW version: %x\n",
415 		     vfe->camss->res->version);
416 		break;
417 	}
418 	return 0;
419 }
420 
421 /*
422  * vfe_hw_version - Process write master done interrupt
423  * @vfe: VFE Device
424  *
425  * Return vfe hw version
426  */
427 u32 vfe_hw_version(struct vfe_device *vfe)
428 {
429 	u32 hw_version = readl_relaxed(vfe->base + VFE_HW_VERSION);
430 
431 	u32 gen = (hw_version >> HW_VERSION_GENERATION) & 0xF;
432 	u32 rev = (hw_version >> HW_VERSION_REVISION) & 0xFFF;
433 	u32 step = (hw_version >> HW_VERSION_STEPPING) & 0xFFFF;
434 
435 	dev_dbg(vfe->camss->dev, "VFE:%d HW Version = %u.%u.%u\n",
436 		vfe->id, gen, rev, step);
437 
438 	return hw_version;
439 }
440 
441 /*
442  * vfe_buf_done - Process write master done interrupt
443  * @vfe: VFE Device
444  * @wm: Write master id
445  */
446 void vfe_buf_done(struct vfe_device *vfe, int wm)
447 {
448 	struct vfe_line *line = &vfe->line[vfe->wm_output_map[wm]];
449 	const struct vfe_hw_ops *ops = vfe->res->hw_ops;
450 	struct camss_buffer *ready_buf;
451 	struct vfe_output *output;
452 	unsigned long flags;
453 	u32 index;
454 	u64 ts = ktime_get_ns();
455 
456 	spin_lock_irqsave(&vfe->output_lock, flags);
457 
458 	if (vfe->wm_output_map[wm] == VFE_LINE_NONE) {
459 		dev_err_ratelimited(vfe->camss->dev,
460 				    "Received wm done for unmapped index\n");
461 		goto out_unlock;
462 	}
463 	output = &vfe->line[vfe->wm_output_map[wm]].output;
464 
465 	ready_buf = output->buf[0];
466 	if (!ready_buf) {
467 		dev_err_ratelimited(vfe->camss->dev,
468 				    "Missing ready buf %d!\n", output->state);
469 		goto out_unlock;
470 	}
471 
472 	ready_buf->vb.vb2_buf.timestamp = ts;
473 	ready_buf->vb.sequence = output->sequence++;
474 
475 	index = 0;
476 	output->buf[0] = output->buf[1];
477 	if (output->buf[0])
478 		index = 1;
479 
480 	output->buf[index] = vfe_buf_get_pending(output);
481 
482 	if (output->buf[index]) {
483 		ops->vfe_wm_update(vfe, output->wm_idx[0],
484 				   output->buf[index]->addr[0],
485 				   line);
486 		ops->reg_update(vfe, line->id);
487 	} else {
488 		output->gen2.active_num--;
489 	}
490 
491 	spin_unlock_irqrestore(&vfe->output_lock, flags);
492 
493 	vb2_buffer_done(&ready_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
494 
495 	return;
496 
497 out_unlock:
498 	spin_unlock_irqrestore(&vfe->output_lock, flags);
499 }
500 
501 int vfe_enable_output_v2(struct vfe_line *line)
502 {
503 	struct vfe_device *vfe = to_vfe(line);
504 	struct vfe_output *output = &line->output;
505 	const struct vfe_hw_ops *ops = vfe->res->hw_ops;
506 	struct media_pad *sensor_pad;
507 	unsigned long flags;
508 	unsigned int frame_skip = 0;
509 	unsigned int i;
510 
511 	sensor_pad = camss_find_sensor_pad(&line->subdev.entity);
512 	if (sensor_pad) {
513 		struct v4l2_subdev *subdev =
514 			media_entity_to_v4l2_subdev(sensor_pad->entity);
515 
516 		v4l2_subdev_call(subdev, sensor, g_skip_frames, &frame_skip);
517 		/* Max frame skip is 29 frames */
518 		if (frame_skip > VFE_FRAME_DROP_VAL - 1)
519 			frame_skip = VFE_FRAME_DROP_VAL - 1;
520 	}
521 
522 	spin_lock_irqsave(&vfe->output_lock, flags);
523 
524 	ops->reg_update_clear(vfe, line->id);
525 
526 	if (output->state > VFE_OUTPUT_RESERVED) {
527 		dev_err(vfe->camss->dev,
528 			"Output is not in reserved state %d\n",
529 			output->state);
530 		spin_unlock_irqrestore(&vfe->output_lock, flags);
531 		return -EINVAL;
532 	}
533 
534 	WARN_ON(output->gen2.active_num);
535 
536 	output->state = VFE_OUTPUT_ON;
537 
538 	output->sequence = 0;
539 	output->wait_reg_update = 0;
540 	reinit_completion(&output->reg_update);
541 
542 	ops->vfe_wm_start(vfe, output->wm_idx[0], line);
543 
544 	for (i = 0; i < 2; i++) {
545 		output->buf[i] = vfe_buf_get_pending(output);
546 		if (!output->buf[i])
547 			break;
548 		output->gen2.active_num++;
549 		ops->vfe_wm_update(vfe, output->wm_idx[0],
550 				   output->buf[i]->addr[0], line);
551 		ops->reg_update(vfe, line->id);
552 	}
553 
554 	spin_unlock_irqrestore(&vfe->output_lock, flags);
555 
556 	return 0;
557 }
558 
559 /*
560  * vfe_queue_buffer_v2 - Add empty buffer
561  * @vid: Video device structure
562  * @buf: Buffer to be enqueued
563  *
564  * Add an empty buffer - depending on the current number of buffers it will be
565  * put in pending buffer queue or directly given to the hardware to be filled.
566  *
567  * Return 0 on success or a negative error code otherwise
568  */
569 int vfe_queue_buffer_v2(struct camss_video *vid,
570 			struct camss_buffer *buf)
571 {
572 	struct vfe_line *line = container_of(vid, struct vfe_line, video_out);
573 	struct vfe_device *vfe = to_vfe(line);
574 	const struct vfe_hw_ops *ops = vfe->res->hw_ops;
575 	struct vfe_output *output;
576 	unsigned long flags;
577 
578 	output = &line->output;
579 
580 	spin_lock_irqsave(&vfe->output_lock, flags);
581 
582 	if (output->state == VFE_OUTPUT_ON &&
583 	    output->gen2.active_num < 2) {
584 		output->buf[output->gen2.active_num++] = buf;
585 		ops->vfe_wm_update(vfe, output->wm_idx[0],
586 				   buf->addr[0], line);
587 		ops->reg_update(vfe, line->id);
588 	} else {
589 		vfe_buf_add_pending(output, buf);
590 	}
591 
592 	spin_unlock_irqrestore(&vfe->output_lock, flags);
593 
594 	return 0;
595 }
596 
597 /*
598  * vfe_enable_v2 - Enable streaming on VFE line
599  * @line: VFE line
600  *
601  * Return 0 on success or a negative error code otherwise
602  */
603 int vfe_enable_v2(struct vfe_line *line)
604 {
605 	struct vfe_device *vfe = to_vfe(line);
606 	const struct vfe_hw_ops *ops = vfe->res->hw_ops;
607 	int ret;
608 
609 	mutex_lock(&vfe->stream_lock);
610 
611 	if (vfe->res->hw_ops->enable_irq)
612 		ops->enable_irq(vfe);
613 
614 	vfe->stream_count++;
615 
616 	mutex_unlock(&vfe->stream_lock);
617 
618 	ret = vfe_get_output_v2(line);
619 	if (ret < 0)
620 		goto error_get_output;
621 
622 	ret = vfe_enable_output_v2(line);
623 	if (ret < 0)
624 		goto error_enable_output;
625 
626 	vfe->was_streaming = 1;
627 
628 	return 0;
629 
630 error_enable_output:
631 	vfe_put_output(line);
632 
633 error_get_output:
634 	mutex_lock(&vfe->stream_lock);
635 
636 	vfe->stream_count--;
637 
638 	mutex_unlock(&vfe->stream_lock);
639 
640 	return ret;
641 }
642 
643 /*
644  * vfe_get_output_v2 - Get vfe output port for corresponding VFE line
645  * @line: VFE line
646  *
647  * Return 0 on success or a negative error code otherwise
648  */
649 int vfe_get_output_v2(struct vfe_line *line)
650 {
651 	struct vfe_device *vfe = to_vfe(line);
652 	struct vfe_output *output;
653 	unsigned long flags;
654 
655 	spin_lock_irqsave(&vfe->output_lock, flags);
656 
657 	output = &line->output;
658 	if (output->state > VFE_OUTPUT_RESERVED) {
659 		dev_err(vfe->camss->dev, "Output is running\n");
660 		goto error;
661 	}
662 
663 	output->wm_num = 1;
664 
665 	/* Correspondence between VFE line number and WM number.
666 	 * line 0 -> RDI 0, line 1 -> RDI1, line 2 -> RDI2, line 3 -> PIX/RDI3
667 	 * Note this 1:1 mapping will not work for PIX streams.
668 	 */
669 	output->wm_idx[0] = line->id;
670 	vfe->wm_output_map[line->id] = line->id;
671 
672 	output->drop_update_idx = 0;
673 
674 	spin_unlock_irqrestore(&vfe->output_lock, flags);
675 
676 	return 0;
677 
678 error:
679 	spin_unlock_irqrestore(&vfe->output_lock, flags);
680 	output->state = VFE_OUTPUT_OFF;
681 
682 	return -EINVAL;
683 }
684 
685 int vfe_reset(struct vfe_device *vfe)
686 {
687 	unsigned long time;
688 
689 	reinit_completion(&vfe->reset_complete);
690 
691 	vfe->res->hw_ops->global_reset(vfe);
692 
693 	time = wait_for_completion_timeout(&vfe->reset_complete,
694 		msecs_to_jiffies(VFE_RESET_TIMEOUT_MS));
695 	if (!time) {
696 		dev_err(vfe->camss->dev, "VFE reset timeout\n");
697 		return -EIO;
698 	}
699 
700 	return 0;
701 }
702 
703 static void vfe_init_outputs(struct vfe_device *vfe)
704 {
705 	int i;
706 
707 	for (i = 0; i < vfe->res->line_num; i++) {
708 		struct vfe_output *output = &vfe->line[i].output;
709 
710 		output->state = VFE_OUTPUT_OFF;
711 		output->buf[0] = NULL;
712 		output->buf[1] = NULL;
713 		INIT_LIST_HEAD(&output->pending_bufs);
714 	}
715 }
716 
717 static void vfe_reset_output_maps(struct vfe_device *vfe)
718 {
719 	int i;
720 
721 	for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++)
722 		vfe->wm_output_map[i] = VFE_LINE_NONE;
723 }
724 
725 int vfe_reserve_wm(struct vfe_device *vfe, enum vfe_line_id line_id)
726 {
727 	int ret = -EBUSY;
728 	int i;
729 
730 	for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++) {
731 		if (vfe->wm_output_map[i] == VFE_LINE_NONE) {
732 			vfe->wm_output_map[i] = line_id;
733 			ret = i;
734 			break;
735 		}
736 	}
737 
738 	return ret;
739 }
740 
741 int vfe_release_wm(struct vfe_device *vfe, u8 wm)
742 {
743 	if (wm >= ARRAY_SIZE(vfe->wm_output_map))
744 		return -EINVAL;
745 
746 	vfe->wm_output_map[wm] = VFE_LINE_NONE;
747 
748 	return 0;
749 }
750 
751 struct camss_buffer *vfe_buf_get_pending(struct vfe_output *output)
752 {
753 	struct camss_buffer *buffer = NULL;
754 
755 	if (!list_empty(&output->pending_bufs)) {
756 		buffer = list_first_entry(&output->pending_bufs,
757 					  struct camss_buffer,
758 					  queue);
759 		list_del(&buffer->queue);
760 	}
761 
762 	return buffer;
763 }
764 
765 void vfe_buf_add_pending(struct vfe_output *output,
766 			 struct camss_buffer *buffer)
767 {
768 	INIT_LIST_HEAD(&buffer->queue);
769 	list_add_tail(&buffer->queue, &output->pending_bufs);
770 }
771 
772 /*
773  * vfe_buf_flush_pending - Flush all pending buffers.
774  * @output: VFE output
775  * @state: vb2 buffer state
776  */
777 static void vfe_buf_flush_pending(struct vfe_output *output,
778 				  enum vb2_buffer_state state)
779 {
780 	struct camss_buffer *buf;
781 	struct camss_buffer *t;
782 
783 	list_for_each_entry_safe(buf, t, &output->pending_bufs, queue) {
784 		vb2_buffer_done(&buf->vb.vb2_buf, state);
785 		list_del(&buf->queue);
786 	}
787 }
788 
789 int vfe_put_output(struct vfe_line *line)
790 {
791 	struct vfe_device *vfe = to_vfe(line);
792 	struct vfe_output *output = &line->output;
793 	unsigned long flags;
794 	unsigned int i;
795 
796 	spin_lock_irqsave(&vfe->output_lock, flags);
797 
798 	for (i = 0; i < output->wm_num; i++)
799 		vfe_release_wm(vfe, output->wm_idx[i]);
800 
801 	output->state = VFE_OUTPUT_OFF;
802 
803 	spin_unlock_irqrestore(&vfe->output_lock, flags);
804 	return 0;
805 }
806 
807 static int vfe_disable_output(struct vfe_line *line)
808 {
809 	struct vfe_device *vfe = to_vfe(line);
810 	struct vfe_output *output = &line->output;
811 	unsigned long flags;
812 	unsigned int i;
813 
814 	spin_lock_irqsave(&vfe->output_lock, flags);
815 	for (i = 0; i < output->wm_num; i++)
816 		vfe->res->hw_ops->vfe_wm_stop(vfe, output->wm_idx[i]);
817 	output->gen2.active_num = 0;
818 	spin_unlock_irqrestore(&vfe->output_lock, flags);
819 
820 	return vfe_reset(vfe);
821 }
822 
823 /*
824  * vfe_disable - Disable streaming on VFE line
825  * @line: VFE line
826  *
827  * Return 0 on success or a negative error code otherwise
828  */
829 int vfe_disable(struct vfe_line *line)
830 {
831 	struct vfe_device *vfe = to_vfe(line);
832 	int ret;
833 
834 	ret = vfe_disable_output(line);
835 	if (ret)
836 		goto error;
837 
838 	vfe_put_output(line);
839 
840 	mutex_lock(&vfe->stream_lock);
841 
842 	vfe->stream_count--;
843 
844 	mutex_unlock(&vfe->stream_lock);
845 
846 error:
847 	return ret;
848 }
849 
850 /**
851  * vfe_isr_comp_done() - Process composite image done interrupt
852  * @vfe: VFE Device
853  * @comp: Composite image id
854  */
855 void vfe_isr_comp_done(struct vfe_device *vfe, u8 comp)
856 {
857 	unsigned int i;
858 
859 	for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++)
860 		if (vfe->wm_output_map[i] == VFE_LINE_PIX) {
861 			vfe->isr_ops.wm_done(vfe, i);
862 			break;
863 		}
864 }
865 
866 void vfe_isr_reset_ack(struct vfe_device *vfe)
867 {
868 	complete(&vfe->reset_complete);
869 }
870 
871 /*
872  * vfe_pm_domain_off - Disable power domains specific to this VFE.
873  * @vfe: VFE Device
874  */
875 void vfe_pm_domain_off(struct vfe_device *vfe)
876 {
877 	if (!vfe->genpd)
878 		return;
879 
880 	device_link_del(vfe->genpd_link);
881 	vfe->genpd_link = NULL;
882 }
883 
884 /*
885  * vfe_pm_domain_on - Enable power domains specific to this VFE.
886  * @vfe: VFE Device
887  */
888 int vfe_pm_domain_on(struct vfe_device *vfe)
889 {
890 	struct camss *camss = vfe->camss;
891 
892 	if (!vfe->genpd)
893 		return 0;
894 
895 	vfe->genpd_link = device_link_add(camss->dev, vfe->genpd,
896 					  DL_FLAG_STATELESS |
897 					  DL_FLAG_PM_RUNTIME |
898 					  DL_FLAG_RPM_ACTIVE);
899 	if (!vfe->genpd_link)
900 		return -EINVAL;
901 
902 	return 0;
903 }
904 
905 static int vfe_match_clock_names(struct vfe_device *vfe,
906 				 struct camss_clock *clock)
907 {
908 	char vfe_name[7]; /* vfeXXX\0 */
909 	char vfe_lite_name[12]; /* vfe_liteXXX\0 */
910 
911 	snprintf(vfe_name, sizeof(vfe_name), "vfe%d", vfe->id);
912 	snprintf(vfe_lite_name, sizeof(vfe_lite_name), "vfe_lite%d", vfe->id);
913 
914 	return (!strcmp(clock->name, vfe_name) ||
915 		!strcmp(clock->name, vfe_lite_name) ||
916 		!strcmp(clock->name, "vfe_lite") ||
917 		!strcmp(clock->name, "camnoc_axi"));
918 }
919 
920 /*
921  * vfe_check_clock_levels - Calculate and set clock rates on VFE module
922  * @clock: clocks data
923  *
924  * Return false if there is no non-zero clock level and true otherwise.
925  */
926 static bool vfe_check_clock_levels(struct camss_clock *clock)
927 {
928 	int i;
929 
930 	for (i = 0; i < clock->nfreqs; i++)
931 		if (clock->freq[i])
932 			return true;
933 	return false;
934 }
935 
936 /*
937  * vfe_set_clock_rates - Calculate and set clock rates on VFE module
938  * @vfe: VFE device
939  *
940  * Return 0 on success or a negative error code otherwise
941  */
942 static int vfe_set_clock_rates(struct vfe_device *vfe)
943 {
944 	struct device *dev = vfe->camss->dev;
945 	u64 pixel_clock[VFE_LINE_NUM_MAX];
946 	int i, j;
947 	int ret;
948 
949 	for (i = VFE_LINE_RDI0; i < vfe->res->line_num; i++) {
950 		ret = camss_get_pixel_clock(&vfe->line[i].subdev.entity,
951 					    &pixel_clock[i]);
952 		if (ret)
953 			pixel_clock[i] = 0;
954 	}
955 
956 	for (i = 0; i < vfe->nclocks; i++) {
957 		struct camss_clock *clock = &vfe->clock[i];
958 
959 		if (vfe_match_clock_names(vfe, clock) && vfe_check_clock_levels(clock)) {
960 			u64 min_rate = 0;
961 			long rate;
962 
963 			for (j = VFE_LINE_RDI0; j < vfe->res->line_num; j++) {
964 				u32 tmp;
965 				u8 bpp;
966 
967 				if (j == VFE_LINE_PIX) {
968 					tmp = pixel_clock[j];
969 				} else {
970 					struct vfe_line *l = &vfe->line[j];
971 
972 					bpp = camss_format_get_bpp(l->formats,
973 								   l->nformats,
974 								   l->fmt[MSM_VFE_PAD_SINK].code);
975 					tmp = pixel_clock[j] * bpp / 64;
976 				}
977 
978 				if (min_rate < tmp)
979 					min_rate = tmp;
980 			}
981 
982 			camss_add_clock_margin(&min_rate);
983 
984 			for (j = 0; j < clock->nfreqs; j++)
985 				if (min_rate < clock->freq[j])
986 					break;
987 
988 			if (j == clock->nfreqs) {
989 				dev_err(dev,
990 					"Pixel clock is too high for VFE");
991 				return -EINVAL;
992 			}
993 
994 			/* if sensor pixel clock is not available */
995 			/* set highest possible VFE clock rate */
996 			if (min_rate == 0)
997 				j = clock->nfreqs - 1;
998 
999 			rate = clk_round_rate(clock->clk, clock->freq[j]);
1000 			if (rate < 0) {
1001 				dev_err(dev, "clk round rate failed: %ld\n",
1002 					rate);
1003 				return -EINVAL;
1004 			}
1005 
1006 			ret = clk_set_rate(clock->clk, rate);
1007 			if (ret < 0) {
1008 				dev_err(dev, "clk set rate failed: %d\n", ret);
1009 				return ret;
1010 			}
1011 		}
1012 	}
1013 
1014 	return 0;
1015 }
1016 
1017 /*
1018  * vfe_check_clock_rates - Check current clock rates on VFE module
1019  * @vfe: VFE device
1020  *
1021  * Return 0 if current clock rates are suitable for a new pipeline
1022  * or a negative error code otherwise
1023  */
1024 static int vfe_check_clock_rates(struct vfe_device *vfe)
1025 {
1026 	u64 pixel_clock[VFE_LINE_NUM_MAX];
1027 	int i, j;
1028 	int ret;
1029 
1030 	for (i = VFE_LINE_RDI0; i < vfe->res->line_num; i++) {
1031 		ret = camss_get_pixel_clock(&vfe->line[i].subdev.entity,
1032 					    &pixel_clock[i]);
1033 		if (ret)
1034 			pixel_clock[i] = 0;
1035 	}
1036 
1037 	for (i = 0; i < vfe->nclocks; i++) {
1038 		struct camss_clock *clock = &vfe->clock[i];
1039 
1040 		if (vfe_match_clock_names(vfe, clock) && vfe_check_clock_levels(clock)) {
1041 			u64 min_rate = 0;
1042 			unsigned long rate;
1043 
1044 			for (j = VFE_LINE_RDI0; j < vfe->res->line_num; j++) {
1045 				u32 tmp;
1046 				u8 bpp;
1047 
1048 				if (j == VFE_LINE_PIX) {
1049 					tmp = pixel_clock[j];
1050 				} else {
1051 					struct vfe_line *l = &vfe->line[j];
1052 
1053 					bpp = camss_format_get_bpp(l->formats,
1054 								   l->nformats,
1055 								   l->fmt[MSM_VFE_PAD_SINK].code);
1056 					tmp = pixel_clock[j] * bpp / 64;
1057 				}
1058 
1059 				if (min_rate < tmp)
1060 					min_rate = tmp;
1061 			}
1062 
1063 			camss_add_clock_margin(&min_rate);
1064 
1065 			rate = clk_get_rate(clock->clk);
1066 			if (rate < min_rate)
1067 				return -EBUSY;
1068 		}
1069 	}
1070 
1071 	return 0;
1072 }
1073 
1074 /*
1075  * vfe_get - Power up and reset VFE module
1076  * @vfe: VFE Device
1077  *
1078  * Return 0 on success or a negative error code otherwise
1079  */
1080 int vfe_get(struct vfe_device *vfe)
1081 {
1082 	int ret;
1083 
1084 	mutex_lock(&vfe->power_lock);
1085 
1086 	if (vfe->power_count == 0) {
1087 		ret = vfe->res->hw_ops->pm_domain_on(vfe);
1088 		if (ret < 0)
1089 			goto error_pm_domain;
1090 
1091 		ret = pm_runtime_resume_and_get(vfe->camss->dev);
1092 		if (ret < 0)
1093 			goto error_domain_off;
1094 
1095 		ret = vfe_set_clock_rates(vfe);
1096 		if (ret < 0)
1097 			goto error_pm_runtime_get;
1098 
1099 		ret = camss_enable_clocks(vfe->nclocks, vfe->clock,
1100 					  vfe->camss->dev);
1101 		if (ret < 0)
1102 			goto error_pm_runtime_get;
1103 
1104 		ret = vfe_reset(vfe);
1105 		if (ret < 0)
1106 			goto error_reset;
1107 
1108 		vfe_reset_output_maps(vfe);
1109 
1110 		vfe_init_outputs(vfe);
1111 
1112 		vfe->res->hw_ops->hw_version(vfe);
1113 	} else {
1114 		ret = vfe_check_clock_rates(vfe);
1115 		if (ret < 0)
1116 			goto error_pm_domain;
1117 	}
1118 	vfe->power_count++;
1119 
1120 	mutex_unlock(&vfe->power_lock);
1121 
1122 	return 0;
1123 
1124 error_reset:
1125 	camss_disable_clocks(vfe->nclocks, vfe->clock);
1126 
1127 error_pm_runtime_get:
1128 	pm_runtime_put_sync(vfe->camss->dev);
1129 error_domain_off:
1130 	vfe->res->hw_ops->pm_domain_off(vfe);
1131 
1132 error_pm_domain:
1133 	mutex_unlock(&vfe->power_lock);
1134 
1135 	return ret;
1136 }
1137 
1138 /*
1139  * vfe_put - Power down VFE module
1140  * @vfe: VFE Device
1141  */
1142 void vfe_put(struct vfe_device *vfe)
1143 {
1144 	mutex_lock(&vfe->power_lock);
1145 
1146 	if (vfe->power_count == 0) {
1147 		dev_err(vfe->camss->dev, "vfe power off on power_count == 0\n");
1148 		goto exit;
1149 	} else if (vfe->power_count == 1) {
1150 		if (vfe->was_streaming) {
1151 			vfe->was_streaming = 0;
1152 			vfe->res->hw_ops->vfe_halt(vfe);
1153 		}
1154 		camss_disable_clocks(vfe->nclocks, vfe->clock);
1155 		pm_runtime_put_sync(vfe->camss->dev);
1156 		vfe->res->hw_ops->pm_domain_off(vfe);
1157 	}
1158 
1159 	vfe->power_count--;
1160 
1161 exit:
1162 	mutex_unlock(&vfe->power_lock);
1163 }
1164 
1165 /*
1166  * vfe_flush_buffers - Return all vb2 buffers
1167  * @vid: Video device structure
1168  * @state: vb2 buffer state of the returned buffers
1169  *
1170  * Return all buffers to vb2. This includes queued pending buffers (still
1171  * unused) and any buffers given to the hardware but again still not used.
1172  *
1173  * Return 0 on success or a negative error code otherwise
1174  */
1175 int vfe_flush_buffers(struct camss_video *vid,
1176 		      enum vb2_buffer_state state)
1177 {
1178 	struct vfe_line *line = container_of(vid, struct vfe_line, video_out);
1179 	struct vfe_device *vfe = to_vfe(line);
1180 	struct vfe_output *output;
1181 	unsigned long flags;
1182 
1183 	output = &line->output;
1184 
1185 	spin_lock_irqsave(&vfe->output_lock, flags);
1186 
1187 	vfe_buf_flush_pending(output, state);
1188 
1189 	if (output->buf[0])
1190 		vb2_buffer_done(&output->buf[0]->vb.vb2_buf, state);
1191 
1192 	if (output->buf[1])
1193 		vb2_buffer_done(&output->buf[1]->vb.vb2_buf, state);
1194 
1195 	if (output->last_buffer) {
1196 		vb2_buffer_done(&output->last_buffer->vb.vb2_buf, state);
1197 		output->last_buffer = NULL;
1198 	}
1199 
1200 	spin_unlock_irqrestore(&vfe->output_lock, flags);
1201 
1202 	return 0;
1203 }
1204 
1205 /*
1206  * vfe_set_power - Power on/off VFE module
1207  * @sd: VFE V4L2 subdevice
1208  * @on: Requested power state
1209  *
1210  * Return 0 on success or a negative error code otherwise
1211  */
1212 static int vfe_set_power(struct v4l2_subdev *sd, int on)
1213 {
1214 	struct vfe_line *line = v4l2_get_subdevdata(sd);
1215 	struct vfe_device *vfe = to_vfe(line);
1216 	int ret;
1217 
1218 	if (on) {
1219 		ret = vfe_get(vfe);
1220 		if (ret < 0)
1221 			return ret;
1222 	} else {
1223 		vfe_put(vfe);
1224 	}
1225 
1226 	return 0;
1227 }
1228 
1229 /*
1230  * vfe_set_stream - Enable/disable streaming on VFE module
1231  * @sd: VFE V4L2 subdevice
1232  * @enable: Requested streaming state
1233  *
1234  * Main configuration of VFE module is triggered here.
1235  *
1236  * Return 0 on success or a negative error code otherwise
1237  */
1238 static int vfe_set_stream(struct v4l2_subdev *sd, int enable)
1239 {
1240 	struct vfe_line *line = v4l2_get_subdevdata(sd);
1241 	struct vfe_device *vfe = to_vfe(line);
1242 	int ret;
1243 
1244 	if (enable) {
1245 		line->output.state = VFE_OUTPUT_RESERVED;
1246 		ret = vfe->res->hw_ops->vfe_enable(line);
1247 		if (ret < 0)
1248 			dev_err(vfe->camss->dev,
1249 				"Failed to enable vfe outputs\n");
1250 	} else {
1251 		ret = vfe->res->hw_ops->vfe_disable(line);
1252 		if (ret < 0)
1253 			dev_err(vfe->camss->dev,
1254 				"Failed to disable vfe outputs\n");
1255 	}
1256 
1257 	return ret;
1258 }
1259 
1260 /*
1261  * __vfe_get_format - Get pointer to format structure
1262  * @line: VFE line
1263  * @sd_state: V4L2 subdev state
1264  * @pad: pad from which format is requested
1265  * @which: TRY or ACTIVE format
1266  *
1267  * Return pointer to TRY or ACTIVE format structure
1268  */
1269 static struct v4l2_mbus_framefmt *
1270 __vfe_get_format(struct vfe_line *line,
1271 		 struct v4l2_subdev_state *sd_state,
1272 		 unsigned int pad,
1273 		 enum v4l2_subdev_format_whence which)
1274 {
1275 	if (which == V4L2_SUBDEV_FORMAT_TRY)
1276 		return v4l2_subdev_state_get_format(sd_state, pad);
1277 
1278 	return &line->fmt[pad];
1279 }
1280 
1281 /*
1282  * __vfe_get_compose - Get pointer to compose selection structure
1283  * @line: VFE line
1284  * @sd_state: V4L2 subdev state
1285  * @which: TRY or ACTIVE format
1286  *
1287  * Return pointer to TRY or ACTIVE compose rectangle structure
1288  */
1289 static struct v4l2_rect *
1290 __vfe_get_compose(struct vfe_line *line,
1291 		  struct v4l2_subdev_state *sd_state,
1292 		  enum v4l2_subdev_format_whence which)
1293 {
1294 	if (which == V4L2_SUBDEV_FORMAT_TRY)
1295 		return v4l2_subdev_state_get_compose(sd_state,
1296 						     MSM_VFE_PAD_SINK);
1297 
1298 	return &line->compose;
1299 }
1300 
1301 /*
1302  * __vfe_get_crop - Get pointer to crop selection structure
1303  * @line: VFE line
1304  * @sd_state: V4L2 subdev state
1305  * @which: TRY or ACTIVE format
1306  *
1307  * Return pointer to TRY or ACTIVE crop rectangle structure
1308  */
1309 static struct v4l2_rect *
1310 __vfe_get_crop(struct vfe_line *line,
1311 	       struct v4l2_subdev_state *sd_state,
1312 	       enum v4l2_subdev_format_whence which)
1313 {
1314 	if (which == V4L2_SUBDEV_FORMAT_TRY)
1315 		return v4l2_subdev_state_get_crop(sd_state, MSM_VFE_PAD_SRC);
1316 
1317 	return &line->crop;
1318 }
1319 
1320 /*
1321  * vfe_try_format - Handle try format by pad subdev method
1322  * @line: VFE line
1323  * @sd_state: V4L2 subdev state
1324  * @pad: pad on which format is requested
1325  * @fmt: pointer to v4l2 format structure
1326  * @which: wanted subdev format
1327  */
1328 static void vfe_try_format(struct vfe_line *line,
1329 			   struct v4l2_subdev_state *sd_state,
1330 			   unsigned int pad,
1331 			   struct v4l2_mbus_framefmt *fmt,
1332 			   enum v4l2_subdev_format_whence which)
1333 {
1334 	unsigned int i;
1335 	u32 code;
1336 
1337 	switch (pad) {
1338 	case MSM_VFE_PAD_SINK:
1339 		/* Set format on sink pad */
1340 
1341 		for (i = 0; i < line->nformats; i++)
1342 			if (fmt->code == line->formats[i].code)
1343 				break;
1344 
1345 		/* If not found, use UYVY as default */
1346 		if (i >= line->nformats)
1347 			fmt->code = MEDIA_BUS_FMT_UYVY8_1X16;
1348 
1349 		fmt->width = clamp_t(u32, fmt->width, 1, 8191);
1350 		fmt->height = clamp_t(u32, fmt->height, 1, 8191);
1351 
1352 		fmt->field = V4L2_FIELD_NONE;
1353 		fmt->colorspace = V4L2_COLORSPACE_SRGB;
1354 
1355 		break;
1356 
1357 	case MSM_VFE_PAD_SRC:
1358 		/* Set and return a format same as sink pad */
1359 		code = fmt->code;
1360 
1361 		*fmt = *__vfe_get_format(line, sd_state, MSM_VFE_PAD_SINK,
1362 					 which);
1363 
1364 		fmt->code = vfe_src_pad_code(line, fmt->code, 0, code);
1365 
1366 		if (line->id == VFE_LINE_PIX) {
1367 			struct v4l2_rect *rect;
1368 
1369 			rect = __vfe_get_crop(line, sd_state, which);
1370 
1371 			fmt->width = rect->width;
1372 			fmt->height = rect->height;
1373 		}
1374 
1375 		break;
1376 	}
1377 
1378 	fmt->colorspace = V4L2_COLORSPACE_SRGB;
1379 }
1380 
1381 /*
1382  * vfe_try_compose - Handle try compose selection by pad subdev method
1383  * @line: VFE line
1384  * @sd_state: V4L2 subdev state
1385  * @rect: pointer to v4l2 rect structure
1386  * @which: wanted subdev format
1387  */
1388 static void vfe_try_compose(struct vfe_line *line,
1389 			    struct v4l2_subdev_state *sd_state,
1390 			    struct v4l2_rect *rect,
1391 			    enum v4l2_subdev_format_whence which)
1392 {
1393 	struct v4l2_mbus_framefmt *fmt;
1394 
1395 	fmt = __vfe_get_format(line, sd_state, MSM_VFE_PAD_SINK, which);
1396 
1397 	if (rect->width > fmt->width)
1398 		rect->width = fmt->width;
1399 
1400 	if (rect->height > fmt->height)
1401 		rect->height = fmt->height;
1402 
1403 	if (fmt->width > rect->width * SCALER_RATIO_MAX)
1404 		rect->width = (fmt->width + SCALER_RATIO_MAX - 1) /
1405 							SCALER_RATIO_MAX;
1406 
1407 	rect->width &= ~0x1;
1408 
1409 	if (fmt->height > rect->height * SCALER_RATIO_MAX)
1410 		rect->height = (fmt->height + SCALER_RATIO_MAX - 1) /
1411 							SCALER_RATIO_MAX;
1412 
1413 	if (rect->width < 16)
1414 		rect->width = 16;
1415 
1416 	if (rect->height < 4)
1417 		rect->height = 4;
1418 }
1419 
1420 /*
1421  * vfe_try_crop - Handle try crop selection by pad subdev method
1422  * @line: VFE line
1423  * @sd_state: V4L2 subdev state
1424  * @rect: pointer to v4l2 rect structure
1425  * @which: wanted subdev format
1426  */
1427 static void vfe_try_crop(struct vfe_line *line,
1428 			 struct v4l2_subdev_state *sd_state,
1429 			 struct v4l2_rect *rect,
1430 			 enum v4l2_subdev_format_whence which)
1431 {
1432 	struct v4l2_rect *compose;
1433 
1434 	compose = __vfe_get_compose(line, sd_state, which);
1435 
1436 	if (rect->width > compose->width)
1437 		rect->width = compose->width;
1438 
1439 	if (rect->width + rect->left > compose->width)
1440 		rect->left = compose->width - rect->width;
1441 
1442 	if (rect->height > compose->height)
1443 		rect->height = compose->height;
1444 
1445 	if (rect->height + rect->top > compose->height)
1446 		rect->top = compose->height - rect->height;
1447 
1448 	/* wm in line based mode writes multiple of 16 horizontally */
1449 	rect->left += (rect->width & 0xf) >> 1;
1450 	rect->width &= ~0xf;
1451 
1452 	if (rect->width < 16) {
1453 		rect->left = 0;
1454 		rect->width = 16;
1455 	}
1456 
1457 	if (rect->height < 4) {
1458 		rect->top = 0;
1459 		rect->height = 4;
1460 	}
1461 }
1462 
1463 /*
1464  * vfe_enum_mbus_code - Handle pixel format enumeration
1465  * @sd: VFE V4L2 subdevice
1466  * @sd_state: V4L2 subdev state
1467  * @code: pointer to v4l2_subdev_mbus_code_enum structure
1468  *
1469  * return -EINVAL or zero on success
1470  */
1471 static int vfe_enum_mbus_code(struct v4l2_subdev *sd,
1472 			      struct v4l2_subdev_state *sd_state,
1473 			      struct v4l2_subdev_mbus_code_enum *code)
1474 {
1475 	struct vfe_line *line = v4l2_get_subdevdata(sd);
1476 
1477 	if (code->pad == MSM_VFE_PAD_SINK) {
1478 		if (code->index >= line->nformats)
1479 			return -EINVAL;
1480 
1481 		code->code = line->formats[code->index].code;
1482 	} else {
1483 		struct v4l2_mbus_framefmt *sink_fmt;
1484 
1485 		sink_fmt = __vfe_get_format(line, sd_state, MSM_VFE_PAD_SINK,
1486 					    code->which);
1487 
1488 		code->code = vfe_src_pad_code(line, sink_fmt->code,
1489 					      code->index, 0);
1490 		if (!code->code)
1491 			return -EINVAL;
1492 	}
1493 
1494 	return 0;
1495 }
1496 
1497 /*
1498  * vfe_enum_frame_size - Handle frame size enumeration
1499  * @sd: VFE V4L2 subdevice
1500  * @sd_state: V4L2 subdev state
1501  * @fse: pointer to v4l2_subdev_frame_size_enum structure
1502  *
1503  * Return -EINVAL or zero on success
1504  */
1505 static int vfe_enum_frame_size(struct v4l2_subdev *sd,
1506 			       struct v4l2_subdev_state *sd_state,
1507 			       struct v4l2_subdev_frame_size_enum *fse)
1508 {
1509 	struct vfe_line *line = v4l2_get_subdevdata(sd);
1510 	struct v4l2_mbus_framefmt format;
1511 
1512 	if (fse->index != 0)
1513 		return -EINVAL;
1514 
1515 	format.code = fse->code;
1516 	format.width = 1;
1517 	format.height = 1;
1518 	vfe_try_format(line, sd_state, fse->pad, &format, fse->which);
1519 	fse->min_width = format.width;
1520 	fse->min_height = format.height;
1521 
1522 	if (format.code != fse->code)
1523 		return -EINVAL;
1524 
1525 	format.code = fse->code;
1526 	format.width = -1;
1527 	format.height = -1;
1528 	vfe_try_format(line, sd_state, fse->pad, &format, fse->which);
1529 	fse->max_width = format.width;
1530 	fse->max_height = format.height;
1531 
1532 	return 0;
1533 }
1534 
1535 /*
1536  * vfe_get_format - Handle get format by pads subdev method
1537  * @sd: VFE V4L2 subdevice
1538  * @sd_state: V4L2 subdev state
1539  * @fmt: pointer to v4l2 subdev format structure
1540  *
1541  * Return -EINVAL or zero on success
1542  */
1543 static int vfe_get_format(struct v4l2_subdev *sd,
1544 			  struct v4l2_subdev_state *sd_state,
1545 			  struct v4l2_subdev_format *fmt)
1546 {
1547 	struct vfe_line *line = v4l2_get_subdevdata(sd);
1548 	struct v4l2_mbus_framefmt *format;
1549 
1550 	format = __vfe_get_format(line, sd_state, fmt->pad, fmt->which);
1551 	if (format == NULL)
1552 		return -EINVAL;
1553 
1554 	fmt->format = *format;
1555 
1556 	return 0;
1557 }
1558 
1559 static int vfe_set_selection(struct v4l2_subdev *sd,
1560 			     struct v4l2_subdev_state *sd_state,
1561 			     struct v4l2_subdev_selection *sel);
1562 
1563 /*
1564  * vfe_set_format - Handle set format by pads subdev method
1565  * @sd: VFE V4L2 subdevice
1566  * @sd_state: V4L2 subdev state
1567  * @fmt: pointer to v4l2 subdev format structure
1568  *
1569  * Return -EINVAL or zero on success
1570  */
1571 static int vfe_set_format(struct v4l2_subdev *sd,
1572 			  struct v4l2_subdev_state *sd_state,
1573 			  struct v4l2_subdev_format *fmt)
1574 {
1575 	struct vfe_line *line = v4l2_get_subdevdata(sd);
1576 	struct v4l2_mbus_framefmt *format;
1577 
1578 	format = __vfe_get_format(line, sd_state, fmt->pad, fmt->which);
1579 	if (format == NULL)
1580 		return -EINVAL;
1581 
1582 	vfe_try_format(line, sd_state, fmt->pad, &fmt->format, fmt->which);
1583 	*format = fmt->format;
1584 
1585 	if (fmt->pad == MSM_VFE_PAD_SINK) {
1586 		struct v4l2_subdev_selection sel = { 0 };
1587 		int ret;
1588 
1589 		/* Propagate the format from sink to source */
1590 		format = __vfe_get_format(line, sd_state, MSM_VFE_PAD_SRC,
1591 					  fmt->which);
1592 
1593 		*format = fmt->format;
1594 		vfe_try_format(line, sd_state, MSM_VFE_PAD_SRC, format,
1595 			       fmt->which);
1596 
1597 		if (line->id != VFE_LINE_PIX)
1598 			return 0;
1599 
1600 		/* Reset sink pad compose selection */
1601 		sel.which = fmt->which;
1602 		sel.pad = MSM_VFE_PAD_SINK;
1603 		sel.target = V4L2_SEL_TGT_COMPOSE;
1604 		sel.r.width = fmt->format.width;
1605 		sel.r.height = fmt->format.height;
1606 		ret = vfe_set_selection(sd, sd_state, &sel);
1607 		if (ret < 0)
1608 			return ret;
1609 	}
1610 
1611 	return 0;
1612 }
1613 
1614 /*
1615  * vfe_get_selection - Handle get selection by pads subdev method
1616  * @sd: VFE V4L2 subdevice
1617  * @sd_state: V4L2 subdev state
1618  * @sel: pointer to v4l2 subdev selection structure
1619  *
1620  * Return -EINVAL or zero on success
1621  */
1622 static int vfe_get_selection(struct v4l2_subdev *sd,
1623 			     struct v4l2_subdev_state *sd_state,
1624 			     struct v4l2_subdev_selection *sel)
1625 {
1626 	struct vfe_line *line = v4l2_get_subdevdata(sd);
1627 	struct v4l2_subdev_format fmt = { 0 };
1628 	struct v4l2_rect *rect;
1629 	int ret;
1630 
1631 	if (line->id != VFE_LINE_PIX)
1632 		return -EINVAL;
1633 
1634 	if (sel->pad == MSM_VFE_PAD_SINK)
1635 		switch (sel->target) {
1636 		case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1637 			fmt.pad = sel->pad;
1638 			fmt.which = sel->which;
1639 			ret = vfe_get_format(sd, sd_state, &fmt);
1640 			if (ret < 0)
1641 				return ret;
1642 
1643 			sel->r.left = 0;
1644 			sel->r.top = 0;
1645 			sel->r.width = fmt.format.width;
1646 			sel->r.height = fmt.format.height;
1647 			break;
1648 		case V4L2_SEL_TGT_COMPOSE:
1649 			rect = __vfe_get_compose(line, sd_state, sel->which);
1650 			if (rect == NULL)
1651 				return -EINVAL;
1652 
1653 			sel->r = *rect;
1654 			break;
1655 		default:
1656 			return -EINVAL;
1657 		}
1658 	else if (sel->pad == MSM_VFE_PAD_SRC)
1659 		switch (sel->target) {
1660 		case V4L2_SEL_TGT_CROP_BOUNDS:
1661 			rect = __vfe_get_compose(line, sd_state, sel->which);
1662 			if (rect == NULL)
1663 				return -EINVAL;
1664 
1665 			sel->r.left = rect->left;
1666 			sel->r.top = rect->top;
1667 			sel->r.width = rect->width;
1668 			sel->r.height = rect->height;
1669 			break;
1670 		case V4L2_SEL_TGT_CROP:
1671 			rect = __vfe_get_crop(line, sd_state, sel->which);
1672 			if (rect == NULL)
1673 				return -EINVAL;
1674 
1675 			sel->r = *rect;
1676 			break;
1677 		default:
1678 			return -EINVAL;
1679 		}
1680 
1681 	return 0;
1682 }
1683 
1684 /*
1685  * vfe_set_selection - Handle set selection by pads subdev method
1686  * @sd: VFE V4L2 subdevice
1687  * @sd_state: V4L2 subdev state
1688  * @sel: pointer to v4l2 subdev selection structure
1689  *
1690  * Return -EINVAL or zero on success
1691  */
1692 static int vfe_set_selection(struct v4l2_subdev *sd,
1693 			     struct v4l2_subdev_state *sd_state,
1694 			     struct v4l2_subdev_selection *sel)
1695 {
1696 	struct vfe_line *line = v4l2_get_subdevdata(sd);
1697 	struct v4l2_rect *rect;
1698 	int ret;
1699 
1700 	if (line->id != VFE_LINE_PIX)
1701 		return -EINVAL;
1702 
1703 	if (sel->target == V4L2_SEL_TGT_COMPOSE &&
1704 		sel->pad == MSM_VFE_PAD_SINK) {
1705 		struct v4l2_subdev_selection crop = { 0 };
1706 
1707 		rect = __vfe_get_compose(line, sd_state, sel->which);
1708 		if (rect == NULL)
1709 			return -EINVAL;
1710 
1711 		vfe_try_compose(line, sd_state, &sel->r, sel->which);
1712 		*rect = sel->r;
1713 
1714 		/* Reset source crop selection */
1715 		crop.which = sel->which;
1716 		crop.pad = MSM_VFE_PAD_SRC;
1717 		crop.target = V4L2_SEL_TGT_CROP;
1718 		crop.r = *rect;
1719 		ret = vfe_set_selection(sd, sd_state, &crop);
1720 	} else if (sel->target == V4L2_SEL_TGT_CROP &&
1721 		sel->pad == MSM_VFE_PAD_SRC) {
1722 		struct v4l2_subdev_format fmt = { 0 };
1723 
1724 		rect = __vfe_get_crop(line, sd_state, sel->which);
1725 		if (rect == NULL)
1726 			return -EINVAL;
1727 
1728 		vfe_try_crop(line, sd_state, &sel->r, sel->which);
1729 		*rect = sel->r;
1730 
1731 		/* Reset source pad format width and height */
1732 		fmt.which = sel->which;
1733 		fmt.pad = MSM_VFE_PAD_SRC;
1734 		ret = vfe_get_format(sd, sd_state, &fmt);
1735 		if (ret < 0)
1736 			return ret;
1737 
1738 		fmt.format.width = rect->width;
1739 		fmt.format.height = rect->height;
1740 		ret = vfe_set_format(sd, sd_state, &fmt);
1741 	} else {
1742 		ret = -EINVAL;
1743 	}
1744 
1745 	return ret;
1746 }
1747 
1748 /*
1749  * vfe_init_formats - Initialize formats on all pads
1750  * @sd: VFE V4L2 subdevice
1751  * @fh: V4L2 subdev file handle
1752  *
1753  * Initialize all pad formats with default values.
1754  *
1755  * Return 0 on success or a negative error code otherwise
1756  */
1757 static int vfe_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1758 {
1759 	struct v4l2_subdev_format format = {
1760 		.pad = MSM_VFE_PAD_SINK,
1761 		.which = fh ? V4L2_SUBDEV_FORMAT_TRY :
1762 			      V4L2_SUBDEV_FORMAT_ACTIVE,
1763 		.format = {
1764 			.code = MEDIA_BUS_FMT_UYVY8_1X16,
1765 			.width = 1920,
1766 			.height = 1080
1767 		}
1768 	};
1769 
1770 	return vfe_set_format(sd, fh ? fh->state : NULL, &format);
1771 }
1772 
1773 /*
1774  * msm_vfe_subdev_init - Initialize VFE device structure and resources
1775  * @vfe: VFE device
1776  * @res: VFE module resources table
1777  *
1778  * Return 0 on success or a negative error code otherwise
1779  */
1780 int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
1781 			const struct camss_subdev_resources *res, u8 id)
1782 {
1783 	struct device *dev = camss->dev;
1784 	struct platform_device *pdev = to_platform_device(dev);
1785 	int i, j;
1786 	int ret;
1787 
1788 	if (!res->vfe.line_num)
1789 		return -EINVAL;
1790 
1791 	vfe->res = &res->vfe;
1792 	vfe->res->hw_ops->subdev_init(dev, vfe);
1793 
1794 	/* Power domain */
1795 
1796 	if (res->vfe.pd_name) {
1797 		vfe->genpd = dev_pm_domain_attach_by_name(camss->dev,
1798 							  res->vfe.pd_name);
1799 		if (IS_ERR(vfe->genpd)) {
1800 			ret = PTR_ERR(vfe->genpd);
1801 			return ret;
1802 		}
1803 	}
1804 
1805 	if (!vfe->genpd && res->vfe.has_pd) {
1806 		/*
1807 		 * Legacy magic index.
1808 		 * Requires
1809 		 * power-domain = <VFE_X>,
1810 		 *                <VFE_Y>,
1811 		 *                <TITAN_TOP>
1812 		 * id must correspondng to the index of the VFE which must
1813 		 * come before the TOP GDSC. VFE Lite has no individually
1814 		 * collapasible domain which is why id < vfe_num is a valid
1815 		 * check.
1816 		 */
1817 		vfe->genpd = dev_pm_domain_attach_by_id(camss->dev, id);
1818 		if (IS_ERR(vfe->genpd))
1819 			return PTR_ERR(vfe->genpd);
1820 	}
1821 
1822 	/* Memory */
1823 
1824 	vfe->base = devm_platform_ioremap_resource_byname(pdev, res->reg[0]);
1825 	if (IS_ERR(vfe->base)) {
1826 		dev_err(dev, "could not map memory\n");
1827 		return PTR_ERR(vfe->base);
1828 	}
1829 
1830 	/* Interrupt */
1831 
1832 	ret = platform_get_irq_byname(pdev, res->interrupt[0]);
1833 	if (ret < 0)
1834 		return ret;
1835 
1836 	vfe->irq = ret;
1837 	snprintf(vfe->irq_name, sizeof(vfe->irq_name), "%s_%s%d",
1838 		 dev_name(dev), MSM_VFE_NAME, id);
1839 	ret = devm_request_irq(dev, vfe->irq, vfe->res->hw_ops->isr,
1840 			       IRQF_TRIGGER_RISING, vfe->irq_name, vfe);
1841 	if (ret < 0) {
1842 		dev_err(dev, "request_irq failed: %d\n", ret);
1843 		return ret;
1844 	}
1845 
1846 	/* Clocks */
1847 
1848 	vfe->nclocks = 0;
1849 	while (res->clock[vfe->nclocks])
1850 		vfe->nclocks++;
1851 
1852 	vfe->clock = devm_kcalloc(dev, vfe->nclocks, sizeof(*vfe->clock),
1853 				  GFP_KERNEL);
1854 	if (!vfe->clock)
1855 		return -ENOMEM;
1856 
1857 	for (i = 0; i < vfe->nclocks; i++) {
1858 		struct camss_clock *clock = &vfe->clock[i];
1859 
1860 		clock->clk = devm_clk_get(dev, res->clock[i]);
1861 		if (IS_ERR(clock->clk))
1862 			return PTR_ERR(clock->clk);
1863 
1864 		clock->name = res->clock[i];
1865 
1866 		clock->nfreqs = 0;
1867 		while (res->clock_rate[i][clock->nfreqs])
1868 			clock->nfreqs++;
1869 
1870 		if (!clock->nfreqs) {
1871 			clock->freq = NULL;
1872 			continue;
1873 		}
1874 
1875 		clock->freq = devm_kcalloc(dev,
1876 					   clock->nfreqs,
1877 					   sizeof(*clock->freq),
1878 					   GFP_KERNEL);
1879 		if (!clock->freq)
1880 			return -ENOMEM;
1881 
1882 		for (j = 0; j < clock->nfreqs; j++)
1883 			clock->freq[j] = res->clock_rate[i][j];
1884 	}
1885 
1886 	mutex_init(&vfe->power_lock);
1887 	vfe->power_count = 0;
1888 
1889 	mutex_init(&vfe->stream_lock);
1890 	vfe->stream_count = 0;
1891 
1892 	spin_lock_init(&vfe->output_lock);
1893 
1894 	vfe->camss = camss;
1895 	vfe->id = id;
1896 	vfe->reg_update = 0;
1897 
1898 	for (i = VFE_LINE_RDI0; i < vfe->res->line_num; i++) {
1899 		struct vfe_line *l = &vfe->line[i];
1900 
1901 		l->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1902 		l->video_out.camss = camss;
1903 		l->id = i;
1904 		init_completion(&l->output.sof);
1905 		init_completion(&l->output.reg_update);
1906 
1907 		if (i == VFE_LINE_PIX) {
1908 			l->nformats = res->vfe.formats_pix->nformats;
1909 			l->formats = res->vfe.formats_pix->formats;
1910 		} else {
1911 			l->nformats = res->vfe.formats_rdi->nformats;
1912 			l->formats = res->vfe.formats_rdi->formats;
1913 		}
1914 	}
1915 
1916 	init_completion(&vfe->reset_complete);
1917 	init_completion(&vfe->halt_complete);
1918 
1919 	return 0;
1920 }
1921 
1922 /*
1923  * msm_vfe_genpd_cleanup - Cleanup VFE genpd linkages
1924  * @vfe: VFE device
1925  */
1926 void msm_vfe_genpd_cleanup(struct vfe_device *vfe)
1927 {
1928 	if (vfe->genpd_link)
1929 		device_link_del(vfe->genpd_link);
1930 
1931 	if (vfe->genpd)
1932 		dev_pm_domain_detach(vfe->genpd, true);
1933 }
1934 
1935 /*
1936  * vfe_link_setup - Setup VFE connections
1937  * @entity: Pointer to media entity structure
1938  * @local: Pointer to local pad
1939  * @remote: Pointer to remote pad
1940  * @flags: Link flags
1941  *
1942  * Return 0 on success
1943  */
1944 static int vfe_link_setup(struct media_entity *entity,
1945 			  const struct media_pad *local,
1946 			  const struct media_pad *remote, u32 flags)
1947 {
1948 	if (flags & MEDIA_LNK_FL_ENABLED)
1949 		if (media_pad_remote_pad_first(local))
1950 			return -EBUSY;
1951 
1952 	return 0;
1953 }
1954 
1955 static const struct v4l2_subdev_core_ops vfe_core_ops = {
1956 	.s_power = vfe_set_power,
1957 };
1958 
1959 static const struct v4l2_subdev_video_ops vfe_video_ops = {
1960 	.s_stream = vfe_set_stream,
1961 };
1962 
1963 static const struct v4l2_subdev_pad_ops vfe_pad_ops = {
1964 	.enum_mbus_code = vfe_enum_mbus_code,
1965 	.enum_frame_size = vfe_enum_frame_size,
1966 	.get_fmt = vfe_get_format,
1967 	.set_fmt = vfe_set_format,
1968 	.get_selection = vfe_get_selection,
1969 	.set_selection = vfe_set_selection,
1970 };
1971 
1972 static const struct v4l2_subdev_ops vfe_v4l2_ops = {
1973 	.core = &vfe_core_ops,
1974 	.video = &vfe_video_ops,
1975 	.pad = &vfe_pad_ops,
1976 };
1977 
1978 static const struct v4l2_subdev_internal_ops vfe_v4l2_internal_ops = {
1979 	.open = vfe_init_formats,
1980 };
1981 
1982 static const struct media_entity_operations vfe_media_ops = {
1983 	.link_setup = vfe_link_setup,
1984 	.link_validate = v4l2_subdev_link_validate,
1985 };
1986 
1987 static int vfe_bpl_align(struct vfe_device *vfe)
1988 {
1989 	int ret = 8;
1990 
1991 	switch (vfe->camss->res->version) {
1992 	case CAMSS_7280:
1993 	case CAMSS_8250:
1994 	case CAMSS_8280XP:
1995 	case CAMSS_8300:
1996 	case CAMSS_845:
1997 	case CAMSS_8550:
1998 	case CAMSS_8775P:
1999 	case CAMSS_X1E80100:
2000 		ret = 16;
2001 		break;
2002 	default:
2003 		break;
2004 	}
2005 
2006 	return ret;
2007 }
2008 
2009 /*
2010  * msm_vfe_register_entities - Register subdev node for VFE module
2011  * @vfe: VFE device
2012  * @v4l2_dev: V4L2 device
2013  *
2014  * Initialize and register a subdev node for the VFE module. Then
2015  * call msm_video_register() to register the video device node which
2016  * will be connected to this subdev node. Then actually create the
2017  * media link between them.
2018  *
2019  * Return 0 on success or a negative error code otherwise
2020  */
2021 int msm_vfe_register_entities(struct vfe_device *vfe,
2022 			      struct v4l2_device *v4l2_dev)
2023 {
2024 	struct device *dev = vfe->camss->dev;
2025 	struct v4l2_subdev *sd;
2026 	struct media_pad *pads;
2027 	struct camss_video *video_out;
2028 	int ret;
2029 	int i;
2030 
2031 	for (i = 0; i < vfe->res->line_num; i++) {
2032 		char name[32];
2033 
2034 		sd = &vfe->line[i].subdev;
2035 		pads = vfe->line[i].pads;
2036 		video_out = &vfe->line[i].video_out;
2037 
2038 		v4l2_subdev_init(sd, &vfe_v4l2_ops);
2039 		sd->internal_ops = &vfe_v4l2_internal_ops;
2040 		sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
2041 		if (i == VFE_LINE_PIX)
2042 			snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d_%s",
2043 				 MSM_VFE_NAME, vfe->id, "pix");
2044 		else
2045 			snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d_%s%d",
2046 				 MSM_VFE_NAME, vfe->id, "rdi", i);
2047 
2048 		v4l2_set_subdevdata(sd, &vfe->line[i]);
2049 
2050 		ret = vfe_init_formats(sd, NULL);
2051 		if (ret < 0) {
2052 			dev_err(dev, "Failed to init format: %d\n", ret);
2053 			goto error_init;
2054 		}
2055 
2056 		pads[MSM_VFE_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
2057 		pads[MSM_VFE_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;
2058 
2059 		sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
2060 		sd->entity.ops = &vfe_media_ops;
2061 		ret = media_entity_pads_init(&sd->entity, MSM_VFE_PADS_NUM,
2062 					     pads);
2063 		if (ret < 0) {
2064 			dev_err(dev, "Failed to init media entity: %d\n", ret);
2065 			goto error_init;
2066 		}
2067 
2068 		ret = v4l2_device_register_subdev(v4l2_dev, sd);
2069 		if (ret < 0) {
2070 			dev_err(dev, "Failed to register subdev: %d\n", ret);
2071 			goto error_reg_subdev;
2072 		}
2073 
2074 		video_out->ops = &vfe->video_ops;
2075 		video_out->bpl_alignment = vfe_bpl_align(vfe);
2076 		video_out->line_based = 0;
2077 		if (i == VFE_LINE_PIX) {
2078 			video_out->bpl_alignment = 16;
2079 			video_out->line_based = 1;
2080 		}
2081 
2082 		video_out->nformats = vfe->line[i].nformats;
2083 		video_out->formats = vfe->line[i].formats;
2084 
2085 		snprintf(name, ARRAY_SIZE(name), "%s%d_%s%d",
2086 			 MSM_VFE_NAME, vfe->id, "video", i);
2087 		ret = msm_video_register(video_out, v4l2_dev, name);
2088 		if (ret < 0) {
2089 			dev_err(dev, "Failed to register video node: %d\n",
2090 				ret);
2091 			goto error_reg_video;
2092 		}
2093 
2094 		ret = media_create_pad_link(
2095 				&sd->entity, MSM_VFE_PAD_SRC,
2096 				&video_out->vdev.entity, 0,
2097 				MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
2098 		if (ret < 0) {
2099 			dev_err(dev, "Failed to link %s->%s entities: %d\n",
2100 				sd->entity.name, video_out->vdev.entity.name,
2101 				ret);
2102 			goto error_link;
2103 		}
2104 	}
2105 
2106 	return 0;
2107 
2108 error_link:
2109 	msm_video_unregister(video_out);
2110 
2111 error_reg_video:
2112 	v4l2_device_unregister_subdev(sd);
2113 
2114 error_reg_subdev:
2115 	media_entity_cleanup(&sd->entity);
2116 
2117 error_init:
2118 	for (i--; i >= 0; i--) {
2119 		sd = &vfe->line[i].subdev;
2120 		video_out = &vfe->line[i].video_out;
2121 
2122 		msm_video_unregister(video_out);
2123 		v4l2_device_unregister_subdev(sd);
2124 		media_entity_cleanup(&sd->entity);
2125 	}
2126 
2127 	return ret;
2128 }
2129 
2130 /*
2131  * msm_vfe_unregister_entities - Unregister VFE module subdev node
2132  * @vfe: VFE device
2133  */
2134 void msm_vfe_unregister_entities(struct vfe_device *vfe)
2135 {
2136 	int i;
2137 
2138 	mutex_destroy(&vfe->power_lock);
2139 	mutex_destroy(&vfe->stream_lock);
2140 
2141 	for (i = 0; i < vfe->res->line_num; i++) {
2142 		struct v4l2_subdev *sd = &vfe->line[i].subdev;
2143 		struct camss_video *video_out = &vfe->line[i].video_out;
2144 
2145 		msm_video_unregister(video_out);
2146 		v4l2_device_unregister_subdev(sd);
2147 		media_entity_cleanup(&sd->entity);
2148 	}
2149 }
2150 
2151 bool vfe_is_lite(struct vfe_device *vfe)
2152 {
2153 	return vfe->camss->res->vfe_res[vfe->id].vfe.is_lite;
2154 }
2155