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