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