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