blob: 78dd64c4cccf9ccf7ef6915eda29d945224e7420 [file] [log] [blame]
Raja Mallikff6c75b2019-01-29 16:52:37 +05301/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
Raja Mallikc7e256f2018-12-06 17:36:28 +05302 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/slab.h>
14#include "cam_cpas_api.h"
15#include "cam_vfe_soc.h"
16#include "cam_debug_util.h"
17
18static bool cam_vfe_cpas_cb(uint32_t client_handle, void *userdata,
19 struct cam_cpas_irq_data *irq_data)
20{
21 bool error_handled = false;
22
23 if (!irq_data)
24 return error_handled;
25
26 switch (irq_data->irq_type) {
27 case CAM_CAMNOC_IRQ_IFE02_UBWC_ENCODE_ERROR:
28 case CAM_CAMNOC_IRQ_IFE13_UBWC_ENCODE_ERROR:
Raja Mallikff6c75b2019-01-29 16:52:37 +053029 case CAM_CAMNOC_IRQ_IFE0_UBWC_ENCODE_ERROR:
30 case CAM_CAMNOC_IRQ_IFE1_WRITE_UBWC_ENCODE_ERROR:
Raja Mallikc7e256f2018-12-06 17:36:28 +053031 CAM_ERR_RATE_LIMIT(CAM_ISP,
32 "IFE UBWC Encode error type=%d status=%x",
33 irq_data->irq_type,
34 irq_data->u.enc_err.encerr_status.value);
35 error_handled = true;
36 break;
37 default:
38 break;
39 }
40
41 return error_handled;
42}
43
44static int cam_vfe_get_dt_properties(struct cam_hw_soc_info *soc_info)
45{
46 int rc = 0;
47
48 rc = cam_soc_util_get_dt_properties(soc_info);
49 if (rc) {
50 CAM_ERR(CAM_ISP, "Error! get DT properties failed rc=%d", rc);
51 return rc;
52 }
53
54 return rc;
55}
56
57static int cam_vfe_request_platform_resource(
58 struct cam_hw_soc_info *soc_info,
59 irq_handler_t vfe_irq_handler, void *irq_data)
60{
61 int rc = 0;
62
63 rc = cam_soc_util_request_platform_resource(soc_info, vfe_irq_handler,
64 irq_data);
65 if (rc)
66 CAM_ERR(CAM_ISP,
67 "Error! Request platform resource failed rc=%d", rc);
68
69 return rc;
70}
71
72static int cam_vfe_release_platform_resource(struct cam_hw_soc_info *soc_info)
73{
74 int rc = 0;
75
76 rc = cam_soc_util_release_platform_resource(soc_info);
77 if (rc)
78 CAM_ERR(CAM_ISP,
79 "Error! Release platform resource failed rc=%d", rc);
80
81 return rc;
82}
83
84int cam_vfe_init_soc_resources(struct cam_hw_soc_info *soc_info,
85 irq_handler_t vfe_irq_handler, void *irq_data)
86{
87 int rc = 0;
88 struct cam_vfe_soc_private *soc_private;
89 struct cam_cpas_register_params cpas_register_param;
90
91 soc_private = kzalloc(sizeof(struct cam_vfe_soc_private),
92 GFP_KERNEL);
93 if (!soc_private) {
94 CAM_DBG(CAM_ISP, "Error! soc_private Alloc Failed");
95 return -ENOMEM;
96 }
97 soc_info->soc_private = soc_private;
98
99 rc = cam_vfe_get_dt_properties(soc_info);
100 if (rc < 0) {
101 CAM_ERR(CAM_ISP, "Error! Get DT properties failed rc=%d", rc);
102 goto free_soc_private;
103 }
104
105 rc = cam_soc_util_get_option_clk_by_name(soc_info,
106 CAM_VFE_DSP_CLK_NAME, &soc_private->dsp_clk,
107 &soc_private->dsp_clk_index, &soc_private->dsp_clk_rate);
108 if (rc)
Raja Mallikd268c822019-02-18 13:50:39 +0530109 CAM_WARN(CAM_ISP, "Option clk get failed with rc %d", rc);
Raja Mallikc7e256f2018-12-06 17:36:28 +0530110
111 rc = cam_vfe_request_platform_resource(soc_info, vfe_irq_handler,
112 irq_data);
113 if (rc < 0) {
114 CAM_ERR(CAM_ISP,
115 "Error! Request platform resources failed rc=%d", rc);
116 goto free_soc_private;
117 }
118
119 memset(&cpas_register_param, 0, sizeof(cpas_register_param));
Raja Mallikff6c75b2019-01-29 16:52:37 +0530120
Raja Mallikc7e256f2018-12-06 17:36:28 +0530121 cpas_register_param.cell_index = soc_info->index;
122 cpas_register_param.dev = soc_info->dev;
123 cpas_register_param.cam_cpas_client_cb = cam_vfe_cpas_cb;
124 cpas_register_param.userdata = soc_info;
Raja Mallikff6c75b2019-01-29 16:52:37 +0530125
126 rc = cam_cpas_get_cpas_hw_version(&soc_private->cpas_version);
Raja Mallikc7e256f2018-12-06 17:36:28 +0530127 if (rc) {
Raja Mallikff6c75b2019-01-29 16:52:37 +0530128 CAM_ERR(CAM_ISP, "Error! Invalid cpas version rc=%d", rc);
129 goto free_soc_private;
Raja Mallikc7e256f2018-12-06 17:36:28 +0530130 }
131
Raja Mallikff6c75b2019-01-29 16:52:37 +0530132 switch (soc_private->cpas_version) {
133 case CAM_CPAS_TITAN_175_V120:
134 strlcpy(cpas_register_param.identifier, "iferdi",
135 CAM_HW_IDENTIFIER_LENGTH);
136 rc = cam_cpas_register_client(&cpas_register_param);
137 if (rc) {
138 CAM_ERR(CAM_ISP, "rdi CPAS registration failed rc=%d",
139 rc);
140 goto release_soc;
141 } else {
142 soc_private->cpas_handle[0] =
143 cpas_register_param.client_handle;
144 }
145
146 strlcpy(cpas_register_param.identifier, "ifenrdi",
147 CAM_HW_IDENTIFIER_LENGTH);
148 rc = cam_cpas_register_client(&cpas_register_param);
149 if (rc) {
150 CAM_ERR(CAM_ISP, "nrdi CPAS registration failed rc=%d",
151 rc);
152 goto release_soc;
153 } else {
154 soc_private->cpas_handle[1] =
155 cpas_register_param.client_handle;
156 }
157 break;
158 default:
159 strlcpy(cpas_register_param.identifier, "ife",
160 CAM_HW_IDENTIFIER_LENGTH);
161 rc = cam_cpas_register_client(&cpas_register_param);
162 if (rc) {
163 CAM_ERR(CAM_ISP, "CPAS registration failed rc=%d", rc);
164 goto release_soc;
165 } else {
166 soc_private->cpas_handle[0] =
167 cpas_register_param.client_handle;
168 }
169 }
Raja Mallikc7e256f2018-12-06 17:36:28 +0530170 return rc;
171
172release_soc:
173 cam_soc_util_release_platform_resource(soc_info);
174free_soc_private:
175 kfree(soc_private);
176
177 return rc;
178}
179
180int cam_vfe_deinit_soc_resources(struct cam_hw_soc_info *soc_info)
181{
182 int rc = 0;
183 struct cam_vfe_soc_private *soc_private;
184
185 if (!soc_info) {
186 CAM_ERR(CAM_ISP, "Error! soc_info NULL");
187 return -ENODEV;
188 }
189
190 soc_private = soc_info->soc_private;
191 if (!soc_private) {
192 CAM_ERR(CAM_ISP, "Error! soc_private NULL");
193 return -ENODEV;
194 }
Raja Mallikff6c75b2019-01-29 16:52:37 +0530195 rc = cam_cpas_unregister_client(soc_private->cpas_handle[0]);
Raja Mallikc7e256f2018-12-06 17:36:28 +0530196 if (rc)
Raja Mallikff6c75b2019-01-29 16:52:37 +0530197 CAM_ERR(CAM_ISP, "CPAS0 unregistration failed rc=%d", rc);
198
199 if (!rc && soc_private->cpas_version == CAM_CPAS_TITAN_175_V120)
200 rc = cam_cpas_unregister_client(soc_private->cpas_handle[1]);
201 if (rc)
202 CAM_ERR(CAM_ISP, "CPAS1 unregistration failed rc=%d",
203 rc);
Raja Mallikc7e256f2018-12-06 17:36:28 +0530204
205 rc = cam_vfe_release_platform_resource(soc_info);
206 if (rc < 0)
207 CAM_ERR(CAM_ISP,
208 "Error! Release platform resources failed rc=%d", rc);
209
210 rc = cam_soc_util_clk_put(&soc_private->dsp_clk);
211 if (rc < 0)
212 CAM_ERR(CAM_ISP,
213 "Error Put dsp clk failed rc=%d", rc);
214
215 kfree(soc_private);
216
217 return rc;
218}
219
220int cam_vfe_enable_soc_resources(struct cam_hw_soc_info *soc_info)
221{
222 int rc = 0;
223 struct cam_vfe_soc_private *soc_private;
224 struct cam_ahb_vote ahb_vote;
225 struct cam_axi_vote axi_vote;
226
227 if (!soc_info) {
228 CAM_ERR(CAM_ISP, "Error! Invalid params");
229 rc = -EINVAL;
230 goto end;
231 }
232 soc_private = soc_info->soc_private;
233
234 ahb_vote.type = CAM_VOTE_ABSOLUTE;
235 ahb_vote.vote.level = CAM_SVS_VOTE;
236
237 axi_vote.compressed_bw = 10640000000L;
Raja Mallik8b88b232019-04-04 14:32:27 +0530238 axi_vote.compressed_bw_ab = 10640000000L;
Raja Mallikc7e256f2018-12-06 17:36:28 +0530239 axi_vote.uncompressed_bw = 10640000000L;
240
Raja Mallikff6c75b2019-01-29 16:52:37 +0530241 rc = cam_cpas_start(soc_private->cpas_handle[0], &ahb_vote, &axi_vote);
Raja Mallikc7e256f2018-12-06 17:36:28 +0530242 if (rc) {
Raja Mallikff6c75b2019-01-29 16:52:37 +0530243 CAM_ERR(CAM_ISP, "Error! CPAS0 start failed rc=%d", rc);
Raja Mallikc7e256f2018-12-06 17:36:28 +0530244 rc = -EFAULT;
245 goto end;
246 }
247
Raja Mallikff6c75b2019-01-29 16:52:37 +0530248 if (!rc && soc_private->cpas_version == CAM_CPAS_TITAN_175_V120)
249 rc = cam_cpas_start(soc_private->cpas_handle[1], &ahb_vote,
250 &axi_vote);
251 if (rc) {
252 CAM_ERR(CAM_ISP, "Error! CPAS1 start failed rc=%d", rc);
253 rc = -EFAULT;
254 goto end;
255 }
256
Raja Mallikc7e256f2018-12-06 17:36:28 +0530257 rc = cam_soc_util_enable_platform_resource(soc_info, true,
258 CAM_TURBO_VOTE, true);
259 if (rc) {
260 CAM_ERR(CAM_ISP, "Error! enable platform failed rc=%d", rc);
261 goto stop_cpas;
262 }
263
264 return rc;
265
266stop_cpas:
Raja Mallikff6c75b2019-01-29 16:52:37 +0530267 cam_cpas_stop(soc_private->cpas_handle[0]);
268 if (soc_private->cpas_version == CAM_CPAS_TITAN_175_V120)
269 cam_cpas_stop(soc_private->cpas_handle[1]);
Raja Mallikc7e256f2018-12-06 17:36:28 +0530270end:
271 return rc;
272}
273
274int cam_vfe_soc_enable_clk(struct cam_hw_soc_info *soc_info,
275 const char *clk_name)
276{
277 int rc = 0;
278 struct cam_vfe_soc_private *soc_private;
279
280 if (!soc_info) {
281 CAM_ERR(CAM_ISP, "Error Invalid params");
282 rc = -EINVAL;
283 return rc;
284 }
285 soc_private = soc_info->soc_private;
286
287 if (strcmp(clk_name, CAM_VFE_DSP_CLK_NAME) == 0) {
288 rc = cam_soc_util_clk_enable(soc_private->dsp_clk,
289 CAM_VFE_DSP_CLK_NAME, soc_private->dsp_clk_rate);
290 if (rc)
291 CAM_ERR(CAM_ISP,
292 "Error enable dsp clk failed rc=%d", rc);
293 }
294
295 return rc;
296}
297
298int cam_vfe_soc_disable_clk(struct cam_hw_soc_info *soc_info,
299 const char *clk_name)
300{
301 int rc = 0;
302 struct cam_vfe_soc_private *soc_private;
303
304 if (!soc_info) {
305 CAM_ERR(CAM_ISP, "Error Invalid params");
306 rc = -EINVAL;
307 return rc;
308 }
309 soc_private = soc_info->soc_private;
310
311 if (strcmp(clk_name, CAM_VFE_DSP_CLK_NAME) == 0) {
312 rc = cam_soc_util_clk_disable(soc_private->dsp_clk,
313 CAM_VFE_DSP_CLK_NAME);
314 if (rc)
315 CAM_ERR(CAM_ISP,
316 "Error enable dsp clk failed rc=%d", rc);
317 }
318
319 return rc;
320}
321
322
323int cam_vfe_disable_soc_resources(struct cam_hw_soc_info *soc_info)
324{
325 int rc = 0;
326 struct cam_vfe_soc_private *soc_private;
327
328 if (!soc_info) {
329 CAM_ERR(CAM_ISP, "Error! Invalid params");
330 rc = -EINVAL;
331 return rc;
332 }
333 soc_private = soc_info->soc_private;
334
335 rc = cam_soc_util_disable_platform_resource(soc_info, true, true);
336 if (rc) {
337 CAM_ERR(CAM_ISP, "Disable platform failed rc=%d", rc);
338 return rc;
339 }
340
Raja Mallikff6c75b2019-01-29 16:52:37 +0530341 rc = cam_cpas_stop(soc_private->cpas_handle[0]);
Raja Mallikc7e256f2018-12-06 17:36:28 +0530342 if (rc) {
343 CAM_ERR(CAM_ISP, "Error! CPAS stop failed rc=%d", rc);
344 return rc;
345 }
346
Raja Mallikff6c75b2019-01-29 16:52:37 +0530347 if (!rc && soc_private->cpas_version == CAM_CPAS_TITAN_175_V120)
348 rc = cam_cpas_stop(soc_private->cpas_handle[1]);
349 if (rc) {
350 CAM_ERR(CAM_ISP, "Error! CPAS stop failed rc=%d", rc);
351 return rc;
352 }
353
Raja Mallikc7e256f2018-12-06 17:36:28 +0530354 return rc;
355}