blob: 3d37e79408229e1ec1e12aaf10ac8a3a1019245f [file] [log] [blame]
Venkat Chintad6de8c82018-01-18 17:14:52 -08001/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002 *
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
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -070013#include <linux/uaccess.h>
14#include <linux/slab.h>
15#include <linux/of.h>
16#include <linux/of_platform.h>
17#include <linux/platform_device.h>
18#include <linux/mutex.h>
19#include <linux/spinlock.h>
20#include <linux/workqueue.h>
21#include <linux/timer.h>
22#include <linux/bitops.h>
23#include <linux/delay.h>
24#include <linux/debugfs.h>
25#include <media/cam_defs.h>
26#include <media/cam_icp.h>
Suresh Vankadaraaa6ff8f2017-10-26 22:51:27 +053027#include <media/cam_cpas.h>
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -070028
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -070029#include "cam_sync_api.h"
Harsh Shahe9e8ff52017-05-16 17:26:45 -070030#include "cam_packet_util.h"
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -070031#include "cam_hw.h"
32#include "cam_hw_mgr_intf.h"
33#include "cam_icp_hw_mgr_intf.h"
34#include "cam_icp_hw_mgr.h"
35#include "cam_a5_hw_intf.h"
36#include "cam_bps_hw_intf.h"
37#include "cam_ipe_hw_intf.h"
38#include "cam_smmu_api.h"
39#include "cam_mem_mgr.h"
40#include "hfi_intf.h"
41#include "hfi_reg.h"
42#include "hfi_session_defs.h"
43#include "hfi_sys_defs.h"
44#include "cam_req_mgr_workq.h"
45#include "cam_mem_mgr.h"
46#include "a5_core.h"
47#include "hfi_sys_defs.h"
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -070048#include "cam_debug_util.h"
Suresh Vankadara34494fc2017-08-12 18:18:09 +053049#include "cam_soc_util.h"
Lakshmi Narayana Kalavaladac0b6c2017-09-13 15:33:42 -070050#include "cam_trace.h"
Suresh Vankadaraaa6ff8f2017-10-26 22:51:27 +053051#include "cam_cpas_api.h"
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -070052
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -070053#define ICP_WORKQ_TASK_CMD_TYPE 1
54#define ICP_WORKQ_TASK_MSG_TYPE 2
55
Junzhe Zoubc37c562017-11-20 18:23:49 -080056#define ICP_DEV_TYPE_TO_CLK_TYPE(dev_type) \
57 ((dev_type == CAM_ICP_RES_TYPE_BPS) ? ICP_CLK_HW_BPS : ICP_CLK_HW_IPE)
58
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -070059static struct cam_icp_hw_mgr icp_hw_mgr;
60
Suresh Vankadaraaa6ff8f2017-10-26 22:51:27 +053061static int cam_icp_send_ubwc_cfg(struct cam_icp_hw_mgr *hw_mgr)
62{
63 struct cam_hw_intf *a5_dev_intf = NULL;
64 int rc;
65
Karthik Anantha Ram9f13d0e2017-11-30 14:55:44 -080066 a5_dev_intf = hw_mgr->a5_dev_intf;
Suresh Vankadaraaa6ff8f2017-10-26 22:51:27 +053067 if (!a5_dev_intf) {
68 CAM_ERR(CAM_ICP, "a5_dev_intf is NULL");
69 return -EINVAL;
70 }
71
72 rc = a5_dev_intf->hw_ops.process_cmd(
73 a5_dev_intf->hw_priv,
74 CAM_ICP_A5_CMD_UBWC_CFG, NULL, 0);
75 if (rc)
76 CAM_ERR(CAM_ICP, "CAM_ICP_A5_CMD_UBWC_CFG is failed");
77
78 return rc;
79}
80
Suresh Vankadara34494fc2017-08-12 18:18:09 +053081static void cam_icp_hw_mgr_clk_info_update(struct cam_icp_hw_mgr *hw_mgr,
82 struct cam_icp_hw_ctx_data *ctx_data)
83{
84 struct cam_icp_clk_info *hw_mgr_clk_info;
85
86 if (ctx_data->icp_dev_acquire_info->dev_type == CAM_ICP_RES_TYPE_BPS)
87 hw_mgr_clk_info = &hw_mgr->clk_info[ICP_CLK_HW_BPS];
88 else
89 hw_mgr_clk_info = &hw_mgr->clk_info[ICP_CLK_HW_IPE];
90
91 if (hw_mgr_clk_info->base_clk >= ctx_data->clk_info.base_clk)
92 hw_mgr_clk_info->base_clk -= ctx_data->clk_info.base_clk;
93}
94
95static void cam_icp_hw_mgr_reset_clk_info(struct cam_icp_hw_mgr *hw_mgr)
96{
97 int i;
98
99 for (i = 0; i < ICP_CLK_HW_MAX; i++) {
100 hw_mgr->clk_info[i].base_clk = 0;
Pavan Kumar Chilamkurthiee7848e2017-11-03 17:33:08 -0700101 hw_mgr->clk_info[i].curr_clk = ICP_CLK_SVS_HZ;
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530102 hw_mgr->clk_info[i].threshold = ICP_OVER_CLK_THRESHOLD;
103 hw_mgr->clk_info[i].over_clked = 0;
104 hw_mgr->clk_info[i].uncompressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
105 hw_mgr->clk_info[i].compressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
106 }
Pavan Kumar Chilamkurthiee7848e2017-11-03 17:33:08 -0700107 hw_mgr->icp_default_clk = ICP_CLK_SVS_HZ;
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530108}
109
110static int cam_icp_get_actual_clk_rate_idx(
111 struct cam_icp_hw_ctx_data *ctx_data, uint32_t base_clk)
112{
113 int i;
114
115 for (i = 0; i < CAM_MAX_VOTE; i++)
116 if (ctx_data->clk_info.clk_rate[i] >= base_clk)
117 return i;
118
Venkat Chintad6de8c82018-01-18 17:14:52 -0800119 /*
120 * Caller has to ensure returned index is within array
121 * size bounds while accessing that index.
122 */
123
124 return i;
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530125}
126
127static bool cam_icp_is_over_clk(struct cam_icp_hw_mgr *hw_mgr,
128 struct cam_icp_hw_ctx_data *ctx_data,
129 struct cam_icp_clk_info *hw_mgr_clk_info)
130{
131 int base_clk_idx;
132 int curr_clk_idx;
133
134 base_clk_idx = cam_icp_get_actual_clk_rate_idx(ctx_data,
135 hw_mgr_clk_info->base_clk);
136
137 curr_clk_idx = cam_icp_get_actual_clk_rate_idx(ctx_data,
138 hw_mgr_clk_info->curr_clk);
139
Venkat Chintad6de8c82018-01-18 17:14:52 -0800140 CAM_DBG(CAM_ICP, "bc_idx = %d cc_idx = %d %d %d",
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530141 base_clk_idx, curr_clk_idx, hw_mgr_clk_info->base_clk,
142 hw_mgr_clk_info->curr_clk);
143
144 if (curr_clk_idx > base_clk_idx)
145 return true;
146
147 return false;
148}
149
150static int cam_icp_get_lower_clk_rate(struct cam_icp_hw_mgr *hw_mgr,
151 struct cam_icp_hw_ctx_data *ctx_data, uint32_t base_clk)
152{
153 int i;
154
155 i = cam_icp_get_actual_clk_rate_idx(ctx_data, base_clk);
156
157 if (i > 0)
158 return ctx_data->clk_info.clk_rate[i - 1];
159
160 CAM_DBG(CAM_ICP, "Already clk at lower level");
161 return base_clk;
162}
163
164static int cam_icp_get_next_clk_rate(struct cam_icp_hw_mgr *hw_mgr,
165 struct cam_icp_hw_ctx_data *ctx_data, uint32_t base_clk)
166{
167 int i;
168
169 i = cam_icp_get_actual_clk_rate_idx(ctx_data, base_clk);
170
171 if (i < CAM_MAX_VOTE - 1)
172 return ctx_data->clk_info.clk_rate[i + 1];
173
174 CAM_DBG(CAM_ICP, "Already clk at higher level");
175
176 return base_clk;
177}
178
179static int cam_icp_get_actual_clk_rate(struct cam_icp_hw_mgr *hw_mgr,
180 struct cam_icp_hw_ctx_data *ctx_data, uint32_t base_clk)
181{
182 int i;
183
184 for (i = 0; i < CAM_MAX_VOTE; i++)
185 if (ctx_data->clk_info.clk_rate[i] >= base_clk)
186 return ctx_data->clk_info.clk_rate[i];
187
188 return base_clk;
189}
190
191static int cam_icp_supported_clk_rates(struct cam_icp_hw_mgr *hw_mgr,
192 struct cam_icp_hw_ctx_data *ctx_data)
193{
194 int i;
195 struct cam_hw_soc_info *soc_info;
196 struct cam_hw_intf *dev_intf = NULL;
197 struct cam_hw_info *dev = NULL;
198
199 if (ctx_data->icp_dev_acquire_info->dev_type == CAM_ICP_RES_TYPE_BPS)
Abhilash Kumar9c3d8192017-12-15 01:36:37 +0530200 dev_intf = hw_mgr->bps_dev_intf;
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530201 else
Abhilash Kumar9c3d8192017-12-15 01:36:37 +0530202 dev_intf = hw_mgr->ipe0_dev_intf;
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530203
204 if (!dev_intf) {
205 CAM_ERR(CAM_ICP, "dev_intf is invalid");
206 return -EINVAL;
207 }
208 dev = (struct cam_hw_info *)dev_intf->hw_priv;
209 soc_info = &dev->soc_info;
210
211 for (i = 0; i < CAM_MAX_VOTE; i++) {
212 ctx_data->clk_info.clk_rate[i] =
213 soc_info->clk_rate[i][soc_info->num_clk - 1];
214 CAM_DBG(CAM_ICP, "clk_info = %d",
215 ctx_data->clk_info.clk_rate[i]);
216 }
217
218 return 0;
219}
220
221static int cam_icp_clk_idx_from_req_id(struct cam_icp_hw_ctx_data *ctx_data,
222 uint64_t req_id)
223{
224 struct hfi_frame_process_info *frame_process;
225 int i;
226
227 frame_process = &ctx_data->hfi_frame_process;
228
229 for (i = 0; i < CAM_FRAME_CMD_MAX; i++)
230 if (frame_process->request_id[i] == req_id)
231 return i;
232
233 return 0;
234}
235
Junzhe Zoubc37c562017-11-20 18:23:49 -0800236static int cam_icp_ctx_clk_info_init(struct cam_icp_hw_ctx_data *ctx_data)
237{
238 ctx_data->clk_info.curr_fc = 0;
239 ctx_data->clk_info.base_clk = 0;
240 ctx_data->clk_info.uncompressed_bw = 0;
241 ctx_data->clk_info.compressed_bw = 0;
242 cam_icp_supported_clk_rates(&icp_hw_mgr, ctx_data);
243
244 return 0;
245}
246
247static int32_t cam_icp_deinit_idle_clk(void *priv, void *data)
248{
249 struct cam_icp_hw_mgr *hw_mgr = (struct cam_icp_hw_mgr *)priv;
250 struct clk_work_data *task_data = (struct clk_work_data *)data;
251 struct cam_icp_clk_info *clk_info =
252 (struct cam_icp_clk_info *)task_data->data;
253 uint32_t id;
254 uint32_t i;
Junzhe Zoubc37c562017-11-20 18:23:49 -0800255 struct cam_icp_hw_ctx_data *ctx_data;
256 struct cam_hw_intf *ipe0_dev_intf = NULL;
257 struct cam_hw_intf *ipe1_dev_intf = NULL;
258 struct cam_hw_intf *bps_dev_intf = NULL;
259 struct cam_hw_intf *dev_intf = NULL;
Alok Pandey1aef7b52017-12-16 20:42:03 +0530260 struct cam_a5_clk_update_cmd clk_upd_cmd;
Junzhe Zoubc37c562017-11-20 18:23:49 -0800261
Abhilash Kumar9c3d8192017-12-15 01:36:37 +0530262 ipe0_dev_intf = hw_mgr->ipe0_dev_intf;
263 ipe1_dev_intf = hw_mgr->ipe1_dev_intf;
264 bps_dev_intf = hw_mgr->bps_dev_intf;
Junzhe Zoubc37c562017-11-20 18:23:49 -0800265
266 clk_info->base_clk = 0;
267 clk_info->curr_clk = 0;
268 clk_info->over_clked = 0;
269
270 for (i = 0; i < CAM_ICP_CTX_MAX; i++) {
271 ctx_data = &hw_mgr->ctx_data[i];
272 mutex_lock(&ctx_data->ctx_mutex);
273 if ((ctx_data->state != CAM_ICP_CTX_STATE_FREE) &&
274 (ICP_DEV_TYPE_TO_CLK_TYPE(ctx_data->
275 icp_dev_acquire_info->dev_type) == clk_info->hw_type))
276 cam_icp_ctx_clk_info_init(ctx_data);
277 mutex_unlock(&ctx_data->ctx_mutex);
278 }
279
280 if ((!ipe0_dev_intf) || (!bps_dev_intf)) {
281 CAM_ERR(CAM_ICP, "dev intfs are wrong, failed to update clk");
282 return -EINVAL;
283 }
284
285 if (clk_info->hw_type == ICP_CLK_HW_BPS) {
286 dev_intf = bps_dev_intf;
287 id = CAM_ICP_BPS_CMD_DISABLE_CLK;
288 } else if (clk_info->hw_type == ICP_CLK_HW_IPE) {
289 dev_intf = ipe0_dev_intf;
290 id = CAM_ICP_IPE_CMD_DISABLE_CLK;
291 } else {
292 CAM_ERR(CAM_ICP, "Error");
293 return 0;
294 }
295
296 CAM_DBG(CAM_ICP, "Disable %d", clk_info->hw_type);
297
Alok Pandey1aef7b52017-12-16 20:42:03 +0530298 clk_upd_cmd.ipe_bps_pc_enable = icp_hw_mgr.ipe_bps_pc_flag;
299
Junzhe Zoubc37c562017-11-20 18:23:49 -0800300 dev_intf->hw_ops.process_cmd(dev_intf->hw_priv, id,
Alok Pandey1aef7b52017-12-16 20:42:03 +0530301 &clk_upd_cmd, sizeof(struct cam_a5_clk_update_cmd));
Junzhe Zoubc37c562017-11-20 18:23:49 -0800302
303 if (clk_info->hw_type != ICP_CLK_HW_BPS)
304 if (ipe1_dev_intf)
305 ipe1_dev_intf->hw_ops.process_cmd(
306 ipe1_dev_intf->hw_priv, id,
Alok Pandey1aef7b52017-12-16 20:42:03 +0530307 &clk_upd_cmd,
308 sizeof(struct cam_a5_clk_update_cmd));
Junzhe Zoubc37c562017-11-20 18:23:49 -0800309
310 return 0;
311}
312
Suresh Vankadarac092e592018-01-11 18:52:41 +0530313static int32_t cam_icp_ctx_timer(void *priv, void *data)
314{
315 struct clk_work_data *task_data = (struct clk_work_data *)data;
316 struct cam_icp_hw_ctx_data *ctx_data =
317 (struct cam_icp_hw_ctx_data *)task_data->data;
318 struct cam_icp_hw_mgr *hw_mgr = &icp_hw_mgr;
319 uint32_t id;
320 struct cam_hw_intf *ipe0_dev_intf = NULL;
321 struct cam_hw_intf *ipe1_dev_intf = NULL;
322 struct cam_hw_intf *bps_dev_intf = NULL;
323 struct cam_hw_intf *dev_intf = NULL;
324 struct cam_icp_clk_info *clk_info;
325 struct cam_icp_cpas_vote clk_update;
326
327 if (!ctx_data) {
328 CAM_ERR(CAM_ICP, "ctx_data is NULL, failed to update clk");
329 return -EINVAL;
330 }
331
332 mutex_lock(&ctx_data->ctx_mutex);
333 if ((ctx_data->state != CAM_ICP_CTX_STATE_ACQUIRED) ||
334 (ctx_data->watch_dog_reset_counter == 0)) {
335 CAM_DBG(CAM_ICP, "state %d, counter=%d",
336 ctx_data->state, ctx_data->watch_dog_reset_counter);
337 mutex_unlock(&ctx_data->ctx_mutex);
338 return 0;
339 }
340
341 CAM_DBG(CAM_ICP,
342 "E :ctx_id = %d ubw = %lld cbw = %lld curr_fc = %u bc = %u",
343 ctx_data->ctx_id,
344 ctx_data->clk_info.uncompressed_bw,
345 ctx_data->clk_info.compressed_bw,
346 ctx_data->clk_info.curr_fc, ctx_data->clk_info.base_clk);
347
348 ipe0_dev_intf = hw_mgr->ipe0_dev_intf;
349 ipe1_dev_intf = hw_mgr->ipe1_dev_intf;
350 bps_dev_intf = hw_mgr->bps_dev_intf;
351
352 if ((!ipe0_dev_intf) || (!bps_dev_intf)) {
353 CAM_ERR(CAM_ICP, "dev intfs are wrong, failed to update clk");
354 mutex_unlock(&ctx_data->ctx_mutex);
355 return -EINVAL;
356 }
357
358 if (!ctx_data->icp_dev_acquire_info) {
359 CAM_WARN(CAM_ICP, "NULL acquire info");
360 mutex_unlock(&ctx_data->ctx_mutex);
361 return -EINVAL;
362 }
363
364 if (ctx_data->icp_dev_acquire_info->dev_type == CAM_ICP_RES_TYPE_BPS) {
365 dev_intf = bps_dev_intf;
366 clk_info = &hw_mgr->clk_info[ICP_CLK_HW_BPS];
367 id = CAM_ICP_BPS_CMD_VOTE_CPAS;
368 } else {
369 dev_intf = ipe0_dev_intf;
370 clk_info = &hw_mgr->clk_info[ICP_CLK_HW_IPE];
371 id = CAM_ICP_IPE_CMD_VOTE_CPAS;
372 }
373
374 clk_info->compressed_bw -= ctx_data->clk_info.compressed_bw;
375 clk_info->uncompressed_bw -= ctx_data->clk_info.uncompressed_bw;
376 ctx_data->clk_info.uncompressed_bw = 0;
377 ctx_data->clk_info.compressed_bw = 0;
378 ctx_data->clk_info.curr_fc = 0;
379 ctx_data->clk_info.base_clk = 0;
380
381 clk_update.ahb_vote.type = CAM_VOTE_DYNAMIC;
382 clk_update.ahb_vote.vote.freq = clk_info->curr_clk;
383 clk_update.ahb_vote_valid = true;
384 clk_update.axi_vote.compressed_bw = clk_info->compressed_bw;
385 clk_update.axi_vote.uncompressed_bw = clk_info->uncompressed_bw;
386 clk_update.axi_vote_valid = true;
387 dev_intf->hw_ops.process_cmd(dev_intf->hw_priv, id,
388 &clk_update, sizeof(clk_update));
389
390 CAM_DBG(CAM_ICP,
391 "X :ctx_id = %d ubw = %lld cbw = %lld curr_fc = %u bc = %u",
392 ctx_data->ctx_id,
393 ctx_data->clk_info.uncompressed_bw,
394 ctx_data->clk_info.compressed_bw,
395 ctx_data->clk_info.curr_fc, ctx_data->clk_info.base_clk);
396
397 mutex_unlock(&ctx_data->ctx_mutex);
398
399 return 0;
400}
401
402static void cam_icp_ctx_timer_cb(unsigned long data)
403{
404 unsigned long flags;
405 struct crm_workq_task *task;
406 struct clk_work_data *task_data;
407 struct cam_req_mgr_timer *timer = (struct cam_req_mgr_timer *)data;
408
409 spin_lock_irqsave(&icp_hw_mgr.hw_mgr_lock, flags);
410 task = cam_req_mgr_workq_get_task(icp_hw_mgr.msg_work);
411 if (!task) {
412 CAM_ERR(CAM_ICP, "no empty task");
413 spin_unlock_irqrestore(&icp_hw_mgr.hw_mgr_lock, flags);
414 return;
415 }
416
417 task_data = (struct clk_work_data *)task->payload;
418 task_data->data = timer->parent;
419 task_data->type = ICP_WORKQ_TASK_MSG_TYPE;
420 task->process_cb = cam_icp_ctx_timer;
421 cam_req_mgr_workq_enqueue_task(task, &icp_hw_mgr,
422 CRM_TASK_PRIORITY_0);
423 spin_unlock_irqrestore(&icp_hw_mgr.hw_mgr_lock, flags);
424}
425
426static void cam_icp_device_timer_cb(unsigned long data)
Junzhe Zoubc37c562017-11-20 18:23:49 -0800427{
428 unsigned long flags;
429 struct crm_workq_task *task;
430 struct clk_work_data *task_data;
431 struct cam_req_mgr_timer *timer = (struct cam_req_mgr_timer *)data;
432
433 spin_lock_irqsave(&icp_hw_mgr.hw_mgr_lock, flags);
434 task = cam_req_mgr_workq_get_task(icp_hw_mgr.msg_work);
435 if (!task) {
436 CAM_ERR(CAM_ICP, "no empty task");
437 spin_unlock_irqrestore(&icp_hw_mgr.hw_mgr_lock, flags);
438 return;
439 }
440
441 task_data = (struct clk_work_data *)task->payload;
442 task_data->data = timer->parent;
443 task_data->type = ICP_WORKQ_TASK_MSG_TYPE;
444 task->process_cb = cam_icp_deinit_idle_clk;
445 cam_req_mgr_workq_enqueue_task(task, &icp_hw_mgr,
446 CRM_TASK_PRIORITY_0);
447 spin_unlock_irqrestore(&icp_hw_mgr.hw_mgr_lock, flags);
448}
449
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530450static int cam_icp_clk_info_init(struct cam_icp_hw_mgr *hw_mgr,
451 struct cam_icp_hw_ctx_data *ctx_data)
452{
453 int i;
454
455 for (i = 0; i < ICP_CLK_HW_MAX; i++) {
Pavan Kumar Chilamkurthiee7848e2017-11-03 17:33:08 -0700456 hw_mgr->clk_info[i].base_clk = ICP_CLK_SVS_HZ;
457 hw_mgr->clk_info[i].curr_clk = ICP_CLK_SVS_HZ;
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530458 hw_mgr->clk_info[i].threshold = ICP_OVER_CLK_THRESHOLD;
459 hw_mgr->clk_info[i].over_clked = 0;
460 hw_mgr->clk_info[i].uncompressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
461 hw_mgr->clk_info[i].compressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
Junzhe Zoubc37c562017-11-20 18:23:49 -0800462 hw_mgr->clk_info[i].hw_type = i;
Suresh Vankadarac092e592018-01-11 18:52:41 +0530463 hw_mgr->clk_info[i].watch_dog_reset_counter = 0;
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530464 }
Pavan Kumar Chilamkurthiee7848e2017-11-03 17:33:08 -0700465 hw_mgr->icp_default_clk = ICP_CLK_SVS_HZ;
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530466
467 return 0;
468}
469
Suresh Vankadarac092e592018-01-11 18:52:41 +0530470static int cam_icp_ctx_timer_start(struct cam_icp_hw_ctx_data *ctx_data)
471{
472 int rc = 0;
473
474 rc = crm_timer_init(&ctx_data->watch_dog,
475 2000, ctx_data, &cam_icp_ctx_timer_cb);
476 if (rc)
477 CAM_ERR(CAM_ICP, "Failed to start timer");
478
479 ctx_data->watch_dog_reset_counter = 0;
480
481 CAM_DBG(CAM_ICP, "stop timer : ctx_id = %d", ctx_data->ctx_id);
482 return rc;
483}
484
485static int cam_icp_device_timer_start(struct cam_icp_hw_mgr *hw_mgr)
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530486{
Junzhe Zoubc37c562017-11-20 18:23:49 -0800487 int rc = 0;
488 int i;
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530489
Junzhe Zoubc37c562017-11-20 18:23:49 -0800490 for (i = 0; i < ICP_CLK_HW_MAX; i++) {
491 if (!hw_mgr->clk_info[i].watch_dog) {
492 rc = crm_timer_init(&hw_mgr->clk_info[i].watch_dog,
Suresh Vankadarac092e592018-01-11 18:52:41 +0530493 3000, &hw_mgr->clk_info[i],
494 &cam_icp_device_timer_cb);
495
Junzhe Zoubc37c562017-11-20 18:23:49 -0800496 if (rc)
497 CAM_ERR(CAM_ICP, "Failed to start timer %d", i);
Suresh Vankadarac092e592018-01-11 18:52:41 +0530498
499 hw_mgr->clk_info[i].watch_dog_reset_counter = 0;
Junzhe Zoubc37c562017-11-20 18:23:49 -0800500 }
501 }
502
503 return rc;
504}
505
Suresh Vankadarac092e592018-01-11 18:52:41 +0530506static int cam_icp_ctx_timer_stop(struct cam_icp_hw_ctx_data *ctx_data)
Junzhe Zoubc37c562017-11-20 18:23:49 -0800507{
Suresh Vankadarac092e592018-01-11 18:52:41 +0530508 if (ctx_data->watch_dog) {
509 CAM_DBG(CAM_ICP, "stop timer : ctx_id = %d", ctx_data->ctx_id);
510 ctx_data->watch_dog_reset_counter = 0;
511 crm_timer_exit(&ctx_data->watch_dog);
512 ctx_data->watch_dog = NULL;
513 }
514
515 return 0;
516}
517
518static void cam_icp_device_timer_stop(struct cam_icp_hw_mgr *hw_mgr)
519{
520 if (!hw_mgr->bps_ctxt_cnt &&
521 hw_mgr->clk_info[ICP_CLK_HW_BPS].watch_dog) {
522 hw_mgr->clk_info[ICP_CLK_HW_BPS].watch_dog_reset_counter = 0;
Junzhe Zoubc37c562017-11-20 18:23:49 -0800523 crm_timer_exit(&hw_mgr->clk_info[ICP_CLK_HW_BPS].watch_dog);
Suresh Vankadarac092e592018-01-11 18:52:41 +0530524 hw_mgr->clk_info[ICP_CLK_HW_BPS].watch_dog = NULL;
525 }
526
527 if (!hw_mgr->ipe_ctxt_cnt &&
528 hw_mgr->clk_info[ICP_CLK_HW_IPE].watch_dog) {
529 hw_mgr->clk_info[ICP_CLK_HW_IPE].watch_dog_reset_counter = 0;
Junzhe Zoubc37c562017-11-20 18:23:49 -0800530 crm_timer_exit(&hw_mgr->clk_info[ICP_CLK_HW_IPE].watch_dog);
Suresh Vankadarac092e592018-01-11 18:52:41 +0530531 hw_mgr->clk_info[ICP_CLK_HW_IPE].watch_dog = NULL;
532 }
533}
534
535static int cam_icp_ctx_timer_reset(struct cam_icp_hw_ctx_data *ctx_data)
536{
537 if (ctx_data && ctx_data->watch_dog) {
538 ctx_data->watch_dog_reset_counter++;
539 CAM_DBG(CAM_ICP, "reset timer : ctx_id = %d, counter=%d",
540 ctx_data->ctx_id, ctx_data->watch_dog_reset_counter);
541 crm_timer_reset(ctx_data->watch_dog);
542 }
543
544 return 0;
545}
546
547static void cam_icp_device_timer_reset(struct cam_icp_hw_mgr *hw_mgr,
548 int device_index)
549{
550 if ((device_index >= ICP_CLK_HW_MAX) || (!hw_mgr))
551 return;
552
553 if (hw_mgr->clk_info[device_index].watch_dog) {
554 crm_timer_reset(hw_mgr->clk_info[device_index].watch_dog);
555 hw_mgr->clk_info[device_index].watch_dog_reset_counter++;
556 }
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530557}
558
559static uint32_t cam_icp_mgr_calc_base_clk(uint32_t frame_cycles,
560 uint64_t budget)
561{
562 uint64_t base_clk;
563 uint64_t mul = 1000000000;
564
565 base_clk = (frame_cycles * mul) / budget;
566
567 CAM_DBG(CAM_ICP, "budget = %lld fc = %d ib = %lld base_clk = %lld",
568 budget, frame_cycles,
569 (long long int)(frame_cycles * mul), base_clk);
570
571 return base_clk;
572}
573
574static bool cam_icp_busy_prev_reqs(struct hfi_frame_process_info *frm_process,
575 uint64_t req_id)
576{
577 int i;
578 int cnt;
579
580 for (i = 0, cnt = 0; i < CAM_FRAME_CMD_MAX; i++) {
581 if (frm_process->request_id[i]) {
582 if (frm_process->fw_process_flag[i]) {
583 CAM_DBG(CAM_ICP, "r id = %lld busy = %d",
584 frm_process->request_id[i],
585 frm_process->fw_process_flag[i]);
586 cnt++;
587 }
588 }
589 }
590 if (cnt > 1)
591 return true;
592
593 return false;
594}
595
596static int cam_icp_calc_total_clk(struct cam_icp_hw_mgr *hw_mgr,
597 struct cam_icp_clk_info *hw_mgr_clk_info, uint32_t dev_type)
598{
599 int i;
600 struct cam_icp_hw_ctx_data *ctx_data;
601
602 hw_mgr_clk_info->base_clk = 0;
603 for (i = 0; i < CAM_ICP_CTX_MAX; i++) {
604 ctx_data = &hw_mgr->ctx_data[i];
Suresh Vankadarac7b0c672017-11-25 00:44:10 +0530605 if (ctx_data->state == CAM_ICP_CTX_STATE_ACQUIRED &&
Suresh Vankadarac092e592018-01-11 18:52:41 +0530606 ICP_DEV_TYPE_TO_CLK_TYPE(
607 ctx_data->icp_dev_acquire_info->dev_type) ==
608 ICP_DEV_TYPE_TO_CLK_TYPE(dev_type))
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530609 hw_mgr_clk_info->base_clk +=
610 ctx_data->clk_info.base_clk;
611 }
612
613 return 0;
614}
615
616static bool cam_icp_update_clk_busy(struct cam_icp_hw_mgr *hw_mgr,
617 struct cam_icp_hw_ctx_data *ctx_data,
618 struct cam_icp_clk_info *hw_mgr_clk_info,
619 struct cam_icp_clk_bw_request *clk_info,
620 uint32_t base_clk)
621{
622 uint32_t next_clk_level;
623 uint32_t actual_clk;
Suresh Vankadara38f7a652017-09-25 20:58:41 +0530624 bool rc = false;
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530625
626 /* 1. if current request frame cycles(fc) are more than previous
627 * frame fc
628 * Calculate the new base clock.
629 * if sum of base clocks are more than next available clk level
630 * Update clock rate, change curr_clk_rate to sum of base clock
631 * rates and make over_clked to zero
632 * else
633 * Update clock rate to next level, update curr_clk_rate and make
634 * overclked cnt to zero
635 * 2. if current fc is less than or equal to previous frame fc
636 * Still Bump up the clock to next available level
637 * if it is available, then update clock, make overclk cnt to
Suresh Vankadara38f7a652017-09-25 20:58:41 +0530638 * zero. If the clock is already at highest clock rate then
639 * no need to update the clock
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530640 */
641 mutex_lock(&hw_mgr->hw_mgr_mutex);
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530642 ctx_data->clk_info.base_clk = base_clk;
643 hw_mgr_clk_info->over_clked = 0;
644 if (clk_info->frame_cycles > ctx_data->clk_info.curr_fc) {
645 cam_icp_calc_total_clk(hw_mgr, hw_mgr_clk_info,
646 ctx_data->icp_dev_acquire_info->dev_type);
647 actual_clk = cam_icp_get_actual_clk_rate(hw_mgr,
648 ctx_data, base_clk);
649 if (hw_mgr_clk_info->base_clk > actual_clk) {
650 hw_mgr_clk_info->curr_clk = hw_mgr_clk_info->base_clk;
651 } else {
652 next_clk_level = cam_icp_get_next_clk_rate(hw_mgr,
653 ctx_data, hw_mgr_clk_info->curr_clk);
654 hw_mgr_clk_info->curr_clk = next_clk_level;
655 }
Suresh Vankadara38f7a652017-09-25 20:58:41 +0530656 rc = true;
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530657 } else {
Suresh Vankadara38f7a652017-09-25 20:58:41 +0530658 next_clk_level =
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530659 cam_icp_get_next_clk_rate(hw_mgr, ctx_data,
660 hw_mgr_clk_info->curr_clk);
Suresh Vankadara38f7a652017-09-25 20:58:41 +0530661 if (hw_mgr_clk_info->curr_clk < next_clk_level) {
662 hw_mgr_clk_info->curr_clk = next_clk_level;
663 rc = true;
664 }
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530665 }
Junzhe Zoubc37c562017-11-20 18:23:49 -0800666 ctx_data->clk_info.curr_fc = clk_info->frame_cycles;
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530667 mutex_unlock(&hw_mgr->hw_mgr_mutex);
668
Suresh Vankadara38f7a652017-09-25 20:58:41 +0530669 return rc;
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530670}
671
672static bool cam_icp_update_clk_overclk_free(struct cam_icp_hw_mgr *hw_mgr,
673 struct cam_icp_hw_ctx_data *ctx_data,
674 struct cam_icp_clk_info *hw_mgr_clk_info,
675 struct cam_icp_clk_bw_request *clk_info,
676 uint32_t base_clk)
677{
678 int rc = false;
679
680 /*
681 * In caseof no pending packets case
682 * 1. In caseof overclk cnt is less than threshold, increase
683 * overclk count and no update in the clock rate
684 * 2. In caseof overclk cnt is greater than or equal to threshold
685 * then lower clock rate by one level and update hw_mgr current
686 * clock value.
687 * a. In case of new clock rate greater than sum of clock
688 * rates, reset overclk count value to zero if it is
689 * overclock
690 * b. if it is less than sum of base clocks then go to next
691 * level of clock and make overclk count to zero
692 * c. if it is same as sum of base clock rates update overclock
693 * cnt to 0
694 */
695 if (hw_mgr_clk_info->over_clked < hw_mgr_clk_info->threshold) {
696 hw_mgr_clk_info->over_clked++;
697 rc = false;
698 } else {
699 hw_mgr_clk_info->curr_clk =
700 cam_icp_get_lower_clk_rate(hw_mgr, ctx_data,
701 hw_mgr_clk_info->curr_clk);
702 if (hw_mgr_clk_info->curr_clk > hw_mgr_clk_info->base_clk) {
703 if (cam_icp_is_over_clk(hw_mgr, ctx_data,
704 hw_mgr_clk_info))
705 hw_mgr_clk_info->over_clked = 0;
706 } else if (hw_mgr_clk_info->curr_clk <
707 hw_mgr_clk_info->base_clk) {
708 hw_mgr_clk_info->curr_clk =
709 cam_icp_get_next_clk_rate(hw_mgr, ctx_data,
710 hw_mgr_clk_info->curr_clk);
711 hw_mgr_clk_info->over_clked = 0;
712 } else if (hw_mgr_clk_info->curr_clk ==
713 hw_mgr_clk_info->base_clk) {
714 hw_mgr_clk_info->over_clked = 0;
715 }
716 rc = true;
717 }
718
719 return rc;
720}
721
722static bool cam_icp_update_clk_free(struct cam_icp_hw_mgr *hw_mgr,
723 struct cam_icp_hw_ctx_data *ctx_data,
724 struct cam_icp_clk_info *hw_mgr_clk_info,
725 struct cam_icp_clk_bw_request *clk_info,
726 uint32_t base_clk)
727{
728 int rc = false;
729 bool over_clocked = false;
730
731 ctx_data->clk_info.curr_fc = clk_info->frame_cycles;
732 ctx_data->clk_info.base_clk = base_clk;
733 mutex_lock(&hw_mgr->hw_mgr_mutex);
734 cam_icp_calc_total_clk(hw_mgr, hw_mgr_clk_info,
735 ctx_data->icp_dev_acquire_info->dev_type);
736 mutex_unlock(&hw_mgr->hw_mgr_mutex);
737
738 /*
739 * Current clock is not always sum of base clocks, due to
740 * clock scales update to next higher or lower levels, it
741 * equals to one of discrete clock values supported by hardware.
742 * So even current clock is higher than sum of base clocks, we
743 * can not consider it is over clocked. if it is greater than
744 * discrete clock level then only it is considered as over clock.
745 * 1. Handle over clock case
746 * 2. If current clock is less than sum of base clocks
747 * update current clock
748 * 3. If current clock is same as sum of base clocks no action
749 */
750
751 over_clocked = cam_icp_is_over_clk(hw_mgr, ctx_data,
752 hw_mgr_clk_info);
753
754 mutex_lock(&hw_mgr->hw_mgr_mutex);
755 if (hw_mgr_clk_info->curr_clk > hw_mgr_clk_info->base_clk &&
756 over_clocked) {
757 rc = cam_icp_update_clk_overclk_free(hw_mgr, ctx_data,
758 hw_mgr_clk_info, clk_info, base_clk);
759 } else if (hw_mgr_clk_info->curr_clk > hw_mgr_clk_info->base_clk) {
760 hw_mgr_clk_info->over_clked = 0;
761 rc = false;
762 } else if (hw_mgr_clk_info->curr_clk < hw_mgr_clk_info->base_clk) {
Suresh Vankadarac092e592018-01-11 18:52:41 +0530763 hw_mgr_clk_info->curr_clk = cam_icp_get_actual_clk_rate(hw_mgr,
764 ctx_data, hw_mgr_clk_info->base_clk);
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530765 rc = true;
766 }
767 mutex_unlock(&hw_mgr->hw_mgr_mutex);
768
769 return rc;
770}
771
772static bool cam_icp_debug_clk_update(struct cam_icp_clk_info *hw_mgr_clk_info)
773{
Pavan Kumar Chilamkurthiee7848e2017-11-03 17:33:08 -0700774 if (icp_hw_mgr.icp_debug_clk < ICP_CLK_TURBO_HZ &&
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530775 icp_hw_mgr.icp_debug_clk &&
776 icp_hw_mgr.icp_debug_clk != hw_mgr_clk_info->curr_clk) {
777 mutex_lock(&icp_hw_mgr.hw_mgr_mutex);
778 hw_mgr_clk_info->base_clk = icp_hw_mgr.icp_debug_clk;
779 hw_mgr_clk_info->curr_clk = icp_hw_mgr.icp_debug_clk;
780 hw_mgr_clk_info->uncompressed_bw = icp_hw_mgr.icp_debug_clk;
781 hw_mgr_clk_info->compressed_bw = icp_hw_mgr.icp_debug_clk;
782 mutex_unlock(&icp_hw_mgr.hw_mgr_mutex);
783 CAM_DBG(CAM_ICP, "bc = %d cc = %d",
784 hw_mgr_clk_info->base_clk, hw_mgr_clk_info->curr_clk);
785 return true;
786 }
787
788 return false;
789}
790
791static bool cam_icp_default_clk_update(struct cam_icp_clk_info *hw_mgr_clk_info)
792{
793 if (icp_hw_mgr.icp_default_clk != hw_mgr_clk_info->curr_clk) {
794 mutex_lock(&icp_hw_mgr.hw_mgr_mutex);
795 hw_mgr_clk_info->base_clk = icp_hw_mgr.icp_default_clk;
796 hw_mgr_clk_info->curr_clk = icp_hw_mgr.icp_default_clk;
797 hw_mgr_clk_info->uncompressed_bw = icp_hw_mgr.icp_default_clk;
798 hw_mgr_clk_info->compressed_bw = icp_hw_mgr.icp_default_clk;
799 mutex_unlock(&icp_hw_mgr.hw_mgr_mutex);
800 CAM_DBG(CAM_ICP, "bc = %d cc = %d",
801 hw_mgr_clk_info->base_clk, hw_mgr_clk_info->curr_clk);
802 return true;
803 }
804
805 return false;
806}
807
808static bool cam_icp_update_bw(struct cam_icp_hw_mgr *hw_mgr,
809 struct cam_icp_hw_ctx_data *ctx_data,
810 struct cam_icp_clk_info *hw_mgr_clk_info,
811 struct cam_icp_clk_bw_request *clk_info,
812 bool busy)
813{
814 int i;
815 struct cam_icp_hw_ctx_data *ctx;
816
817 /*
818 * If current request bandwidth is different from previous frames, then
819 * recalculate bandwidth of all contexts of same hardware and update
820 * voting of bandwidth
821 */
Suresh Vankadarac092e592018-01-11 18:52:41 +0530822 CAM_DBG(CAM_ICP, "ubw ctx = %lld clk_info ubw = %lld busy = %d",
823 ctx_data->clk_info.uncompressed_bw,
824 clk_info->uncompressed_bw, busy);
825
826 if ((clk_info->uncompressed_bw == ctx_data->clk_info.uncompressed_bw) &&
827 (ctx_data->clk_info.uncompressed_bw ==
828 hw_mgr_clk_info->uncompressed_bw))
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530829 return false;
830
831 if (busy &&
832 ctx_data->clk_info.uncompressed_bw > clk_info->uncompressed_bw)
833 return false;
834
835 ctx_data->clk_info.uncompressed_bw = clk_info->uncompressed_bw;
836 ctx_data->clk_info.compressed_bw = clk_info->compressed_bw;
837 hw_mgr_clk_info->uncompressed_bw = 0;
838 hw_mgr_clk_info->compressed_bw = 0;
839 for (i = 0; i < CAM_ICP_CTX_MAX; i++) {
840 ctx = &hw_mgr->ctx_data[i];
Suresh Vankadarac7b0c672017-11-25 00:44:10 +0530841 if (ctx->state == CAM_ICP_CTX_STATE_ACQUIRED &&
Suresh Vankadarac092e592018-01-11 18:52:41 +0530842 ICP_DEV_TYPE_TO_CLK_TYPE(
843 ctx->icp_dev_acquire_info->dev_type) ==
844 ICP_DEV_TYPE_TO_CLK_TYPE(
845 ctx_data->icp_dev_acquire_info->dev_type)) {
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530846 mutex_lock(&hw_mgr->hw_mgr_mutex);
847 hw_mgr_clk_info->uncompressed_bw +=
848 ctx->clk_info.uncompressed_bw;
849 hw_mgr_clk_info->compressed_bw +=
850 ctx->clk_info.compressed_bw;
Suresh Vankadarac092e592018-01-11 18:52:41 +0530851 CAM_DBG(CAM_ICP, "ubw = %lld, cbw = %lld",
852 hw_mgr_clk_info->uncompressed_bw,
853 hw_mgr_clk_info->compressed_bw);
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530854 mutex_unlock(&hw_mgr->hw_mgr_mutex);
855 }
856 }
857
858 return true;
859}
860
861static bool cam_icp_check_clk_update(struct cam_icp_hw_mgr *hw_mgr,
862 struct cam_icp_hw_ctx_data *ctx_data, int idx)
863{
864 bool busy, rc = false;
865 uint32_t base_clk;
866 struct cam_icp_clk_bw_request *clk_info;
867 struct hfi_frame_process_info *frame_info;
868 uint64_t req_id;
869 struct cam_icp_clk_info *hw_mgr_clk_info;
870
Suresh Vankadarac092e592018-01-11 18:52:41 +0530871 cam_icp_ctx_timer_reset(ctx_data);
Junzhe Zoubc37c562017-11-20 18:23:49 -0800872 if (ctx_data->icp_dev_acquire_info->dev_type == CAM_ICP_RES_TYPE_BPS) {
Suresh Vankadarac092e592018-01-11 18:52:41 +0530873 cam_icp_device_timer_reset(hw_mgr, ICP_CLK_HW_BPS);
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530874 hw_mgr_clk_info = &hw_mgr->clk_info[ICP_CLK_HW_BPS];
Junzhe Zoubc37c562017-11-20 18:23:49 -0800875 CAM_DBG(CAM_ICP, "Reset bps timer");
876 } else {
Suresh Vankadarac092e592018-01-11 18:52:41 +0530877 cam_icp_device_timer_reset(hw_mgr, ICP_CLK_HW_IPE);
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530878 hw_mgr_clk_info = &hw_mgr->clk_info[ICP_CLK_HW_IPE];
Junzhe Zoubc37c562017-11-20 18:23:49 -0800879 CAM_DBG(CAM_ICP, "Reset ipe timer");
880 }
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530881
882 if (icp_hw_mgr.icp_debug_clk)
883 return cam_icp_debug_clk_update(hw_mgr_clk_info);
884
885 /* Check is there any pending frames in this context */
886 frame_info = &ctx_data->hfi_frame_process;
887 req_id = frame_info->request_id[idx];
888 busy = cam_icp_busy_prev_reqs(frame_info, req_id);
889 CAM_DBG(CAM_ICP, "busy = %d req_id = %lld", busy, req_id);
890
891 clk_info = &ctx_data->hfi_frame_process.clk_info[idx];
892 if (!clk_info->frame_cycles)
893 return cam_icp_default_clk_update(hw_mgr_clk_info);
894
895 /* Calculate base clk rate */
896 base_clk = cam_icp_mgr_calc_base_clk(
897 clk_info->frame_cycles, clk_info->budget_ns);
898 ctx_data->clk_info.rt_flag = clk_info->rt_flag;
899
900 if (busy)
901 rc = cam_icp_update_clk_busy(hw_mgr, ctx_data,
902 hw_mgr_clk_info, clk_info, base_clk);
903 else
904 rc = cam_icp_update_clk_free(hw_mgr, ctx_data,
905 hw_mgr_clk_info, clk_info, base_clk);
906
907 CAM_DBG(CAM_ICP, "bc = %d cc = %d busy = %d overclk = %d uc = %d",
908 hw_mgr_clk_info->base_clk, hw_mgr_clk_info->curr_clk,
909 busy, hw_mgr_clk_info->over_clked, rc);
910
911 return rc;
912}
913
914static bool cam_icp_check_bw_update(struct cam_icp_hw_mgr *hw_mgr,
915 struct cam_icp_hw_ctx_data *ctx_data, int idx)
916{
917 bool busy, rc = false;
918 struct cam_icp_clk_bw_request *clk_info;
919 struct cam_icp_clk_info *hw_mgr_clk_info;
920 struct hfi_frame_process_info *frame_info;
921 uint64_t req_id;
922
923 if (ctx_data->icp_dev_acquire_info->dev_type == CAM_ICP_RES_TYPE_BPS)
924 hw_mgr_clk_info = &hw_mgr->clk_info[ICP_CLK_HW_BPS];
925 else
926 hw_mgr_clk_info = &hw_mgr->clk_info[ICP_CLK_HW_IPE];
927
928 clk_info = &ctx_data->hfi_frame_process.clk_info[idx];
929 frame_info = &ctx_data->hfi_frame_process;
930 req_id = frame_info->request_id[idx];
931 busy = cam_icp_busy_prev_reqs(frame_info, req_id);
932 rc = cam_icp_update_bw(hw_mgr, ctx_data, hw_mgr_clk_info,
933 clk_info, busy);
934
Suresh Vankadara38f7a652017-09-25 20:58:41 +0530935 CAM_DBG(CAM_ICP, "ubw = %lld, cbw = %lld, update_bw = %d",
936 hw_mgr_clk_info->uncompressed_bw,
937 hw_mgr_clk_info->compressed_bw, rc);
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530938
939 return rc;
940}
941
942static int cam_icp_update_clk_rate(struct cam_icp_hw_mgr *hw_mgr,
943 struct cam_icp_hw_ctx_data *ctx_data)
944{
945 uint32_t id;
946 uint32_t curr_clk_rate;
947 struct cam_hw_intf *ipe0_dev_intf = NULL;
948 struct cam_hw_intf *ipe1_dev_intf = NULL;
949 struct cam_hw_intf *bps_dev_intf = NULL;
950 struct cam_hw_intf *dev_intf = NULL;
Alok Pandey1aef7b52017-12-16 20:42:03 +0530951 struct cam_a5_clk_update_cmd clk_upd_cmd;
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530952
Karthik Anantha Ram9f13d0e2017-11-30 14:55:44 -0800953 ipe0_dev_intf = hw_mgr->ipe0_dev_intf;
954 ipe1_dev_intf = hw_mgr->ipe1_dev_intf;
955 bps_dev_intf = hw_mgr->bps_dev_intf;
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530956
957
958 if ((!ipe0_dev_intf) || (!bps_dev_intf)) {
959 CAM_ERR(CAM_ICP, "dev intfs are wrong, failed to update clk");
960 return -EINVAL;
961 }
962
963 if (ctx_data->icp_dev_acquire_info->dev_type == CAM_ICP_RES_TYPE_BPS) {
964 dev_intf = bps_dev_intf;
965 curr_clk_rate = hw_mgr->clk_info[ICP_CLK_HW_BPS].curr_clk;
966 id = CAM_ICP_BPS_CMD_UPDATE_CLK;
967 } else {
968 dev_intf = ipe0_dev_intf;
969 curr_clk_rate = hw_mgr->clk_info[ICP_CLK_HW_IPE].curr_clk;
970 id = CAM_ICP_IPE_CMD_UPDATE_CLK;
971 }
972
Alok Pandey1aef7b52017-12-16 20:42:03 +0530973 clk_upd_cmd.curr_clk_rate = curr_clk_rate;
974 clk_upd_cmd.ipe_bps_pc_enable = icp_hw_mgr.ipe_bps_pc_flag;
975
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530976 dev_intf->hw_ops.process_cmd(dev_intf->hw_priv, id,
Alok Pandey1aef7b52017-12-16 20:42:03 +0530977 &clk_upd_cmd, sizeof(struct cam_a5_clk_update_cmd));
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530978
979 if (ctx_data->icp_dev_acquire_info->dev_type != CAM_ICP_RES_TYPE_BPS)
980 if (ipe1_dev_intf)
981 ipe1_dev_intf->hw_ops.process_cmd(
982 ipe1_dev_intf->hw_priv, id,
Alok Pandey1aef7b52017-12-16 20:42:03 +0530983 &clk_upd_cmd,
984 sizeof(struct cam_a5_clk_update_cmd));
Suresh Vankadara34494fc2017-08-12 18:18:09 +0530985
986 return 0;
987}
988
989static int cam_icp_update_cpas_vote(struct cam_icp_hw_mgr *hw_mgr,
990 struct cam_icp_hw_ctx_data *ctx_data)
991{
992 uint32_t id;
993 struct cam_hw_intf *ipe0_dev_intf = NULL;
994 struct cam_hw_intf *ipe1_dev_intf = NULL;
995 struct cam_hw_intf *bps_dev_intf = NULL;
996 struct cam_hw_intf *dev_intf = NULL;
997 struct cam_icp_clk_info *clk_info;
998 struct cam_icp_cpas_vote clk_update;
999
Karthik Anantha Ram9f13d0e2017-11-30 14:55:44 -08001000 ipe0_dev_intf = hw_mgr->ipe0_dev_intf;
1001 ipe1_dev_intf = hw_mgr->ipe1_dev_intf;
1002 bps_dev_intf = hw_mgr->bps_dev_intf;
Suresh Vankadara34494fc2017-08-12 18:18:09 +05301003
1004 if ((!ipe0_dev_intf) || (!bps_dev_intf)) {
1005 CAM_ERR(CAM_ICP, "dev intfs are wrong, failed to update clk");
1006 return -EINVAL;
1007 }
1008
1009 if (ctx_data->icp_dev_acquire_info->dev_type == CAM_ICP_RES_TYPE_BPS) {
1010 dev_intf = bps_dev_intf;
1011 clk_info = &hw_mgr->clk_info[ICP_CLK_HW_BPS];
1012 id = CAM_ICP_BPS_CMD_VOTE_CPAS;
1013 } else {
1014 dev_intf = ipe0_dev_intf;
1015 clk_info = &hw_mgr->clk_info[ICP_CLK_HW_IPE];
1016 id = CAM_ICP_IPE_CMD_VOTE_CPAS;
1017 }
1018
1019 clk_update.ahb_vote.type = CAM_VOTE_DYNAMIC;
1020 clk_update.ahb_vote.vote.freq = clk_info->curr_clk;
1021 clk_update.ahb_vote_valid = true;
1022 clk_update.axi_vote.compressed_bw = clk_info->compressed_bw;
1023 clk_update.axi_vote.uncompressed_bw = clk_info->uncompressed_bw;
1024 clk_update.axi_vote_valid = true;
1025 dev_intf->hw_ops.process_cmd(dev_intf->hw_priv, id,
1026 &clk_update, sizeof(clk_update));
1027
Pavan Kumar Chilamkurthi6c7bb892018-01-24 12:21:04 -08001028 /*
1029 * Consolidated bw needs to be voted on only one IPE client. Otherwise
1030 * total bw that we vote at bus client would be doubled. So either
1031 * remove voting on IPE1 or divide the vote for each IPE client
1032 * and vote to cpas - cpas will add up and vote full bw to sf client
1033 * anyway.
1034 */
Suresh Vankadara34494fc2017-08-12 18:18:09 +05301035
1036 return 0;
1037}
1038
1039static int cam_icp_mgr_ipe_bps_clk_update(struct cam_icp_hw_mgr *hw_mgr,
1040 struct cam_icp_hw_ctx_data *ctx_data, int idx)
1041{
1042 int rc = 0;
1043
1044 if (cam_icp_check_clk_update(hw_mgr, ctx_data, idx))
1045 rc = cam_icp_update_clk_rate(hw_mgr, ctx_data);
1046
1047 if (cam_icp_check_bw_update(hw_mgr, ctx_data, idx))
1048 rc |= cam_icp_update_cpas_vote(hw_mgr, ctx_data);
1049
1050 return rc;
1051}
1052
Suresh Vankadara6657bc22017-07-31 10:33:04 +05301053static int cam_icp_mgr_ipe_bps_resume(struct cam_icp_hw_mgr *hw_mgr,
1054 struct cam_icp_hw_ctx_data *ctx_data)
1055{
1056 struct cam_hw_intf *ipe0_dev_intf = NULL;
1057 struct cam_hw_intf *ipe1_dev_intf = NULL;
1058 struct cam_hw_intf *bps_dev_intf = NULL;
1059 int rc = 0;
1060
Karthik Anantha Ram9f13d0e2017-11-30 14:55:44 -08001061 ipe0_dev_intf = hw_mgr->ipe0_dev_intf;
1062 ipe1_dev_intf = hw_mgr->ipe1_dev_intf;
1063 bps_dev_intf = hw_mgr->bps_dev_intf;
Suresh Vankadara6657bc22017-07-31 10:33:04 +05301064
1065 if ((!ipe0_dev_intf) || (!bps_dev_intf)) {
1066 CAM_ERR(CAM_ICP, "dev intfs are wrong, failed to close");
1067 return -EINVAL;
1068 }
1069
Suresh Vankadara466bed22017-11-30 06:30:20 +05301070 if (ctx_data->icp_dev_acquire_info->dev_type == CAM_ICP_RES_TYPE_BPS) {
1071 if (hw_mgr->bps_ctxt_cnt++)
1072 goto end;
1073 bps_dev_intf->hw_ops.init(bps_dev_intf->hw_priv, NULL, 0);
Alok Pandey1aef7b52017-12-16 20:42:03 +05301074 if (icp_hw_mgr.ipe_bps_pc_flag) {
Suresh Vankadara466bed22017-11-30 06:30:20 +05301075 bps_dev_intf->hw_ops.process_cmd(
1076 bps_dev_intf->hw_priv,
1077 CAM_ICP_BPS_CMD_POWER_RESUME, NULL, 0);
1078 hw_mgr->core_info = hw_mgr->core_info | ICP_PWR_CLP_BPS;
1079 }
1080 } else {
1081 if (hw_mgr->ipe_ctxt_cnt++)
1082 goto end;
Suresh Vankadara6657bc22017-07-31 10:33:04 +05301083
Suresh Vankadara466bed22017-11-30 06:30:20 +05301084 ipe0_dev_intf->hw_ops.init(ipe0_dev_intf->hw_priv, NULL, 0);
Alok Pandey1aef7b52017-12-16 20:42:03 +05301085 if (icp_hw_mgr.ipe_bps_pc_flag) {
Suresh Vankadara466bed22017-11-30 06:30:20 +05301086 ipe0_dev_intf->hw_ops.process_cmd(
1087 ipe0_dev_intf->hw_priv,
1088 CAM_ICP_IPE_CMD_POWER_RESUME, NULL, 0);
1089 }
Suresh Vankadara6657bc22017-07-31 10:33:04 +05301090
Suresh Vankadara466bed22017-11-30 06:30:20 +05301091 if ((icp_hw_mgr.ipe1_enable) && (ipe1_dev_intf)) {
1092 ipe1_dev_intf->hw_ops.init(ipe1_dev_intf->hw_priv,
1093 NULL, 0);
1094
Alok Pandey1aef7b52017-12-16 20:42:03 +05301095 if (icp_hw_mgr.ipe_bps_pc_flag) {
Suresh Vankadara466bed22017-11-30 06:30:20 +05301096 ipe1_dev_intf->hw_ops.process_cmd(
1097 ipe1_dev_intf->hw_priv,
1098 CAM_ICP_IPE_CMD_POWER_RESUME,
1099 NULL, 0);
1100 }
1101 }
Alok Pandey1aef7b52017-12-16 20:42:03 +05301102 if (icp_hw_mgr.ipe_bps_pc_flag) {
Suresh Vankadara466bed22017-11-30 06:30:20 +05301103 hw_mgr->core_info = hw_mgr->core_info |
1104 (ICP_PWR_CLP_IPE0 | ICP_PWR_CLP_IPE1);
1105 }
Suresh Vankadara6657bc22017-07-31 10:33:04 +05301106 }
1107
Suresh Vankadara466bed22017-11-30 06:30:20 +05301108 CAM_DBG(CAM_ICP, "core_info %X", hw_mgr->core_info);
Alok Pandey1aef7b52017-12-16 20:42:03 +05301109 if (icp_hw_mgr.ipe_bps_pc_flag)
Suresh Vankadara466bed22017-11-30 06:30:20 +05301110 rc = hfi_enable_ipe_bps_pc(true, hw_mgr->core_info);
1111 else
1112 rc = hfi_enable_ipe_bps_pc(false, hw_mgr->core_info);
1113end:
Suresh Vankadara6657bc22017-07-31 10:33:04 +05301114 return rc;
1115}
1116
1117static int cam_icp_mgr_ipe_bps_power_collapse(struct cam_icp_hw_mgr *hw_mgr,
1118 struct cam_icp_hw_ctx_data *ctx_data, int dev_type)
1119{
Suresh Vankadara466bed22017-11-30 06:30:20 +05301120 int rc = 0, dev;
Suresh Vankadara6657bc22017-07-31 10:33:04 +05301121 struct cam_hw_intf *ipe0_dev_intf = NULL;
1122 struct cam_hw_intf *ipe1_dev_intf = NULL;
1123 struct cam_hw_intf *bps_dev_intf = NULL;
1124
Karthik Anantha Ram9f13d0e2017-11-30 14:55:44 -08001125 ipe0_dev_intf = hw_mgr->ipe0_dev_intf;
1126 ipe1_dev_intf = hw_mgr->ipe1_dev_intf;
1127 bps_dev_intf = hw_mgr->bps_dev_intf;
Suresh Vankadara6657bc22017-07-31 10:33:04 +05301128
1129 if ((!ipe0_dev_intf) || (!bps_dev_intf)) {
1130 CAM_ERR(CAM_ICP, "dev intfs are wrong, failed to close");
1131 return -EINVAL;
1132 }
1133
Suresh Vankadara466bed22017-11-30 06:30:20 +05301134 if (!ctx_data)
1135 dev = dev_type;
1136 else
1137 dev = ctx_data->icp_dev_acquire_info->dev_type;
Suresh Vankadara6657bc22017-07-31 10:33:04 +05301138
Suresh Vankadara466bed22017-11-30 06:30:20 +05301139 if (dev == CAM_ICP_RES_TYPE_BPS) {
1140 CAM_DBG(CAM_ICP, "bps ctx cnt %d", hw_mgr->bps_ctxt_cnt);
1141 if (ctx_data)
1142 --hw_mgr->bps_ctxt_cnt;
Suresh Vankadara6657bc22017-07-31 10:33:04 +05301143
Suresh Vankadara466bed22017-11-30 06:30:20 +05301144 if (hw_mgr->bps_ctxt_cnt)
1145 goto end;
1146
Alok Pandey1aef7b52017-12-16 20:42:03 +05301147 if (icp_hw_mgr.ipe_bps_pc_flag) {
Suresh Vankadara466bed22017-11-30 06:30:20 +05301148 rc = bps_dev_intf->hw_ops.process_cmd(
1149 bps_dev_intf->hw_priv,
1150 CAM_ICP_BPS_CMD_POWER_COLLAPSE,
1151 NULL, 0);
1152 hw_mgr->core_info =
1153 hw_mgr->core_info & (~ICP_PWR_CLP_BPS);
1154 }
1155
1156 bps_dev_intf->hw_ops.deinit(bps_dev_intf->hw_priv, NULL, 0);
1157 } else {
1158 CAM_DBG(CAM_ICP, "ipe ctx cnt %d", hw_mgr->ipe_ctxt_cnt);
1159 if (ctx_data)
1160 --hw_mgr->ipe_ctxt_cnt;
1161
1162 if (hw_mgr->ipe_ctxt_cnt)
1163 goto end;
1164
Alok Pandey1aef7b52017-12-16 20:42:03 +05301165 if (icp_hw_mgr.ipe_bps_pc_flag) {
Suresh Vankadara466bed22017-11-30 06:30:20 +05301166 rc = ipe0_dev_intf->hw_ops.process_cmd(
1167 ipe0_dev_intf->hw_priv,
1168 CAM_ICP_IPE_CMD_POWER_COLLAPSE, NULL, 0);
1169
1170 }
1171 ipe0_dev_intf->hw_ops.deinit(ipe0_dev_intf->hw_priv, NULL, 0);
1172
1173 if (ipe1_dev_intf) {
Alok Pandey1aef7b52017-12-16 20:42:03 +05301174 if (icp_hw_mgr.ipe_bps_pc_flag) {
Suresh Vankadara466bed22017-11-30 06:30:20 +05301175 rc = ipe1_dev_intf->hw_ops.process_cmd(
1176 ipe1_dev_intf->hw_priv,
1177 CAM_ICP_IPE_CMD_POWER_COLLAPSE,
1178 NULL, 0);
1179 }
1180
1181 ipe1_dev_intf->hw_ops.deinit(ipe1_dev_intf->hw_priv,
1182 NULL, 0);
1183 }
Alok Pandey1aef7b52017-12-16 20:42:03 +05301184 if (icp_hw_mgr.ipe_bps_pc_flag) {
Suresh Vankadara466bed22017-11-30 06:30:20 +05301185 hw_mgr->core_info = hw_mgr->core_info &
1186 (~(ICP_PWR_CLP_IPE0 | ICP_PWR_CLP_IPE1));
1187 }
Suresh Vankadara6657bc22017-07-31 10:33:04 +05301188 }
1189
Suresh Vankadara466bed22017-11-30 06:30:20 +05301190 CAM_DBG(CAM_ICP, "Exit: core_info = %x", hw_mgr->core_info);
1191end:
Suresh Vankadara6657bc22017-07-31 10:33:04 +05301192 return rc;
1193}
1194
Suresh Vankadara34494fc2017-08-12 18:18:09 +05301195static int cam_icp_set_dbg_default_clk(void *data, u64 val)
1196{
1197 icp_hw_mgr.icp_debug_clk = val;
1198 return 0;
1199}
1200
1201static int cam_icp_get_dbg_default_clk(void *data, u64 *val)
1202{
1203 *val = icp_hw_mgr.icp_debug_clk;
1204 return 0;
1205}
1206
1207DEFINE_SIMPLE_ATTRIBUTE(cam_icp_debug_default_clk,
1208 cam_icp_get_dbg_default_clk,
1209 cam_icp_set_dbg_default_clk, "%16llu");
1210
Lakshmi Narayana Kalavaladac0b6c2017-09-13 15:33:42 -07001211static int cam_icp_set_a5_dbg_lvl(void *data, u64 val)
1212{
1213 icp_hw_mgr.a5_dbg_lvl = val;
1214 return 0;
1215}
1216
1217static int cam_icp_get_a5_dbg_lvl(void *data, u64 *val)
1218{
1219 *val = icp_hw_mgr.a5_dbg_lvl;
1220 return 0;
1221}
1222
1223DEFINE_SIMPLE_ATTRIBUTE(cam_icp_debug_fs, cam_icp_get_a5_dbg_lvl,
1224 cam_icp_set_a5_dbg_lvl, "%08llu");
1225
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07001226static int cam_icp_hw_mgr_create_debugfs_entry(void)
1227{
Suresh Vankadara34494fc2017-08-12 18:18:09 +05301228 int rc = 0;
1229
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07001230 icp_hw_mgr.dentry = debugfs_create_dir("camera_icp", NULL);
1231 if (!icp_hw_mgr.dentry)
1232 return -ENOMEM;
1233
Suresh Vankadara6657bc22017-07-31 10:33:04 +05301234 if (!debugfs_create_bool("icp_pc",
1235 0644,
1236 icp_hw_mgr.dentry,
1237 &icp_hw_mgr.icp_pc_flag)) {
1238 CAM_ERR(CAM_ICP, "failed to create icp_pc entry");
Suresh Vankadara34494fc2017-08-12 18:18:09 +05301239 rc = -ENOMEM;
1240 goto err;
Suresh Vankadara6657bc22017-07-31 10:33:04 +05301241 }
Alok Pandey1aef7b52017-12-16 20:42:03 +05301242 icp_hw_mgr.icp_pc_flag = false;
1243
1244 if (!debugfs_create_bool("ipe_bps_pc",
1245 0644,
1246 icp_hw_mgr.dentry,
1247 &icp_hw_mgr.ipe_bps_pc_flag)) {
1248 CAM_ERR(CAM_ICP, "failed to create ipe_bps_pc entry");
1249 rc = -ENOMEM;
1250 goto err;
1251 }
1252
1253 icp_hw_mgr.ipe_bps_pc_flag = false;
Suresh Vankadara6657bc22017-07-31 10:33:04 +05301254
Suresh Vankadara34494fc2017-08-12 18:18:09 +05301255 if (!debugfs_create_file("icp_debug_clk",
1256 0644,
1257 icp_hw_mgr.dentry, NULL,
1258 &cam_icp_debug_default_clk)) {
1259 CAM_ERR(CAM_ICP, "failed to create icp_debug_clk entry");
1260 rc = -ENOMEM;
1261 goto err;
1262 }
1263
Lakshmi Narayana Kalavaladac0b6c2017-09-13 15:33:42 -07001264 if (!debugfs_create_bool("a5_jtag_debug",
1265 0644,
1266 icp_hw_mgr.dentry,
1267 &icp_hw_mgr.a5_jtag_debug)) {
1268 rc = -ENOMEM;
1269 goto err;
1270 }
1271
1272 if (!debugfs_create_bool("a5_debug_q",
1273 0644,
1274 icp_hw_mgr.dentry,
1275 &icp_hw_mgr.a5_debug_q)) {
1276 CAM_ERR(CAM_ICP, "failed to create a5_debug_q\n");
1277 rc = -ENOMEM;
1278 goto err;
1279 }
1280
1281 if (!debugfs_create_file("a5_debug_lvl",
1282 0644,
1283 icp_hw_mgr.dentry,
1284 NULL, &cam_icp_debug_fs)) {
1285 CAM_ERR(CAM_ICP, "failed to create a5_dbg_lvl\n");
1286 rc = -ENOMEM;
1287 goto err;
1288 }
1289
Suresh Vankadara34494fc2017-08-12 18:18:09 +05301290 return rc;
1291err:
1292 debugfs_remove_recursive(icp_hw_mgr.dentry);
1293 return rc;
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07001294}
1295
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001296static int cam_icp_mgr_process_cmd(void *priv, void *data)
1297{
1298 int rc;
1299 struct hfi_cmd_work_data *task_data = NULL;
1300 struct cam_icp_hw_mgr *hw_mgr;
1301
1302 if (!data || !priv) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001303 CAM_ERR(CAM_ICP, "Invalid params%pK %pK", data, priv);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001304 return -EINVAL;
1305 }
1306
1307 hw_mgr = priv;
1308 task_data = (struct hfi_cmd_work_data *)data;
1309
1310 rc = hfi_write_cmd(task_data->data);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301311
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001312 return rc;
1313}
1314
Suresh Vankadara502c2882017-11-17 02:25:49 +05301315static int cam_icp_mgr_cleanup_ctx(struct cam_icp_hw_ctx_data *ctx_data)
1316{
1317 int i;
1318 struct hfi_frame_process_info *hfi_frame_process;
1319 struct cam_hw_done_event_data buf_data;
1320
1321 hfi_frame_process = &ctx_data->hfi_frame_process;
1322 for (i = 0; i < CAM_FRAME_CMD_MAX; i++) {
1323 if (!hfi_frame_process->request_id[i])
1324 continue;
1325 buf_data.request_id = hfi_frame_process->request_id[i];
1326 ctx_data->ctxt_event_cb(ctx_data->context_priv,
1327 false, &buf_data);
1328 hfi_frame_process->request_id[i] = 0;
1329 if (ctx_data->hfi_frame_process.in_resource[i] > 0) {
1330 CAM_DBG(CAM_ICP, "Delete merged sync in object: %d",
1331 ctx_data->hfi_frame_process.in_resource[i]);
1332 cam_sync_destroy(
1333 ctx_data->hfi_frame_process.in_resource[i]);
1334 ctx_data->hfi_frame_process.in_resource[i] = 0;
1335 }
1336 hfi_frame_process->fw_process_flag[i] = false;
1337 clear_bit(i, ctx_data->hfi_frame_process.bitmap);
1338 }
1339
Junzhe Zou4b11e7a2017-11-13 17:21:32 -08001340 for (i = 0; i < CAM_FRAME_CMD_MAX; i++) {
1341 if (!hfi_frame_process->in_free_resource[i])
1342 continue;
1343
1344 CAM_INFO(CAM_ICP, "Delete merged sync in object: %d",
1345 ctx_data->hfi_frame_process.in_free_resource[i]);
1346 cam_sync_destroy(
1347 ctx_data->hfi_frame_process.in_free_resource[i]);
1348 ctx_data->hfi_frame_process.in_resource[i] = 0;
1349 }
1350
Suresh Vankadara502c2882017-11-17 02:25:49 +05301351 return 0;
1352}
1353
Suresh Vankadara22697d32017-07-03 12:14:09 -07001354static int cam_icp_mgr_handle_frame_process(uint32_t *msg_ptr, int flag)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001355{
1356 int i;
1357 uint32_t idx;
Sagar Gorecdd6a5e2017-05-17 19:06:59 -07001358 uint64_t request_id;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001359 struct cam_icp_hw_ctx_data *ctx_data = NULL;
1360 struct hfi_msg_ipebps_async_ack *ioconfig_ack = NULL;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001361 struct hfi_frame_process_info *hfi_frame_process;
Sagar Gorecdd6a5e2017-05-17 19:06:59 -07001362 struct cam_hw_done_event_data buf_data;
Junzhe Zoubc37c562017-11-20 18:23:49 -08001363 uint32_t clk_type;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001364
1365 ioconfig_ack = (struct hfi_msg_ipebps_async_ack *)msg_ptr;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001366 request_id = ioconfig_ack->user_data2;
Suresh Vankadara22697d32017-07-03 12:14:09 -07001367 ctx_data = (struct cam_icp_hw_ctx_data *)ioconfig_ack->user_data1;
1368 if (!ctx_data) {
1369 CAM_ERR(CAM_ICP, "Invalid Context");
1370 return -EINVAL;
1371 }
1372 CAM_DBG(CAM_ICP, "ctx : %pK, request_id :%lld",
1373 (void *)ctx_data->context_priv, request_id);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001374
Junzhe Zoubc37c562017-11-20 18:23:49 -08001375 clk_type = ICP_DEV_TYPE_TO_CLK_TYPE(ctx_data->icp_dev_acquire_info->
1376 dev_type);
Suresh Vankadarac092e592018-01-11 18:52:41 +05301377 cam_icp_device_timer_reset(&icp_hw_mgr, clk_type);
Junzhe Zoubc37c562017-11-20 18:23:49 -08001378
Suresh Vankadara22697d32017-07-03 12:14:09 -07001379 mutex_lock(&ctx_data->ctx_mutex);
Suresh Vankadarac092e592018-01-11 18:52:41 +05301380 cam_icp_ctx_timer_reset(ctx_data);
Suresh Vankadarac7b0c672017-11-25 00:44:10 +05301381 if (ctx_data->state != CAM_ICP_CTX_STATE_ACQUIRED) {
Karthik Anantha Ram599c4e152017-12-14 15:03:48 -08001382 CAM_DBG(CAM_ICP, "ctx %u is in %d state",
1383 ctx_data->ctx_id, ctx_data->state);
Suresh Vankadara502c2882017-11-17 02:25:49 +05301384 mutex_unlock(&ctx_data->ctx_mutex);
1385 return 0;
1386 }
1387
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001388 hfi_frame_process = &ctx_data->hfi_frame_process;
1389 for (i = 0; i < CAM_FRAME_CMD_MAX; i++)
1390 if (hfi_frame_process->request_id[i] == request_id)
1391 break;
1392
1393 if (i >= CAM_FRAME_CMD_MAX) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001394 CAM_ERR(CAM_ICP, "pkt not found in ctx data for req_id =%lld",
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001395 request_id);
Suresh Vankadara22697d32017-07-03 12:14:09 -07001396 mutex_unlock(&ctx_data->ctx_mutex);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001397 return -EINVAL;
1398 }
1399 idx = i;
1400
Sagar Gorecdd6a5e2017-05-17 19:06:59 -07001401 buf_data.request_id = hfi_frame_process->request_id[idx];
Suresh Vankadara22697d32017-07-03 12:14:09 -07001402 ctx_data->ctxt_event_cb(ctx_data->context_priv, flag, &buf_data);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001403 hfi_frame_process->request_id[idx] = 0;
Suresh Vankadaraad2d3a92017-09-25 12:18:11 +05301404 if (ctx_data->hfi_frame_process.in_resource[idx] > 0) {
1405 CAM_DBG(CAM_ICP, "Delete merged sync in object: %d",
1406 ctx_data->hfi_frame_process.in_resource[idx]);
1407 cam_sync_destroy(ctx_data->hfi_frame_process.in_resource[idx]);
1408 ctx_data->hfi_frame_process.in_resource[idx] = 0;
1409 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001410 clear_bit(idx, ctx_data->hfi_frame_process.bitmap);
Suresh Vankadara34494fc2017-08-12 18:18:09 +05301411 hfi_frame_process->fw_process_flag[idx] = false;
Suresh Vankadara22697d32017-07-03 12:14:09 -07001412 mutex_unlock(&ctx_data->ctx_mutex);
1413
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001414 return 0;
1415}
1416
Suresh Vankadara22697d32017-07-03 12:14:09 -07001417static int cam_icp_mgr_process_msg_frame_process(uint32_t *msg_ptr)
1418{
1419 struct hfi_msg_ipebps_async_ack *ioconfig_ack = NULL;
1420 struct hfi_msg_frame_process_done *frame_done;
1421
1422 if (!msg_ptr) {
1423 CAM_ERR(CAM_ICP, "msg ptr is NULL");
1424 return -EINVAL;
1425 }
1426
1427 ioconfig_ack = (struct hfi_msg_ipebps_async_ack *)msg_ptr;
1428 if (ioconfig_ack->err_type != HFI_ERR_SYS_NONE) {
1429 CAM_ERR(CAM_ICP, "failed with error : %u",
Suresh Vankadara34494fc2017-08-12 18:18:09 +05301430 ioconfig_ack->err_type);
Suresh Vankadara22697d32017-07-03 12:14:09 -07001431 cam_icp_mgr_handle_frame_process(msg_ptr,
1432 ICP_FRAME_PROCESS_FAILURE);
1433 return -EIO;
1434 }
1435
1436 frame_done =
1437 (struct hfi_msg_frame_process_done *)ioconfig_ack->msg_data;
1438 if (!frame_done) {
1439 cam_icp_mgr_handle_frame_process(msg_ptr,
1440 ICP_FRAME_PROCESS_FAILURE);
1441 return -EINVAL;
1442 }
1443
1444 if (frame_done->result)
1445 return cam_icp_mgr_handle_frame_process(msg_ptr,
1446 ICP_FRAME_PROCESS_FAILURE);
1447 else
1448 return cam_icp_mgr_handle_frame_process(msg_ptr,
1449 ICP_FRAME_PROCESS_SUCCESS);
1450}
1451
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001452static int cam_icp_mgr_process_msg_config_io(uint32_t *msg_ptr)
1453{
1454 struct cam_icp_hw_ctx_data *ctx_data = NULL;
1455 struct hfi_msg_ipebps_async_ack *ioconfig_ack = NULL;
1456 struct hfi_msg_ipe_config *ipe_config_ack = NULL;
1457 struct hfi_msg_bps_common *bps_config_ack = NULL;
1458
Suresh Vankadara22697d32017-07-03 12:14:09 -07001459 if (!msg_ptr) {
1460 CAM_ERR(CAM_ICP, "msg ptr is NULL");
1461 return -EINVAL;
1462 }
1463
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001464 ioconfig_ack = (struct hfi_msg_ipebps_async_ack *)msg_ptr;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001465
1466 if (ioconfig_ack->opcode == HFI_IPEBPS_CMD_OPCODE_IPE_CONFIG_IO) {
1467 ipe_config_ack =
1468 (struct hfi_msg_ipe_config *)(ioconfig_ack->msg_data);
1469 if (ipe_config_ack->rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001470 CAM_ERR(CAM_ICP, "rc = %d err = %u",
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001471 ipe_config_ack->rc, ioconfig_ack->err_type);
1472 return -EIO;
1473 }
1474 ctx_data =
1475 (struct cam_icp_hw_ctx_data *)ioconfig_ack->user_data1;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05301476 if (!ctx_data) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001477 CAM_ERR(CAM_ICP, "wrong ctx data from IPE response");
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05301478 return -EINVAL;
1479 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001480 ctx_data->scratch_mem_size = ipe_config_ack->scratch_mem_size;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001481 } else {
1482 bps_config_ack =
1483 (struct hfi_msg_bps_common *)(ioconfig_ack->msg_data);
1484 if (bps_config_ack->rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001485 CAM_ERR(CAM_ICP, "rc : %u, opcode :%u",
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001486 bps_config_ack->rc, ioconfig_ack->opcode);
1487 return -EIO;
1488 }
1489 ctx_data =
1490 (struct cam_icp_hw_ctx_data *)ioconfig_ack->user_data1;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05301491 if (!ctx_data) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001492 CAM_ERR(CAM_ICP, "wrong ctx data from BPS response");
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05301493 return -EINVAL;
1494 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001495 }
1496 complete(&ctx_data->wait_complete);
1497
1498 return 0;
1499}
1500
1501static int cam_icp_mgr_process_msg_create_handle(uint32_t *msg_ptr)
1502{
1503 struct hfi_msg_create_handle_ack *create_handle_ack = NULL;
1504 struct cam_icp_hw_ctx_data *ctx_data = NULL;
1505
1506 create_handle_ack = (struct hfi_msg_create_handle_ack *)msg_ptr;
1507 if (!create_handle_ack) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001508 CAM_ERR(CAM_ICP, "Invalid create_handle_ack");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001509 return -EINVAL;
1510 }
1511
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001512 ctx_data = (struct cam_icp_hw_ctx_data *)create_handle_ack->user_data1;
1513 if (!ctx_data) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001514 CAM_ERR(CAM_ICP, "Invalid ctx_data");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001515 return -EINVAL;
1516 }
1517
Suresh Vankadarac7b0c672017-11-25 00:44:10 +05301518 if (ctx_data->state == CAM_ICP_CTX_STATE_IN_USE) {
Suresh Vankadara502c2882017-11-17 02:25:49 +05301519 ctx_data->fw_handle = create_handle_ack->fw_handle;
1520 CAM_DBG(CAM_ICP, "fw_handle = %x", ctx_data->fw_handle);
1521 complete(&ctx_data->wait_complete);
Suresh Vankadarac7b0c672017-11-25 00:44:10 +05301522 } else
1523 CAM_WARN(CAM_ICP, "Timeout failed to create fw handle");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001524
1525 return 0;
1526}
1527
1528static int cam_icp_mgr_process_msg_ping_ack(uint32_t *msg_ptr)
1529{
1530 struct hfi_msg_ping_ack *ping_ack = NULL;
1531 struct cam_icp_hw_ctx_data *ctx_data = NULL;
1532
1533 ping_ack = (struct hfi_msg_ping_ack *)msg_ptr;
1534 if (!ping_ack) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001535 CAM_ERR(CAM_ICP, "Empty ping ack message");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001536 return -EINVAL;
1537 }
1538
1539 ctx_data = (struct cam_icp_hw_ctx_data *)ping_ack->user_data;
1540 if (!ctx_data) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001541 CAM_ERR(CAM_ICP, "Invalid ctx_data");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001542 return -EINVAL;
1543 }
1544
Suresh Vankadarac7b0c672017-11-25 00:44:10 +05301545 if (ctx_data->state == CAM_ICP_CTX_STATE_IN_USE)
Suresh Vankadara502c2882017-11-17 02:25:49 +05301546 complete(&ctx_data->wait_complete);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001547
1548 return 0;
1549}
1550
1551static int cam_icp_mgr_process_indirect_ack_msg(uint32_t *msg_ptr)
1552{
1553 int rc;
1554
Suresh Vankadara22697d32017-07-03 12:14:09 -07001555 if (!msg_ptr) {
1556 CAM_ERR(CAM_ICP, "msg ptr is NULL");
1557 return -EINVAL;
1558 }
1559
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05301560 switch (msg_ptr[ICP_PACKET_OPCODE]) {
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001561 case HFI_IPEBPS_CMD_OPCODE_IPE_CONFIG_IO:
1562 case HFI_IPEBPS_CMD_OPCODE_BPS_CONFIG_IO:
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001563 CAM_DBG(CAM_ICP, "received IPE/BPS_CONFIG_IO:");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001564 rc = cam_icp_mgr_process_msg_config_io(msg_ptr);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301565 if (rc)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001566 return rc;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001567 break;
1568
1569 case HFI_IPEBPS_CMD_OPCODE_IPE_FRAME_PROCESS:
1570 case HFI_IPEBPS_CMD_OPCODE_BPS_FRAME_PROCESS:
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001571 rc = cam_icp_mgr_process_msg_frame_process(msg_ptr);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301572 if (rc)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001573 return rc;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001574 break;
1575 default:
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001576 CAM_ERR(CAM_ICP, "Invalid opcode : %u",
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05301577 msg_ptr[ICP_PACKET_OPCODE]);
Suresh Vankadara22697d32017-07-03 12:14:09 -07001578 rc = -EINVAL;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001579 break;
1580 }
1581
Suresh Vankadara22697d32017-07-03 12:14:09 -07001582 return rc;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001583}
1584
1585static int cam_icp_mgr_process_direct_ack_msg(uint32_t *msg_ptr)
1586{
1587 struct cam_icp_hw_ctx_data *ctx_data = NULL;
1588 struct hfi_msg_ipebps_async_ack *ioconfig_ack = NULL;
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05301589 int rc = 0;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001590
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05301591 switch (msg_ptr[ICP_PACKET_OPCODE]) {
Abhijit Trivedi36ea6a12018-01-15 18:48:15 -08001592 case HFI_IPEBPS_CMD_OPCODE_IPE_DESTROY:
1593 case HFI_IPEBPS_CMD_OPCODE_BPS_DESTROY:
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05301594 case HFI_IPEBPS_CMD_OPCODE_IPE_ABORT:
1595 case HFI_IPEBPS_CMD_OPCODE_BPS_ABORT:
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001596 CAM_DBG(CAM_ICP, "received IPE/BPS_DESTROY/ABORT:");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001597 ioconfig_ack = (struct hfi_msg_ipebps_async_ack *)msg_ptr;
1598 ctx_data =
1599 (struct cam_icp_hw_ctx_data *)ioconfig_ack->user_data1;
Vishalsingh Hajerieeeb1c32018-01-16 15:04:00 -08001600 if (ctx_data->state != CAM_ICP_CTX_STATE_FREE)
Suresh Vankadara502c2882017-11-17 02:25:49 +05301601 complete(&ctx_data->wait_complete);
1602
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05301603 break;
1604 default:
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001605 CAM_ERR(CAM_ICP, "Invalid opcode : %u",
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05301606 msg_ptr[ICP_PACKET_OPCODE]);
1607 rc = -EINVAL;
1608 break;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001609 }
1610
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05301611 return rc;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001612}
1613
Lakshmi Narayana Kalavaladac0b6c2017-09-13 15:33:42 -07001614static void cam_icp_mgr_process_dbg_buf(void)
1615{
1616 uint32_t *msg_ptr = NULL, *pkt_ptr = NULL;
1617 struct hfi_msg_debug *dbg_msg;
Karthik Anantha Ramad347282017-11-01 13:09:17 -07001618 uint32_t read_len, size_processed = 0;
Lakshmi Narayana Kalavaladac0b6c2017-09-13 15:33:42 -07001619 char *dbg_buf;
Karthik Anantha Ramad347282017-11-01 13:09:17 -07001620 int rc = 0;
Lakshmi Narayana Kalavaladac0b6c2017-09-13 15:33:42 -07001621
Karthik Anantha Ramad347282017-11-01 13:09:17 -07001622 rc = hfi_read_message(icp_hw_mgr.dbg_buf, Q_DBG, &read_len);
1623 if (rc)
Lakshmi Narayana Kalavaladac0b6c2017-09-13 15:33:42 -07001624 return;
1625
1626 msg_ptr = (uint32_t *)icp_hw_mgr.dbg_buf;
1627 while (true) {
1628 pkt_ptr = msg_ptr;
1629 if (pkt_ptr[ICP_PACKET_TYPE] == HFI_MSG_SYS_DEBUG) {
1630 dbg_msg = (struct hfi_msg_debug *)pkt_ptr;
1631 dbg_buf = (char *)&dbg_msg->msg_data;
1632 trace_cam_icp_fw_dbg(dbg_buf);
1633 }
1634 size_processed += (pkt_ptr[ICP_PACKET_SIZE] >>
1635 BYTE_WORD_SHIFT);
1636 if (size_processed >= read_len)
1637 return;
1638 msg_ptr += (pkt_ptr[ICP_PACKET_SIZE] >>
1639 BYTE_WORD_SHIFT);
1640 pkt_ptr = NULL;
1641 dbg_msg = NULL;
1642 dbg_buf = NULL;
1643 }
1644}
1645
1646static int cam_icp_process_msg_pkt_type(
1647 struct cam_icp_hw_mgr *hw_mgr,
Karthik Anantha Ramad347282017-11-01 13:09:17 -07001648 uint32_t *msg_ptr,
1649 uint32_t *msg_processed_len)
Lakshmi Narayana Kalavaladac0b6c2017-09-13 15:33:42 -07001650{
1651 int rc = 0;
1652 int size_processed = 0;
Lakshmi Narayana Kalavaladac0b6c2017-09-13 15:33:42 -07001653
1654 switch (msg_ptr[ICP_PACKET_TYPE]) {
1655 case HFI_MSG_SYS_INIT_DONE:
1656 CAM_DBG(CAM_ICP, "received SYS_INIT_DONE");
1657 complete(&hw_mgr->a5_complete);
Karthik Anantha Ram78af8402017-12-04 13:16:26 -08001658 size_processed = (
1659 (struct hfi_msg_init_done *)msg_ptr)->size;
Lakshmi Narayana Kalavaladac0b6c2017-09-13 15:33:42 -07001660 break;
1661
Suresh Vankadara466bed22017-11-30 06:30:20 +05301662 case HFI_MSG_SYS_PC_PREP_DONE:
1663 CAM_DBG(CAM_ICP, "HFI_MSG_SYS_PC_PREP_DONE is received\n");
1664 complete(&hw_mgr->a5_complete);
1665 size_processed = sizeof(struct hfi_msg_pc_prep_done);
1666 break;
1667
Lakshmi Narayana Kalavaladac0b6c2017-09-13 15:33:42 -07001668 case HFI_MSG_SYS_PING_ACK:
1669 CAM_DBG(CAM_ICP, "received SYS_PING_ACK");
1670 rc = cam_icp_mgr_process_msg_ping_ack(msg_ptr);
1671 size_processed = sizeof(struct hfi_msg_ping_ack);
1672 break;
1673
1674 case HFI_MSG_IPEBPS_CREATE_HANDLE_ACK:
1675 CAM_DBG(CAM_ICP, "received IPEBPS_CREATE_HANDLE_ACK");
1676 rc = cam_icp_mgr_process_msg_create_handle(msg_ptr);
1677 size_processed = sizeof(struct hfi_msg_create_handle_ack);
1678 break;
1679
1680 case HFI_MSG_IPEBPS_ASYNC_COMMAND_INDIRECT_ACK:
1681 CAM_DBG(CAM_ICP, "received ASYNC_INDIRECT_ACK");
1682 rc = cam_icp_mgr_process_indirect_ack_msg(msg_ptr);
Karthik Anantha Ram78af8402017-12-04 13:16:26 -08001683 size_processed = (
1684 (struct hfi_msg_ipebps_async_ack *)msg_ptr)->size;
Lakshmi Narayana Kalavaladac0b6c2017-09-13 15:33:42 -07001685 break;
1686
1687 case HFI_MSG_IPEBPS_ASYNC_COMMAND_DIRECT_ACK:
1688 CAM_DBG(CAM_ICP, "received ASYNC_DIRECT_ACK");
1689 rc = cam_icp_mgr_process_direct_ack_msg(msg_ptr);
Karthik Anantha Ram78af8402017-12-04 13:16:26 -08001690 size_processed = (
1691 (struct hfi_msg_ipebps_async_ack *)msg_ptr)->size;
Lakshmi Narayana Kalavaladac0b6c2017-09-13 15:33:42 -07001692 break;
1693
1694 case HFI_MSG_EVENT_NOTIFY:
1695 CAM_DBG(CAM_ICP, "received EVENT_NOTIFY");
Karthik Anantha Ram78af8402017-12-04 13:16:26 -08001696 size_processed = (
1697 (struct hfi_msg_event_notify *)msg_ptr)->size;
Lakshmi Narayana Kalavaladac0b6c2017-09-13 15:33:42 -07001698 break;
1699
1700 default:
1701 CAM_ERR(CAM_ICP, "invalid msg : %u",
1702 msg_ptr[ICP_PACKET_TYPE]);
1703 rc = -EINVAL;
1704 break;
1705 }
1706
Karthik Anantha Ramad347282017-11-01 13:09:17 -07001707 *msg_processed_len = size_processed;
1708 return rc;
Lakshmi Narayana Kalavaladac0b6c2017-09-13 15:33:42 -07001709}
1710
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001711static int32_t cam_icp_mgr_process_msg(void *priv, void *data)
1712{
Karthik Anantha Ramad347282017-11-01 13:09:17 -07001713 uint32_t read_len, msg_processed_len;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001714 uint32_t *msg_ptr = NULL;
1715 struct hfi_msg_work_data *task_data;
1716 struct cam_icp_hw_mgr *hw_mgr;
Karthik Anantha Ramad347282017-11-01 13:09:17 -07001717 int rc = 0;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001718
1719 if (!data || !priv) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001720 CAM_ERR(CAM_ICP, "Invalid data");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001721 return -EINVAL;
1722 }
1723
1724 task_data = data;
1725 hw_mgr = priv;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001726
Karthik Anantha Ramad347282017-11-01 13:09:17 -07001727 rc = hfi_read_message(icp_hw_mgr.msg_buf, Q_MSG, &read_len);
1728 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001729 CAM_DBG(CAM_ICP, "Unable to read msg q");
Lakshmi Narayana Kalavaladac0b6c2017-09-13 15:33:42 -07001730 } else {
Karthik Anantha Ramb0ab3dd2017-10-31 21:11:27 -07001731 read_len = read_len << BYTE_WORD_SHIFT;
Lakshmi Narayana Kalavaladac0b6c2017-09-13 15:33:42 -07001732 msg_ptr = (uint32_t *)icp_hw_mgr.msg_buf;
1733 while (true) {
Karthik Anantha Ramad347282017-11-01 13:09:17 -07001734 rc = cam_icp_process_msg_pkt_type(hw_mgr, msg_ptr,
1735 &msg_processed_len);
1736 if (rc)
Lakshmi Narayana Kalavaladac0b6c2017-09-13 15:33:42 -07001737 return rc;
Lakshmi Narayana Kalavaladac0b6c2017-09-13 15:33:42 -07001738
1739 read_len -= msg_processed_len;
Karthik Anantha Ramad347282017-11-01 13:09:17 -07001740 if (read_len > 0) {
Karthik Anantha Ramb0ab3dd2017-10-31 21:11:27 -07001741 msg_ptr += (msg_processed_len >>
1742 BYTE_WORD_SHIFT);
Karthik Anantha Ramad347282017-11-01 13:09:17 -07001743 msg_processed_len = 0;
1744 }
Lakshmi Narayana Kalavaladac0b6c2017-09-13 15:33:42 -07001745 else
1746 break;
1747 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001748 }
1749
Lakshmi Narayana Kalavaladac0b6c2017-09-13 15:33:42 -07001750 if (icp_hw_mgr.a5_debug_q)
1751 cam_icp_mgr_process_dbg_buf();
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001752
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001753 return rc;
1754}
1755
1756int32_t cam_icp_hw_mgr_cb(uint32_t irq_status, void *data)
1757{
1758 int32_t rc = 0;
1759 unsigned long flags;
1760 struct cam_icp_hw_mgr *hw_mgr = data;
1761 struct crm_workq_task *task;
1762 struct hfi_msg_work_data *task_data;
1763
1764 spin_lock_irqsave(&hw_mgr->hw_mgr_lock, flags);
1765 task = cam_req_mgr_workq_get_task(icp_hw_mgr.msg_work);
1766 if (!task) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001767 CAM_ERR(CAM_ICP, "no empty task");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001768 spin_unlock_irqrestore(&hw_mgr->hw_mgr_lock, flags);
1769 return -ENOMEM;
1770 }
1771
1772 task_data = (struct hfi_msg_work_data *)task->payload;
1773 task_data->data = hw_mgr;
1774 task_data->irq_status = irq_status;
1775 task_data->type = ICP_WORKQ_TASK_MSG_TYPE;
1776 task->process_cb = cam_icp_mgr_process_msg;
1777 rc = cam_req_mgr_workq_enqueue_task(task, &icp_hw_mgr,
1778 CRM_TASK_PRIORITY_0);
1779 spin_unlock_irqrestore(&hw_mgr->hw_mgr_lock, flags);
1780
1781 return rc;
1782}
1783
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -07001784static void cam_icp_free_hfi_mem(void)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001785{
Seemanta Dutta93f940c2017-10-13 14:34:18 -07001786 int rc;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001787 cam_smmu_dealloc_firmware(icp_hw_mgr.iommu_hdl);
Suresh Vankadara466bed22017-11-30 06:30:20 +05301788 rc = cam_mem_mgr_free_memory_region(&icp_hw_mgr.hfi_mem.sec_heap);
1789 if (rc)
1790 CAM_ERR(CAM_ICP, "failed to unreserve sec heap");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001791 cam_mem_mgr_release_mem(&icp_hw_mgr.hfi_mem.qtbl);
1792 cam_mem_mgr_release_mem(&icp_hw_mgr.hfi_mem.cmd_q);
1793 cam_mem_mgr_release_mem(&icp_hw_mgr.hfi_mem.msg_q);
1794 cam_mem_mgr_release_mem(&icp_hw_mgr.hfi_mem.dbg_q);
Seemanta Dutta93f940c2017-10-13 14:34:18 -07001795}
1796
1797static int cam_icp_alloc_secheap_mem(struct cam_mem_mgr_memory_desc *secheap)
1798{
1799 int rc;
1800 struct cam_mem_mgr_request_desc alloc;
1801 struct cam_mem_mgr_memory_desc out;
1802 struct cam_smmu_region_info secheap_info;
1803
1804 memset(&alloc, 0, sizeof(alloc));
1805 memset(&out, 0, sizeof(out));
1806
1807 rc = cam_smmu_get_region_info(icp_hw_mgr.iommu_hdl,
1808 CAM_SMMU_REGION_SECHEAP,
1809 &secheap_info);
1810 if (rc) {
1811 CAM_ERR(CAM_ICP, "Unable to get secheap memory info");
1812 return rc;
1813 }
1814
1815 alloc.size = secheap_info.iova_len;
1816 alloc.align = 0;
1817 alloc.flags = 0;
1818 alloc.smmu_hdl = icp_hw_mgr.iommu_hdl;
1819 rc = cam_mem_mgr_reserve_memory_region(&alloc,
1820 CAM_SMMU_REGION_SECHEAP,
1821 &out);
1822 if (rc) {
1823 CAM_ERR(CAM_ICP, "Unable to reserve secheap memory");
1824 return rc;
1825 }
1826
1827 *secheap = out;
1828 CAM_DBG(CAM_ICP, "kva: %llX, iova: %x, hdl: %x, len: %lld",
1829 out.kva, out.iova, out.mem_handle, out.len);
1830
1831 return rc;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001832}
1833
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301834static int cam_icp_alloc_shared_mem(struct cam_mem_mgr_memory_desc *qtbl)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001835{
1836 int rc;
1837 struct cam_mem_mgr_request_desc alloc;
1838 struct cam_mem_mgr_memory_desc out;
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301839
1840 memset(&alloc, 0, sizeof(alloc));
1841 memset(&out, 0, sizeof(out));
1842 alloc.size = SZ_1M;
1843 alloc.align = 0;
Seemanta Duttaa037cd12017-07-06 15:45:29 -07001844 alloc.flags = CAM_MEM_FLAG_HW_READ_WRITE |
1845 CAM_MEM_FLAG_HW_SHARED_ACCESS;
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301846 alloc.smmu_hdl = icp_hw_mgr.iommu_hdl;
1847 rc = cam_mem_mgr_request_mem(&alloc, &out);
1848 if (rc)
1849 return rc;
1850
1851 *qtbl = out;
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001852 CAM_DBG(CAM_ICP, "kva: %llX, iova: %x, hdl: %x, len: %lld",
1853 out.kva, out.iova, out.mem_handle, out.len);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301854
1855 return rc;
1856}
1857
1858static int cam_icp_allocate_fw_mem(void)
1859{
1860 int rc;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001861 uint64_t kvaddr;
1862 size_t len;
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301863 dma_addr_t iova;
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07001864
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001865 rc = cam_smmu_alloc_firmware(icp_hw_mgr.iommu_hdl,
1866 &iova, &kvaddr, &len);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301867 if (rc)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001868 return -ENOMEM;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001869
1870 icp_hw_mgr.hfi_mem.fw_buf.len = len;
1871 icp_hw_mgr.hfi_mem.fw_buf.kva = kvaddr;
1872 icp_hw_mgr.hfi_mem.fw_buf.iova = iova;
1873 icp_hw_mgr.hfi_mem.fw_buf.smmu_hdl = icp_hw_mgr.iommu_hdl;
1874
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001875 CAM_DBG(CAM_ICP, "kva: %llX, iova: %llx, len: %zu",
1876 kvaddr, iova, len);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001877
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301878 return rc;
1879}
1880
1881static int cam_icp_allocate_hfi_mem(void)
1882{
1883 int rc;
1884
1885 rc = cam_smmu_get_region_info(icp_hw_mgr.iommu_hdl,
Seemanta Duttaa037cd12017-07-06 15:45:29 -07001886 CAM_SMMU_REGION_SHARED,
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301887 &icp_hw_mgr.hfi_mem.shmem);
1888 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001889 CAM_ERR(CAM_ICP, "Unable to get shared memory info");
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301890 return rc;
1891 }
1892
1893 rc = cam_icp_allocate_fw_mem();
1894 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001895 CAM_ERR(CAM_ICP, "Unable to allocate FW memory");
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301896 return rc;
1897 }
1898
1899 rc = cam_icp_alloc_shared_mem(&icp_hw_mgr.hfi_mem.qtbl);
1900 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001901 CAM_ERR(CAM_ICP, "Unable to allocate qtbl memory");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001902 goto qtbl_alloc_failed;
1903 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001904
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301905 rc = cam_icp_alloc_shared_mem(&icp_hw_mgr.hfi_mem.cmd_q);
1906 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001907 CAM_ERR(CAM_ICP, "Unable to allocate cmd q memory");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001908 goto cmd_q_alloc_failed;
1909 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001910
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301911 rc = cam_icp_alloc_shared_mem(&icp_hw_mgr.hfi_mem.msg_q);
1912 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001913 CAM_ERR(CAM_ICP, "Unable to allocate msg q memory");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001914 goto msg_q_alloc_failed;
1915 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001916
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301917 rc = cam_icp_alloc_shared_mem(&icp_hw_mgr.hfi_mem.dbg_q);
1918 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001919 CAM_ERR(CAM_ICP, "Unable to allocate dbg q memory");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001920 goto dbg_q_alloc_failed;
1921 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001922
Seemanta Dutta93f940c2017-10-13 14:34:18 -07001923 rc = cam_icp_alloc_secheap_mem(&icp_hw_mgr.hfi_mem.sec_heap);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301924 if (rc) {
Seemanta Dutta93f940c2017-10-13 14:34:18 -07001925 CAM_ERR(CAM_ICP, "Unable to allocate sec heap memory");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001926 goto sec_heap_alloc_failed;
1927 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001928
1929 return rc;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001930sec_heap_alloc_failed:
1931 cam_mem_mgr_release_mem(&icp_hw_mgr.hfi_mem.dbg_q);
1932dbg_q_alloc_failed:
1933 cam_mem_mgr_release_mem(&icp_hw_mgr.hfi_mem.msg_q);
1934msg_q_alloc_failed:
1935 cam_mem_mgr_release_mem(&icp_hw_mgr.hfi_mem.cmd_q);
1936cmd_q_alloc_failed:
1937 cam_mem_mgr_release_mem(&icp_hw_mgr.hfi_mem.qtbl);
1938qtbl_alloc_failed:
1939 cam_smmu_dealloc_firmware(icp_hw_mgr.iommu_hdl);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001940 return rc;
1941}
1942
1943static int cam_icp_mgr_get_free_ctx(struct cam_icp_hw_mgr *hw_mgr)
1944{
1945 int i = 0;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001946
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05301947 for (i = 0; i < CAM_ICP_CTX_MAX; i++) {
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001948 mutex_lock(&hw_mgr->ctx_data[i].ctx_mutex);
Suresh Vankadarac7b0c672017-11-25 00:44:10 +05301949 if (hw_mgr->ctx_data[i].state == CAM_ICP_CTX_STATE_FREE) {
1950 hw_mgr->ctx_data[i].state = CAM_ICP_CTX_STATE_IN_USE;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001951 mutex_unlock(&hw_mgr->ctx_data[i].ctx_mutex);
1952 break;
1953 }
1954 mutex_unlock(&hw_mgr->ctx_data[i].ctx_mutex);
1955 }
1956
1957 return i;
1958}
1959
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05301960static void cam_icp_mgr_put_ctx(struct cam_icp_hw_ctx_data *ctx_data)
1961{
Suresh Vankadarac7b0c672017-11-25 00:44:10 +05301962 ctx_data->state = CAM_ICP_CTX_STATE_FREE;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05301963}
1964
Suresh Vankadara466bed22017-11-30 06:30:20 +05301965static int cam_icp_mgr_send_pc_prep(struct cam_icp_hw_mgr *hw_mgr)
1966{
1967 int rc;
1968 struct cam_hw_intf *a5_dev_intf = NULL;
1969 unsigned long rem_jiffies;
1970 int timeout = 5000;
1971
Karthik Anantha Ram9f13d0e2017-11-30 14:55:44 -08001972 a5_dev_intf = hw_mgr->a5_dev_intf;
Suresh Vankadara466bed22017-11-30 06:30:20 +05301973 if (!a5_dev_intf) {
1974 CAM_ERR(CAM_ICP, "a5_dev_intf is invalid\n");
1975 return -EINVAL;
1976 }
1977
1978 reinit_completion(&hw_mgr->a5_complete);
1979 CAM_DBG(CAM_ICP, "Sending HFI init command");
1980 rc = a5_dev_intf->hw_ops.process_cmd(
1981 a5_dev_intf->hw_priv, CAM_ICP_A5_CMD_PC_PREP, NULL, 0);
1982 if (rc)
1983 return rc;
1984
1985 CAM_DBG(CAM_ICP, "Wait for PC_PREP_DONE Message\n");
1986 rem_jiffies = wait_for_completion_timeout(&icp_hw_mgr.a5_complete,
1987 msecs_to_jiffies((timeout)));
1988 if (!rem_jiffies) {
1989 rc = -ETIMEDOUT;
1990 CAM_ERR(CAM_ICP, "PC_PREP response timed out %d\n", rc);
1991 }
1992 CAM_DBG(CAM_ICP, "Done Waiting for PC_PREP Message\n");
1993
1994 return rc;
1995}
1996
1997static int cam_ipe_bps_deint(struct cam_icp_hw_mgr *hw_mgr)
1998{
1999 struct cam_hw_intf *ipe0_dev_intf = NULL;
2000 struct cam_hw_intf *ipe1_dev_intf = NULL;
2001 struct cam_hw_intf *bps_dev_intf = NULL;
2002
Karthik Anantha Ram9f13d0e2017-11-30 14:55:44 -08002003 ipe0_dev_intf = hw_mgr->ipe0_dev_intf;
2004 ipe1_dev_intf = hw_mgr->ipe1_dev_intf;
2005 bps_dev_intf = hw_mgr->bps_dev_intf;
Suresh Vankadara466bed22017-11-30 06:30:20 +05302006 if ((!ipe0_dev_intf) || (!bps_dev_intf)) {
2007 CAM_ERR(CAM_ICP, "dev intfs are wrong, failed to close");
2008 return 0;
2009 }
2010
2011 if (ipe1_dev_intf) {
2012 ipe1_dev_intf->hw_ops.deinit(ipe1_dev_intf->hw_priv,
2013 NULL, 0);
2014 }
2015 ipe0_dev_intf->hw_ops.deinit(ipe0_dev_intf->hw_priv, NULL, 0);
2016 bps_dev_intf->hw_ops.deinit(bps_dev_intf->hw_priv, NULL, 0);
2017 return 0;
2018}
2019static int cam_icp_mgr_icp_power_collapse(struct cam_icp_hw_mgr *hw_mgr)
2020{
2021 int rc;
2022 struct cam_hw_intf *a5_dev_intf = NULL;
2023 struct cam_hw_info *a5_dev = NULL;
2024
2025 CAM_DBG(CAM_ICP, "ENTER");
2026
Karthik Anantha Ram9f13d0e2017-11-30 14:55:44 -08002027 a5_dev_intf = hw_mgr->a5_dev_intf;
Suresh Vankadara466bed22017-11-30 06:30:20 +05302028 if (!a5_dev_intf) {
2029 CAM_ERR(CAM_ICP, "a5_dev_intf is invalid\n");
2030 return -EINVAL;
2031 }
2032 a5_dev = (struct cam_hw_info *)a5_dev_intf->hw_priv;
2033
Alok Pandey1aef7b52017-12-16 20:42:03 +05302034 if (!hw_mgr->icp_pc_flag)
2035 rc = cam_icp_mgr_hw_close(hw_mgr, NULL);
2036 else
2037 rc = cam_icp_mgr_send_pc_prep(hw_mgr);
Suresh Vankadara466bed22017-11-30 06:30:20 +05302038
2039 cam_hfi_disable_cpu(a5_dev->soc_info.reg_map[A5_SIERRA_BASE].mem_base);
2040 a5_dev_intf->hw_ops.deinit(a5_dev_intf->hw_priv, NULL, 0);
2041 CAM_DBG(CAM_ICP, "EXIT");
2042
2043 return rc;
2044}
2045
2046static int cam_icp_mgr_hfi_resume(struct cam_icp_hw_mgr *hw_mgr)
2047{
2048 struct cam_hw_intf *a5_dev_intf = NULL;
2049 struct cam_hw_info *a5_dev = NULL;
2050 struct hfi_mem_info hfi_mem;
2051
Karthik Anantha Ram9f13d0e2017-11-30 14:55:44 -08002052 a5_dev_intf = hw_mgr->a5_dev_intf;
Suresh Vankadara466bed22017-11-30 06:30:20 +05302053 if (!a5_dev_intf) {
2054 CAM_ERR(CAM_ICP, "a5_dev_intf is invalid\n");
2055 return -EINVAL;
2056 }
2057 a5_dev = (struct cam_hw_info *)a5_dev_intf->hw_priv;
2058
2059 hfi_mem.qtbl.kva = icp_hw_mgr.hfi_mem.qtbl.kva;
2060 hfi_mem.qtbl.iova = icp_hw_mgr.hfi_mem.qtbl.iova;
2061 hfi_mem.qtbl.len = icp_hw_mgr.hfi_mem.qtbl.len;
2062 CAM_DBG(CAM_ICP, "kva = %llX IOVA = %X length = %lld\n",
2063 hfi_mem.qtbl.kva, hfi_mem.qtbl.iova, hfi_mem.qtbl.len);
2064
2065 hfi_mem.cmd_q.kva = icp_hw_mgr.hfi_mem.cmd_q.kva;
2066 hfi_mem.cmd_q.iova = icp_hw_mgr.hfi_mem.cmd_q.iova;
2067 hfi_mem.cmd_q.len = icp_hw_mgr.hfi_mem.cmd_q.len;
2068 CAM_DBG(CAM_ICP, "kva = %llX IOVA = %X length = %lld\n",
2069 hfi_mem.cmd_q.kva, hfi_mem.cmd_q.iova, hfi_mem.cmd_q.len);
2070
2071 hfi_mem.msg_q.kva = icp_hw_mgr.hfi_mem.msg_q.kva;
2072 hfi_mem.msg_q.iova = icp_hw_mgr.hfi_mem.msg_q.iova;
2073 hfi_mem.msg_q.len = icp_hw_mgr.hfi_mem.msg_q.len;
2074 CAM_DBG(CAM_ICP, "kva = %llX IOVA = %X length = %lld\n",
2075 hfi_mem.msg_q.kva, hfi_mem.msg_q.iova, hfi_mem.msg_q.len);
2076
2077 hfi_mem.dbg_q.kva = icp_hw_mgr.hfi_mem.dbg_q.kva;
2078 hfi_mem.dbg_q.iova = icp_hw_mgr.hfi_mem.dbg_q.iova;
2079 hfi_mem.dbg_q.len = icp_hw_mgr.hfi_mem.dbg_q.len;
2080 CAM_DBG(CAM_ICP, "kva = %llX IOVA = %X length = %lld\n",
2081 hfi_mem.dbg_q.kva, hfi_mem.dbg_q.iova, hfi_mem.dbg_q.len);
2082
2083 hfi_mem.sec_heap.kva = icp_hw_mgr.hfi_mem.sec_heap.kva;
2084 hfi_mem.sec_heap.iova = icp_hw_mgr.hfi_mem.sec_heap.iova;
2085 hfi_mem.sec_heap.len = icp_hw_mgr.hfi_mem.sec_heap.len;
2086
2087 hfi_mem.shmem.iova = icp_hw_mgr.hfi_mem.shmem.iova_start;
2088 hfi_mem.shmem.len = icp_hw_mgr.hfi_mem.shmem.iova_len;
2089 return cam_hfi_resume(&hfi_mem,
2090 a5_dev->soc_info.reg_map[A5_SIERRA_BASE].mem_base,
2091 hw_mgr->a5_jtag_debug);
2092}
2093
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05302094static int cam_icp_mgr_abort_handle(
2095 struct cam_icp_hw_ctx_data *ctx_data)
2096{
2097 int rc = 0;
Suresh Vankadara22697d32017-07-03 12:14:09 -07002098 unsigned long rem_jiffies;
Karthik Anantha Ram300662f2017-08-29 13:31:10 -07002099 size_t packet_size;
Venkat Chinta7747cbf2018-01-02 14:54:32 -08002100 int timeout = 100;
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05302101 struct hfi_cmd_work_data *task_data;
Karthik Anantha Ram300662f2017-08-29 13:31:10 -07002102 struct hfi_cmd_ipebps_async *abort_cmd;
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05302103 struct crm_workq_task *task;
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05302104
2105 task = cam_req_mgr_workq_get_task(icp_hw_mgr.cmd_work);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302106 if (!task)
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05302107 return -ENOMEM;
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05302108
Karthik Anantha Ram300662f2017-08-29 13:31:10 -07002109 packet_size =
Karthik Anantha Ram21885822017-08-28 15:47:17 -07002110 sizeof(struct hfi_cmd_ipebps_async) +
2111 sizeof(struct hfi_cmd_abort_destroy) -
Karthik Anantha Ram300662f2017-08-29 13:31:10 -07002112 sizeof(((struct hfi_cmd_ipebps_async *)0)->payload.direct);
2113 abort_cmd = kzalloc(packet_size, GFP_KERNEL);
2114 if (!abort_cmd) {
2115 rc = -ENOMEM;
2116 return rc;
2117 }
2118
Karthik Anantha Ram730718d2017-08-29 18:43:21 -07002119 abort_cmd->size = packet_size;
Karthik Anantha Ram300662f2017-08-29 13:31:10 -07002120 abort_cmd->pkt_type = HFI_CMD_IPEBPS_ASYNC_COMMAND_DIRECT;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05302121 if (ctx_data->icp_dev_acquire_info->dev_type == CAM_ICP_RES_TYPE_BPS)
Karthik Anantha Ram300662f2017-08-29 13:31:10 -07002122 abort_cmd->opcode = HFI_IPEBPS_CMD_OPCODE_BPS_ABORT;
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05302123 else
Karthik Anantha Ram300662f2017-08-29 13:31:10 -07002124 abort_cmd->opcode = HFI_IPEBPS_CMD_OPCODE_IPE_ABORT;
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05302125
2126 reinit_completion(&ctx_data->wait_complete);
Karthik Anantha Ram300662f2017-08-29 13:31:10 -07002127 abort_cmd->num_fw_handles = 1;
2128 abort_cmd->fw_handles[0] = ctx_data->fw_handle;
2129 abort_cmd->user_data1 = (uint64_t)ctx_data;
2130 abort_cmd->user_data2 = (uint64_t)0x0;
2131 memcpy(abort_cmd->payload.direct, &ctx_data->temp_payload,
2132 sizeof(uint64_t));
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05302133
2134 task_data = (struct hfi_cmd_work_data *)task->payload;
Karthik Anantha Ram300662f2017-08-29 13:31:10 -07002135 task_data->data = (void *)abort_cmd;
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05302136 task_data->request_id = 0;
2137 task_data->type = ICP_WORKQ_TASK_CMD_TYPE;
2138 task->process_cb = cam_icp_mgr_process_cmd;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05302139 rc = cam_req_mgr_workq_enqueue_task(task, &icp_hw_mgr,
2140 CRM_TASK_PRIORITY_0);
Karthik Anantha Ram300662f2017-08-29 13:31:10 -07002141 if (rc) {
2142 kfree(abort_cmd);
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05302143 return rc;
Karthik Anantha Ram300662f2017-08-29 13:31:10 -07002144 }
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05302145
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07002146 CAM_DBG(CAM_ICP, "fw_handle = %x ctx_data = %pK",
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05302147 ctx_data->fw_handle, ctx_data);
2148 rem_jiffies = wait_for_completion_timeout(&ctx_data->wait_complete,
2149 msecs_to_jiffies((timeout)));
2150 if (!rem_jiffies) {
2151 rc = -ETIMEDOUT;
Junzhe Zou4b11e7a2017-11-13 17:21:32 -08002152 CAM_ERR(CAM_ICP, "FW timeout/err in abort handle command");
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05302153 }
2154
Karthik Anantha Ram300662f2017-08-29 13:31:10 -07002155 kfree(abort_cmd);
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05302156 return rc;
2157}
2158
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002159static int cam_icp_mgr_destroy_handle(
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05302160 struct cam_icp_hw_ctx_data *ctx_data)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002161{
2162 int rc = 0;
Venkat Chinta7747cbf2018-01-02 14:54:32 -08002163 int timeout = 100;
Suresh Vankadara22697d32017-07-03 12:14:09 -07002164 unsigned long rem_jiffies;
Karthik Anantha Ram300662f2017-08-29 13:31:10 -07002165 size_t packet_size;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002166 struct hfi_cmd_work_data *task_data;
Karthik Anantha Ram300662f2017-08-29 13:31:10 -07002167 struct hfi_cmd_ipebps_async *destroy_cmd;
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05302168 struct crm_workq_task *task;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002169
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05302170 task = cam_req_mgr_workq_get_task(icp_hw_mgr.cmd_work);
2171 if (!task)
2172 return -ENOMEM;
2173
Karthik Anantha Ram300662f2017-08-29 13:31:10 -07002174 packet_size =
Karthik Anantha Ram21885822017-08-28 15:47:17 -07002175 sizeof(struct hfi_cmd_ipebps_async) +
Karthik Anantha Ram300662f2017-08-29 13:31:10 -07002176 sizeof(struct hfi_cmd_abort_destroy) -
2177 sizeof(((struct hfi_cmd_ipebps_async *)0)->payload.direct);
2178 destroy_cmd = kzalloc(packet_size, GFP_KERNEL);
2179 if (!destroy_cmd) {
2180 rc = -ENOMEM;
2181 return rc;
2182 }
2183
Karthik Anantha Ram730718d2017-08-29 18:43:21 -07002184 destroy_cmd->size = packet_size;
Karthik Anantha Ram300662f2017-08-29 13:31:10 -07002185 destroy_cmd->pkt_type = HFI_CMD_IPEBPS_ASYNC_COMMAND_DIRECT;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05302186 if (ctx_data->icp_dev_acquire_info->dev_type == CAM_ICP_RES_TYPE_BPS)
Karthik Anantha Ram300662f2017-08-29 13:31:10 -07002187 destroy_cmd->opcode = HFI_IPEBPS_CMD_OPCODE_BPS_DESTROY;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002188 else
Karthik Anantha Ram300662f2017-08-29 13:31:10 -07002189 destroy_cmd->opcode = HFI_IPEBPS_CMD_OPCODE_IPE_DESTROY;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002190
2191 reinit_completion(&ctx_data->wait_complete);
Karthik Anantha Ram300662f2017-08-29 13:31:10 -07002192 destroy_cmd->num_fw_handles = 1;
2193 destroy_cmd->fw_handles[0] = ctx_data->fw_handle;
2194 destroy_cmd->user_data1 = (uint64_t)ctx_data;
2195 destroy_cmd->user_data2 = (uint64_t)0x0;
2196 memcpy(destroy_cmd->payload.direct, &ctx_data->temp_payload,
2197 sizeof(uint64_t));
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002198
2199 task_data = (struct hfi_cmd_work_data *)task->payload;
Karthik Anantha Ram300662f2017-08-29 13:31:10 -07002200 task_data->data = (void *)destroy_cmd;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002201 task_data->request_id = 0;
2202 task_data->type = ICP_WORKQ_TASK_CMD_TYPE;
2203 task->process_cb = cam_icp_mgr_process_cmd;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05302204 rc = cam_req_mgr_workq_enqueue_task(task, &icp_hw_mgr,
2205 CRM_TASK_PRIORITY_0);
Karthik Anantha Ram300662f2017-08-29 13:31:10 -07002206 if (rc) {
2207 kfree(destroy_cmd);
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05302208 return rc;
Karthik Anantha Ram300662f2017-08-29 13:31:10 -07002209 }
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05302210
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07002211 CAM_DBG(CAM_ICP, "fw_handle = %x ctx_data = %pK",
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002212 ctx_data->fw_handle, ctx_data);
2213 rem_jiffies = wait_for_completion_timeout(&ctx_data->wait_complete,
2214 msecs_to_jiffies((timeout)));
2215 if (!rem_jiffies) {
2216 rc = -ETIMEDOUT;
Karthik Anantha Ram599c4e152017-12-14 15:03:48 -08002217 CAM_ERR(CAM_ICP, "FW response timeout: %d for %u",
2218 rc, ctx_data->ctx_id);
2219 if (icp_hw_mgr.a5_debug_q)
2220 cam_icp_mgr_process_dbg_buf();
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002221 }
2222
Karthik Anantha Ram300662f2017-08-29 13:31:10 -07002223 kfree(destroy_cmd);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002224 return rc;
2225}
2226
2227static int cam_icp_mgr_release_ctx(struct cam_icp_hw_mgr *hw_mgr, int ctx_id)
2228{
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002229 int i = 0;
2230
2231 if (ctx_id >= CAM_ICP_CTX_MAX) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07002232 CAM_ERR(CAM_ICP, "ctx_id is wrong: %d", ctx_id);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002233 return -EINVAL;
2234 }
2235
2236 mutex_lock(&hw_mgr->ctx_data[ctx_id].ctx_mutex);
Suresh Vankadarac7b0c672017-11-25 00:44:10 +05302237 if (hw_mgr->ctx_data[ctx_id].state !=
2238 CAM_ICP_CTX_STATE_ACQUIRED) {
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002239 mutex_unlock(&hw_mgr->ctx_data[ctx_id].ctx_mutex);
Suresh Vankadara22697d32017-07-03 12:14:09 -07002240 mutex_unlock(&hw_mgr->hw_mgr_mutex);
Karthik Anantha Ram78af8402017-12-04 13:16:26 -08002241 CAM_DBG(CAM_ICP,
Suresh Vankadarac7b0c672017-11-25 00:44:10 +05302242 "ctx with id: %d not in right state to release: %d",
2243 ctx_id, hw_mgr->ctx_data[ctx_id].state);
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -07002244 return 0;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002245 }
Alok Pandey78093d32017-11-08 18:56:54 +05302246 cam_icp_mgr_ipe_bps_power_collapse(hw_mgr,
2247 &hw_mgr->ctx_data[ctx_id], 0);
Suresh Vankadarac7b0c672017-11-25 00:44:10 +05302248 hw_mgr->ctx_data[ctx_id].state = CAM_ICP_CTX_STATE_RELEASE;
Karthik Anantha Ram599c4e152017-12-14 15:03:48 -08002249 CAM_DBG(CAM_ICP, "E: ctx_id = %d", ctx_id);
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05302250 cam_icp_mgr_destroy_handle(&hw_mgr->ctx_data[ctx_id]);
Suresh Vankadara502c2882017-11-17 02:25:49 +05302251 cam_icp_mgr_cleanup_ctx(&hw_mgr->ctx_data[ctx_id]);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002252
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002253 hw_mgr->ctx_data[ctx_id].fw_handle = 0;
2254 hw_mgr->ctx_data[ctx_id].scratch_mem_size = 0;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002255 for (i = 0; i < CAM_FRAME_CMD_MAX; i++)
2256 clear_bit(i, hw_mgr->ctx_data[ctx_id].hfi_frame_process.bitmap);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002257 kfree(hw_mgr->ctx_data[ctx_id].hfi_frame_process.bitmap);
Kyle Piefercf2e8612017-11-14 17:00:13 -08002258 hw_mgr->ctx_data[ctx_id].hfi_frame_process.bitmap = NULL;
Suresh Vankadara34494fc2017-08-12 18:18:09 +05302259 cam_icp_hw_mgr_clk_info_update(hw_mgr, &hw_mgr->ctx_data[ctx_id]);
2260 hw_mgr->ctx_data[ctx_id].clk_info.curr_fc = 0;
2261 hw_mgr->ctx_data[ctx_id].clk_info.base_clk = 0;
Suresh Vankadara5499a5f2017-06-16 22:13:56 +05302262 hw_mgr->ctxt_cnt--;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05302263 kfree(hw_mgr->ctx_data[ctx_id].icp_dev_acquire_info);
2264 hw_mgr->ctx_data[ctx_id].icp_dev_acquire_info = NULL;
Suresh Vankadarac7b0c672017-11-25 00:44:10 +05302265 hw_mgr->ctx_data[ctx_id].state = CAM_ICP_CTX_STATE_FREE;
Suresh Vankadarac092e592018-01-11 18:52:41 +05302266 cam_icp_ctx_timer_stop(&hw_mgr->ctx_data[ctx_id]);
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05302267 mutex_unlock(&hw_mgr->ctx_data[ctx_id].ctx_mutex);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002268
Karthik Anantha Ram599c4e152017-12-14 15:03:48 -08002269 CAM_DBG(CAM_ICP, "X: ctx_id = %d", ctx_id);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002270 return 0;
2271}
2272
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302273static void cam_icp_mgr_device_deinit(struct cam_icp_hw_mgr *hw_mgr)
2274{
2275 struct cam_hw_intf *a5_dev_intf = NULL;
2276 struct cam_hw_intf *ipe0_dev_intf = NULL;
2277 struct cam_hw_intf *ipe1_dev_intf = NULL;
2278 struct cam_hw_intf *bps_dev_intf = NULL;
2279
Karthik Anantha Ram9f13d0e2017-11-30 14:55:44 -08002280 a5_dev_intf = hw_mgr->a5_dev_intf;
2281 ipe0_dev_intf = hw_mgr->ipe0_dev_intf;
2282 ipe1_dev_intf = hw_mgr->ipe1_dev_intf;
2283 bps_dev_intf = hw_mgr->bps_dev_intf;
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302284
2285 if ((!a5_dev_intf) || (!ipe0_dev_intf) || (!bps_dev_intf)) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07002286 CAM_ERR(CAM_ICP, "dev intfs are wrong, failed to close");
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302287 return;
2288 }
2289
2290 if (ipe1_dev_intf)
2291 ipe1_dev_intf->hw_ops.deinit(ipe1_dev_intf->hw_priv, NULL, 0);
2292 ipe0_dev_intf->hw_ops.deinit(ipe0_dev_intf->hw_priv, NULL, 0);
2293 bps_dev_intf->hw_ops.deinit(bps_dev_intf->hw_priv, NULL, 0);
2294 a5_dev_intf->hw_ops.deinit(a5_dev_intf->hw_priv, NULL, 0);
2295}
2296
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002297static int cam_icp_mgr_hw_close(void *hw_priv, void *hw_close_args)
2298{
2299 struct cam_icp_hw_mgr *hw_mgr = hw_priv;
2300 struct cam_hw_intf *a5_dev_intf = NULL;
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -07002301 struct cam_icp_a5_set_irq_cb irq_cb;
2302 struct cam_icp_a5_set_fw_buf_info fw_buf_info;
Suresh Vankadara466bed22017-11-30 06:30:20 +05302303 int rc = 0;
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -07002304
Suresh Vankadara466bed22017-11-30 06:30:20 +05302305 CAM_DBG(CAM_ICP, "E");
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -07002306 mutex_lock(&hw_mgr->hw_mgr_mutex);
Suresh Vankadara466bed22017-11-30 06:30:20 +05302307 if (hw_mgr->fw_download == false) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07002308 CAM_DBG(CAM_ICP, "hw mgr is already closed");
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -07002309 mutex_unlock(&hw_mgr->hw_mgr_mutex);
2310 return 0;
2311 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002312
Karthik Anantha Ram9f13d0e2017-11-30 14:55:44 -08002313 a5_dev_intf = hw_mgr->a5_dev_intf;
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302314 if (!a5_dev_intf) {
Suresh Vankadara466bed22017-11-30 06:30:20 +05302315 CAM_DBG(CAM_ICP, "a5_dev_intf is NULL");
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -07002316 mutex_unlock(&hw_mgr->hw_mgr_mutex);
2317 return -EINVAL;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002318 }
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -07002319
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -07002320 fw_buf_info.kva = 0;
2321 fw_buf_info.iova = 0;
2322 fw_buf_info.len = 0;
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302323 rc = a5_dev_intf->hw_ops.process_cmd(
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -07002324 a5_dev_intf->hw_priv,
2325 CAM_ICP_A5_CMD_SET_FW_BUF,
2326 &fw_buf_info,
2327 sizeof(fw_buf_info));
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302328 if (rc)
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07002329 CAM_ERR(CAM_ICP, "nullify the fw buf failed");
Suresh Vankadara22697d32017-07-03 12:14:09 -07002330
Abhijit Trivedi36ea6a12018-01-15 18:48:15 -08002331 cam_hfi_deinit();
Harsh Shah6baba8c2017-10-16 19:23:29 -07002332
2333 irq_cb.icp_hw_mgr_cb = NULL;
2334 irq_cb.data = NULL;
2335 rc = a5_dev_intf->hw_ops.process_cmd(
2336 a5_dev_intf->hw_priv,
2337 CAM_ICP_A5_SET_IRQ_CB,
2338 &irq_cb, sizeof(irq_cb));
2339 if (rc)
2340 CAM_ERR(CAM_ICP, "deregister irq call back failed");
2341
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002342 cam_icp_free_hfi_mem();
2343 hw_mgr->fw_download = false;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002344 hw_mgr->secure_mode = CAM_SECURE_MODE_NON_SECURE;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002345 mutex_unlock(&hw_mgr->hw_mgr_mutex);
Suresh Vankadara22697d32017-07-03 12:14:09 -07002346
Alok Pandey1aef7b52017-12-16 20:42:03 +05302347 CAM_DBG(CAM_ICP, "Exit");
Suresh Vankadara22697d32017-07-03 12:14:09 -07002348 return rc;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002349}
2350
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302351static int cam_icp_mgr_device_init(struct cam_icp_hw_mgr *hw_mgr)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002352{
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302353 int rc = 0;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002354 struct cam_hw_intf *a5_dev_intf = NULL;
2355 struct cam_hw_intf *ipe0_dev_intf = NULL;
2356 struct cam_hw_intf *ipe1_dev_intf = NULL;
2357 struct cam_hw_intf *bps_dev_intf = NULL;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002358
Karthik Anantha Ram9f13d0e2017-11-30 14:55:44 -08002359 a5_dev_intf = hw_mgr->a5_dev_intf;
2360 ipe0_dev_intf = hw_mgr->ipe0_dev_intf;
2361 ipe1_dev_intf = hw_mgr->ipe1_dev_intf;
2362 bps_dev_intf = hw_mgr->bps_dev_intf;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002363
2364 if ((!a5_dev_intf) || (!ipe0_dev_intf) || (!bps_dev_intf)) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07002365 CAM_ERR(CAM_ICP, "dev intfs are wrong");
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302366 return -EINVAL;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002367 }
2368
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002369 rc = a5_dev_intf->hw_ops.init(a5_dev_intf->hw_priv, NULL, 0);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302370 if (rc)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002371 goto a5_dev_init_failed;
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302372
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002373 rc = bps_dev_intf->hw_ops.init(bps_dev_intf->hw_priv, NULL, 0);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302374 if (rc)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002375 goto bps_dev_init_failed;
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302376
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002377 rc = ipe0_dev_intf->hw_ops.init(ipe0_dev_intf->hw_priv, NULL, 0);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302378 if (rc)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002379 goto ipe0_dev_init_failed;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002380
2381 if (ipe1_dev_intf) {
2382 rc = ipe1_dev_intf->hw_ops.init(ipe1_dev_intf->hw_priv,
2383 NULL, 0);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302384 if (rc)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002385 goto ipe1_dev_init_failed;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002386 }
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302387
2388 return rc;
2389ipe1_dev_init_failed:
2390 ipe0_dev_intf->hw_ops.deinit(ipe0_dev_intf->hw_priv, NULL, 0);
2391ipe0_dev_init_failed:
2392 bps_dev_intf->hw_ops.deinit(bps_dev_intf->hw_priv, NULL, 0);
2393bps_dev_init_failed:
2394 a5_dev_intf->hw_ops.deinit(a5_dev_intf->hw_priv, NULL, 0);
2395a5_dev_init_failed:
2396 return rc;
2397}
2398
2399static int cam_icp_mgr_fw_download(struct cam_icp_hw_mgr *hw_mgr)
2400{
2401 int rc;
2402 struct cam_hw_intf *a5_dev_intf = NULL;
2403 struct cam_hw_info *a5_dev = NULL;
2404 struct cam_icp_a5_set_irq_cb irq_cb;
2405 struct cam_icp_a5_set_fw_buf_info fw_buf_info;
2406
Karthik Anantha Ram9f13d0e2017-11-30 14:55:44 -08002407 a5_dev_intf = hw_mgr->a5_dev_intf;
Suresh Vankadara22697d32017-07-03 12:14:09 -07002408 if (!a5_dev_intf) {
2409 CAM_ERR(CAM_ICP, "a5_dev_intf is invalid");
2410 return -EINVAL;
2411 }
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302412 a5_dev = (struct cam_hw_info *)a5_dev_intf->hw_priv;
2413
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002414 irq_cb.icp_hw_mgr_cb = cam_icp_hw_mgr_cb;
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302415 irq_cb.data = hw_mgr;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002416 rc = a5_dev_intf->hw_ops.process_cmd(
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -07002417 a5_dev_intf->hw_priv,
2418 CAM_ICP_A5_SET_IRQ_CB,
2419 &irq_cb, sizeof(irq_cb));
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302420 if (rc)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002421 goto set_irq_failed;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002422
2423 fw_buf_info.kva = icp_hw_mgr.hfi_mem.fw_buf.kva;
2424 fw_buf_info.iova = icp_hw_mgr.hfi_mem.fw_buf.iova;
2425 fw_buf_info.len = icp_hw_mgr.hfi_mem.fw_buf.len;
2426
2427 rc = a5_dev_intf->hw_ops.process_cmd(
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -07002428 a5_dev_intf->hw_priv,
2429 CAM_ICP_A5_CMD_SET_FW_BUF,
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302430 &fw_buf_info, sizeof(fw_buf_info));
2431 if (rc)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002432 goto set_irq_failed;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002433
2434 cam_hfi_enable_cpu(a5_dev->soc_info.reg_map[A5_SIERRA_BASE].mem_base);
2435
2436 rc = a5_dev_intf->hw_ops.process_cmd(
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -07002437 a5_dev_intf->hw_priv,
2438 CAM_ICP_A5_CMD_FW_DOWNLOAD,
2439 NULL, 0);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302440 if (rc)
2441 goto fw_download_failed;
2442
2443 return rc;
2444fw_download_failed:
2445 cam_hfi_disable_cpu(a5_dev->soc_info.reg_map[A5_SIERRA_BASE].mem_base);
2446set_irq_failed:
2447 return rc;
2448}
2449
2450static int cam_icp_mgr_hfi_init(struct cam_icp_hw_mgr *hw_mgr)
2451{
2452 struct cam_hw_intf *a5_dev_intf = NULL;
2453 struct cam_hw_info *a5_dev = NULL;
2454 struct hfi_mem_info hfi_mem;
2455
Karthik Anantha Ram9f13d0e2017-11-30 14:55:44 -08002456 a5_dev_intf = hw_mgr->a5_dev_intf;
Suresh Vankadara22697d32017-07-03 12:14:09 -07002457 if (!a5_dev_intf) {
2458 CAM_ERR(CAM_ICP, "a5_dev_intf is invalid");
2459 return -EINVAL;
2460 }
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302461 a5_dev = (struct cam_hw_info *)a5_dev_intf->hw_priv;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002462
2463 hfi_mem.qtbl.kva = icp_hw_mgr.hfi_mem.qtbl.kva;
2464 hfi_mem.qtbl.iova = icp_hw_mgr.hfi_mem.qtbl.iova;
2465 hfi_mem.qtbl.len = icp_hw_mgr.hfi_mem.qtbl.len;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002466
2467 hfi_mem.cmd_q.kva = icp_hw_mgr.hfi_mem.cmd_q.kva;
2468 hfi_mem.cmd_q.iova = icp_hw_mgr.hfi_mem.cmd_q.iova;
2469 hfi_mem.cmd_q.len = icp_hw_mgr.hfi_mem.cmd_q.len;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002470
2471 hfi_mem.msg_q.kva = icp_hw_mgr.hfi_mem.msg_q.kva;
2472 hfi_mem.msg_q.iova = icp_hw_mgr.hfi_mem.msg_q.iova;
2473 hfi_mem.msg_q.len = icp_hw_mgr.hfi_mem.msg_q.len;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002474
2475 hfi_mem.dbg_q.kva = icp_hw_mgr.hfi_mem.dbg_q.kva;
2476 hfi_mem.dbg_q.iova = icp_hw_mgr.hfi_mem.dbg_q.iova;
2477 hfi_mem.dbg_q.len = icp_hw_mgr.hfi_mem.dbg_q.len;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002478
2479 hfi_mem.sec_heap.kva = icp_hw_mgr.hfi_mem.sec_heap.kva;
2480 hfi_mem.sec_heap.iova = icp_hw_mgr.hfi_mem.sec_heap.iova;
2481 hfi_mem.sec_heap.len = icp_hw_mgr.hfi_mem.sec_heap.len;
2482
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07002483 hfi_mem.shmem.iova = icp_hw_mgr.hfi_mem.shmem.iova_start;
2484 hfi_mem.shmem.len = icp_hw_mgr.hfi_mem.shmem.iova_len;
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07002485
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302486 return cam_hfi_init(0, &hfi_mem,
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002487 a5_dev->soc_info.reg_map[A5_SIERRA_BASE].mem_base,
Lakshmi Narayana Kalavaladac0b6c2017-09-13 15:33:42 -07002488 hw_mgr->a5_jtag_debug);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302489}
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002490
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302491static int cam_icp_mgr_send_fw_init(struct cam_icp_hw_mgr *hw_mgr)
2492{
2493 int rc;
2494 struct cam_hw_intf *a5_dev_intf = NULL;
2495 unsigned long rem_jiffies;
2496 int timeout = 5000;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002497
Karthik Anantha Ram9f13d0e2017-11-30 14:55:44 -08002498 a5_dev_intf = hw_mgr->a5_dev_intf;
Suresh Vankadara22697d32017-07-03 12:14:09 -07002499 if (!a5_dev_intf) {
2500 CAM_ERR(CAM_ICP, "a5_dev_intf is invalid");
2501 return -EINVAL;
2502 }
2503
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002504 reinit_completion(&hw_mgr->a5_complete);
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07002505 CAM_DBG(CAM_ICP, "Sending HFI init command");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002506 rc = a5_dev_intf->hw_ops.process_cmd(
2507 a5_dev_intf->hw_priv,
2508 CAM_ICP_A5_SEND_INIT,
2509 NULL, 0);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302510 if (rc)
2511 return rc;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002512
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07002513 rem_jiffies = wait_for_completion_timeout(&icp_hw_mgr.a5_complete,
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302514 msecs_to_jiffies((timeout)));
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07002515 if (!rem_jiffies) {
2516 rc = -ETIMEDOUT;
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07002517 CAM_ERR(CAM_ICP, "FW response timed out %d", rc);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302518 }
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07002519 CAM_DBG(CAM_ICP, "Done Waiting for INIT DONE Message");
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302520
2521 return rc;
2522}
2523
Alok Pandey1aef7b52017-12-16 20:42:03 +05302524static int cam_icp_mgr_icp_resume(struct cam_icp_hw_mgr *hw_mgr)
2525{
2526 int rc = 0;
2527 struct cam_hw_intf *a5_dev_intf = NULL;
2528 bool downloadFromResume = true;
2529
2530 CAM_DBG(CAM_ICP, "Enter");
2531 a5_dev_intf = hw_mgr->devices[CAM_ICP_DEV_A5][0];
2532
2533 if (!a5_dev_intf) {
2534 CAM_ERR(CAM_ICP, "a5 dev intf is wrong");
2535 return -EINVAL;
2536 }
2537
2538 if (hw_mgr->fw_download == false) {
2539 CAM_DBG(CAM_ICP, "Downloading FW");
2540 mutex_unlock(&hw_mgr->hw_mgr_mutex);
Alok Pandeyb350a642018-01-15 16:43:35 +05302541 rc = cam_icp_mgr_hw_open(hw_mgr, &downloadFromResume);
Alok Pandey1aef7b52017-12-16 20:42:03 +05302542 mutex_lock(&hw_mgr->hw_mgr_mutex);
2543 CAM_DBG(CAM_ICP, "FW Download Done Exit");
Alok Pandeyb350a642018-01-15 16:43:35 +05302544 return rc;
Alok Pandey1aef7b52017-12-16 20:42:03 +05302545 }
2546
2547 rc = a5_dev_intf->hw_ops.init(a5_dev_intf->hw_priv, NULL, 0);
2548 if (rc)
2549 return -EINVAL;
2550
2551 rc = cam_icp_mgr_hfi_resume(hw_mgr);
2552 if (rc)
2553 goto hfi_resume_failed;
2554
2555 CAM_DBG(CAM_ICP, "Exit");
2556 return rc;
2557hfi_resume_failed:
2558 cam_icp_mgr_icp_power_collapse(hw_mgr);
2559 return rc;
2560}
2561
Harsh Shah6baba8c2017-10-16 19:23:29 -07002562static int cam_icp_mgr_hw_open(void *hw_mgr_priv, void *download_fw_args)
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302563{
2564 struct cam_hw_intf *a5_dev_intf = NULL;
2565 struct cam_hw_info *a5_dev = NULL;
2566 struct cam_icp_hw_mgr *hw_mgr = hw_mgr_priv;
Alok Pandey1aef7b52017-12-16 20:42:03 +05302567 bool icp_pc = false;
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302568 int rc = 0;
2569
2570 if (!hw_mgr) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07002571 CAM_ERR(CAM_ICP, "hw_mgr is NULL");
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302572 return -EINVAL;
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07002573 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002574
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302575 mutex_lock(&hw_mgr->hw_mgr_mutex);
2576 if (hw_mgr->fw_download) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07002577 CAM_DBG(CAM_ICP, "FW already downloaded");
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302578 mutex_unlock(&hw_mgr->hw_mgr_mutex);
2579 return rc;
2580 }
2581
Karthik Anantha Ram9f13d0e2017-11-30 14:55:44 -08002582 a5_dev_intf = hw_mgr->a5_dev_intf;
Suresh Vankadara22697d32017-07-03 12:14:09 -07002583 if (!a5_dev_intf) {
2584 CAM_ERR(CAM_ICP, "a5_dev_intf is invalid");
2585 mutex_unlock(&hw_mgr->hw_mgr_mutex);
2586 return -EINVAL;
2587 }
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302588 a5_dev = (struct cam_hw_info *)a5_dev_intf->hw_priv;
2589 rc = cam_icp_allocate_hfi_mem();
Lynus Vazf25f1b72018-01-15 02:38:35 +05302590 if (rc)
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302591 goto alloc_hfi_mem_failed;
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302592
2593 rc = cam_icp_mgr_device_init(hw_mgr);
Lynus Vazf25f1b72018-01-15 02:38:35 +05302594 if (rc)
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302595 goto dev_init_fail;
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302596
2597 rc = cam_icp_mgr_fw_download(hw_mgr);
Lynus Vazf25f1b72018-01-15 02:38:35 +05302598 if (rc)
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302599 goto fw_download_failed;
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302600
2601 rc = cam_icp_mgr_hfi_init(hw_mgr);
Lynus Vazf25f1b72018-01-15 02:38:35 +05302602 if (rc)
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302603 goto hfi_init_failed;
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302604
2605 rc = cam_icp_mgr_send_fw_init(hw_mgr);
Lynus Vazf25f1b72018-01-15 02:38:35 +05302606 if (rc)
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302607 goto fw_init_failed;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002608
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002609 hw_mgr->ctxt_cnt = 0;
Alok Pandey1aef7b52017-12-16 20:42:03 +05302610 hw_mgr->fw_download = true;
Lakshmi Narayana Kalavaladac0b6c2017-09-13 15:33:42 -07002611
2612 if (icp_hw_mgr.a5_debug_q)
2613 hfi_set_debug_level(icp_hw_mgr.a5_dbg_lvl);
2614
2615 mutex_unlock(&hw_mgr->hw_mgr_mutex);
Alok Pandey1aef7b52017-12-16 20:42:03 +05302616 CAM_INFO(CAM_ICP, "FW download done successfully");
Lakshmi Narayana Kalavaladac0b6c2017-09-13 15:33:42 -07002617
Suresh Vankadara466bed22017-11-30 06:30:20 +05302618 rc = cam_ipe_bps_deint(hw_mgr);
Alok Pandey1aef7b52017-12-16 20:42:03 +05302619 if (download_fw_args)
2620 icp_pc = *((bool *)download_fw_args);
2621
2622 if (download_fw_args && icp_pc == true)
2623 return rc;
2624
Suresh Vankadara466bed22017-11-30 06:30:20 +05302625 rc = cam_icp_mgr_icp_power_collapse(hw_mgr);
2626
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002627 return rc;
2628
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302629fw_init_failed:
Abhijit Trivedi36ea6a12018-01-15 18:48:15 -08002630 cam_hfi_deinit();
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302631hfi_init_failed:
2632 cam_hfi_disable_cpu(a5_dev->soc_info.reg_map[A5_SIERRA_BASE].mem_base);
2633fw_download_failed:
2634 cam_icp_mgr_device_deinit(hw_mgr);
2635dev_init_fail:
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002636 cam_icp_free_hfi_mem();
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302637alloc_hfi_mem_failed:
Lynus Vazf25f1b72018-01-15 02:38:35 +05302638 mutex_unlock(&hw_mgr->hw_mgr_mutex);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002639 return rc;
2640}
2641
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302642static int cam_icp_mgr_handle_config_err(
2643 struct cam_hw_config_args *config_args,
Suresh Vankadara34494fc2017-08-12 18:18:09 +05302644 struct cam_icp_hw_ctx_data *ctx_data,
2645 int idx)
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302646{
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302647 struct cam_hw_done_event_data buf_data;
2648
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302649 buf_data.request_id = *(uint64_t *)config_args->priv;
Suresh Vankadara502c2882017-11-17 02:25:49 +05302650 ctx_data->ctxt_event_cb(ctx_data->context_priv, false, &buf_data);
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302651
Suresh Vankadara34494fc2017-08-12 18:18:09 +05302652 ctx_data->hfi_frame_process.request_id[idx] = 0;
2653 ctx_data->hfi_frame_process.fw_process_flag[idx] = false;
2654 clear_bit(idx, ctx_data->hfi_frame_process.bitmap);
2655
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302656 return 0;
2657}
2658
2659static int cam_icp_mgr_enqueue_config(struct cam_icp_hw_mgr *hw_mgr,
2660 struct cam_hw_config_args *config_args)
2661{
2662 int rc = 0;
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302663 uint64_t request_id = 0;
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302664 struct crm_workq_task *task;
2665 struct hfi_cmd_work_data *task_data;
2666 struct hfi_cmd_ipebps_async *hfi_cmd;
2667 struct cam_hw_update_entry *hw_update_entries;
2668
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302669 request_id = *(uint64_t *)config_args->priv;
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302670 hw_update_entries = config_args->hw_update_entries;
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07002671 CAM_DBG(CAM_ICP, "req_id = %lld %pK", request_id, config_args->priv);
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302672
2673 task = cam_req_mgr_workq_get_task(icp_hw_mgr.cmd_work);
2674 if (!task) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07002675 CAM_ERR(CAM_ICP, "no empty task");
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302676 return -ENOMEM;
2677 }
2678
2679 task_data = (struct hfi_cmd_work_data *)task->payload;
2680 task_data->data = (void *)hw_update_entries->addr;
2681 hfi_cmd = (struct hfi_cmd_ipebps_async *)hw_update_entries->addr;
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302682 task_data->request_id = request_id;
2683 task_data->type = ICP_WORKQ_TASK_CMD_TYPE;
2684 task->process_cb = cam_icp_mgr_process_cmd;
2685 rc = cam_req_mgr_workq_enqueue_task(task, &icp_hw_mgr,
2686 CRM_TASK_PRIORITY_0);
2687
2688 return rc;
2689}
2690
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002691static int cam_icp_mgr_config_hw(void *hw_mgr_priv, void *config_hw_args)
2692{
2693 int rc = 0;
Suresh Vankadara34494fc2017-08-12 18:18:09 +05302694 int idx;
2695 uint64_t req_id;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002696 struct cam_icp_hw_mgr *hw_mgr = hw_mgr_priv;
2697 struct cam_hw_config_args *config_args = config_hw_args;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002698 struct cam_icp_hw_ctx_data *ctx_data = NULL;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002699
2700 if (!hw_mgr || !config_args) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07002701 CAM_ERR(CAM_ICP, "Invalid arguments %pK %pK",
2702 hw_mgr, config_args);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002703 return -EINVAL;
2704 }
2705
2706 if (!config_args->num_hw_update_entries) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07002707 CAM_ERR(CAM_ICP, "No hw update enteries are available");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002708 return -EINVAL;
2709 }
2710
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05302711 ctx_data = config_args->ctxt_to_hw_map;
Suresh Vankadara22697d32017-07-03 12:14:09 -07002712 mutex_lock(&ctx_data->ctx_mutex);
Suresh Vankadarac7b0c672017-11-25 00:44:10 +05302713 if (ctx_data->state != CAM_ICP_CTX_STATE_ACQUIRED) {
Kyle Piefercf2e8612017-11-14 17:00:13 -08002714 mutex_unlock(&ctx_data->ctx_mutex);
Suresh Vankadarac7b0c672017-11-25 00:44:10 +05302715 CAM_ERR(CAM_ICP, "ctx id :%u is not in use",
2716 ctx_data->ctx_id);
Suresh Vankadara34494fc2017-08-12 18:18:09 +05302717 return -EINVAL;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002718 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002719
Suresh Vankadara34494fc2017-08-12 18:18:09 +05302720 req_id = *(uint64_t *)config_args->priv;
2721 idx = cam_icp_clk_idx_from_req_id(ctx_data, req_id);
2722 ctx_data->hfi_frame_process.fw_process_flag[idx] = true;
2723 cam_icp_mgr_ipe_bps_clk_update(hw_mgr, ctx_data, idx);
2724
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302725 rc = cam_icp_mgr_enqueue_config(hw_mgr, config_args);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302726 if (rc)
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302727 goto config_err;
Karthik Anantha Ram599c4e152017-12-14 15:03:48 -08002728 CAM_DBG(CAM_ICP, "req_id = %lld %u",
2729 req_id, ctx_data->ctx_id);
Suresh Vankadara22697d32017-07-03 12:14:09 -07002730 mutex_unlock(&ctx_data->ctx_mutex);
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302731
2732 return 0;
2733config_err:
Suresh Vankadara34494fc2017-08-12 18:18:09 +05302734 cam_icp_mgr_handle_config_err(config_args, ctx_data, idx);
Suresh Vankadara22697d32017-07-03 12:14:09 -07002735 mutex_unlock(&ctx_data->ctx_mutex);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002736 return rc;
2737}
2738
2739static int cam_icp_mgr_prepare_frame_process_cmd(
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05302740 struct cam_icp_hw_ctx_data *ctx_data,
2741 struct hfi_cmd_ipebps_async *hfi_cmd,
Suresh Vankadarad8905f42017-06-04 13:33:49 +05302742 uint64_t request_id,
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05302743 uint32_t fw_cmd_buf_iova_addr)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002744{
2745 hfi_cmd->size = sizeof(struct hfi_cmd_ipebps_async);
2746 hfi_cmd->pkt_type = HFI_CMD_IPEBPS_ASYNC_COMMAND_INDIRECT;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05302747 if (ctx_data->icp_dev_acquire_info->dev_type == CAM_ICP_RES_TYPE_BPS)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002748 hfi_cmd->opcode = HFI_IPEBPS_CMD_OPCODE_BPS_FRAME_PROCESS;
2749 else
2750 hfi_cmd->opcode = HFI_IPEBPS_CMD_OPCODE_IPE_FRAME_PROCESS;
2751 hfi_cmd->num_fw_handles = 1;
2752 hfi_cmd->fw_handles[0] = ctx_data->fw_handle;
2753 hfi_cmd->payload.indirect = fw_cmd_buf_iova_addr;
2754 hfi_cmd->user_data1 = (uint64_t)ctx_data;
2755 hfi_cmd->user_data2 = request_id;
2756
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07002757 CAM_DBG(CAM_ICP, "ctx_data : %pK, request_id :%lld cmd_buf %x",
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302758 (void *)ctx_data->context_priv, request_id,
2759 fw_cmd_buf_iova_addr);
2760
2761 return 0;
2762}
2763
2764static int cam_icp_mgr_pkt_validation(struct cam_packet *packet)
2765{
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302766 if (((packet->header.op_code & 0xff) !=
2767 CAM_ICP_OPCODE_IPE_UPDATE) &&
2768 ((packet->header.op_code & 0xff) !=
2769 CAM_ICP_OPCODE_BPS_UPDATE)) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07002770 CAM_ERR(CAM_ICP, "Invalid Opcode in pkt: %d",
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302771 packet->header.op_code & 0xff);
2772 return -EINVAL;
2773 }
Suresh Vankadara34494fc2017-08-12 18:18:09 +05302774 CAM_DBG(CAM_ICP, "number of cmd/patch info: %u %u",
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302775 packet->num_cmd_buf, packet->num_patches);
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302776 return 0;
2777}
2778
2779static int cam_icp_mgr_process_cmd_desc(struct cam_icp_hw_mgr *hw_mgr,
Karthik Anantha Ram599c4e152017-12-14 15:03:48 -08002780 struct cam_packet *packet, struct cam_icp_hw_ctx_data *ctx_data,
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302781 uint32_t *fw_cmd_buf_iova_addr)
2782{
2783 int rc = 0;
Karthik Anantha Ram599c4e152017-12-14 15:03:48 -08002784 int i, j, k;
Suresh Vankadara34494fc2017-08-12 18:18:09 +05302785 uint64_t addr;
2786 size_t len;
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302787 struct cam_cmd_buf_desc *cmd_desc = NULL;
Karthik Anantha Ram599c4e152017-12-14 15:03:48 -08002788 uint64_t cpu_addr = 0;
2789 struct ipe_frame_process_data *frame_process_data = NULL;
2790 struct bps_frame_process_data *bps_frame_process_data = NULL;
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302791
2792 cmd_desc = (struct cam_cmd_buf_desc *)
2793 ((uint32_t *) &packet->payload + packet->cmd_buf_offset/4);
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302794
Suresh Vankadara34494fc2017-08-12 18:18:09 +05302795 *fw_cmd_buf_iova_addr = 0;
2796 for (i = 0; i < packet->num_cmd_buf; i++) {
2797 if (cmd_desc[i].type == CAM_CMD_BUF_FW) {
2798 rc = cam_mem_get_io_buf(cmd_desc[i].mem_handle,
2799 hw_mgr->iommu_hdl, &addr, &len);
2800 if (rc) {
2801 CAM_ERR(CAM_ICP, "get cmd buf failed %x",
2802 hw_mgr->iommu_hdl);
2803 return rc;
2804 }
2805 *fw_cmd_buf_iova_addr = addr;
2806 *fw_cmd_buf_iova_addr =
2807 (*fw_cmd_buf_iova_addr + cmd_desc[i].offset);
Karthik Anantha Ram599c4e152017-12-14 15:03:48 -08002808 rc = cam_mem_get_cpu_buf(cmd_desc[i].mem_handle,
2809 &cpu_addr, &len);
2810 if (rc) {
2811 CAM_ERR(CAM_ICP, "get cmd buf failed %x",
2812 hw_mgr->iommu_hdl);
2813 *fw_cmd_buf_iova_addr = 0;
2814 return rc;
2815 }
2816 cpu_addr = cpu_addr + cmd_desc[i].offset;
2817 }
2818 }
2819
2820 if (!cpu_addr) {
2821 CAM_ERR(CAM_ICP, "Invalid cpu addr");
2822 return -EINVAL;
2823 }
2824
2825 if (ctx_data->icp_dev_acquire_info->dev_type !=
2826 CAM_ICP_RES_TYPE_BPS) {
2827 CAM_DBG(CAM_ICP, "cpu addr = %llx", cpu_addr);
2828 frame_process_data = (struct ipe_frame_process_data *)cpu_addr;
2829 CAM_DBG(CAM_ICP, "%u %u %u", frame_process_data->max_num_cores,
2830 frame_process_data->target_time,
2831 frame_process_data->frames_in_batch);
2832 frame_process_data->strip_lib_out_addr = 0;
2833 frame_process_data->iq_settings_addr = 0;
2834 frame_process_data->scratch_buffer_addr = 0;
2835 frame_process_data->ubwc_stats_buffer_addr = 0;
2836 frame_process_data->cdm_buffer_addr = 0;
2837 frame_process_data->cdm_prog_base = 0;
2838 for (i = 0; i < frame_process_data->frames_in_batch; i++) {
2839 for (j = 0; j < IPE_IO_IMAGES_MAX; j++) {
2840 for (k = 0; k < MAX_NUM_OF_IMAGE_PLANES; k++) {
2841 frame_process_data->
2842 framesets[i].buffers[j].
2843 buffer_ptr[k] = 0;
2844 frame_process_data->
2845 framesets[i].buffers[j].
2846 meta_buffer_ptr[k] = 0;
2847 }
2848 }
2849 }
2850 } else {
2851 CAM_DBG(CAM_ICP, "cpu addr = %llx", cpu_addr);
2852 bps_frame_process_data =
2853 (struct bps_frame_process_data *)cpu_addr;
2854 CAM_DBG(CAM_ICP, "%u %u",
2855 bps_frame_process_data->max_num_cores,
2856 bps_frame_process_data->target_time);
2857 bps_frame_process_data->ubwc_stats_buffer_addr = 0;
2858 bps_frame_process_data->cdm_buffer_addr = 0;
2859 bps_frame_process_data->iq_settings_addr = 0;
2860 bps_frame_process_data->strip_lib_out_addr = 0;
2861 bps_frame_process_data->cdm_prog_addr = 0;
2862 for (i = 0; i < BPS_IO_IMAGES_MAX; i++) {
2863 for (j = 0; j < MAX_NUM_OF_IMAGE_PLANES; j++) {
2864 bps_frame_process_data->
2865 buffers[i].buffer_ptr[j] = 0;
2866 bps_frame_process_data->
2867 buffers[i].meta_buffer_ptr[j] = 0;
2868 }
Suresh Vankadara34494fc2017-08-12 18:18:09 +05302869 }
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302870 }
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302871
2872 return rc;
2873}
2874
Suresh Vankadaraad2d3a92017-09-25 12:18:11 +05302875static int cam_icp_mgr_process_io_cfg(struct cam_icp_hw_mgr *hw_mgr,
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302876 struct cam_icp_hw_ctx_data *ctx_data,
2877 struct cam_packet *packet,
Suresh Vankadaraad2d3a92017-09-25 12:18:11 +05302878 struct cam_hw_prepare_update_args *prepare_args,
2879 int32_t index)
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302880{
Suresh Vankadaraad2d3a92017-09-25 12:18:11 +05302881 int i, j, k, rc = 0;
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302882 struct cam_buf_io_cfg *io_cfg_ptr = NULL;
Sagar Goref13f75c2017-11-02 17:50:15 -07002883 int32_t sync_in_obj[CAM_MAX_IN_RES];
Suresh Vankadaraad2d3a92017-09-25 12:18:11 +05302884 int32_t merged_sync_in_obj;
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302885
2886 io_cfg_ptr = (struct cam_buf_io_cfg *) ((uint32_t *) &packet->payload +
2887 packet->io_configs_offset/4);
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302888 prepare_args->num_out_map_entries = 0;
Lakshmi Narayana Kalavalacfed4e92017-07-17 16:10:50 -07002889 prepare_args->num_in_map_entries = 0;
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302890
Lakshmi Narayana Kalavalacfed4e92017-07-17 16:10:50 -07002891 for (i = 0, j = 0, k = 0; i < packet->num_io_configs; i++) {
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302892 if (io_cfg_ptr[i].direction == CAM_BUF_INPUT) {
Suresh Vankadaraad2d3a92017-09-25 12:18:11 +05302893 sync_in_obj[j++] = io_cfg_ptr[i].fence;
Lakshmi Narayana Kalavalacfed4e92017-07-17 16:10:50 -07002894 prepare_args->num_in_map_entries++;
2895 } else {
2896 prepare_args->out_map_entries[k++].sync_id =
2897 io_cfg_ptr[i].fence;
2898 prepare_args->num_out_map_entries++;
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302899 }
Lakshmi Narayana Kalavalacfed4e92017-07-17 16:10:50 -07002900 CAM_DBG(CAM_ICP, "dir[%d]: %u, fence: %u",
2901 i, io_cfg_ptr[i].direction, io_cfg_ptr[i].fence);
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302902 }
Suresh Vankadaraad2d3a92017-09-25 12:18:11 +05302903
2904 if (prepare_args->num_in_map_entries > 1) {
2905 rc = cam_sync_merge(&sync_in_obj[0],
2906 prepare_args->num_in_map_entries, &merged_sync_in_obj);
2907 if (rc) {
2908 prepare_args->num_out_map_entries = 0;
2909 prepare_args->num_in_map_entries = 0;
2910 return rc;
2911 }
2912
2913 ctx_data->hfi_frame_process.in_resource[index] =
2914 merged_sync_in_obj;
2915 prepare_args->in_map_entries[0].sync_id = merged_sync_in_obj;
2916 prepare_args->num_in_map_entries = 1;
2917 CAM_DBG(CAM_ICP, "Merged Sync obj = %d", merged_sync_in_obj);
2918 } else if (prepare_args->num_in_map_entries == 1) {
2919 prepare_args->in_map_entries[0].sync_id = sync_in_obj[0];
2920 prepare_args->num_in_map_entries = 1;
2921 ctx_data->hfi_frame_process.in_resource[index] = 0;
2922 } else {
2923 CAM_ERR(CAM_ICP, "No input fences");
2924 prepare_args->num_in_map_entries = 0;
2925 ctx_data->hfi_frame_process.in_resource[index] = 0;
2926 rc = -EINVAL;
2927 }
2928
2929 return rc;
Suresh Vankadarae1b11082017-05-25 12:27:50 +05302930}
2931
Suresh Vankadara34494fc2017-08-12 18:18:09 +05302932static int cam_icp_packet_generic_blob_handler(void *user_data,
2933 uint32_t blob_type, uint32_t blob_size, uint8_t *blob_data)
2934{
2935 struct cam_icp_clk_bw_request *soc_req;
2936 struct cam_icp_clk_bw_request *clk_info;
2937 struct icp_cmd_generic_blob *blob;
2938 struct cam_icp_hw_ctx_data *ctx_data;
2939 uint32_t index;
2940 int rc = 0;
2941
2942 if (!blob_data || (blob_size == 0)) {
2943 CAM_ERR(CAM_ICP, "Invalid blob info %pK %d", blob_data,
2944 blob_size);
2945 return -EINVAL;
2946 }
2947
2948 blob = (struct icp_cmd_generic_blob *)user_data;
2949 ctx_data = blob->ctx;
2950 index = blob->frame_info_idx;
2951
2952 switch (blob_type) {
2953 case CAM_ICP_CMD_GENERIC_BLOB_CLK:
2954 if (blob_size != sizeof(struct cam_icp_clk_bw_request)) {
2955 rc = -EINVAL;
2956 break;
2957 }
2958 clk_info = &ctx_data->hfi_frame_process.clk_info[index];
2959 memset(clk_info, 0, sizeof(struct cam_icp_clk_bw_request));
2960
2961 soc_req = (struct cam_icp_clk_bw_request *)blob_data;
2962 *clk_info = *soc_req;
2963 CAM_DBG(CAM_ICP, "%llu %llu %d %d %d",
2964 clk_info->budget_ns, clk_info->frame_cycles,
2965 clk_info->rt_flag, clk_info->uncompressed_bw,
2966 clk_info->compressed_bw);
2967 break;
2968
2969 default:
2970 CAM_WARN(CAM_ICP, "Invalid blob type %d", blob_type);
2971 break;
2972 }
2973 return rc;
2974}
2975
2976static int cam_icp_process_generic_cmd_buffer(
2977 struct cam_packet *packet,
2978 struct cam_icp_hw_ctx_data *ctx_data,
2979 int32_t index)
2980{
2981 int i, rc = 0;
2982 struct cam_cmd_buf_desc *cmd_desc = NULL;
2983 struct icp_cmd_generic_blob cmd_generic_blob;
2984
2985 cmd_generic_blob.ctx = ctx_data;
2986 cmd_generic_blob.frame_info_idx = index;
2987
2988 cmd_desc = (struct cam_cmd_buf_desc *)
2989 ((uint32_t *) &packet->payload + packet->cmd_buf_offset/4);
2990 for (i = 0; i < packet->num_cmd_buf; i++) {
2991 if (!cmd_desc[i].length)
2992 continue;
2993
2994 if (cmd_desc[i].meta_data != CAM_ICP_CMD_META_GENERIC_BLOB)
2995 continue;
2996
2997 rc = cam_packet_util_process_generic_cmd_buffer(&cmd_desc[i],
2998 cam_icp_packet_generic_blob_handler, &cmd_generic_blob);
2999 if (rc)
3000 CAM_ERR(CAM_ICP, "Failed in processing blobs %d", rc);
3001 }
3002
3003 return rc;
3004}
3005
Suresh Vankadarae1b11082017-05-25 12:27:50 +05303006static int cam_icp_mgr_update_hfi_frame_process(
3007 struct cam_icp_hw_ctx_data *ctx_data,
3008 struct cam_packet *packet,
3009 struct cam_hw_prepare_update_args *prepare_args,
3010 int32_t *idx)
3011{
Suresh Vankadara34494fc2017-08-12 18:18:09 +05303012 int32_t index, rc;
Suresh Vankadarae1b11082017-05-25 12:27:50 +05303013
Suresh Vankadarae1b11082017-05-25 12:27:50 +05303014 index = find_first_zero_bit(ctx_data->hfi_frame_process.bitmap,
3015 ctx_data->hfi_frame_process.bits);
3016 if (index < 0 || index >= CAM_FRAME_CMD_MAX) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07003017 CAM_ERR(CAM_ICP, "request idx is wrong: %d", index);
Suresh Vankadarae1b11082017-05-25 12:27:50 +05303018 return -EINVAL;
3019 }
3020 set_bit(index, ctx_data->hfi_frame_process.bitmap);
Suresh Vankadarae1b11082017-05-25 12:27:50 +05303021
3022 ctx_data->hfi_frame_process.request_id[index] =
3023 packet->header.request_id;
Suresh Vankadara34494fc2017-08-12 18:18:09 +05303024 rc = cam_icp_process_generic_cmd_buffer(packet, ctx_data, index);
3025 if (rc) {
3026 clear_bit(index, ctx_data->hfi_frame_process.bitmap);
3027 ctx_data->hfi_frame_process.request_id[index] = -1;
3028 return rc;
3029 }
Suresh Vankadarae1b11082017-05-25 12:27:50 +05303030 *idx = index;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003031
3032 return 0;
3033}
3034
3035static int cam_icp_mgr_prepare_hw_update(void *hw_mgr_priv,
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05303036 void *prepare_hw_update_args)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003037{
Suresh Vankadarae1b11082017-05-25 12:27:50 +05303038 int rc = 0;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003039 int32_t idx;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003040 uint32_t fw_cmd_buf_iova_addr;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003041 struct cam_icp_hw_ctx_data *ctx_data = NULL;
3042 struct cam_packet *packet = NULL;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003043 struct hfi_cmd_ipebps_async *hfi_cmd = NULL;
Suresh Vankadarae1b11082017-05-25 12:27:50 +05303044 struct cam_icp_hw_mgr *hw_mgr = hw_mgr_priv;
3045 struct cam_hw_prepare_update_args *prepare_args =
3046 prepare_hw_update_args;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003047
Suresh Vankadarad8905f42017-06-04 13:33:49 +05303048 if ((!prepare_args) || (!hw_mgr) || (!prepare_args->packet)) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07003049 CAM_ERR(CAM_ICP, "Invalid args");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003050 return -EINVAL;
3051 }
3052
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05303053 ctx_data = prepare_args->ctxt_to_hw_map;
Suresh Vankadara22697d32017-07-03 12:14:09 -07003054 mutex_lock(&ctx_data->ctx_mutex);
Suresh Vankadarac7b0c672017-11-25 00:44:10 +05303055 if (ctx_data->state != CAM_ICP_CTX_STATE_ACQUIRED) {
Suresh Vankadara22697d32017-07-03 12:14:09 -07003056 mutex_unlock(&ctx_data->ctx_mutex);
Suresh Vankadarac7b0c672017-11-25 00:44:10 +05303057 CAM_ERR(CAM_ICP, "ctx id: %u is not in use",
3058 ctx_data->ctx_id);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003059 return -EINVAL;
3060 }
3061
3062 packet = prepare_args->packet;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003063
Suresh Vankadarae1b11082017-05-25 12:27:50 +05303064 rc = cam_icp_mgr_pkt_validation(packet);
Suresh Vankadara22697d32017-07-03 12:14:09 -07003065 if (rc) {
3066 mutex_unlock(&ctx_data->ctx_mutex);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003067 return rc;
Suresh Vankadara22697d32017-07-03 12:14:09 -07003068 }
Suresh Vankadarae1b11082017-05-25 12:27:50 +05303069
3070 rc = cam_icp_mgr_process_cmd_desc(hw_mgr, packet,
Karthik Anantha Ram599c4e152017-12-14 15:03:48 -08003071 ctx_data, &fw_cmd_buf_iova_addr);
Suresh Vankadara22697d32017-07-03 12:14:09 -07003072 if (rc) {
3073 mutex_unlock(&ctx_data->ctx_mutex);
Suresh Vankadarae1b11082017-05-25 12:27:50 +05303074 return rc;
Suresh Vankadara22697d32017-07-03 12:14:09 -07003075 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003076
Karthik Anantha Ram599c4e152017-12-14 15:03:48 -08003077 CAM_DBG(CAM_ICP, "E: req id = %lld", packet->header.request_id);
Harsh Shahe9e8ff52017-05-16 17:26:45 -07003078 /* Update Buffer Address from handles and patch information */
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07003079 rc = cam_packet_util_process_patches(packet, hw_mgr->iommu_hdl,
3080 hw_mgr->iommu_sec_hdl);
Suresh Vankadara22697d32017-07-03 12:14:09 -07003081 if (rc) {
3082 mutex_unlock(&ctx_data->ctx_mutex);
Harsh Shahe9e8ff52017-05-16 17:26:45 -07003083 return rc;
Suresh Vankadara22697d32017-07-03 12:14:09 -07003084 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003085
Suresh Vankadarae1b11082017-05-25 12:27:50 +05303086 rc = cam_icp_mgr_update_hfi_frame_process(ctx_data, packet,
3087 prepare_args, &idx);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05303088 if (rc) {
Suresh Vankadaraad2d3a92017-09-25 12:18:11 +05303089 mutex_unlock(&ctx_data->ctx_mutex);
3090 return rc;
3091 }
3092
3093 rc = cam_icp_mgr_process_io_cfg(hw_mgr, ctx_data,
3094 packet, prepare_args, idx);
3095 if (rc) {
3096 if (ctx_data->hfi_frame_process.in_resource[idx] > 0)
Suresh Vankadarae1b11082017-05-25 12:27:50 +05303097 cam_sync_destroy(
Suresh Vankadaraad2d3a92017-09-25 12:18:11 +05303098 ctx_data->hfi_frame_process.in_resource[idx]);
3099 clear_bit(idx, ctx_data->hfi_frame_process.bitmap);
3100 ctx_data->hfi_frame_process.request_id[idx] = -1;
Suresh Vankadara22697d32017-07-03 12:14:09 -07003101 mutex_unlock(&ctx_data->ctx_mutex);
Suresh Vankadarae1b11082017-05-25 12:27:50 +05303102 return rc;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003103 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003104
3105 hfi_cmd = (struct hfi_cmd_ipebps_async *)
3106 &ctx_data->hfi_frame_process.hfi_frame_cmd[idx];
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003107 cam_icp_mgr_prepare_frame_process_cmd(
Suresh Vankadarae1b11082017-05-25 12:27:50 +05303108 ctx_data, hfi_cmd, packet->header.request_id,
3109 fw_cmd_buf_iova_addr);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003110
3111 prepare_args->num_hw_update_entries = 1;
3112 prepare_args->hw_update_entries[0].addr = (uint64_t)hfi_cmd;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003113 prepare_args->priv = &ctx_data->hfi_frame_process.request_id[idx];
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003114
Karthik Anantha Ram599c4e152017-12-14 15:03:48 -08003115 CAM_DBG(CAM_ICP, "X: req id = %lld ctx_id = %u",
3116 packet->header.request_id, ctx_data->ctx_id);
Suresh Vankadara22697d32017-07-03 12:14:09 -07003117 mutex_unlock(&ctx_data->ctx_mutex);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003118 return rc;
3119}
3120
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05303121static int cam_icp_mgr_send_abort_status(struct cam_icp_hw_ctx_data *ctx_data)
3122{
3123 struct hfi_frame_process_info *hfi_frame_process;
3124 int idx;
3125
Suresh Vankadara22697d32017-07-03 12:14:09 -07003126 mutex_lock(&ctx_data->ctx_mutex);
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05303127 hfi_frame_process = &ctx_data->hfi_frame_process;
3128 for (idx = 0; idx < CAM_FRAME_CMD_MAX; idx++) {
3129 if (!hfi_frame_process->request_id[idx])
3130 continue;
3131
3132 ctx_data->ctxt_event_cb(ctx_data->context_priv, true,
3133 &hfi_frame_process->request_id[idx]);
3134
3135 /* now release memory for hfi frame process command */
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05303136 hfi_frame_process->request_id[idx] = 0;
Suresh Vankadaraad2d3a92017-09-25 12:18:11 +05303137 if (ctx_data->hfi_frame_process.in_resource[idx] > 0) {
3138 CAM_DBG(CAM_ICP, "Delete merged sync in object: %d",
3139 ctx_data->hfi_frame_process.in_resource[idx]);
3140 cam_sync_destroy(
3141 ctx_data->hfi_frame_process.in_resource[idx]);
3142 ctx_data->hfi_frame_process.in_resource[idx] = 0;
3143 }
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05303144 clear_bit(idx, ctx_data->hfi_frame_process.bitmap);
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05303145 }
Suresh Vankadara22697d32017-07-03 12:14:09 -07003146 mutex_unlock(&ctx_data->ctx_mutex);
Junzhe Zou4b11e7a2017-11-13 17:21:32 -08003147 return 0;
3148}
3149
3150static int cam_icp_mgr_delete_sync(void *priv, void *data)
3151{
3152 struct hfi_cmd_work_data *task_data = NULL;
3153 struct cam_icp_hw_ctx_data *ctx_data;
3154 struct hfi_frame_process_info *hfi_frame_process;
3155 int idx;
3156
3157 if (!data || !priv) {
3158 CAM_ERR(CAM_ICP, "Invalid params%pK %pK", data, priv);
3159 return -EINVAL;
3160 }
3161
3162 task_data = (struct hfi_cmd_work_data *)data;
3163 ctx_data = task_data->data;
3164
3165 if (!ctx_data) {
3166 CAM_ERR(CAM_ICP, "Null Context");
3167 return -EINVAL;
3168 }
3169
3170 mutex_lock(&ctx_data->ctx_mutex);
3171 hfi_frame_process = &ctx_data->hfi_frame_process;
3172 for (idx = 0; idx < CAM_FRAME_CMD_MAX; idx++) {
3173 if (!hfi_frame_process->in_free_resource[idx])
3174 continue;
3175 //cam_sync_destroy(
3176 //ctx_data->hfi_frame_process.in_free_resource[idx]);
3177 ctx_data->hfi_frame_process.in_resource[idx] = 0;
3178 }
3179 mutex_unlock(&ctx_data->ctx_mutex);
3180 return 0;
3181}
3182
3183static int cam_icp_mgr_delete_sync_obj(struct cam_icp_hw_ctx_data *ctx_data)
3184{
3185 int rc = 0;
3186 struct crm_workq_task *task;
3187 struct hfi_cmd_work_data *task_data;
3188
3189 task = cam_req_mgr_workq_get_task(icp_hw_mgr.cmd_work);
3190 if (!task) {
3191 CAM_ERR(CAM_ICP, "no empty task");
3192 return -ENOMEM;
3193 }
3194
3195 task_data = (struct hfi_cmd_work_data *)task->payload;
3196 task_data->data = (void *)ctx_data;
3197 task_data->request_id = 0;
3198 task_data->type = ICP_WORKQ_TASK_CMD_TYPE;
3199 task->process_cb = cam_icp_mgr_delete_sync;
3200 rc = cam_req_mgr_workq_enqueue_task(task, &icp_hw_mgr,
3201 CRM_TASK_PRIORITY_0);
3202
3203 return rc;
3204}
3205
3206static int cam_icp_mgr_flush_all(struct cam_icp_hw_ctx_data *ctx_data,
3207 struct cam_hw_flush_args *flush_args)
3208{
3209 struct hfi_frame_process_info *hfi_frame_process;
3210 int idx;
3211 bool clear_in_resource = false;
3212
3213 hfi_frame_process = &ctx_data->hfi_frame_process;
3214 for (idx = 0; idx < CAM_FRAME_CMD_MAX; idx++) {
3215 if (!hfi_frame_process->request_id[idx])
3216 continue;
3217
3218 /* now release memory for hfi frame process command */
3219 hfi_frame_process->request_id[idx] = 0;
3220 if (ctx_data->hfi_frame_process.in_resource[idx] > 0) {
3221 ctx_data->hfi_frame_process.in_free_resource[idx] =
3222 ctx_data->hfi_frame_process.in_resource[idx];
3223 ctx_data->hfi_frame_process.in_resource[idx] = 0;
3224 }
3225 clear_bit(idx, ctx_data->hfi_frame_process.bitmap);
3226 clear_in_resource = true;
3227 }
3228
3229 if (clear_in_resource)
3230 cam_icp_mgr_delete_sync_obj(ctx_data);
3231
3232 return 0;
3233}
3234
3235static int cam_icp_mgr_flush_req(struct cam_icp_hw_ctx_data *ctx_data,
3236 struct cam_hw_flush_args *flush_args)
3237{
3238 int64_t request_id;
3239 struct hfi_frame_process_info *hfi_frame_process;
3240 int idx;
3241 bool clear_in_resource = false;
3242
3243 hfi_frame_process = &ctx_data->hfi_frame_process;
3244 request_id = *(int64_t *)flush_args->flush_req_pending[0];
3245 for (idx = 0; idx < CAM_FRAME_CMD_MAX; idx++) {
3246 if (!hfi_frame_process->request_id[idx])
3247 continue;
3248
3249 if (hfi_frame_process->request_id[idx] != request_id)
3250 continue;
3251
3252 /* now release memory for hfi frame process command */
3253 hfi_frame_process->request_id[idx] = 0;
3254 if (ctx_data->hfi_frame_process.in_resource[idx] > 0) {
3255 ctx_data->hfi_frame_process.in_free_resource[idx] =
3256 ctx_data->hfi_frame_process.in_resource[idx];
3257 ctx_data->hfi_frame_process.in_resource[idx] = 0;
3258 }
3259 clear_bit(idx, ctx_data->hfi_frame_process.bitmap);
3260 clear_in_resource = true;
3261 }
3262
3263 if (clear_in_resource)
3264 cam_icp_mgr_delete_sync_obj(ctx_data);
3265
3266 return 0;
3267}
3268
3269static int cam_icp_mgr_hw_flush(void *hw_priv, void *hw_flush_args)
3270{
3271 struct cam_hw_flush_args *flush_args = hw_flush_args;
3272 struct cam_icp_hw_ctx_data *ctx_data;
3273
3274 if ((!hw_priv) || (!hw_flush_args)) {
3275 CAM_ERR(CAM_ICP, "Input params are Null:");
3276 return -EINVAL;
3277 }
3278
3279 ctx_data = flush_args->ctxt_to_hw_map;
3280 if (!ctx_data) {
3281 CAM_ERR(CAM_ICP, "Ctx data is NULL");
3282 return -EINVAL;
3283 }
3284
3285 if ((flush_args->flush_type >= CAM_FLUSH_TYPE_MAX) ||
3286 (flush_args->flush_type < CAM_FLUSH_TYPE_REQ)) {
3287 CAM_ERR(CAM_ICP, "Invalid lush type: %d",
3288 flush_args->flush_type);
3289 return -EINVAL;
3290 }
3291
3292 switch (flush_args->flush_type) {
3293 case CAM_FLUSH_TYPE_ALL:
3294 if (flush_args->num_req_active)
3295 cam_icp_mgr_abort_handle(ctx_data);
3296 mutex_lock(&ctx_data->ctx_mutex);
3297 cam_icp_mgr_flush_all(ctx_data, flush_args);
3298 mutex_unlock(&ctx_data->ctx_mutex);
3299 break;
3300 case CAM_FLUSH_TYPE_REQ:
3301 mutex_lock(&ctx_data->ctx_mutex);
3302 if (flush_args->num_req_active) {
3303 CAM_ERR(CAM_ICP, "Flush request is not supported");
3304 mutex_unlock(&ctx_data->ctx_mutex);
3305 return -EINVAL;
3306 }
3307 if (flush_args->num_req_pending)
3308 cam_icp_mgr_flush_req(ctx_data, flush_args);
3309 mutex_unlock(&ctx_data->ctx_mutex);
3310 break;
3311 default:
3312 CAM_ERR(CAM_ICP, "Invalid flush type: %d",
3313 flush_args->flush_type);
3314 return -EINVAL;
3315 }
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05303316
3317 return 0;
3318}
3319
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003320static int cam_icp_mgr_release_hw(void *hw_mgr_priv, void *release_hw_args)
3321{
3322 int rc = 0;
3323 int ctx_id = 0;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003324 struct cam_hw_release_args *release_hw = release_hw_args;
3325 struct cam_icp_hw_mgr *hw_mgr = hw_mgr_priv;
3326 struct cam_icp_hw_ctx_data *ctx_data = NULL;
3327
3328 if (!release_hw || !hw_mgr) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07003329 CAM_ERR(CAM_ICP, "Invalid args: %pK %pK", release_hw, hw_mgr);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003330 return -EINVAL;
3331 }
3332
Alok Pandey1aef7b52017-12-16 20:42:03 +05303333 CAM_DBG(CAM_ICP, "Enter");
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05303334 ctx_data = release_hw->ctxt_to_hw_map;
Karthik Anantha Ram811209b2017-11-07 10:53:03 -08003335 if (!ctx_data) {
Suresh Vankadara466bed22017-11-30 06:30:20 +05303336 CAM_ERR(CAM_ICP, "NULL ctx data");
Karthik Anantha Ram811209b2017-11-07 10:53:03 -08003337 return -EINVAL;
3338 }
3339
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05303340 ctx_id = ctx_data->ctx_id;
Karthik Anantha Ram811209b2017-11-07 10:53:03 -08003341 if (ctx_id < 0 || ctx_id >= CAM_ICP_CTX_MAX) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07003342 CAM_ERR(CAM_ICP, "Invalid ctx id: %d", ctx_id);
Karthik Anantha Ram811209b2017-11-07 10:53:03 -08003343 return -EINVAL;
3344 }
Suresh Vankadara22697d32017-07-03 12:14:09 -07003345
3346 mutex_lock(&hw_mgr->ctx_data[ctx_id].ctx_mutex);
Suresh Vankadarac7b0c672017-11-25 00:44:10 +05303347 if (hw_mgr->ctx_data[ctx_id].state != CAM_ICP_CTX_STATE_ACQUIRED) {
Suresh Vankadara22697d32017-07-03 12:14:09 -07003348 CAM_DBG(CAM_ICP, "ctx is not in use: %d", ctx_id);
3349 mutex_unlock(&hw_mgr->ctx_data[ctx_id].ctx_mutex);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003350 return -EINVAL;
3351 }
Suresh Vankadara22697d32017-07-03 12:14:09 -07003352 mutex_unlock(&hw_mgr->ctx_data[ctx_id].ctx_mutex);
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05303353
3354 if (release_hw->active_req) {
3355 cam_icp_mgr_abort_handle(ctx_data);
3356 cam_icp_mgr_send_abort_status(ctx_data);
3357 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003358
Suresh Vankadara466bed22017-11-30 06:30:20 +05303359 mutex_lock(&hw_mgr->hw_mgr_mutex);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003360 rc = cam_icp_mgr_release_ctx(hw_mgr, ctx_id);
Suresh Vankadara6657bc22017-07-31 10:33:04 +05303361 if (!hw_mgr->ctxt_cnt) {
Suresh Vankadara466bed22017-11-30 06:30:20 +05303362 CAM_DBG(CAM_ICP, "Last Release");
Alok Pandey1aef7b52017-12-16 20:42:03 +05303363 mutex_unlock(&hw_mgr->hw_mgr_mutex);
Suresh Vankadara466bed22017-11-30 06:30:20 +05303364 cam_icp_mgr_icp_power_collapse(hw_mgr);
Alok Pandey1aef7b52017-12-16 20:42:03 +05303365 mutex_lock(&hw_mgr->hw_mgr_mutex);
Suresh Vankadara34494fc2017-08-12 18:18:09 +05303366 cam_icp_hw_mgr_reset_clk_info(hw_mgr);
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07003367 hw_mgr->secure_mode = CAM_SECURE_MODE_NON_SECURE;
Suresh Vankadara6657bc22017-07-31 10:33:04 +05303368 }
Suresh Vankadara466bed22017-11-30 06:30:20 +05303369 mutex_unlock(&hw_mgr->hw_mgr_mutex);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003370
Junzhe Zoubc37c562017-11-20 18:23:49 -08003371 if (!hw_mgr->bps_ctxt_cnt || !hw_mgr->ipe_ctxt_cnt)
Suresh Vankadarac092e592018-01-11 18:52:41 +05303372 cam_icp_device_timer_stop(hw_mgr);
Junzhe Zoubc37c562017-11-20 18:23:49 -08003373
Alok Pandey1aef7b52017-12-16 20:42:03 +05303374 CAM_DBG(CAM_ICP, "Exit");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003375 return rc;
3376}
3377
3378static int cam_icp_mgr_send_config_io(struct cam_icp_hw_ctx_data *ctx_data,
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05303379 uint32_t io_buf_addr)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003380{
3381 int rc = 0;
3382 struct hfi_cmd_work_data *task_data;
3383 struct hfi_cmd_ipebps_async ioconfig_cmd;
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07003384 unsigned long rem_jiffies;
3385 int timeout = 5000;
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05303386 struct crm_workq_task *task;
3387
3388 task = cam_req_mgr_workq_get_task(icp_hw_mgr.cmd_work);
3389 if (!task)
3390 return -ENOMEM;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003391
3392 ioconfig_cmd.size = sizeof(struct hfi_cmd_ipebps_async);
3393 ioconfig_cmd.pkt_type = HFI_CMD_IPEBPS_ASYNC_COMMAND_INDIRECT;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05303394 if (ctx_data->icp_dev_acquire_info->dev_type == CAM_ICP_RES_TYPE_BPS)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003395 ioconfig_cmd.opcode = HFI_IPEBPS_CMD_OPCODE_BPS_CONFIG_IO;
3396 else
3397 ioconfig_cmd.opcode = HFI_IPEBPS_CMD_OPCODE_IPE_CONFIG_IO;
3398
3399 reinit_completion(&ctx_data->wait_complete);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003400 ioconfig_cmd.num_fw_handles = 1;
3401 ioconfig_cmd.fw_handles[0] = ctx_data->fw_handle;
3402 ioconfig_cmd.payload.indirect = io_buf_addr;
3403 ioconfig_cmd.user_data1 = (uint64_t)ctx_data;
3404 ioconfig_cmd.user_data2 = (uint64_t)0x0;
3405 task_data = (struct hfi_cmd_work_data *)task->payload;
3406 task_data->data = (void *)&ioconfig_cmd;
3407 task_data->request_id = 0;
3408 task_data->type = ICP_WORKQ_TASK_CMD_TYPE;
3409 task->process_cb = cam_icp_mgr_process_cmd;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05303410 rc = cam_req_mgr_workq_enqueue_task(task, &icp_hw_mgr,
3411 CRM_TASK_PRIORITY_0);
3412 if (rc)
3413 return rc;
3414
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07003415 rem_jiffies = wait_for_completion_timeout(&ctx_data->wait_complete,
3416 msecs_to_jiffies((timeout)));
3417 if (!rem_jiffies) {
3418 rc = -ETIMEDOUT;
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07003419 CAM_ERR(CAM_ICP, "FW response timed out %d", rc);
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07003420 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003421
3422 return rc;
3423}
3424
3425static int cam_icp_mgr_create_handle(uint32_t dev_type,
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05303426 struct cam_icp_hw_ctx_data *ctx_data)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003427{
3428 struct hfi_cmd_create_handle create_handle;
3429 struct hfi_cmd_work_data *task_data;
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07003430 unsigned long rem_jiffies;
3431 int timeout = 5000;
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05303432 struct crm_workq_task *task;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003433 int rc = 0;
3434
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05303435 task = cam_req_mgr_workq_get_task(icp_hw_mgr.cmd_work);
3436 if (!task)
3437 return -ENOMEM;
3438
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003439 create_handle.size = sizeof(struct hfi_cmd_create_handle);
3440 create_handle.pkt_type = HFI_CMD_IPEBPS_CREATE_HANDLE;
3441 create_handle.handle_type = dev_type;
3442 create_handle.user_data1 = (uint64_t)ctx_data;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003443 reinit_completion(&ctx_data->wait_complete);
3444 task_data = (struct hfi_cmd_work_data *)task->payload;
3445 task_data->data = (void *)&create_handle;
3446 task_data->request_id = 0;
3447 task_data->type = ICP_WORKQ_TASK_CMD_TYPE;
3448 task->process_cb = cam_icp_mgr_process_cmd;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05303449 rc = cam_req_mgr_workq_enqueue_task(task, &icp_hw_mgr,
3450 CRM_TASK_PRIORITY_0);
3451 if (rc)
3452 return rc;
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07003453
3454 rem_jiffies = wait_for_completion_timeout(&ctx_data->wait_complete,
3455 msecs_to_jiffies((timeout)));
3456 if (!rem_jiffies) {
3457 rc = -ETIMEDOUT;
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07003458 CAM_ERR(CAM_ICP, "FW response timed out %d", rc);
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07003459 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003460
3461 return rc;
3462}
3463
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05303464static int cam_icp_mgr_send_ping(struct cam_icp_hw_ctx_data *ctx_data)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003465{
3466 struct hfi_cmd_ping_pkt ping_pkt;
3467 struct hfi_cmd_work_data *task_data;
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07003468 unsigned long rem_jiffies;
3469 int timeout = 5000;
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05303470 struct crm_workq_task *task;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003471 int rc = 0;
3472
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05303473 task = cam_req_mgr_workq_get_task(icp_hw_mgr.cmd_work);
3474 if (!task) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07003475 CAM_ERR(CAM_ICP, "No free task to send ping command");
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05303476 return -ENOMEM;
3477 }
3478
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003479 ping_pkt.size = sizeof(struct hfi_cmd_ping_pkt);
3480 ping_pkt.pkt_type = HFI_CMD_SYS_PING;
3481 ping_pkt.user_data = (uint64_t)ctx_data;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003482 init_completion(&ctx_data->wait_complete);
3483 task_data = (struct hfi_cmd_work_data *)task->payload;
3484 task_data->data = (void *)&ping_pkt;
3485 task_data->request_id = 0;
3486 task_data->type = ICP_WORKQ_TASK_CMD_TYPE;
3487 task->process_cb = cam_icp_mgr_process_cmd;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05303488
3489 rc = cam_req_mgr_workq_enqueue_task(task, &icp_hw_mgr,
3490 CRM_TASK_PRIORITY_0);
3491 if (rc)
3492 return rc;
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07003493
3494 rem_jiffies = wait_for_completion_timeout(&ctx_data->wait_complete,
3495 msecs_to_jiffies((timeout)));
3496 if (!rem_jiffies) {
3497 rc = -ETIMEDOUT;
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07003498 CAM_ERR(CAM_ICP, "FW response timed out %d", rc);
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07003499 }
3500
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003501 return rc;
3502}
3503
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05303504static int cam_icp_get_acquire_info(struct cam_icp_hw_mgr *hw_mgr,
3505 struct cam_hw_acquire_args *args,
3506 struct cam_icp_hw_ctx_data *ctx_data)
3507{
3508 int i;
3509 int acquire_size;
3510 struct cam_icp_acquire_dev_info icp_dev_acquire_info;
3511 struct cam_icp_res_info *p_icp_out = NULL;
3512
3513 if (copy_from_user(&icp_dev_acquire_info,
3514 (void __user *)args->acquire_info,
Suresh Vankadara2948e772017-12-07 05:09:45 +05303515 sizeof(struct cam_icp_acquire_dev_info))) {
3516 CAM_ERR(CAM_ICP, "Failed in acquire");
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05303517 return -EFAULT;
Suresh Vankadara2948e772017-12-07 05:09:45 +05303518 }
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05303519
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07003520 if (icp_dev_acquire_info.secure_mode > CAM_SECURE_MODE_SECURE) {
3521 CAM_ERR(CAM_ICP, "Invalid mode:%d",
3522 icp_dev_acquire_info.secure_mode);
3523 return -EINVAL;
3524 }
3525
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05303526 if (icp_dev_acquire_info.num_out_res > ICP_MAX_OUTPUT_SUPPORTED) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07003527 CAM_ERR(CAM_ICP, "num of out resources exceeding : %u",
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05303528 icp_dev_acquire_info.num_out_res);
3529 return -EINVAL;
3530 }
3531
Suresh Vankadara22697d32017-07-03 12:14:09 -07003532 if (icp_dev_acquire_info.dev_type >= CAM_ICP_RES_TYPE_MAX) {
3533 CAM_ERR(CAM_ICP, "Invalid device type: %d",
3534 icp_dev_acquire_info.dev_type);
3535 return -EFAULT;
3536 }
3537
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07003538 if (!hw_mgr->ctxt_cnt) {
3539 hw_mgr->secure_mode = icp_dev_acquire_info.secure_mode;
3540 } else {
3541 if (hw_mgr->secure_mode != icp_dev_acquire_info.secure_mode) {
3542 CAM_ERR(CAM_ICP,
3543 "secure mode mismatch driver:%d, context:%d",
3544 hw_mgr->secure_mode,
3545 icp_dev_acquire_info.secure_mode);
3546 return -EINVAL;
3547 }
3548 }
3549
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05303550 acquire_size = sizeof(struct cam_icp_acquire_dev_info) +
Suresh Vankadara2948e772017-12-07 05:09:45 +05303551 ((icp_dev_acquire_info.num_out_res - 1) *
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05303552 sizeof(struct cam_icp_res_info));
3553 ctx_data->icp_dev_acquire_info = kzalloc(acquire_size, GFP_KERNEL);
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07003554 if (!ctx_data->icp_dev_acquire_info) {
3555 if (!hw_mgr->ctxt_cnt)
3556 hw_mgr->secure_mode = CAM_SECURE_MODE_NON_SECURE;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05303557 return -ENOMEM;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07003558 }
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05303559
3560 if (copy_from_user(ctx_data->icp_dev_acquire_info,
3561 (void __user *)args->acquire_info, acquire_size)) {
Suresh Vankadara2948e772017-12-07 05:09:45 +05303562 CAM_ERR(CAM_ICP, "Failed in acquire: size = %d", acquire_size);
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07003563 if (!hw_mgr->ctxt_cnt)
3564 hw_mgr->secure_mode = CAM_SECURE_MODE_NON_SECURE;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05303565 kfree(ctx_data->icp_dev_acquire_info);
3566 ctx_data->icp_dev_acquire_info = NULL;
3567 return -EFAULT;
3568 }
3569
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07003570 CAM_DBG(CAM_ICP, "%x %x %x %x %x %x %x %u",
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05303571 ctx_data->icp_dev_acquire_info->dev_type,
3572 ctx_data->icp_dev_acquire_info->in_res.format,
3573 ctx_data->icp_dev_acquire_info->in_res.width,
3574 ctx_data->icp_dev_acquire_info->in_res.height,
3575 ctx_data->icp_dev_acquire_info->in_res.fps,
3576 ctx_data->icp_dev_acquire_info->num_out_res,
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07003577 ctx_data->icp_dev_acquire_info->scratch_mem_size,
3578 hw_mgr->secure_mode);
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05303579
3580 p_icp_out = ctx_data->icp_dev_acquire_info->out_res;
Lakshmi Narayana Kalavala92d90c32017-08-04 10:51:53 -07003581 for (i = 0; i < icp_dev_acquire_info.num_out_res; i++)
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07003582 CAM_DBG(CAM_ICP, "out[i] %x %x %x %x",
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05303583 p_icp_out[i].format,
3584 p_icp_out[i].width,
3585 p_icp_out[i].height,
3586 p_icp_out[i].fps);
3587
3588 return 0;
3589}
3590
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003591static int cam_icp_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
3592{
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05303593 int rc = 0, bitmap_size = 0;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003594 uint32_t ctx_id = 0;
3595 uint64_t io_buf_addr;
3596 size_t io_buf_size;
3597 struct cam_icp_hw_mgr *hw_mgr = hw_mgr_priv;
3598 struct cam_icp_hw_ctx_data *ctx_data = NULL;
3599 struct cam_hw_acquire_args *args = acquire_hw_args;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05303600 struct cam_icp_acquire_dev_info *icp_dev_acquire_info;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003601
3602 if ((!hw_mgr_priv) || (!acquire_hw_args)) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07003603 CAM_ERR(CAM_ICP, "Invalid params: %pK %pK", hw_mgr_priv,
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003604 acquire_hw_args);
3605 return -EINVAL;
3606 }
3607
3608 if (args->num_acq > 1) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07003609 CAM_ERR(CAM_ICP, "number of resources are wrong: %u",
3610 args->num_acq);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003611 return -EINVAL;
3612 }
3613
Alok Pandey1aef7b52017-12-16 20:42:03 +05303614 CAM_DBG(CAM_ICP, "ENTER");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003615 mutex_lock(&hw_mgr->hw_mgr_mutex);
3616 ctx_id = cam_icp_mgr_get_free_ctx(hw_mgr);
3617 if (ctx_id >= CAM_ICP_CTX_MAX) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07003618 CAM_ERR(CAM_ICP, "No free ctx space in hw_mgr");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003619 mutex_unlock(&hw_mgr->hw_mgr_mutex);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05303620 return -ENOSPC;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003621 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003622 ctx_data = &hw_mgr->ctx_data[ctx_id];
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05303623 ctx_data->ctx_id = ctx_id;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003624 mutex_unlock(&hw_mgr->hw_mgr_mutex);
3625
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003626 mutex_lock(&ctx_data->ctx_mutex);
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05303627 rc = cam_icp_get_acquire_info(hw_mgr, args, ctx_data);
Suresh Vankadara22697d32017-07-03 12:14:09 -07003628 if (rc)
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05303629 goto acquire_info_failed;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05303630 icp_dev_acquire_info = ctx_data->icp_dev_acquire_info;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003631
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07003632 rc = cam_mem_get_io_buf(
3633 icp_dev_acquire_info->io_config_cmd_handle,
3634 hw_mgr->iommu_hdl,
3635 &io_buf_addr, &io_buf_size);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05303636 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07003637 CAM_ERR(CAM_ICP, "unable to get src buf info from io desc");
Suresh Vankadarad8905f42017-06-04 13:33:49 +05303638 goto get_io_buf_failed;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003639 }
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07003640
3641 CAM_DBG(CAM_ICP, "hdl: %d, addr: %pK, size: %zu",
3642 icp_dev_acquire_info->io_config_cmd_handle,
3643 (void *)io_buf_addr, io_buf_size);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003644
Suresh Vankadarad8905f42017-06-04 13:33:49 +05303645 mutex_lock(&hw_mgr->hw_mgr_mutex);
Suresh Vankadara5499a5f2017-06-16 22:13:56 +05303646 if (!hw_mgr->ctxt_cnt) {
Suresh Vankadara34494fc2017-08-12 18:18:09 +05303647 rc = cam_icp_clk_info_init(hw_mgr, ctx_data);
Suresh Vankadara466bed22017-11-30 06:30:20 +05303648 if (rc) {
3649 mutex_unlock(&hw_mgr->hw_mgr_mutex);
Suresh Vankadara34494fc2017-08-12 18:18:09 +05303650 goto get_io_buf_failed;
Suresh Vankadara466bed22017-11-30 06:30:20 +05303651 }
3652
3653 rc = cam_icp_mgr_icp_resume(hw_mgr);
3654 if (rc) {
3655 mutex_unlock(&hw_mgr->hw_mgr_mutex);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05303656 goto get_io_buf_failed;
Suresh Vankadara466bed22017-11-30 06:30:20 +05303657 }
Suresh Vankadaraaa6ff8f2017-10-26 22:51:27 +05303658
Abhilash Kumar8d511bc2018-01-05 11:44:43 +05303659 if (icp_hw_mgr.a5_debug_q)
3660 hfi_set_debug_level(icp_hw_mgr.a5_dbg_lvl);
3661
Suresh Vankadaraaa6ff8f2017-10-26 22:51:27 +05303662 rc = cam_icp_send_ubwc_cfg(hw_mgr);
Suresh Vankadara466bed22017-11-30 06:30:20 +05303663 if (rc) {
3664 mutex_unlock(&hw_mgr->hw_mgr_mutex);
Suresh Vankadaraaa6ff8f2017-10-26 22:51:27 +05303665 goto ubwc_cfg_failed;
Suresh Vankadara466bed22017-11-30 06:30:20 +05303666 }
3667 }
Junzhe Zoubc37c562017-11-20 18:23:49 -08003668
3669 if (!hw_mgr->bps_ctxt_cnt || !hw_mgr->ipe_ctxt_cnt)
Suresh Vankadarac092e592018-01-11 18:52:41 +05303670 cam_icp_device_timer_start(hw_mgr);
3671
3672 cam_icp_ctx_timer_start(ctx_data);
Junzhe Zoubc37c562017-11-20 18:23:49 -08003673
Suresh Vankadara466bed22017-11-30 06:30:20 +05303674 rc = cam_icp_mgr_ipe_bps_resume(hw_mgr, ctx_data);
3675 if (rc) {
3676 mutex_unlock(&hw_mgr->hw_mgr_mutex);
3677 goto ipe_bps_resume_failed;
Suresh Vankadara5499a5f2017-06-16 22:13:56 +05303678 }
Suresh Vankadarad8905f42017-06-04 13:33:49 +05303679 mutex_unlock(&hw_mgr->hw_mgr_mutex);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003680
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05303681 rc = cam_icp_mgr_send_ping(ctx_data);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003682 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07003683 CAM_ERR(CAM_ICP, "ping ack not received");
Suresh Vankadarad8905f42017-06-04 13:33:49 +05303684 goto send_ping_failed;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003685 }
Suresh Vankadara466bed22017-11-30 06:30:20 +05303686 CAM_DBG(CAM_ICP, "ping ack received");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003687
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05303688 rc = cam_icp_mgr_create_handle(icp_dev_acquire_info->dev_type,
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05303689 ctx_data);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003690 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07003691 CAM_ERR(CAM_ICP, "create handle failed");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003692 goto create_handle_failed;
3693 }
3694
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05303695 rc = cam_icp_mgr_send_config_io(ctx_data, io_buf_addr);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003696 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07003697 CAM_ERR(CAM_ICP, "IO Config command failed");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003698 goto ioconfig_failed;
3699 }
3700
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003701 ctx_data->context_priv = args->context_data;
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05303702 args->ctxt_to_hw_map = ctx_data;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003703
3704 bitmap_size = BITS_TO_LONGS(CAM_FRAME_CMD_MAX) * sizeof(long);
3705 ctx_data->hfi_frame_process.bitmap =
Lakshmi Narayana Kalavalaaae1e6b2017-06-14 09:58:40 -07003706 kzalloc(bitmap_size, GFP_KERNEL);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05303707 if (!ctx_data->hfi_frame_process.bitmap)
3708 goto ioconfig_failed;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003709 ctx_data->hfi_frame_process.bits = bitmap_size * BITS_PER_BYTE;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003710 hw_mgr->ctx_data[ctx_id].ctxt_event_cb = args->event_cb;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05303711 icp_dev_acquire_info->scratch_mem_size = ctx_data->scratch_mem_size;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003712
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003713 if (copy_to_user((void __user *)args->acquire_info,
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05303714 icp_dev_acquire_info, sizeof(struct cam_icp_acquire_dev_info)))
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003715 goto copy_to_user_failed;
3716
Suresh Vankadara34494fc2017-08-12 18:18:09 +05303717 cam_icp_ctx_clk_info_init(ctx_data);
Suresh Vankadarac7b0c672017-11-25 00:44:10 +05303718 ctx_data->state = CAM_ICP_CTX_STATE_ACQUIRED;
Suresh Vankadara22697d32017-07-03 12:14:09 -07003719 mutex_unlock(&ctx_data->ctx_mutex);
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07003720 CAM_DBG(CAM_ICP, "scratch size = %x fw_handle = %x",
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05303721 (unsigned int)icp_dev_acquire_info->scratch_mem_size,
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003722 (unsigned int)ctx_data->fw_handle);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05303723 mutex_lock(&hw_mgr->hw_mgr_mutex);
Suresh Vankadara5499a5f2017-06-16 22:13:56 +05303724 hw_mgr->ctxt_cnt++;
Suresh Vankadarad8905f42017-06-04 13:33:49 +05303725 mutex_unlock(&hw_mgr->hw_mgr_mutex);
Suresh Vankadara466bed22017-11-30 06:30:20 +05303726 CAM_DBG(CAM_ICP, "Acquire Done");
Suresh Vankadarad8905f42017-06-04 13:33:49 +05303727
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003728 return 0;
3729
3730copy_to_user_failed:
Suresh Vankadarad8905f42017-06-04 13:33:49 +05303731 kfree(ctx_data->hfi_frame_process.bitmap);
3732 ctx_data->hfi_frame_process.bitmap = NULL;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003733ioconfig_failed:
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05303734 cam_icp_mgr_destroy_handle(ctx_data);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003735create_handle_failed:
Suresh Vankadara6657bc22017-07-31 10:33:04 +05303736send_ping_failed:
3737 cam_icp_mgr_ipe_bps_power_collapse(hw_mgr, ctx_data, 0);
3738ipe_bps_resume_failed:
Suresh Vankadarac092e592018-01-11 18:52:41 +05303739 cam_icp_ctx_timer_stop(&hw_mgr->ctx_data[ctx_id]);
Suresh Vankadara466bed22017-11-30 06:30:20 +05303740ubwc_cfg_failed:
Suresh Vankadara5499a5f2017-06-16 22:13:56 +05303741 if (!hw_mgr->ctxt_cnt)
Suresh Vankadara466bed22017-11-30 06:30:20 +05303742 cam_icp_mgr_icp_power_collapse(hw_mgr);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05303743get_io_buf_failed:
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05303744 kfree(hw_mgr->ctx_data[ctx_id].icp_dev_acquire_info);
3745 hw_mgr->ctx_data[ctx_id].icp_dev_acquire_info = NULL;
3746acquire_info_failed:
3747 cam_icp_mgr_put_ctx(ctx_data);
Suresh Vankadara22697d32017-07-03 12:14:09 -07003748 mutex_unlock(&ctx_data->ctx_mutex);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003749 return rc;
3750}
3751
3752static int cam_icp_mgr_get_hw_caps(void *hw_mgr_priv, void *hw_caps_args)
3753{
3754 int rc = 0;
3755 struct cam_icp_hw_mgr *hw_mgr = hw_mgr_priv;
3756 struct cam_query_cap_cmd *query_cap = hw_caps_args;
3757
3758 if ((!hw_mgr_priv) || (!hw_caps_args)) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07003759 CAM_ERR(CAM_ICP, "Invalid params: %pK %pK",
3760 hw_mgr_priv, hw_caps_args);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003761 return -EINVAL;
3762 }
3763
Suresh Vankadara22697d32017-07-03 12:14:09 -07003764 mutex_lock(&hw_mgr->hw_mgr_mutex);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003765 if (copy_from_user(&icp_hw_mgr.icp_caps,
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05303766 (void __user *)query_cap->caps_handle,
3767 sizeof(struct cam_icp_query_cap_cmd))) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07003768 CAM_ERR(CAM_ICP, "copy_from_user failed");
Suresh Vankadara22697d32017-07-03 12:14:09 -07003769 rc = -EFAULT;
3770 goto end;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003771 }
3772
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003773 rc = hfi_get_hw_caps(&icp_hw_mgr.icp_caps);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05303774 if (rc)
Suresh Vankadara22697d32017-07-03 12:14:09 -07003775 goto end;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003776
3777 icp_hw_mgr.icp_caps.dev_iommu_handle.non_secure = hw_mgr->iommu_hdl;
3778 icp_hw_mgr.icp_caps.dev_iommu_handle.secure = hw_mgr->iommu_sec_hdl;
3779
3780 if (copy_to_user((void __user *)query_cap->caps_handle,
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05303781 &icp_hw_mgr.icp_caps, sizeof(struct cam_icp_query_cap_cmd))) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07003782 CAM_ERR(CAM_ICP, "copy_to_user failed");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003783 rc = -EFAULT;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003784 }
Suresh Vankadara22697d32017-07-03 12:14:09 -07003785end:
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003786 mutex_unlock(&hw_mgr->hw_mgr_mutex);
3787 return rc;
3788}
3789
Suresh Vankadara22697d32017-07-03 12:14:09 -07003790static int cam_icp_mgr_alloc_devs(struct device_node *of_node)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003791{
Suresh Vankadara22697d32017-07-03 12:14:09 -07003792 int rc;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003793 uint32_t num_dev;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003794
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003795 rc = of_property_read_u32(of_node, "num-a5", &num_dev);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05303796 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07003797 CAM_ERR(CAM_ICP, "getting num of a5 failed");
Suresh Vankadara22697d32017-07-03 12:14:09 -07003798 goto num_a5_failed;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003799 }
3800
3801 icp_hw_mgr.devices[CAM_ICP_DEV_A5] = kzalloc(
3802 sizeof(struct cam_hw_intf *) * num_dev, GFP_KERNEL);
3803 if (!icp_hw_mgr.devices[CAM_ICP_DEV_A5]) {
3804 rc = -ENOMEM;
Suresh Vankadara22697d32017-07-03 12:14:09 -07003805 goto num_a5_failed;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003806 }
3807
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05303808 rc = of_property_read_u32(of_node, "num-ipe", &num_dev);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05303809 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07003810 CAM_ERR(CAM_ICP, "getting number of ipe dev nodes failed");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003811 goto num_ipe_failed;
3812 }
3813
Suresh Vankadaraaa6ff8f2017-10-26 22:51:27 +05303814 if (!icp_hw_mgr.ipe1_enable)
3815 num_dev = 1;
3816
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003817 icp_hw_mgr.devices[CAM_ICP_DEV_IPE] = kzalloc(
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05303818 sizeof(struct cam_hw_intf *) * num_dev, GFP_KERNEL);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003819 if (!icp_hw_mgr.devices[CAM_ICP_DEV_IPE]) {
3820 rc = -ENOMEM;
3821 goto num_ipe_failed;
3822 }
3823
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003824 rc = of_property_read_u32(of_node, "num-bps", &num_dev);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05303825 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07003826 CAM_ERR(CAM_ICP, "read num bps devices failed");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003827 goto num_bps_failed;
3828 }
3829 icp_hw_mgr.devices[CAM_ICP_DEV_BPS] = kzalloc(
3830 sizeof(struct cam_hw_intf *) * num_dev, GFP_KERNEL);
3831 if (!icp_hw_mgr.devices[CAM_ICP_DEV_BPS]) {
3832 rc = -ENOMEM;
3833 goto num_bps_failed;
3834 }
3835
Suresh Vankadara22697d32017-07-03 12:14:09 -07003836 return 0;
3837num_bps_failed:
3838 kfree(icp_hw_mgr.devices[CAM_ICP_DEV_IPE]);
3839num_ipe_failed:
3840 kfree(icp_hw_mgr.devices[CAM_ICP_DEV_A5]);
3841num_a5_failed:
3842 return rc;
3843}
3844
3845static int cam_icp_mgr_init_devs(struct device_node *of_node)
3846{
3847 int rc = 0;
3848 int count, i;
3849 const char *name = NULL;
3850 struct device_node *child_node = NULL;
3851 struct platform_device *child_pdev = NULL;
3852 struct cam_hw_intf *child_dev_intf = NULL;
3853
3854 rc = cam_icp_mgr_alloc_devs(of_node);
3855 if (rc)
3856 return rc;
3857
3858 count = of_property_count_strings(of_node, "compat-hw-name");
3859 if (!count) {
3860 CAM_ERR(CAM_ICP, "no compat hw found in dev tree, cnt = %d",
3861 count);
3862 rc = -EINVAL;
3863 goto compat_hw_name_failed;
3864 }
3865
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003866 for (i = 0; i < count; i++) {
3867 rc = of_property_read_string_index(of_node, "compat-hw-name",
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05303868 i, &name);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05303869 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07003870 CAM_ERR(CAM_ICP, "getting dev object name failed");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003871 goto compat_hw_name_failed;
3872 }
3873
3874 child_node = of_find_node_by_name(NULL, name);
3875 if (!child_node) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07003876 CAM_ERR(CAM_ICP, "Cannot find node in dtsi %s", name);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003877 rc = -ENODEV;
3878 goto compat_hw_name_failed;
3879 }
3880
3881 child_pdev = of_find_device_by_node(child_node);
3882 if (!child_pdev) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07003883 CAM_ERR(CAM_ICP, "failed to find device on bus %s",
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003884 child_node->name);
3885 rc = -ENODEV;
3886 of_node_put(child_node);
3887 goto compat_hw_name_failed;
3888 }
3889
3890 child_dev_intf = (struct cam_hw_intf *)platform_get_drvdata(
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05303891 child_pdev);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003892 if (!child_dev_intf) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07003893 CAM_ERR(CAM_ICP, "no child device");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003894 of_node_put(child_node);
Suresh Vankadaraaa6ff8f2017-10-26 22:51:27 +05303895 if (!icp_hw_mgr.ipe1_enable)
3896 continue;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003897 goto compat_hw_name_failed;
3898 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003899 icp_hw_mgr.devices[child_dev_intf->hw_type]
3900 [child_dev_intf->hw_idx] = child_dev_intf;
3901
Suresh Vankadara6657bc22017-07-31 10:33:04 +05303902 if (!child_dev_intf->hw_ops.process_cmd)
3903 goto compat_hw_name_failed;
3904
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003905 of_node_put(child_node);
3906 }
3907
Karthik Anantha Ram9f13d0e2017-11-30 14:55:44 -08003908 icp_hw_mgr.a5_dev_intf = icp_hw_mgr.devices[CAM_ICP_DEV_A5][0];
3909 icp_hw_mgr.bps_dev_intf = icp_hw_mgr.devices[CAM_ICP_DEV_BPS][0];
3910 icp_hw_mgr.ipe0_dev_intf = icp_hw_mgr.devices[CAM_ICP_DEV_IPE][0];
3911 if (icp_hw_mgr.ipe1_enable)
3912 icp_hw_mgr.ipe1_dev_intf =
3913 icp_hw_mgr.devices[CAM_ICP_DEV_IPE][1];
3914
Suresh Vankadara22697d32017-07-03 12:14:09 -07003915 return 0;
3916compat_hw_name_failed:
3917 kfree(icp_hw_mgr.devices[CAM_ICP_DEV_BPS]);
3918 kfree(icp_hw_mgr.devices[CAM_ICP_DEV_IPE]);
3919 kfree(icp_hw_mgr.devices[CAM_ICP_DEV_A5]);
3920 return rc;
3921}
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003922
Suresh Vankadara22697d32017-07-03 12:14:09 -07003923static int cam_icp_mgr_create_wq(void)
3924{
3925 int rc;
3926 int i;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003927
3928 rc = cam_req_mgr_workq_create("icp_command_queue", ICP_WORKQ_NUM_TASK,
Sagar Gore9f404712017-05-22 16:57:25 -07003929 &icp_hw_mgr.cmd_work, CRM_WORKQ_USAGE_NON_IRQ);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05303930 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07003931 CAM_ERR(CAM_ICP, "unable to create a worker");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003932 goto cmd_work_failed;
3933 }
3934
3935 rc = cam_req_mgr_workq_create("icp_message_queue", ICP_WORKQ_NUM_TASK,
Sagar Gore9f404712017-05-22 16:57:25 -07003936 &icp_hw_mgr.msg_work, CRM_WORKQ_USAGE_IRQ);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05303937 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07003938 CAM_ERR(CAM_ICP, "unable to create a worker");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003939 goto msg_work_failed;
3940 }
3941
3942 icp_hw_mgr.cmd_work_data = (struct hfi_cmd_work_data *)
3943 kzalloc(sizeof(struct hfi_cmd_work_data) * ICP_WORKQ_NUM_TASK,
3944 GFP_KERNEL);
3945 if (!icp_hw_mgr.cmd_work_data)
3946 goto cmd_work_data_failed;
3947
3948 icp_hw_mgr.msg_work_data = (struct hfi_msg_work_data *)
3949 kzalloc(sizeof(struct hfi_msg_work_data) * ICP_WORKQ_NUM_TASK,
3950 GFP_KERNEL);
3951 if (!icp_hw_mgr.msg_work_data)
3952 goto msg_work_data_failed;
3953
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07003954 rc = cam_icp_hw_mgr_create_debugfs_entry();
3955 if (rc)
3956 goto msg_work_data_failed;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003957
3958 for (i = 0; i < ICP_WORKQ_NUM_TASK; i++)
3959 icp_hw_mgr.msg_work->task.pool[i].payload =
3960 &icp_hw_mgr.msg_work_data[i];
3961
3962 for (i = 0; i < ICP_WORKQ_NUM_TASK; i++)
3963 icp_hw_mgr.cmd_work->task.pool[i].payload =
3964 &icp_hw_mgr.cmd_work_data[i];
3965
Suresh Vankadara22697d32017-07-03 12:14:09 -07003966 return 0;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07003967msg_work_data_failed:
3968 kfree(icp_hw_mgr.cmd_work_data);
3969cmd_work_data_failed:
3970 cam_req_mgr_workq_destroy(&icp_hw_mgr.msg_work);
3971msg_work_failed:
3972 cam_req_mgr_workq_destroy(&icp_hw_mgr.cmd_work);
3973cmd_work_failed:
Suresh Vankadara22697d32017-07-03 12:14:09 -07003974 return rc;
3975}
3976
3977int cam_icp_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl)
3978{
3979 int i, rc = 0;
3980 struct cam_hw_mgr_intf *hw_mgr_intf;
Suresh Vankadaraaa6ff8f2017-10-26 22:51:27 +05303981 struct cam_cpas_query_cap query;
3982 uint32_t cam_caps;
Suresh Vankadara22697d32017-07-03 12:14:09 -07003983
3984 hw_mgr_intf = (struct cam_hw_mgr_intf *)hw_mgr_hdl;
3985 if (!of_node || !hw_mgr_intf) {
3986 CAM_ERR(CAM_ICP, "Invalid args of_node %pK hw_mgr %pK",
3987 of_node, hw_mgr_intf);
3988 return -EINVAL;
3989 }
3990
3991 hw_mgr_intf->hw_mgr_priv = &icp_hw_mgr;
3992 hw_mgr_intf->hw_get_caps = cam_icp_mgr_get_hw_caps;
3993 hw_mgr_intf->hw_acquire = cam_icp_mgr_acquire_hw;
3994 hw_mgr_intf->hw_release = cam_icp_mgr_release_hw;
3995 hw_mgr_intf->hw_prepare_update = cam_icp_mgr_prepare_hw_update;
3996 hw_mgr_intf->hw_config = cam_icp_mgr_config_hw;
Harsh Shah6baba8c2017-10-16 19:23:29 -07003997 hw_mgr_intf->hw_open = cam_icp_mgr_hw_open;
Suresh Vankadara22697d32017-07-03 12:14:09 -07003998 hw_mgr_intf->hw_close = cam_icp_mgr_hw_close;
Junzhe Zou4b11e7a2017-11-13 17:21:32 -08003999 hw_mgr_intf->hw_flush = cam_icp_mgr_hw_flush;
Suresh Vankadara22697d32017-07-03 12:14:09 -07004000
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07004001 icp_hw_mgr.secure_mode = CAM_SECURE_MODE_NON_SECURE;
Suresh Vankadara22697d32017-07-03 12:14:09 -07004002 mutex_init(&icp_hw_mgr.hw_mgr_mutex);
4003 spin_lock_init(&icp_hw_mgr.hw_mgr_lock);
4004
4005 for (i = 0; i < CAM_ICP_CTX_MAX; i++)
4006 mutex_init(&icp_hw_mgr.ctx_data[i].ctx_mutex);
4007
Suresh Vankadaraaa6ff8f2017-10-26 22:51:27 +05304008 cam_cpas_get_hw_info(&query.camera_family,
4009 &query.camera_version, &query.cpas_version, &cam_caps);
4010 if (cam_caps & CPAS_IPE0_BIT)
4011 icp_hw_mgr.ipe0_enable = true;
4012 if (cam_caps & CPAS_IPE1_BIT)
4013 icp_hw_mgr.ipe1_enable = true;
4014 if (cam_caps & CPAS_BPS_BIT)
4015 icp_hw_mgr.bps_enable = true;
4016
Suresh Vankadara22697d32017-07-03 12:14:09 -07004017 rc = cam_icp_mgr_init_devs(of_node);
4018 if (rc)
4019 goto dev_init_failed;
4020
4021 rc = cam_smmu_get_handle("icp", &icp_hw_mgr.iommu_hdl);
4022 if (rc) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07004023 CAM_ERR(CAM_ICP, "get mmu handle failed: %d", rc);
Suresh Vankadara22697d32017-07-03 12:14:09 -07004024 goto icp_get_hdl_failed;
4025 }
4026
4027 rc = cam_smmu_ops(icp_hw_mgr.iommu_hdl, CAM_SMMU_ATTACH);
4028 if (rc) {
4029 CAM_ERR(CAM_ICP, "icp attach failed: %d", rc);
4030 goto icp_attach_failed;
4031 }
4032
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07004033 rc = cam_smmu_get_handle("cam-secure", &icp_hw_mgr.iommu_sec_hdl);
4034 if (rc) {
4035 CAM_ERR(CAM_ICP, "get secure mmu handle failed: %d", rc);
4036 goto secure_hdl_failed;
4037 }
4038
Suresh Vankadara22697d32017-07-03 12:14:09 -07004039 rc = cam_icp_mgr_create_wq();
4040 if (rc)
4041 goto icp_wq_create_failed;
4042
4043 init_completion(&icp_hw_mgr.a5_complete);
4044
4045 return rc;
4046
4047icp_wq_create_failed:
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07004048 cam_smmu_destroy_handle(icp_hw_mgr.iommu_sec_hdl);
4049 icp_hw_mgr.iommu_sec_hdl = -1;
4050secure_hdl_failed:
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07004051 cam_smmu_ops(icp_hw_mgr.iommu_hdl, CAM_SMMU_DETACH);
4052icp_attach_failed:
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05304053 cam_smmu_destroy_handle(icp_hw_mgr.iommu_hdl);
Suresh Vankadara22697d32017-07-03 12:14:09 -07004054 icp_hw_mgr.iommu_hdl = -1;
4055icp_get_hdl_failed:
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07004056 kfree(icp_hw_mgr.devices[CAM_ICP_DEV_BPS]);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07004057 kfree(icp_hw_mgr.devices[CAM_ICP_DEV_IPE]);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07004058 kfree(icp_hw_mgr.devices[CAM_ICP_DEV_A5]);
Suresh Vankadara22697d32017-07-03 12:14:09 -07004059dev_init_failed:
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07004060 mutex_destroy(&icp_hw_mgr.hw_mgr_mutex);
4061 for (i = 0; i < CAM_ICP_CTX_MAX; i++)
4062 mutex_destroy(&icp_hw_mgr.ctx_data[i].ctx_mutex);
4063
4064 return rc;
4065}