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