blob: 171d8bdd785471d66cb8eca4c5d2aa28b4d76efa [file] [log] [blame]
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
2 *
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>
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -070027
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -070028#include "cam_sync_api.h"
Harsh Shahe9e8ff52017-05-16 17:26:45 -070029#include "cam_packet_util.h"
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -070030#include "cam_hw.h"
31#include "cam_hw_mgr_intf.h"
32#include "cam_icp_hw_mgr_intf.h"
33#include "cam_icp_hw_mgr.h"
34#include "cam_a5_hw_intf.h"
35#include "cam_bps_hw_intf.h"
36#include "cam_ipe_hw_intf.h"
37#include "cam_smmu_api.h"
38#include "cam_mem_mgr.h"
39#include "hfi_intf.h"
40#include "hfi_reg.h"
41#include "hfi_session_defs.h"
42#include "hfi_sys_defs.h"
43#include "cam_req_mgr_workq.h"
44#include "cam_mem_mgr.h"
45#include "a5_core.h"
46#include "hfi_sys_defs.h"
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -070047#include "cam_debug_util.h"
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -070048
Suresh Vankadara22697d32017-07-03 12:14:09 -070049#define ICP_WORKQ_NUM_TASK 30
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -070050#define ICP_WORKQ_TASK_CMD_TYPE 1
51#define ICP_WORKQ_TASK_MSG_TYPE 2
52
53static struct cam_icp_hw_mgr icp_hw_mgr;
54
Suresh Vankadara6657bc22017-07-31 10:33:04 +053055static int cam_icp_mgr_ipe_bps_resume(struct cam_icp_hw_mgr *hw_mgr,
56 struct cam_icp_hw_ctx_data *ctx_data)
57{
58 struct cam_hw_intf *ipe0_dev_intf = NULL;
59 struct cam_hw_intf *ipe1_dev_intf = NULL;
60 struct cam_hw_intf *bps_dev_intf = NULL;
61 int rc = 0;
62
63 if (!icp_hw_mgr.icp_pc_flag)
64 return rc;
65
66 ipe0_dev_intf = hw_mgr->devices[CAM_ICP_DEV_IPE][0];
67 ipe1_dev_intf = hw_mgr->devices[CAM_ICP_DEV_IPE][1];
68 bps_dev_intf = hw_mgr->devices[CAM_ICP_DEV_BPS][0];
69
70 if ((!ipe0_dev_intf) || (!bps_dev_intf)) {
71 CAM_ERR(CAM_ICP, "dev intfs are wrong, failed to close");
72 return -EINVAL;
73 }
74
75 bps_dev_intf->hw_ops.process_cmd(
76 bps_dev_intf->hw_priv,
77 CAM_ICP_BPS_CMD_POWER_RESUME, NULL, 0);
78
79 ipe0_dev_intf->hw_ops.process_cmd(
80 ipe0_dev_intf->hw_priv,
81 CAM_ICP_IPE_CMD_POWER_RESUME, NULL, 0);
82
83 if (ipe1_dev_intf) {
84 ipe1_dev_intf->hw_ops.process_cmd(
85 ipe1_dev_intf->hw_priv,
86 CAM_ICP_IPE_CMD_POWER_RESUME, NULL, 0);
87 }
88
89 rc = hfi_enable_ipe_bps_pc(true);
90
91 return rc;
92}
93
94static int cam_icp_mgr_ipe_bps_power_collapse(struct cam_icp_hw_mgr *hw_mgr,
95 struct cam_icp_hw_ctx_data *ctx_data, int dev_type)
96{
97 int rc = 0;
98 struct cam_hw_intf *ipe0_dev_intf = NULL;
99 struct cam_hw_intf *ipe1_dev_intf = NULL;
100 struct cam_hw_intf *bps_dev_intf = NULL;
101
102 if (!icp_hw_mgr.icp_pc_flag)
103 return rc;
104
105 ipe0_dev_intf = hw_mgr->devices[CAM_ICP_DEV_IPE][0];
106 ipe1_dev_intf = hw_mgr->devices[CAM_ICP_DEV_IPE][1];
107 bps_dev_intf = hw_mgr->devices[CAM_ICP_DEV_BPS][0];
108
109 if ((!ipe0_dev_intf) || (!bps_dev_intf)) {
110 CAM_ERR(CAM_ICP, "dev intfs are wrong, failed to close");
111 return -EINVAL;
112 }
113
114 rc = bps_dev_intf->hw_ops.process_cmd(
115 bps_dev_intf->hw_priv,
116 CAM_ICP_BPS_CMD_POWER_COLLAPSE, NULL, 0);
117
118 rc = ipe0_dev_intf->hw_ops.process_cmd(
119 ipe0_dev_intf->hw_priv,
120 CAM_ICP_IPE_CMD_POWER_COLLAPSE, NULL, 0);
121
122 if (ipe1_dev_intf) {
123 rc = ipe1_dev_intf->hw_ops.process_cmd(
124 ipe1_dev_intf->hw_priv,
125 CAM_ICP_IPE_CMD_POWER_COLLAPSE, NULL, 0);
126 }
127
128 return rc;
129}
130
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -0700131static int cam_icp_hw_mgr_create_debugfs_entry(void)
132{
133 icp_hw_mgr.dentry = debugfs_create_dir("camera_icp", NULL);
134 if (!icp_hw_mgr.dentry)
135 return -ENOMEM;
136
137 if (!debugfs_create_bool("a5_debug",
138 0644,
139 icp_hw_mgr.dentry,
140 &icp_hw_mgr.a5_debug)) {
141 debugfs_remove_recursive(icp_hw_mgr.dentry);
142 return -ENOMEM;
143 }
144
Suresh Vankadara6657bc22017-07-31 10:33:04 +0530145 if (!debugfs_create_bool("icp_pc",
146 0644,
147 icp_hw_mgr.dentry,
148 &icp_hw_mgr.icp_pc_flag)) {
149 CAM_ERR(CAM_ICP, "failed to create icp_pc entry");
150 return -ENOMEM;
151 }
152
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -0700153 return 0;
154}
155
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700156static int cam_icp_mgr_process_cmd(void *priv, void *data)
157{
158 int rc;
159 struct hfi_cmd_work_data *task_data = NULL;
160 struct cam_icp_hw_mgr *hw_mgr;
161
162 if (!data || !priv) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700163 CAM_ERR(CAM_ICP, "Invalid params%pK %pK", data, priv);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700164 return -EINVAL;
165 }
166
167 hw_mgr = priv;
168 task_data = (struct hfi_cmd_work_data *)data;
169
170 rc = hfi_write_cmd(task_data->data);
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530171
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700172 return rc;
173}
174
Suresh Vankadara22697d32017-07-03 12:14:09 -0700175static int cam_icp_mgr_handle_frame_process(uint32_t *msg_ptr, int flag)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700176{
177 int i;
178 uint32_t idx;
Sagar Gorecdd6a5e2017-05-17 19:06:59 -0700179 uint64_t request_id;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700180 struct cam_icp_hw_ctx_data *ctx_data = NULL;
181 struct hfi_msg_ipebps_async_ack *ioconfig_ack = NULL;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700182 struct hfi_frame_process_info *hfi_frame_process;
Sagar Gorecdd6a5e2017-05-17 19:06:59 -0700183 struct cam_hw_done_event_data buf_data;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700184
185 ioconfig_ack = (struct hfi_msg_ipebps_async_ack *)msg_ptr;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700186 request_id = ioconfig_ack->user_data2;
Suresh Vankadara22697d32017-07-03 12:14:09 -0700187 ctx_data = (struct cam_icp_hw_ctx_data *)ioconfig_ack->user_data1;
188 if (!ctx_data) {
189 CAM_ERR(CAM_ICP, "Invalid Context");
190 return -EINVAL;
191 }
192 CAM_DBG(CAM_ICP, "ctx : %pK, request_id :%lld",
193 (void *)ctx_data->context_priv, request_id);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700194
Suresh Vankadara22697d32017-07-03 12:14:09 -0700195 mutex_lock(&ctx_data->ctx_mutex);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700196 hfi_frame_process = &ctx_data->hfi_frame_process;
197 for (i = 0; i < CAM_FRAME_CMD_MAX; i++)
198 if (hfi_frame_process->request_id[i] == request_id)
199 break;
200
201 if (i >= CAM_FRAME_CMD_MAX) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700202 CAM_ERR(CAM_ICP, "pkt not found in ctx data for req_id =%lld",
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700203 request_id);
Suresh Vankadara22697d32017-07-03 12:14:09 -0700204 mutex_unlock(&ctx_data->ctx_mutex);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700205 return -EINVAL;
206 }
207 idx = i;
208
Sagar Gorecdd6a5e2017-05-17 19:06:59 -0700209 buf_data.request_id = hfi_frame_process->request_id[idx];
Suresh Vankadara22697d32017-07-03 12:14:09 -0700210 ctx_data->ctxt_event_cb(ctx_data->context_priv, flag, &buf_data);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700211 hfi_frame_process->request_id[idx] = 0;
212 clear_bit(idx, ctx_data->hfi_frame_process.bitmap);
Suresh Vankadara22697d32017-07-03 12:14:09 -0700213 mutex_unlock(&ctx_data->ctx_mutex);
214
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700215 return 0;
216}
217
Suresh Vankadara22697d32017-07-03 12:14:09 -0700218static int cam_icp_mgr_process_msg_frame_process(uint32_t *msg_ptr)
219{
220 struct hfi_msg_ipebps_async_ack *ioconfig_ack = NULL;
221 struct hfi_msg_frame_process_done *frame_done;
222
223 if (!msg_ptr) {
224 CAM_ERR(CAM_ICP, "msg ptr is NULL");
225 return -EINVAL;
226 }
227
228 ioconfig_ack = (struct hfi_msg_ipebps_async_ack *)msg_ptr;
229 if (ioconfig_ack->err_type != HFI_ERR_SYS_NONE) {
230 CAM_ERR(CAM_ICP, "failed with error : %u",
231 ioconfig_ack->err_type);
232 cam_icp_mgr_handle_frame_process(msg_ptr,
233 ICP_FRAME_PROCESS_FAILURE);
234 return -EIO;
235 }
236
237 frame_done =
238 (struct hfi_msg_frame_process_done *)ioconfig_ack->msg_data;
239 if (!frame_done) {
240 cam_icp_mgr_handle_frame_process(msg_ptr,
241 ICP_FRAME_PROCESS_FAILURE);
242 return -EINVAL;
243 }
244
245 if (frame_done->result)
246 return cam_icp_mgr_handle_frame_process(msg_ptr,
247 ICP_FRAME_PROCESS_FAILURE);
248 else
249 return cam_icp_mgr_handle_frame_process(msg_ptr,
250 ICP_FRAME_PROCESS_SUCCESS);
251}
252
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700253static int cam_icp_mgr_process_msg_config_io(uint32_t *msg_ptr)
254{
255 struct cam_icp_hw_ctx_data *ctx_data = NULL;
256 struct hfi_msg_ipebps_async_ack *ioconfig_ack = NULL;
257 struct hfi_msg_ipe_config *ipe_config_ack = NULL;
258 struct hfi_msg_bps_common *bps_config_ack = NULL;
259
Suresh Vankadara22697d32017-07-03 12:14:09 -0700260 if (!msg_ptr) {
261 CAM_ERR(CAM_ICP, "msg ptr is NULL");
262 return -EINVAL;
263 }
264
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700265 ioconfig_ack = (struct hfi_msg_ipebps_async_ack *)msg_ptr;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700266
267 if (ioconfig_ack->opcode == HFI_IPEBPS_CMD_OPCODE_IPE_CONFIG_IO) {
268 ipe_config_ack =
269 (struct hfi_msg_ipe_config *)(ioconfig_ack->msg_data);
270 if (ipe_config_ack->rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700271 CAM_ERR(CAM_ICP, "rc = %d err = %u",
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700272 ipe_config_ack->rc, ioconfig_ack->err_type);
273 return -EIO;
274 }
275 ctx_data =
276 (struct cam_icp_hw_ctx_data *)ioconfig_ack->user_data1;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +0530277 if (!ctx_data) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700278 CAM_ERR(CAM_ICP, "wrong ctx data from IPE response");
Suresh Vankadaraadcf0582017-05-24 09:53:36 +0530279 return -EINVAL;
280 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700281 ctx_data->scratch_mem_size = ipe_config_ack->scratch_mem_size;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700282 } else {
283 bps_config_ack =
284 (struct hfi_msg_bps_common *)(ioconfig_ack->msg_data);
285 if (bps_config_ack->rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700286 CAM_ERR(CAM_ICP, "rc : %u, opcode :%u",
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700287 bps_config_ack->rc, ioconfig_ack->opcode);
288 return -EIO;
289 }
290 ctx_data =
291 (struct cam_icp_hw_ctx_data *)ioconfig_ack->user_data1;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +0530292 if (!ctx_data) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700293 CAM_ERR(CAM_ICP, "wrong ctx data from BPS response");
Suresh Vankadaraadcf0582017-05-24 09:53:36 +0530294 return -EINVAL;
295 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700296 }
297 complete(&ctx_data->wait_complete);
298
299 return 0;
300}
301
302static int cam_icp_mgr_process_msg_create_handle(uint32_t *msg_ptr)
303{
304 struct hfi_msg_create_handle_ack *create_handle_ack = NULL;
305 struct cam_icp_hw_ctx_data *ctx_data = NULL;
306
307 create_handle_ack = (struct hfi_msg_create_handle_ack *)msg_ptr;
308 if (!create_handle_ack) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700309 CAM_ERR(CAM_ICP, "Invalid create_handle_ack");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700310 return -EINVAL;
311 }
312
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700313 ctx_data = (struct cam_icp_hw_ctx_data *)create_handle_ack->user_data1;
314 if (!ctx_data) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700315 CAM_ERR(CAM_ICP, "Invalid ctx_data");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700316 return -EINVAL;
317 }
318
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700319 ctx_data->fw_handle = create_handle_ack->fw_handle;
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700320 CAM_DBG(CAM_ICP, "fw_handle = %x", ctx_data->fw_handle);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700321 complete(&ctx_data->wait_complete);
322
323 return 0;
324}
325
326static int cam_icp_mgr_process_msg_ping_ack(uint32_t *msg_ptr)
327{
328 struct hfi_msg_ping_ack *ping_ack = NULL;
329 struct cam_icp_hw_ctx_data *ctx_data = NULL;
330
331 ping_ack = (struct hfi_msg_ping_ack *)msg_ptr;
332 if (!ping_ack) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700333 CAM_ERR(CAM_ICP, "Empty ping ack message");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700334 return -EINVAL;
335 }
336
337 ctx_data = (struct cam_icp_hw_ctx_data *)ping_ack->user_data;
338 if (!ctx_data) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700339 CAM_ERR(CAM_ICP, "Invalid ctx_data");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700340 return -EINVAL;
341 }
342
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700343 complete(&ctx_data->wait_complete);
344
345 return 0;
346}
347
348static int cam_icp_mgr_process_indirect_ack_msg(uint32_t *msg_ptr)
349{
350 int rc;
351
Suresh Vankadara22697d32017-07-03 12:14:09 -0700352 if (!msg_ptr) {
353 CAM_ERR(CAM_ICP, "msg ptr is NULL");
354 return -EINVAL;
355 }
356
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +0530357 switch (msg_ptr[ICP_PACKET_OPCODE]) {
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700358 case HFI_IPEBPS_CMD_OPCODE_IPE_CONFIG_IO:
359 case HFI_IPEBPS_CMD_OPCODE_BPS_CONFIG_IO:
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700360 CAM_DBG(CAM_ICP, "received IPE/BPS_CONFIG_IO:");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700361 rc = cam_icp_mgr_process_msg_config_io(msg_ptr);
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530362 if (rc)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700363 return rc;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700364 break;
365
366 case HFI_IPEBPS_CMD_OPCODE_IPE_FRAME_PROCESS:
367 case HFI_IPEBPS_CMD_OPCODE_BPS_FRAME_PROCESS:
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700368 rc = cam_icp_mgr_process_msg_frame_process(msg_ptr);
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530369 if (rc)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700370 return rc;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700371 break;
372 default:
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700373 CAM_ERR(CAM_ICP, "Invalid opcode : %u",
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +0530374 msg_ptr[ICP_PACKET_OPCODE]);
Suresh Vankadara22697d32017-07-03 12:14:09 -0700375 rc = -EINVAL;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700376 break;
377 }
378
Suresh Vankadara22697d32017-07-03 12:14:09 -0700379 return rc;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700380}
381
382static int cam_icp_mgr_process_direct_ack_msg(uint32_t *msg_ptr)
383{
384 struct cam_icp_hw_ctx_data *ctx_data = NULL;
385 struct hfi_msg_ipebps_async_ack *ioconfig_ack = NULL;
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +0530386 int rc = 0;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700387
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +0530388 switch (msg_ptr[ICP_PACKET_OPCODE]) {
389 case HFI_IPEBPS_CMD_OPCODE_IPE_DESTROY:
390 case HFI_IPEBPS_CMD_OPCODE_BPS_DESTROY:
391 case HFI_IPEBPS_CMD_OPCODE_IPE_ABORT:
392 case HFI_IPEBPS_CMD_OPCODE_BPS_ABORT:
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700393 CAM_DBG(CAM_ICP, "received IPE/BPS_DESTROY/ABORT:");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700394 ioconfig_ack = (struct hfi_msg_ipebps_async_ack *)msg_ptr;
395 ctx_data =
396 (struct cam_icp_hw_ctx_data *)ioconfig_ack->user_data1;
397 complete(&ctx_data->wait_complete);
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +0530398 break;
399 default:
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700400 CAM_ERR(CAM_ICP, "Invalid opcode : %u",
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +0530401 msg_ptr[ICP_PACKET_OPCODE]);
402 rc = -EINVAL;
403 break;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700404 }
405
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +0530406 return rc;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700407}
408
409static int32_t cam_icp_mgr_process_msg(void *priv, void *data)
410{
411 int rc = 0;
412 uint32_t *msg_ptr = NULL;
413 struct hfi_msg_work_data *task_data;
414 struct cam_icp_hw_mgr *hw_mgr;
415 int read_len;
416
417 if (!data || !priv) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700418 CAM_ERR(CAM_ICP, "Invalid data");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700419 return -EINVAL;
420 }
421
422 task_data = data;
423 hw_mgr = priv;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700424
425 read_len = hfi_read_message(icp_hw_mgr.msg_buf, Q_MSG);
426 if (read_len < 0) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700427 CAM_DBG(CAM_ICP, "Unable to read msg q");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700428 return read_len;
429 }
430
431 msg_ptr = (uint32_t *)icp_hw_mgr.msg_buf;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700432
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700433 switch (msg_ptr[ICP_PACKET_TYPE]) {
434 case HFI_MSG_SYS_INIT_DONE:
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700435 CAM_DBG(CAM_ICP, "received SYS_INIT_DONE");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700436 complete(&hw_mgr->a5_complete);
437 break;
438
439 case HFI_MSG_SYS_PING_ACK:
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700440 CAM_DBG(CAM_ICP, "received SYS_PING_ACK");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700441 rc = cam_icp_mgr_process_msg_ping_ack(msg_ptr);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700442 break;
443
444 case HFI_MSG_IPEBPS_CREATE_HANDLE_ACK:
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700445 CAM_DBG(CAM_ICP, "received IPEBPS_CREATE_HANDLE_ACK");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700446 rc = cam_icp_mgr_process_msg_create_handle(msg_ptr);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700447 break;
448
449 case HFI_MSG_IPEBPS_ASYNC_COMMAND_INDIRECT_ACK:
450 rc = cam_icp_mgr_process_indirect_ack_msg(msg_ptr);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700451 break;
452
453 case HFI_MSG_IPEBPS_ASYNC_COMMAND_DIRECT_ACK:
454 rc = cam_icp_mgr_process_direct_ack_msg(msg_ptr);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700455 break;
456
457 case HFI_MSG_EVENT_NOTIFY:
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700458 CAM_DBG(CAM_ICP, "received EVENT_NOTIFY");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700459 break;
460
461 default:
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700462 CAM_ERR(CAM_ICP, "invalid msg : %u",
463 msg_ptr[ICP_PACKET_TYPE]);
Suresh Vankadara22697d32017-07-03 12:14:09 -0700464 rc = -EINVAL;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700465 break;
466 }
467
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700468 return rc;
469}
470
471int32_t cam_icp_hw_mgr_cb(uint32_t irq_status, void *data)
472{
473 int32_t rc = 0;
474 unsigned long flags;
475 struct cam_icp_hw_mgr *hw_mgr = data;
476 struct crm_workq_task *task;
477 struct hfi_msg_work_data *task_data;
478
479 spin_lock_irqsave(&hw_mgr->hw_mgr_lock, flags);
480 task = cam_req_mgr_workq_get_task(icp_hw_mgr.msg_work);
481 if (!task) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700482 CAM_ERR(CAM_ICP, "no empty task");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700483 spin_unlock_irqrestore(&hw_mgr->hw_mgr_lock, flags);
484 return -ENOMEM;
485 }
486
487 task_data = (struct hfi_msg_work_data *)task->payload;
488 task_data->data = hw_mgr;
489 task_data->irq_status = irq_status;
490 task_data->type = ICP_WORKQ_TASK_MSG_TYPE;
491 task->process_cb = cam_icp_mgr_process_msg;
492 rc = cam_req_mgr_workq_enqueue_task(task, &icp_hw_mgr,
493 CRM_TASK_PRIORITY_0);
494 spin_unlock_irqrestore(&hw_mgr->hw_mgr_lock, flags);
495
496 return rc;
497}
498
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -0700499static void cam_icp_free_hfi_mem(void)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700500{
501 cam_smmu_dealloc_firmware(icp_hw_mgr.iommu_hdl);
502 cam_mem_mgr_release_mem(&icp_hw_mgr.hfi_mem.qtbl);
503 cam_mem_mgr_release_mem(&icp_hw_mgr.hfi_mem.cmd_q);
504 cam_mem_mgr_release_mem(&icp_hw_mgr.hfi_mem.msg_q);
505 cam_mem_mgr_release_mem(&icp_hw_mgr.hfi_mem.dbg_q);
506 cam_mem_mgr_release_mem(&icp_hw_mgr.hfi_mem.sec_heap);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700507}
508
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530509static int cam_icp_alloc_shared_mem(struct cam_mem_mgr_memory_desc *qtbl)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700510{
511 int rc;
512 struct cam_mem_mgr_request_desc alloc;
513 struct cam_mem_mgr_memory_desc out;
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530514
515 memset(&alloc, 0, sizeof(alloc));
516 memset(&out, 0, sizeof(out));
517 alloc.size = SZ_1M;
518 alloc.align = 0;
Seemanta Duttaa037cd12017-07-06 15:45:29 -0700519 alloc.flags = CAM_MEM_FLAG_HW_READ_WRITE |
520 CAM_MEM_FLAG_HW_SHARED_ACCESS;
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530521 alloc.smmu_hdl = icp_hw_mgr.iommu_hdl;
522 rc = cam_mem_mgr_request_mem(&alloc, &out);
523 if (rc)
524 return rc;
525
526 *qtbl = out;
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700527 CAM_DBG(CAM_ICP, "kva: %llX, iova: %x, hdl: %x, len: %lld",
528 out.kva, out.iova, out.mem_handle, out.len);
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530529
530 return rc;
531}
532
533static int cam_icp_allocate_fw_mem(void)
534{
535 int rc;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700536 uint64_t kvaddr;
537 size_t len;
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530538 dma_addr_t iova;
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -0700539
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700540 rc = cam_smmu_alloc_firmware(icp_hw_mgr.iommu_hdl,
541 &iova, &kvaddr, &len);
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530542 if (rc)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700543 return -ENOMEM;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700544
545 icp_hw_mgr.hfi_mem.fw_buf.len = len;
546 icp_hw_mgr.hfi_mem.fw_buf.kva = kvaddr;
547 icp_hw_mgr.hfi_mem.fw_buf.iova = iova;
548 icp_hw_mgr.hfi_mem.fw_buf.smmu_hdl = icp_hw_mgr.iommu_hdl;
549
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700550 CAM_DBG(CAM_ICP, "kva: %llX, iova: %llx, len: %zu",
551 kvaddr, iova, len);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700552
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530553 return rc;
554}
555
556static int cam_icp_allocate_hfi_mem(void)
557{
558 int rc;
559
560 rc = cam_smmu_get_region_info(icp_hw_mgr.iommu_hdl,
Seemanta Duttaa037cd12017-07-06 15:45:29 -0700561 CAM_SMMU_REGION_SHARED,
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530562 &icp_hw_mgr.hfi_mem.shmem);
563 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700564 CAM_ERR(CAM_ICP, "Unable to get shared memory info");
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530565 return rc;
566 }
567
568 rc = cam_icp_allocate_fw_mem();
569 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700570 CAM_ERR(CAM_ICP, "Unable to allocate FW memory");
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530571 return rc;
572 }
573
574 rc = cam_icp_alloc_shared_mem(&icp_hw_mgr.hfi_mem.qtbl);
575 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700576 CAM_ERR(CAM_ICP, "Unable to allocate qtbl memory");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700577 goto qtbl_alloc_failed;
578 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700579
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530580 rc = cam_icp_alloc_shared_mem(&icp_hw_mgr.hfi_mem.cmd_q);
581 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700582 CAM_ERR(CAM_ICP, "Unable to allocate cmd q memory");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700583 goto cmd_q_alloc_failed;
584 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700585
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530586 rc = cam_icp_alloc_shared_mem(&icp_hw_mgr.hfi_mem.msg_q);
587 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700588 CAM_ERR(CAM_ICP, "Unable to allocate msg q memory");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700589 goto msg_q_alloc_failed;
590 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700591
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530592 rc = cam_icp_alloc_shared_mem(&icp_hw_mgr.hfi_mem.dbg_q);
593 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700594 CAM_ERR(CAM_ICP, "Unable to allocate dbg q memory");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700595 goto dbg_q_alloc_failed;
596 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700597
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530598 rc = cam_icp_alloc_shared_mem(&icp_hw_mgr.hfi_mem.sec_heap);
599 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700600 CAM_ERR(CAM_ICP, "Unable to allocate sec heap q memory");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700601 goto sec_heap_alloc_failed;
602 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700603
604 return rc;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700605sec_heap_alloc_failed:
606 cam_mem_mgr_release_mem(&icp_hw_mgr.hfi_mem.dbg_q);
607dbg_q_alloc_failed:
608 cam_mem_mgr_release_mem(&icp_hw_mgr.hfi_mem.msg_q);
609msg_q_alloc_failed:
610 cam_mem_mgr_release_mem(&icp_hw_mgr.hfi_mem.cmd_q);
611cmd_q_alloc_failed:
612 cam_mem_mgr_release_mem(&icp_hw_mgr.hfi_mem.qtbl);
613qtbl_alloc_failed:
614 cam_smmu_dealloc_firmware(icp_hw_mgr.iommu_hdl);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700615 return rc;
616}
617
618static int cam_icp_mgr_get_free_ctx(struct cam_icp_hw_mgr *hw_mgr)
619{
620 int i = 0;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700621
Suresh Vankadaraadcf0582017-05-24 09:53:36 +0530622 for (i = 0; i < CAM_ICP_CTX_MAX; i++) {
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700623 mutex_lock(&hw_mgr->ctx_data[i].ctx_mutex);
Suresh Vankadaraadcf0582017-05-24 09:53:36 +0530624 if (hw_mgr->ctx_data[i].in_use == false) {
625 hw_mgr->ctx_data[i].in_use = true;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700626 mutex_unlock(&hw_mgr->ctx_data[i].ctx_mutex);
627 break;
628 }
629 mutex_unlock(&hw_mgr->ctx_data[i].ctx_mutex);
630 }
631
632 return i;
633}
634
Suresh Vankadaraadcf0582017-05-24 09:53:36 +0530635static void cam_icp_mgr_put_ctx(struct cam_icp_hw_ctx_data *ctx_data)
636{
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530637 ctx_data->in_use = false;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +0530638}
639
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +0530640static int cam_icp_mgr_abort_handle(
641 struct cam_icp_hw_ctx_data *ctx_data)
642{
643 int rc = 0;
Suresh Vankadara22697d32017-07-03 12:14:09 -0700644 unsigned long rem_jiffies;
Karthik Anantha Ram300662f2017-08-29 13:31:10 -0700645 size_t packet_size;
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +0530646 int timeout = 5000;
647 struct hfi_cmd_work_data *task_data;
Karthik Anantha Ram300662f2017-08-29 13:31:10 -0700648 struct hfi_cmd_ipebps_async *abort_cmd;
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +0530649 struct crm_workq_task *task;
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +0530650
651 task = cam_req_mgr_workq_get_task(icp_hw_mgr.cmd_work);
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530652 if (!task)
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +0530653 return -ENOMEM;
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +0530654
Karthik Anantha Ram300662f2017-08-29 13:31:10 -0700655 packet_size =
Karthik Anantha Ram21885822017-08-28 15:47:17 -0700656 sizeof(struct hfi_cmd_ipebps_async) +
657 sizeof(struct hfi_cmd_abort_destroy) -
Karthik Anantha Ram300662f2017-08-29 13:31:10 -0700658 sizeof(((struct hfi_cmd_ipebps_async *)0)->payload.direct);
659 abort_cmd = kzalloc(packet_size, GFP_KERNEL);
660 if (!abort_cmd) {
661 rc = -ENOMEM;
662 return rc;
663 }
664
Karthik Anantha Ram730718d2017-08-29 18:43:21 -0700665 abort_cmd->size = packet_size;
Karthik Anantha Ram300662f2017-08-29 13:31:10 -0700666 abort_cmd->pkt_type = HFI_CMD_IPEBPS_ASYNC_COMMAND_DIRECT;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +0530667 if (ctx_data->icp_dev_acquire_info->dev_type == CAM_ICP_RES_TYPE_BPS)
Karthik Anantha Ram300662f2017-08-29 13:31:10 -0700668 abort_cmd->opcode = HFI_IPEBPS_CMD_OPCODE_BPS_ABORT;
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +0530669 else
Karthik Anantha Ram300662f2017-08-29 13:31:10 -0700670 abort_cmd->opcode = HFI_IPEBPS_CMD_OPCODE_IPE_ABORT;
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +0530671
672 reinit_completion(&ctx_data->wait_complete);
Karthik Anantha Ram300662f2017-08-29 13:31:10 -0700673 abort_cmd->num_fw_handles = 1;
674 abort_cmd->fw_handles[0] = ctx_data->fw_handle;
675 abort_cmd->user_data1 = (uint64_t)ctx_data;
676 abort_cmd->user_data2 = (uint64_t)0x0;
677 memcpy(abort_cmd->payload.direct, &ctx_data->temp_payload,
678 sizeof(uint64_t));
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +0530679
680 task_data = (struct hfi_cmd_work_data *)task->payload;
Karthik Anantha Ram300662f2017-08-29 13:31:10 -0700681 task_data->data = (void *)abort_cmd;
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +0530682 task_data->request_id = 0;
683 task_data->type = ICP_WORKQ_TASK_CMD_TYPE;
684 task->process_cb = cam_icp_mgr_process_cmd;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +0530685 rc = cam_req_mgr_workq_enqueue_task(task, &icp_hw_mgr,
686 CRM_TASK_PRIORITY_0);
Karthik Anantha Ram300662f2017-08-29 13:31:10 -0700687 if (rc) {
688 kfree(abort_cmd);
Suresh Vankadaraadcf0582017-05-24 09:53:36 +0530689 return rc;
Karthik Anantha Ram300662f2017-08-29 13:31:10 -0700690 }
Suresh Vankadaraadcf0582017-05-24 09:53:36 +0530691
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700692 CAM_DBG(CAM_ICP, "fw_handle = %x ctx_data = %pK",
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +0530693 ctx_data->fw_handle, ctx_data);
694 rem_jiffies = wait_for_completion_timeout(&ctx_data->wait_complete,
695 msecs_to_jiffies((timeout)));
696 if (!rem_jiffies) {
697 rc = -ETIMEDOUT;
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700698 CAM_DBG(CAM_ICP, "FW timeout/err in abort handle command");
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +0530699 }
700
Karthik Anantha Ram300662f2017-08-29 13:31:10 -0700701 kfree(abort_cmd);
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +0530702 return rc;
703}
704
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700705static int cam_icp_mgr_destroy_handle(
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +0530706 struct cam_icp_hw_ctx_data *ctx_data)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700707{
708 int rc = 0;
709 int timeout = 5000;
Suresh Vankadara22697d32017-07-03 12:14:09 -0700710 unsigned long rem_jiffies;
Karthik Anantha Ram300662f2017-08-29 13:31:10 -0700711 size_t packet_size;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700712 struct hfi_cmd_work_data *task_data;
Karthik Anantha Ram300662f2017-08-29 13:31:10 -0700713 struct hfi_cmd_ipebps_async *destroy_cmd;
Suresh Vankadara5a1ae562017-06-03 12:59:15 +0530714 struct crm_workq_task *task;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700715
Suresh Vankadara5a1ae562017-06-03 12:59:15 +0530716 task = cam_req_mgr_workq_get_task(icp_hw_mgr.cmd_work);
717 if (!task)
718 return -ENOMEM;
719
Karthik Anantha Ram300662f2017-08-29 13:31:10 -0700720 packet_size =
Karthik Anantha Ram21885822017-08-28 15:47:17 -0700721 sizeof(struct hfi_cmd_ipebps_async) +
Karthik Anantha Ram300662f2017-08-29 13:31:10 -0700722 sizeof(struct hfi_cmd_abort_destroy) -
723 sizeof(((struct hfi_cmd_ipebps_async *)0)->payload.direct);
724 destroy_cmd = kzalloc(packet_size, GFP_KERNEL);
725 if (!destroy_cmd) {
726 rc = -ENOMEM;
727 return rc;
728 }
729
Karthik Anantha Ram730718d2017-08-29 18:43:21 -0700730 destroy_cmd->size = packet_size;
Karthik Anantha Ram300662f2017-08-29 13:31:10 -0700731 destroy_cmd->pkt_type = HFI_CMD_IPEBPS_ASYNC_COMMAND_DIRECT;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +0530732 if (ctx_data->icp_dev_acquire_info->dev_type == CAM_ICP_RES_TYPE_BPS)
Karthik Anantha Ram300662f2017-08-29 13:31:10 -0700733 destroy_cmd->opcode = HFI_IPEBPS_CMD_OPCODE_BPS_DESTROY;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700734 else
Karthik Anantha Ram300662f2017-08-29 13:31:10 -0700735 destroy_cmd->opcode = HFI_IPEBPS_CMD_OPCODE_IPE_DESTROY;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700736
737 reinit_completion(&ctx_data->wait_complete);
Karthik Anantha Ram300662f2017-08-29 13:31:10 -0700738 destroy_cmd->num_fw_handles = 1;
739 destroy_cmd->fw_handles[0] = ctx_data->fw_handle;
740 destroy_cmd->user_data1 = (uint64_t)ctx_data;
741 destroy_cmd->user_data2 = (uint64_t)0x0;
742 memcpy(destroy_cmd->payload.direct, &ctx_data->temp_payload,
743 sizeof(uint64_t));
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700744
745 task_data = (struct hfi_cmd_work_data *)task->payload;
Karthik Anantha Ram300662f2017-08-29 13:31:10 -0700746 task_data->data = (void *)destroy_cmd;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700747 task_data->request_id = 0;
748 task_data->type = ICP_WORKQ_TASK_CMD_TYPE;
749 task->process_cb = cam_icp_mgr_process_cmd;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +0530750 rc = cam_req_mgr_workq_enqueue_task(task, &icp_hw_mgr,
751 CRM_TASK_PRIORITY_0);
Karthik Anantha Ram300662f2017-08-29 13:31:10 -0700752 if (rc) {
753 kfree(destroy_cmd);
Suresh Vankadaraadcf0582017-05-24 09:53:36 +0530754 return rc;
Karthik Anantha Ram300662f2017-08-29 13:31:10 -0700755 }
Suresh Vankadaraadcf0582017-05-24 09:53:36 +0530756
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700757 CAM_DBG(CAM_ICP, "fw_handle = %x ctx_data = %pK",
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700758 ctx_data->fw_handle, ctx_data);
759 rem_jiffies = wait_for_completion_timeout(&ctx_data->wait_complete,
760 msecs_to_jiffies((timeout)));
761 if (!rem_jiffies) {
762 rc = -ETIMEDOUT;
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700763 CAM_ERR(CAM_ICP, "FW response timeout: %d", rc);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700764 }
765
Karthik Anantha Ram300662f2017-08-29 13:31:10 -0700766 kfree(destroy_cmd);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700767 return rc;
768}
769
770static int cam_icp_mgr_release_ctx(struct cam_icp_hw_mgr *hw_mgr, int ctx_id)
771{
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700772 int i = 0;
773
774 if (ctx_id >= CAM_ICP_CTX_MAX) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700775 CAM_ERR(CAM_ICP, "ctx_id is wrong: %d", ctx_id);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700776 return -EINVAL;
777 }
778
Suresh Vankadara22697d32017-07-03 12:14:09 -0700779 mutex_lock(&hw_mgr->hw_mgr_mutex);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700780 mutex_lock(&hw_mgr->ctx_data[ctx_id].ctx_mutex);
781 if (!hw_mgr->ctx_data[ctx_id].in_use) {
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700782 mutex_unlock(&hw_mgr->ctx_data[ctx_id].ctx_mutex);
Suresh Vankadara22697d32017-07-03 12:14:09 -0700783 mutex_unlock(&hw_mgr->hw_mgr_mutex);
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -0700784 return 0;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700785 }
Suresh Vankadara5a1ae562017-06-03 12:59:15 +0530786 cam_icp_mgr_destroy_handle(&hw_mgr->ctx_data[ctx_id]);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700787
Suresh Vankadaraadcf0582017-05-24 09:53:36 +0530788 hw_mgr->ctx_data[ctx_id].in_use = false;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700789 hw_mgr->ctx_data[ctx_id].fw_handle = 0;
790 hw_mgr->ctx_data[ctx_id].scratch_mem_size = 0;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700791 for (i = 0; i < CAM_FRAME_CMD_MAX; i++)
792 clear_bit(i, hw_mgr->ctx_data[ctx_id].hfi_frame_process.bitmap);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700793 kfree(hw_mgr->ctx_data[ctx_id].hfi_frame_process.bitmap);
Suresh Vankadara5499a5f2017-06-16 22:13:56 +0530794 hw_mgr->ctxt_cnt--;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +0530795 kfree(hw_mgr->ctx_data[ctx_id].icp_dev_acquire_info);
796 hw_mgr->ctx_data[ctx_id].icp_dev_acquire_info = NULL;
797 mutex_unlock(&hw_mgr->ctx_data[ctx_id].ctx_mutex);
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530798 mutex_unlock(&hw_mgr->hw_mgr_mutex);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700799
800 return 0;
801}
802
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530803static void cam_icp_mgr_device_deinit(struct cam_icp_hw_mgr *hw_mgr)
804{
805 struct cam_hw_intf *a5_dev_intf = NULL;
806 struct cam_hw_intf *ipe0_dev_intf = NULL;
807 struct cam_hw_intf *ipe1_dev_intf = NULL;
808 struct cam_hw_intf *bps_dev_intf = NULL;
809
810 a5_dev_intf = hw_mgr->devices[CAM_ICP_DEV_A5][0];
811 ipe0_dev_intf = hw_mgr->devices[CAM_ICP_DEV_IPE][0];
812 ipe1_dev_intf = hw_mgr->devices[CAM_ICP_DEV_IPE][1];
813 bps_dev_intf = hw_mgr->devices[CAM_ICP_DEV_BPS][0];
814
815 if ((!a5_dev_intf) || (!ipe0_dev_intf) || (!bps_dev_intf)) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700816 CAM_ERR(CAM_ICP, "dev intfs are wrong, failed to close");
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530817 return;
818 }
819
820 if (ipe1_dev_intf)
821 ipe1_dev_intf->hw_ops.deinit(ipe1_dev_intf->hw_priv, NULL, 0);
822 ipe0_dev_intf->hw_ops.deinit(ipe0_dev_intf->hw_priv, NULL, 0);
823 bps_dev_intf->hw_ops.deinit(bps_dev_intf->hw_priv, NULL, 0);
824 a5_dev_intf->hw_ops.deinit(a5_dev_intf->hw_priv, NULL, 0);
825}
826
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700827static int cam_icp_mgr_hw_close(void *hw_priv, void *hw_close_args)
828{
829 struct cam_icp_hw_mgr *hw_mgr = hw_priv;
830 struct cam_hw_intf *a5_dev_intf = NULL;
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -0700831 struct cam_icp_a5_set_irq_cb irq_cb;
832 struct cam_icp_a5_set_fw_buf_info fw_buf_info;
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530833 int i, rc = 0;
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -0700834
835 mutex_lock(&hw_mgr->hw_mgr_mutex);
Suresh Vankadara5499a5f2017-06-16 22:13:56 +0530836 if ((hw_mgr->fw_download == false) && (!hw_mgr->ctxt_cnt)) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700837 CAM_DBG(CAM_ICP, "hw mgr is already closed");
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -0700838 mutex_unlock(&hw_mgr->hw_mgr_mutex);
839 return 0;
840 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700841
842 a5_dev_intf = hw_mgr->devices[CAM_ICP_DEV_A5][0];
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530843 if (!a5_dev_intf) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700844 CAM_ERR(CAM_ICP, "a5_dev_intf is NULL");
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -0700845 mutex_unlock(&hw_mgr->hw_mgr_mutex);
846 return -EINVAL;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700847 }
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -0700848
849 irq_cb.icp_hw_mgr_cb = NULL;
850 irq_cb.data = NULL;
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530851 rc = a5_dev_intf->hw_ops.process_cmd(
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -0700852 a5_dev_intf->hw_priv,
853 CAM_ICP_A5_SET_IRQ_CB,
854 &irq_cb, sizeof(irq_cb));
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530855 if (rc)
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700856 CAM_ERR(CAM_ICP, "deregister irq call back failed");
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -0700857
858 fw_buf_info.kva = 0;
859 fw_buf_info.iova = 0;
860 fw_buf_info.len = 0;
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530861 rc = a5_dev_intf->hw_ops.process_cmd(
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -0700862 a5_dev_intf->hw_priv,
863 CAM_ICP_A5_CMD_SET_FW_BUF,
864 &fw_buf_info,
865 sizeof(fw_buf_info));
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530866 if (rc)
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700867 CAM_ERR(CAM_ICP, "nullify the fw buf failed");
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -0700868 mutex_unlock(&hw_mgr->hw_mgr_mutex);
Suresh Vankadara22697d32017-07-03 12:14:09 -0700869
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530870 for (i = 0; i < CAM_ICP_CTX_MAX; i++)
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -0700871 cam_icp_mgr_release_ctx(hw_mgr, i);
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -0700872
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700873 mutex_lock(&hw_mgr->hw_mgr_mutex);
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -0700874 cam_hfi_deinit();
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530875 cam_icp_mgr_device_deinit(hw_mgr);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700876 cam_icp_free_hfi_mem();
877 hw_mgr->fw_download = false;
878 mutex_unlock(&hw_mgr->hw_mgr_mutex);
Suresh Vankadara22697d32017-07-03 12:14:09 -0700879
880 return rc;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700881}
882
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530883static int cam_icp_mgr_device_init(struct cam_icp_hw_mgr *hw_mgr)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700884{
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530885 int rc = 0;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700886 struct cam_hw_intf *a5_dev_intf = NULL;
887 struct cam_hw_intf *ipe0_dev_intf = NULL;
888 struct cam_hw_intf *ipe1_dev_intf = NULL;
889 struct cam_hw_intf *bps_dev_intf = NULL;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700890
891 a5_dev_intf = hw_mgr->devices[CAM_ICP_DEV_A5][0];
892 ipe0_dev_intf = hw_mgr->devices[CAM_ICP_DEV_IPE][0];
893 ipe1_dev_intf = hw_mgr->devices[CAM_ICP_DEV_IPE][1];
894 bps_dev_intf = hw_mgr->devices[CAM_ICP_DEV_BPS][0];
895
896 if ((!a5_dev_intf) || (!ipe0_dev_intf) || (!bps_dev_intf)) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700897 CAM_ERR(CAM_ICP, "dev intfs are wrong");
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530898 return -EINVAL;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700899 }
900
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700901 rc = a5_dev_intf->hw_ops.init(a5_dev_intf->hw_priv, NULL, 0);
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530902 if (rc)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700903 goto a5_dev_init_failed;
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530904
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700905 rc = bps_dev_intf->hw_ops.init(bps_dev_intf->hw_priv, NULL, 0);
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530906 if (rc)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700907 goto bps_dev_init_failed;
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530908
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700909 rc = ipe0_dev_intf->hw_ops.init(ipe0_dev_intf->hw_priv, NULL, 0);
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530910 if (rc)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700911 goto ipe0_dev_init_failed;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700912
913 if (ipe1_dev_intf) {
914 rc = ipe1_dev_intf->hw_ops.init(ipe1_dev_intf->hw_priv,
915 NULL, 0);
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530916 if (rc)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700917 goto ipe1_dev_init_failed;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700918 }
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530919
920 return rc;
921ipe1_dev_init_failed:
922 ipe0_dev_intf->hw_ops.deinit(ipe0_dev_intf->hw_priv, NULL, 0);
923ipe0_dev_init_failed:
924 bps_dev_intf->hw_ops.deinit(bps_dev_intf->hw_priv, NULL, 0);
925bps_dev_init_failed:
926 a5_dev_intf->hw_ops.deinit(a5_dev_intf->hw_priv, NULL, 0);
927a5_dev_init_failed:
928 return rc;
929}
930
931static int cam_icp_mgr_fw_download(struct cam_icp_hw_mgr *hw_mgr)
932{
933 int rc;
934 struct cam_hw_intf *a5_dev_intf = NULL;
935 struct cam_hw_info *a5_dev = NULL;
936 struct cam_icp_a5_set_irq_cb irq_cb;
937 struct cam_icp_a5_set_fw_buf_info fw_buf_info;
938
939 a5_dev_intf = hw_mgr->devices[CAM_ICP_DEV_A5][0];
Suresh Vankadara22697d32017-07-03 12:14:09 -0700940 if (!a5_dev_intf) {
941 CAM_ERR(CAM_ICP, "a5_dev_intf is invalid");
942 return -EINVAL;
943 }
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530944 a5_dev = (struct cam_hw_info *)a5_dev_intf->hw_priv;
945
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700946 irq_cb.icp_hw_mgr_cb = cam_icp_hw_mgr_cb;
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530947 irq_cb.data = hw_mgr;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700948 rc = a5_dev_intf->hw_ops.process_cmd(
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -0700949 a5_dev_intf->hw_priv,
950 CAM_ICP_A5_SET_IRQ_CB,
951 &irq_cb, sizeof(irq_cb));
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530952 if (rc)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700953 goto set_irq_failed;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700954
955 fw_buf_info.kva = icp_hw_mgr.hfi_mem.fw_buf.kva;
956 fw_buf_info.iova = icp_hw_mgr.hfi_mem.fw_buf.iova;
957 fw_buf_info.len = icp_hw_mgr.hfi_mem.fw_buf.len;
958
959 rc = a5_dev_intf->hw_ops.process_cmd(
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -0700960 a5_dev_intf->hw_priv,
961 CAM_ICP_A5_CMD_SET_FW_BUF,
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530962 &fw_buf_info, sizeof(fw_buf_info));
963 if (rc)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700964 goto set_irq_failed;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700965
966 cam_hfi_enable_cpu(a5_dev->soc_info.reg_map[A5_SIERRA_BASE].mem_base);
967
968 rc = a5_dev_intf->hw_ops.process_cmd(
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -0700969 a5_dev_intf->hw_priv,
970 CAM_ICP_A5_CMD_FW_DOWNLOAD,
971 NULL, 0);
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530972 if (rc)
973 goto fw_download_failed;
974
975 return rc;
976fw_download_failed:
977 cam_hfi_disable_cpu(a5_dev->soc_info.reg_map[A5_SIERRA_BASE].mem_base);
978set_irq_failed:
979 return rc;
980}
981
982static int cam_icp_mgr_hfi_init(struct cam_icp_hw_mgr *hw_mgr)
983{
984 struct cam_hw_intf *a5_dev_intf = NULL;
985 struct cam_hw_info *a5_dev = NULL;
986 struct hfi_mem_info hfi_mem;
987
988 a5_dev_intf = hw_mgr->devices[CAM_ICP_DEV_A5][0];
Suresh Vankadara22697d32017-07-03 12:14:09 -0700989 if (!a5_dev_intf) {
990 CAM_ERR(CAM_ICP, "a5_dev_intf is invalid");
991 return -EINVAL;
992 }
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530993 a5_dev = (struct cam_hw_info *)a5_dev_intf->hw_priv;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700994
995 hfi_mem.qtbl.kva = icp_hw_mgr.hfi_mem.qtbl.kva;
996 hfi_mem.qtbl.iova = icp_hw_mgr.hfi_mem.qtbl.iova;
997 hfi_mem.qtbl.len = icp_hw_mgr.hfi_mem.qtbl.len;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700998
999 hfi_mem.cmd_q.kva = icp_hw_mgr.hfi_mem.cmd_q.kva;
1000 hfi_mem.cmd_q.iova = icp_hw_mgr.hfi_mem.cmd_q.iova;
1001 hfi_mem.cmd_q.len = icp_hw_mgr.hfi_mem.cmd_q.len;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001002
1003 hfi_mem.msg_q.kva = icp_hw_mgr.hfi_mem.msg_q.kva;
1004 hfi_mem.msg_q.iova = icp_hw_mgr.hfi_mem.msg_q.iova;
1005 hfi_mem.msg_q.len = icp_hw_mgr.hfi_mem.msg_q.len;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001006
1007 hfi_mem.dbg_q.kva = icp_hw_mgr.hfi_mem.dbg_q.kva;
1008 hfi_mem.dbg_q.iova = icp_hw_mgr.hfi_mem.dbg_q.iova;
1009 hfi_mem.dbg_q.len = icp_hw_mgr.hfi_mem.dbg_q.len;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001010
1011 hfi_mem.sec_heap.kva = icp_hw_mgr.hfi_mem.sec_heap.kva;
1012 hfi_mem.sec_heap.iova = icp_hw_mgr.hfi_mem.sec_heap.iova;
1013 hfi_mem.sec_heap.len = icp_hw_mgr.hfi_mem.sec_heap.len;
1014
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07001015 hfi_mem.shmem.iova = icp_hw_mgr.hfi_mem.shmem.iova_start;
1016 hfi_mem.shmem.len = icp_hw_mgr.hfi_mem.shmem.iova_len;
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001017
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301018 return cam_hfi_init(0, &hfi_mem,
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001019 a5_dev->soc_info.reg_map[A5_SIERRA_BASE].mem_base,
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07001020 hw_mgr->a5_debug);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301021}
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001022
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301023static int cam_icp_mgr_send_fw_init(struct cam_icp_hw_mgr *hw_mgr)
1024{
1025 int rc;
1026 struct cam_hw_intf *a5_dev_intf = NULL;
1027 unsigned long rem_jiffies;
1028 int timeout = 5000;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001029
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301030 a5_dev_intf = hw_mgr->devices[CAM_ICP_DEV_A5][0];
Suresh Vankadara22697d32017-07-03 12:14:09 -07001031 if (!a5_dev_intf) {
1032 CAM_ERR(CAM_ICP, "a5_dev_intf is invalid");
1033 return -EINVAL;
1034 }
1035
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001036 reinit_completion(&hw_mgr->a5_complete);
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001037 CAM_DBG(CAM_ICP, "Sending HFI init command");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001038 rc = a5_dev_intf->hw_ops.process_cmd(
1039 a5_dev_intf->hw_priv,
1040 CAM_ICP_A5_SEND_INIT,
1041 NULL, 0);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301042 if (rc)
1043 return rc;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001044
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07001045 rem_jiffies = wait_for_completion_timeout(&icp_hw_mgr.a5_complete,
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301046 msecs_to_jiffies((timeout)));
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07001047 if (!rem_jiffies) {
1048 rc = -ETIMEDOUT;
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001049 CAM_ERR(CAM_ICP, "FW response timed out %d", rc);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301050 }
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001051 CAM_DBG(CAM_ICP, "Done Waiting for INIT DONE Message");
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301052
1053 return rc;
1054}
1055
1056static int cam_icp_mgr_download_fw(void *hw_mgr_priv, void *download_fw_args)
1057{
1058 struct cam_hw_intf *a5_dev_intf = NULL;
1059 struct cam_hw_info *a5_dev = NULL;
1060 struct cam_icp_hw_mgr *hw_mgr = hw_mgr_priv;
1061 int rc = 0;
1062
1063 if (!hw_mgr) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001064 CAM_ERR(CAM_ICP, "hw_mgr is NULL");
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301065 return -EINVAL;
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07001066 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001067
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301068 mutex_lock(&hw_mgr->hw_mgr_mutex);
1069 if (hw_mgr->fw_download) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001070 CAM_DBG(CAM_ICP, "FW already downloaded");
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301071 mutex_unlock(&hw_mgr->hw_mgr_mutex);
1072 return rc;
1073 }
1074
1075 a5_dev_intf = hw_mgr->devices[CAM_ICP_DEV_A5][0];
Suresh Vankadara22697d32017-07-03 12:14:09 -07001076 if (!a5_dev_intf) {
1077 CAM_ERR(CAM_ICP, "a5_dev_intf is invalid");
1078 mutex_unlock(&hw_mgr->hw_mgr_mutex);
1079 return -EINVAL;
1080 }
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301081 a5_dev = (struct cam_hw_info *)a5_dev_intf->hw_priv;
1082 rc = cam_icp_allocate_hfi_mem();
1083 if (rc) {
1084 mutex_unlock(&hw_mgr->hw_mgr_mutex);
1085 goto alloc_hfi_mem_failed;
1086 }
1087
1088 rc = cam_icp_mgr_device_init(hw_mgr);
1089 if (rc) {
1090 mutex_unlock(&hw_mgr->hw_mgr_mutex);
1091 goto dev_init_fail;
1092 }
1093
1094 rc = cam_icp_mgr_fw_download(hw_mgr);
1095 if (rc) {
1096 mutex_unlock(&hw_mgr->hw_mgr_mutex);
1097 goto fw_download_failed;
1098 }
1099
1100 rc = cam_icp_mgr_hfi_init(hw_mgr);
1101 if (rc) {
1102 mutex_unlock(&hw_mgr->hw_mgr_mutex);
1103 goto hfi_init_failed;
1104 }
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301105
1106 rc = cam_icp_mgr_send_fw_init(hw_mgr);
Suresh Vankadara22697d32017-07-03 12:14:09 -07001107 if (rc) {
1108 mutex_unlock(&hw_mgr->hw_mgr_mutex);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301109 goto fw_init_failed;
Suresh Vankadara22697d32017-07-03 12:14:09 -07001110 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001111
1112 rc = a5_dev_intf->hw_ops.process_cmd(
1113 a5_dev_intf->hw_priv,
1114 CAM_ICP_A5_CMD_POWER_COLLAPSE,
1115 NULL, 0);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001116 hw_mgr->fw_download = true;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001117 hw_mgr->ctxt_cnt = 0;
Suresh Vankadara22697d32017-07-03 12:14:09 -07001118 mutex_unlock(&hw_mgr->hw_mgr_mutex);
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001119 CAM_DBG(CAM_ICP, "FW download done successfully");
Suresh Vankadara5499a5f2017-06-16 22:13:56 +05301120 if (!download_fw_args)
1121 cam_icp_mgr_hw_close(hw_mgr, NULL);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001122 return rc;
1123
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301124fw_init_failed:
1125 cam_hfi_deinit();
1126hfi_init_failed:
1127 cam_hfi_disable_cpu(a5_dev->soc_info.reg_map[A5_SIERRA_BASE].mem_base);
1128fw_download_failed:
1129 cam_icp_mgr_device_deinit(hw_mgr);
1130dev_init_fail:
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001131 cam_icp_free_hfi_mem();
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301132alloc_hfi_mem_failed:
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001133 return rc;
1134}
1135
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301136static int cam_icp_mgr_handle_config_err(
1137 struct cam_hw_config_args *config_args,
1138 struct cam_icp_hw_ctx_data *ctx_data)
1139{
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301140 struct cam_hw_done_event_data buf_data;
1141
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301142 buf_data.request_id = *(uint64_t *)config_args->priv;
1143 ctx_data->ctxt_event_cb(ctx_data->context_priv, true, &buf_data);
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301144
1145 return 0;
1146}
1147
1148static int cam_icp_mgr_enqueue_config(struct cam_icp_hw_mgr *hw_mgr,
1149 struct cam_hw_config_args *config_args)
1150{
1151 int rc = 0;
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301152 uint64_t request_id = 0;
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301153 struct crm_workq_task *task;
1154 struct hfi_cmd_work_data *task_data;
1155 struct hfi_cmd_ipebps_async *hfi_cmd;
1156 struct cam_hw_update_entry *hw_update_entries;
1157
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301158 request_id = *(uint64_t *)config_args->priv;
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301159 hw_update_entries = config_args->hw_update_entries;
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001160 CAM_DBG(CAM_ICP, "req_id = %lld %pK", request_id, config_args->priv);
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301161
1162 task = cam_req_mgr_workq_get_task(icp_hw_mgr.cmd_work);
1163 if (!task) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001164 CAM_ERR(CAM_ICP, "no empty task");
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301165 return -ENOMEM;
1166 }
1167
1168 task_data = (struct hfi_cmd_work_data *)task->payload;
1169 task_data->data = (void *)hw_update_entries->addr;
1170 hfi_cmd = (struct hfi_cmd_ipebps_async *)hw_update_entries->addr;
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301171 task_data->request_id = request_id;
1172 task_data->type = ICP_WORKQ_TASK_CMD_TYPE;
1173 task->process_cb = cam_icp_mgr_process_cmd;
1174 rc = cam_req_mgr_workq_enqueue_task(task, &icp_hw_mgr,
1175 CRM_TASK_PRIORITY_0);
1176
1177 return rc;
1178}
1179
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001180static int cam_icp_mgr_config_hw(void *hw_mgr_priv, void *config_hw_args)
1181{
1182 int rc = 0;
1183 struct cam_icp_hw_mgr *hw_mgr = hw_mgr_priv;
1184 struct cam_hw_config_args *config_args = config_hw_args;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001185 struct cam_icp_hw_ctx_data *ctx_data = NULL;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001186
1187 if (!hw_mgr || !config_args) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001188 CAM_ERR(CAM_ICP, "Invalid arguments %pK %pK",
1189 hw_mgr, config_args);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001190 return -EINVAL;
1191 }
1192
1193 if (!config_args->num_hw_update_entries) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001194 CAM_ERR(CAM_ICP, "No hw update enteries are available");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001195 return -EINVAL;
1196 }
1197
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05301198 ctx_data = config_args->ctxt_to_hw_map;
Suresh Vankadara22697d32017-07-03 12:14:09 -07001199 mutex_lock(&ctx_data->ctx_mutex);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001200 if (!ctx_data->in_use) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001201 CAM_ERR(CAM_ICP, "ctx is not in use");
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301202 rc = -EINVAL;
1203 goto config_err;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001204 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001205
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301206 rc = cam_icp_mgr_enqueue_config(hw_mgr, config_args);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301207 if (rc)
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301208 goto config_err;
Suresh Vankadara22697d32017-07-03 12:14:09 -07001209 mutex_unlock(&ctx_data->ctx_mutex);
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301210
1211 return 0;
1212config_err:
Suresh Vankadara22697d32017-07-03 12:14:09 -07001213 mutex_unlock(&ctx_data->ctx_mutex);
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301214 cam_icp_mgr_handle_config_err(config_args, ctx_data);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001215 return rc;
1216}
1217
1218static int cam_icp_mgr_prepare_frame_process_cmd(
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05301219 struct cam_icp_hw_ctx_data *ctx_data,
1220 struct hfi_cmd_ipebps_async *hfi_cmd,
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301221 uint64_t request_id,
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05301222 uint32_t fw_cmd_buf_iova_addr)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001223{
1224 hfi_cmd->size = sizeof(struct hfi_cmd_ipebps_async);
1225 hfi_cmd->pkt_type = HFI_CMD_IPEBPS_ASYNC_COMMAND_INDIRECT;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05301226 if (ctx_data->icp_dev_acquire_info->dev_type == CAM_ICP_RES_TYPE_BPS)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001227 hfi_cmd->opcode = HFI_IPEBPS_CMD_OPCODE_BPS_FRAME_PROCESS;
1228 else
1229 hfi_cmd->opcode = HFI_IPEBPS_CMD_OPCODE_IPE_FRAME_PROCESS;
1230 hfi_cmd->num_fw_handles = 1;
1231 hfi_cmd->fw_handles[0] = ctx_data->fw_handle;
1232 hfi_cmd->payload.indirect = fw_cmd_buf_iova_addr;
1233 hfi_cmd->user_data1 = (uint64_t)ctx_data;
1234 hfi_cmd->user_data2 = request_id;
1235
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001236 CAM_DBG(CAM_ICP, "ctx_data : %pK, request_id :%lld cmd_buf %x",
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301237 (void *)ctx_data->context_priv, request_id,
1238 fw_cmd_buf_iova_addr);
1239
1240 return 0;
1241}
1242
1243static int cam_icp_mgr_pkt_validation(struct cam_packet *packet)
1244{
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301245 if (((packet->header.op_code & 0xff) !=
1246 CAM_ICP_OPCODE_IPE_UPDATE) &&
1247 ((packet->header.op_code & 0xff) !=
1248 CAM_ICP_OPCODE_BPS_UPDATE)) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001249 CAM_ERR(CAM_ICP, "Invalid Opcode in pkt: %d",
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301250 packet->header.op_code & 0xff);
1251 return -EINVAL;
1252 }
1253
1254 if ((packet->num_cmd_buf > 1) || (!packet->num_patches) ||
1255 (!packet->num_io_configs)) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001256 CAM_ERR(CAM_ICP, "wrong number of cmd/patch info: %u %u",
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301257 packet->num_cmd_buf, packet->num_patches);
1258 return -EINVAL;
1259 }
1260
1261 return 0;
1262}
1263
1264static int cam_icp_mgr_process_cmd_desc(struct cam_icp_hw_mgr *hw_mgr,
1265 struct cam_packet *packet,
1266 uint32_t *fw_cmd_buf_iova_addr)
1267{
1268 int rc = 0;
1269 uint64_t iova_addr;
1270 size_t fw_cmd_buf_len;
1271 struct cam_cmd_buf_desc *cmd_desc = NULL;
1272
1273 cmd_desc = (struct cam_cmd_buf_desc *)
1274 ((uint32_t *) &packet->payload + packet->cmd_buf_offset/4);
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301275
1276 rc = cam_mem_get_io_buf(cmd_desc->mem_handle,
1277 hw_mgr->iommu_hdl, &iova_addr, &fw_cmd_buf_len);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301278 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001279 CAM_ERR(CAM_ICP, "unable to get src buf info for cmd buf: %x",
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301280 hw_mgr->iommu_hdl);
1281 return rc;
1282 }
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001283 CAM_DBG(CAM_ICP, "cmd_buf desc cpu and iova address: %pK %zu",
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301284 (void *)iova_addr, fw_cmd_buf_len);
1285
1286 *fw_cmd_buf_iova_addr = iova_addr;
1287 *fw_cmd_buf_iova_addr = (*fw_cmd_buf_iova_addr + cmd_desc->offset);
1288
1289 return rc;
1290}
1291
Lakshmi Narayana Kalavalacfed4e92017-07-17 16:10:50 -07001292static void cam_icp_mgr_process_io_cfg(struct cam_icp_hw_mgr *hw_mgr,
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301293 struct cam_icp_hw_ctx_data *ctx_data,
1294 struct cam_packet *packet,
1295 struct cam_hw_prepare_update_args *prepare_args)
1296{
Lakshmi Narayana Kalavalacfed4e92017-07-17 16:10:50 -07001297 int i, j, k;
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301298 struct cam_buf_io_cfg *io_cfg_ptr = NULL;
1299
1300 io_cfg_ptr = (struct cam_buf_io_cfg *) ((uint32_t *) &packet->payload +
1301 packet->io_configs_offset/4);
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301302 prepare_args->num_out_map_entries = 0;
Lakshmi Narayana Kalavalacfed4e92017-07-17 16:10:50 -07001303 prepare_args->num_in_map_entries = 0;
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301304
Lakshmi Narayana Kalavalacfed4e92017-07-17 16:10:50 -07001305 for (i = 0, j = 0, k = 0; i < packet->num_io_configs; i++) {
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301306 if (io_cfg_ptr[i].direction == CAM_BUF_INPUT) {
Lakshmi Narayana Kalavalacfed4e92017-07-17 16:10:50 -07001307 prepare_args->in_map_entries[j++].sync_id =
1308 io_cfg_ptr[i].fence;
1309 prepare_args->num_in_map_entries++;
1310 } else {
1311 prepare_args->out_map_entries[k++].sync_id =
1312 io_cfg_ptr[i].fence;
1313 prepare_args->num_out_map_entries++;
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301314 }
Lakshmi Narayana Kalavalacfed4e92017-07-17 16:10:50 -07001315 CAM_DBG(CAM_ICP, "dir[%d]: %u, fence: %u",
1316 i, io_cfg_ptr[i].direction, io_cfg_ptr[i].fence);
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301317 }
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301318}
1319
1320static int cam_icp_mgr_update_hfi_frame_process(
1321 struct cam_icp_hw_ctx_data *ctx_data,
1322 struct cam_packet *packet,
1323 struct cam_hw_prepare_update_args *prepare_args,
1324 int32_t *idx)
1325{
1326 int32_t index;
1327
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301328 index = find_first_zero_bit(ctx_data->hfi_frame_process.bitmap,
1329 ctx_data->hfi_frame_process.bits);
1330 if (index < 0 || index >= CAM_FRAME_CMD_MAX) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001331 CAM_ERR(CAM_ICP, "request idx is wrong: %d", index);
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301332 return -EINVAL;
1333 }
1334 set_bit(index, ctx_data->hfi_frame_process.bitmap);
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301335
1336 ctx_data->hfi_frame_process.request_id[index] =
1337 packet->header.request_id;
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001338
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301339 *idx = index;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001340
1341 return 0;
1342}
1343
1344static int cam_icp_mgr_prepare_hw_update(void *hw_mgr_priv,
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05301345 void *prepare_hw_update_args)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001346{
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301347 int rc = 0;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001348 int32_t idx;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001349 uint32_t fw_cmd_buf_iova_addr;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001350 struct cam_icp_hw_ctx_data *ctx_data = NULL;
1351 struct cam_packet *packet = NULL;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001352 struct hfi_cmd_ipebps_async *hfi_cmd = NULL;
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301353 struct cam_icp_hw_mgr *hw_mgr = hw_mgr_priv;
1354 struct cam_hw_prepare_update_args *prepare_args =
1355 prepare_hw_update_args;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001356
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301357 if ((!prepare_args) || (!hw_mgr) || (!prepare_args->packet)) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001358 CAM_ERR(CAM_ICP, "Invalid args");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001359 return -EINVAL;
1360 }
1361
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05301362 ctx_data = prepare_args->ctxt_to_hw_map;
Suresh Vankadara22697d32017-07-03 12:14:09 -07001363 mutex_lock(&ctx_data->ctx_mutex);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001364 if (!ctx_data->in_use) {
Suresh Vankadara22697d32017-07-03 12:14:09 -07001365 mutex_unlock(&ctx_data->ctx_mutex);
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001366 CAM_ERR(CAM_ICP, "ctx is not in use");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001367 return -EINVAL;
1368 }
1369
1370 packet = prepare_args->packet;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001371
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301372 rc = cam_icp_mgr_pkt_validation(packet);
Suresh Vankadara22697d32017-07-03 12:14:09 -07001373 if (rc) {
1374 mutex_unlock(&ctx_data->ctx_mutex);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001375 return rc;
Suresh Vankadara22697d32017-07-03 12:14:09 -07001376 }
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301377
1378 rc = cam_icp_mgr_process_cmd_desc(hw_mgr, packet,
1379 &fw_cmd_buf_iova_addr);
Suresh Vankadara22697d32017-07-03 12:14:09 -07001380 if (rc) {
1381 mutex_unlock(&ctx_data->ctx_mutex);
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301382 return rc;
Suresh Vankadara22697d32017-07-03 12:14:09 -07001383 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001384
Harsh Shahe9e8ff52017-05-16 17:26:45 -07001385 /* Update Buffer Address from handles and patch information */
1386 rc = cam_packet_util_process_patches(packet, hw_mgr->iommu_hdl);
Suresh Vankadara22697d32017-07-03 12:14:09 -07001387 if (rc) {
1388 mutex_unlock(&ctx_data->ctx_mutex);
Harsh Shahe9e8ff52017-05-16 17:26:45 -07001389 return rc;
Suresh Vankadara22697d32017-07-03 12:14:09 -07001390 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001391
Lakshmi Narayana Kalavalacfed4e92017-07-17 16:10:50 -07001392 cam_icp_mgr_process_io_cfg(hw_mgr, ctx_data,
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301393 packet, prepare_args);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001394
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301395 rc = cam_icp_mgr_update_hfi_frame_process(ctx_data, packet,
1396 prepare_args, &idx);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301397 if (rc) {
1398 if (prepare_args->in_map_entries[0].sync_id > 0)
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301399 cam_sync_destroy(
1400 prepare_args->in_map_entries[0].sync_id);
Suresh Vankadara22697d32017-07-03 12:14:09 -07001401 mutex_unlock(&ctx_data->ctx_mutex);
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301402 return rc;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001403 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001404
1405 hfi_cmd = (struct hfi_cmd_ipebps_async *)
1406 &ctx_data->hfi_frame_process.hfi_frame_cmd[idx];
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001407 cam_icp_mgr_prepare_frame_process_cmd(
Suresh Vankadarae1b11082017-05-25 12:27:50 +05301408 ctx_data, hfi_cmd, packet->header.request_id,
1409 fw_cmd_buf_iova_addr);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001410
1411 prepare_args->num_hw_update_entries = 1;
1412 prepare_args->hw_update_entries[0].addr = (uint64_t)hfi_cmd;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001413 prepare_args->priv = &ctx_data->hfi_frame_process.request_id[idx];
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001414
Suresh Vankadara22697d32017-07-03 12:14:09 -07001415 mutex_unlock(&ctx_data->ctx_mutex);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001416 return rc;
1417}
1418
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05301419static int cam_icp_mgr_send_abort_status(struct cam_icp_hw_ctx_data *ctx_data)
1420{
1421 struct hfi_frame_process_info *hfi_frame_process;
1422 int idx;
1423
Suresh Vankadara22697d32017-07-03 12:14:09 -07001424 mutex_lock(&ctx_data->ctx_mutex);
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05301425 hfi_frame_process = &ctx_data->hfi_frame_process;
1426 for (idx = 0; idx < CAM_FRAME_CMD_MAX; idx++) {
1427 if (!hfi_frame_process->request_id[idx])
1428 continue;
1429
1430 ctx_data->ctxt_event_cb(ctx_data->context_priv, true,
1431 &hfi_frame_process->request_id[idx]);
1432
1433 /* now release memory for hfi frame process command */
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05301434 hfi_frame_process->request_id[idx] = 0;
1435 clear_bit(idx, ctx_data->hfi_frame_process.bitmap);
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05301436 }
Suresh Vankadara22697d32017-07-03 12:14:09 -07001437 mutex_unlock(&ctx_data->ctx_mutex);
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05301438
1439 return 0;
1440}
1441
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001442static int cam_icp_mgr_release_hw(void *hw_mgr_priv, void *release_hw_args)
1443{
1444 int rc = 0;
1445 int ctx_id = 0;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001446 struct cam_hw_release_args *release_hw = release_hw_args;
1447 struct cam_icp_hw_mgr *hw_mgr = hw_mgr_priv;
1448 struct cam_icp_hw_ctx_data *ctx_data = NULL;
1449
1450 if (!release_hw || !hw_mgr) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001451 CAM_ERR(CAM_ICP, "Invalid args: %pK %pK", release_hw, hw_mgr);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001452 return -EINVAL;
1453 }
1454
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05301455 ctx_data = release_hw->ctxt_to_hw_map;
1456 ctx_id = ctx_data->ctx_id;
Suresh Vankadara22697d32017-07-03 12:14:09 -07001457 if (ctx_id < 0 || ctx_id >= CAM_ICP_CTX_MAX)
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001458 CAM_ERR(CAM_ICP, "Invalid ctx id: %d", ctx_id);
Suresh Vankadara22697d32017-07-03 12:14:09 -07001459
1460 mutex_lock(&hw_mgr->ctx_data[ctx_id].ctx_mutex);
1461 if (!hw_mgr->ctx_data[ctx_id].in_use) {
1462 CAM_DBG(CAM_ICP, "ctx is not in use: %d", ctx_id);
1463 mutex_unlock(&hw_mgr->ctx_data[ctx_id].ctx_mutex);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001464 return -EINVAL;
1465 }
Suresh Vankadara22697d32017-07-03 12:14:09 -07001466 mutex_unlock(&hw_mgr->ctx_data[ctx_id].ctx_mutex);
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05301467
1468 if (release_hw->active_req) {
1469 cam_icp_mgr_abort_handle(ctx_data);
1470 cam_icp_mgr_send_abort_status(ctx_data);
1471 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001472
1473 rc = cam_icp_mgr_release_ctx(hw_mgr, ctx_id);
Suresh Vankadara6657bc22017-07-31 10:33:04 +05301474 if (!hw_mgr->ctxt_cnt) {
1475 cam_icp_mgr_ipe_bps_power_collapse(hw_mgr,
1476 NULL, 0);
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05301477 cam_icp_mgr_hw_close(hw_mgr, NULL);
Suresh Vankadara6657bc22017-07-31 10:33:04 +05301478 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001479
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001480 return rc;
1481}
1482
1483static int cam_icp_mgr_send_config_io(struct cam_icp_hw_ctx_data *ctx_data,
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05301484 uint32_t io_buf_addr)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001485{
1486 int rc = 0;
1487 struct hfi_cmd_work_data *task_data;
1488 struct hfi_cmd_ipebps_async ioconfig_cmd;
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07001489 unsigned long rem_jiffies;
1490 int timeout = 5000;
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05301491 struct crm_workq_task *task;
1492
1493 task = cam_req_mgr_workq_get_task(icp_hw_mgr.cmd_work);
1494 if (!task)
1495 return -ENOMEM;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001496
1497 ioconfig_cmd.size = sizeof(struct hfi_cmd_ipebps_async);
1498 ioconfig_cmd.pkt_type = HFI_CMD_IPEBPS_ASYNC_COMMAND_INDIRECT;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05301499 if (ctx_data->icp_dev_acquire_info->dev_type == CAM_ICP_RES_TYPE_BPS)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001500 ioconfig_cmd.opcode = HFI_IPEBPS_CMD_OPCODE_BPS_CONFIG_IO;
1501 else
1502 ioconfig_cmd.opcode = HFI_IPEBPS_CMD_OPCODE_IPE_CONFIG_IO;
1503
1504 reinit_completion(&ctx_data->wait_complete);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001505 ioconfig_cmd.num_fw_handles = 1;
1506 ioconfig_cmd.fw_handles[0] = ctx_data->fw_handle;
1507 ioconfig_cmd.payload.indirect = io_buf_addr;
1508 ioconfig_cmd.user_data1 = (uint64_t)ctx_data;
1509 ioconfig_cmd.user_data2 = (uint64_t)0x0;
1510 task_data = (struct hfi_cmd_work_data *)task->payload;
1511 task_data->data = (void *)&ioconfig_cmd;
1512 task_data->request_id = 0;
1513 task_data->type = ICP_WORKQ_TASK_CMD_TYPE;
1514 task->process_cb = cam_icp_mgr_process_cmd;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05301515 rc = cam_req_mgr_workq_enqueue_task(task, &icp_hw_mgr,
1516 CRM_TASK_PRIORITY_0);
1517 if (rc)
1518 return rc;
1519
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07001520 rem_jiffies = wait_for_completion_timeout(&ctx_data->wait_complete,
1521 msecs_to_jiffies((timeout)));
1522 if (!rem_jiffies) {
1523 rc = -ETIMEDOUT;
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001524 CAM_ERR(CAM_ICP, "FW response timed out %d", rc);
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07001525 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001526
1527 return rc;
1528}
1529
1530static int cam_icp_mgr_create_handle(uint32_t dev_type,
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05301531 struct cam_icp_hw_ctx_data *ctx_data)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001532{
1533 struct hfi_cmd_create_handle create_handle;
1534 struct hfi_cmd_work_data *task_data;
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07001535 unsigned long rem_jiffies;
1536 int timeout = 5000;
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05301537 struct crm_workq_task *task;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001538 int rc = 0;
1539
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05301540 task = cam_req_mgr_workq_get_task(icp_hw_mgr.cmd_work);
1541 if (!task)
1542 return -ENOMEM;
1543
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001544 create_handle.size = sizeof(struct hfi_cmd_create_handle);
1545 create_handle.pkt_type = HFI_CMD_IPEBPS_CREATE_HANDLE;
1546 create_handle.handle_type = dev_type;
1547 create_handle.user_data1 = (uint64_t)ctx_data;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001548 reinit_completion(&ctx_data->wait_complete);
1549 task_data = (struct hfi_cmd_work_data *)task->payload;
1550 task_data->data = (void *)&create_handle;
1551 task_data->request_id = 0;
1552 task_data->type = ICP_WORKQ_TASK_CMD_TYPE;
1553 task->process_cb = cam_icp_mgr_process_cmd;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05301554 rc = cam_req_mgr_workq_enqueue_task(task, &icp_hw_mgr,
1555 CRM_TASK_PRIORITY_0);
1556 if (rc)
1557 return rc;
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07001558
1559 rem_jiffies = wait_for_completion_timeout(&ctx_data->wait_complete,
1560 msecs_to_jiffies((timeout)));
1561 if (!rem_jiffies) {
1562 rc = -ETIMEDOUT;
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001563 CAM_ERR(CAM_ICP, "FW response timed out %d", rc);
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07001564 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001565
1566 return rc;
1567}
1568
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05301569static int cam_icp_mgr_send_ping(struct cam_icp_hw_ctx_data *ctx_data)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001570{
1571 struct hfi_cmd_ping_pkt ping_pkt;
1572 struct hfi_cmd_work_data *task_data;
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07001573 unsigned long rem_jiffies;
1574 int timeout = 5000;
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05301575 struct crm_workq_task *task;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001576 int rc = 0;
1577
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05301578 task = cam_req_mgr_workq_get_task(icp_hw_mgr.cmd_work);
1579 if (!task) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001580 CAM_ERR(CAM_ICP, "No free task to send ping command");
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05301581 return -ENOMEM;
1582 }
1583
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001584 ping_pkt.size = sizeof(struct hfi_cmd_ping_pkt);
1585 ping_pkt.pkt_type = HFI_CMD_SYS_PING;
1586 ping_pkt.user_data = (uint64_t)ctx_data;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001587 init_completion(&ctx_data->wait_complete);
1588 task_data = (struct hfi_cmd_work_data *)task->payload;
1589 task_data->data = (void *)&ping_pkt;
1590 task_data->request_id = 0;
1591 task_data->type = ICP_WORKQ_TASK_CMD_TYPE;
1592 task->process_cb = cam_icp_mgr_process_cmd;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05301593
1594 rc = cam_req_mgr_workq_enqueue_task(task, &icp_hw_mgr,
1595 CRM_TASK_PRIORITY_0);
1596 if (rc)
1597 return rc;
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07001598
1599 rem_jiffies = wait_for_completion_timeout(&ctx_data->wait_complete,
1600 msecs_to_jiffies((timeout)));
1601 if (!rem_jiffies) {
1602 rc = -ETIMEDOUT;
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001603 CAM_ERR(CAM_ICP, "FW response timed out %d", rc);
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07001604 }
1605
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001606 return rc;
1607}
1608
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05301609static int cam_icp_get_acquire_info(struct cam_icp_hw_mgr *hw_mgr,
1610 struct cam_hw_acquire_args *args,
1611 struct cam_icp_hw_ctx_data *ctx_data)
1612{
1613 int i;
1614 int acquire_size;
1615 struct cam_icp_acquire_dev_info icp_dev_acquire_info;
1616 struct cam_icp_res_info *p_icp_out = NULL;
1617
1618 if (copy_from_user(&icp_dev_acquire_info,
1619 (void __user *)args->acquire_info,
1620 sizeof(struct cam_icp_acquire_dev_info)))
1621 return -EFAULT;
1622
1623 if (icp_dev_acquire_info.num_out_res > ICP_MAX_OUTPUT_SUPPORTED) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001624 CAM_ERR(CAM_ICP, "num of out resources exceeding : %u",
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05301625 icp_dev_acquire_info.num_out_res);
1626 return -EINVAL;
1627 }
1628
Suresh Vankadara22697d32017-07-03 12:14:09 -07001629 if (icp_dev_acquire_info.dev_type >= CAM_ICP_RES_TYPE_MAX) {
1630 CAM_ERR(CAM_ICP, "Invalid device type: %d",
1631 icp_dev_acquire_info.dev_type);
1632 return -EFAULT;
1633 }
1634
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05301635 acquire_size = sizeof(struct cam_icp_acquire_dev_info) +
1636 (icp_dev_acquire_info.num_out_res *
1637 sizeof(struct cam_icp_res_info));
1638 ctx_data->icp_dev_acquire_info = kzalloc(acquire_size, GFP_KERNEL);
1639 if (!ctx_data->icp_dev_acquire_info)
1640 return -ENOMEM;
1641
1642 if (copy_from_user(ctx_data->icp_dev_acquire_info,
1643 (void __user *)args->acquire_info, acquire_size)) {
1644 kfree(ctx_data->icp_dev_acquire_info);
1645 ctx_data->icp_dev_acquire_info = NULL;
1646 return -EFAULT;
1647 }
1648
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001649 CAM_DBG(CAM_ICP, "%x %x %x %x %x %x %x",
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05301650 ctx_data->icp_dev_acquire_info->dev_type,
1651 ctx_data->icp_dev_acquire_info->in_res.format,
1652 ctx_data->icp_dev_acquire_info->in_res.width,
1653 ctx_data->icp_dev_acquire_info->in_res.height,
1654 ctx_data->icp_dev_acquire_info->in_res.fps,
1655 ctx_data->icp_dev_acquire_info->num_out_res,
1656 ctx_data->icp_dev_acquire_info->scratch_mem_size);
1657
1658 p_icp_out = ctx_data->icp_dev_acquire_info->out_res;
Lakshmi Narayana Kalavala92d90c32017-08-04 10:51:53 -07001659 for (i = 0; i < icp_dev_acquire_info.num_out_res; i++)
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001660 CAM_DBG(CAM_ICP, "out[i] %x %x %x %x",
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05301661 p_icp_out[i].format,
1662 p_icp_out[i].width,
1663 p_icp_out[i].height,
1664 p_icp_out[i].fps);
1665
1666 return 0;
1667}
1668
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001669static int cam_icp_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
1670{
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05301671 int rc = 0, bitmap_size = 0;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001672 uint32_t ctx_id = 0;
1673 uint64_t io_buf_addr;
1674 size_t io_buf_size;
1675 struct cam_icp_hw_mgr *hw_mgr = hw_mgr_priv;
1676 struct cam_icp_hw_ctx_data *ctx_data = NULL;
1677 struct cam_hw_acquire_args *args = acquire_hw_args;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05301678 struct cam_icp_acquire_dev_info *icp_dev_acquire_info;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001679
1680 if ((!hw_mgr_priv) || (!acquire_hw_args)) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001681 CAM_ERR(CAM_ICP, "Invalid params: %pK %pK", hw_mgr_priv,
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001682 acquire_hw_args);
1683 return -EINVAL;
1684 }
1685
1686 if (args->num_acq > 1) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001687 CAM_ERR(CAM_ICP, "number of resources are wrong: %u",
1688 args->num_acq);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001689 return -EINVAL;
1690 }
1691
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001692 mutex_lock(&hw_mgr->hw_mgr_mutex);
1693 ctx_id = cam_icp_mgr_get_free_ctx(hw_mgr);
1694 if (ctx_id >= CAM_ICP_CTX_MAX) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001695 CAM_ERR(CAM_ICP, "No free ctx space in hw_mgr");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001696 mutex_unlock(&hw_mgr->hw_mgr_mutex);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301697 return -ENOSPC;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001698 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001699 ctx_data = &hw_mgr->ctx_data[ctx_id];
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05301700 ctx_data->ctx_id = ctx_id;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001701 mutex_unlock(&hw_mgr->hw_mgr_mutex);
1702
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001703 mutex_lock(&ctx_data->ctx_mutex);
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05301704 rc = cam_icp_get_acquire_info(hw_mgr, args, ctx_data);
Suresh Vankadara22697d32017-07-03 12:14:09 -07001705 if (rc)
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05301706 goto acquire_info_failed;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05301707 icp_dev_acquire_info = ctx_data->icp_dev_acquire_info;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001708
1709 /* Get IOCONFIG command info */
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05301710 if (icp_dev_acquire_info->secure_mode)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001711 rc = cam_mem_get_io_buf(
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05301712 icp_dev_acquire_info->io_config_cmd_handle,
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001713 hw_mgr->iommu_sec_hdl,
1714 &io_buf_addr, &io_buf_size);
1715 else
1716 rc = cam_mem_get_io_buf(
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05301717 icp_dev_acquire_info->io_config_cmd_handle,
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001718 hw_mgr->iommu_hdl,
1719 &io_buf_addr, &io_buf_size);
1720
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301721 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001722 CAM_ERR(CAM_ICP, "unable to get src buf info from io desc");
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301723 goto get_io_buf_failed;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001724 }
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001725
1726 CAM_DBG(CAM_ICP, "hdl: %d, addr: %pK, size: %zu",
1727 icp_dev_acquire_info->io_config_cmd_handle,
1728 (void *)io_buf_addr, io_buf_size);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001729
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301730 mutex_lock(&hw_mgr->hw_mgr_mutex);
Suresh Vankadara5499a5f2017-06-16 22:13:56 +05301731 if (!hw_mgr->ctxt_cnt) {
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301732 mutex_unlock(&hw_mgr->hw_mgr_mutex);
Suresh Vankadara5499a5f2017-06-16 22:13:56 +05301733 rc = cam_icp_mgr_download_fw(hw_mgr, ctx_data);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301734 if (rc)
1735 goto get_io_buf_failed;
Suresh Vankadara6657bc22017-07-31 10:33:04 +05301736 rc = cam_icp_mgr_ipe_bps_resume(hw_mgr, ctx_data);
1737 if (rc)
1738 goto ipe_bps_resume_failed;
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301739 mutex_lock(&hw_mgr->hw_mgr_mutex);
Suresh Vankadara5499a5f2017-06-16 22:13:56 +05301740 }
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301741 mutex_unlock(&hw_mgr->hw_mgr_mutex);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001742
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05301743 rc = cam_icp_mgr_send_ping(ctx_data);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001744 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001745 CAM_ERR(CAM_ICP, "ping ack not received");
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301746 goto send_ping_failed;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001747 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001748
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05301749 rc = cam_icp_mgr_create_handle(icp_dev_acquire_info->dev_type,
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05301750 ctx_data);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001751 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001752 CAM_ERR(CAM_ICP, "create handle failed");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001753 goto create_handle_failed;
1754 }
1755
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05301756 rc = cam_icp_mgr_send_config_io(ctx_data, io_buf_addr);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001757 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001758 CAM_ERR(CAM_ICP, "IO Config command failed");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001759 goto ioconfig_failed;
1760 }
1761
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001762 ctx_data->context_priv = args->context_data;
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05301763 args->ctxt_to_hw_map = ctx_data;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001764
1765 bitmap_size = BITS_TO_LONGS(CAM_FRAME_CMD_MAX) * sizeof(long);
1766 ctx_data->hfi_frame_process.bitmap =
Lakshmi Narayana Kalavalaaae1e6b2017-06-14 09:58:40 -07001767 kzalloc(bitmap_size, GFP_KERNEL);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301768 if (!ctx_data->hfi_frame_process.bitmap)
1769 goto ioconfig_failed;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001770 ctx_data->hfi_frame_process.bits = bitmap_size * BITS_PER_BYTE;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001771 hw_mgr->ctx_data[ctx_id].ctxt_event_cb = args->event_cb;
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05301772 icp_dev_acquire_info->scratch_mem_size = ctx_data->scratch_mem_size;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001773
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001774 if (copy_to_user((void __user *)args->acquire_info,
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05301775 icp_dev_acquire_info, sizeof(struct cam_icp_acquire_dev_info)))
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001776 goto copy_to_user_failed;
1777
Suresh Vankadara22697d32017-07-03 12:14:09 -07001778 mutex_unlock(&ctx_data->ctx_mutex);
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001779 CAM_DBG(CAM_ICP, "scratch size = %x fw_handle = %x",
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05301780 (unsigned int)icp_dev_acquire_info->scratch_mem_size,
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001781 (unsigned int)ctx_data->fw_handle);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301782 mutex_lock(&hw_mgr->hw_mgr_mutex);
Suresh Vankadara5499a5f2017-06-16 22:13:56 +05301783 hw_mgr->ctxt_cnt++;
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301784 mutex_unlock(&hw_mgr->hw_mgr_mutex);
1785
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001786 return 0;
1787
1788copy_to_user_failed:
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301789 kfree(ctx_data->hfi_frame_process.bitmap);
1790 ctx_data->hfi_frame_process.bitmap = NULL;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001791ioconfig_failed:
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05301792 cam_icp_mgr_destroy_handle(ctx_data);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001793create_handle_failed:
Suresh Vankadara6657bc22017-07-31 10:33:04 +05301794send_ping_failed:
1795 cam_icp_mgr_ipe_bps_power_collapse(hw_mgr, ctx_data, 0);
1796ipe_bps_resume_failed:
Suresh Vankadara5499a5f2017-06-16 22:13:56 +05301797 if (!hw_mgr->ctxt_cnt)
1798 cam_icp_mgr_hw_close(hw_mgr, NULL);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301799get_io_buf_failed:
Suresh Vankadaraadcf0582017-05-24 09:53:36 +05301800 kfree(hw_mgr->ctx_data[ctx_id].icp_dev_acquire_info);
1801 hw_mgr->ctx_data[ctx_id].icp_dev_acquire_info = NULL;
1802acquire_info_failed:
1803 cam_icp_mgr_put_ctx(ctx_data);
Suresh Vankadara22697d32017-07-03 12:14:09 -07001804 mutex_unlock(&ctx_data->ctx_mutex);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001805 return rc;
1806}
1807
1808static int cam_icp_mgr_get_hw_caps(void *hw_mgr_priv, void *hw_caps_args)
1809{
1810 int rc = 0;
1811 struct cam_icp_hw_mgr *hw_mgr = hw_mgr_priv;
1812 struct cam_query_cap_cmd *query_cap = hw_caps_args;
1813
1814 if ((!hw_mgr_priv) || (!hw_caps_args)) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001815 CAM_ERR(CAM_ICP, "Invalid params: %pK %pK",
1816 hw_mgr_priv, hw_caps_args);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001817 return -EINVAL;
1818 }
1819
Suresh Vankadara22697d32017-07-03 12:14:09 -07001820 mutex_lock(&hw_mgr->hw_mgr_mutex);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001821 if (copy_from_user(&icp_hw_mgr.icp_caps,
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05301822 (void __user *)query_cap->caps_handle,
1823 sizeof(struct cam_icp_query_cap_cmd))) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001824 CAM_ERR(CAM_ICP, "copy_from_user failed");
Suresh Vankadara22697d32017-07-03 12:14:09 -07001825 rc = -EFAULT;
1826 goto end;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001827 }
1828
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001829 rc = hfi_get_hw_caps(&icp_hw_mgr.icp_caps);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301830 if (rc)
Suresh Vankadara22697d32017-07-03 12:14:09 -07001831 goto end;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001832
1833 icp_hw_mgr.icp_caps.dev_iommu_handle.non_secure = hw_mgr->iommu_hdl;
1834 icp_hw_mgr.icp_caps.dev_iommu_handle.secure = hw_mgr->iommu_sec_hdl;
1835
1836 if (copy_to_user((void __user *)query_cap->caps_handle,
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05301837 &icp_hw_mgr.icp_caps, sizeof(struct cam_icp_query_cap_cmd))) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001838 CAM_ERR(CAM_ICP, "copy_to_user failed");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001839 rc = -EFAULT;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001840 }
Suresh Vankadara22697d32017-07-03 12:14:09 -07001841end:
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001842 mutex_unlock(&hw_mgr->hw_mgr_mutex);
1843 return rc;
1844}
1845
Suresh Vankadara22697d32017-07-03 12:14:09 -07001846static int cam_icp_mgr_alloc_devs(struct device_node *of_node)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001847{
Suresh Vankadara22697d32017-07-03 12:14:09 -07001848 int rc;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001849 uint32_t num_dev;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001850
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001851 rc = of_property_read_u32(of_node, "num-a5", &num_dev);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301852 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001853 CAM_ERR(CAM_ICP, "getting num of a5 failed");
Suresh Vankadara22697d32017-07-03 12:14:09 -07001854 goto num_a5_failed;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001855 }
1856
1857 icp_hw_mgr.devices[CAM_ICP_DEV_A5] = kzalloc(
1858 sizeof(struct cam_hw_intf *) * num_dev, GFP_KERNEL);
1859 if (!icp_hw_mgr.devices[CAM_ICP_DEV_A5]) {
1860 rc = -ENOMEM;
Suresh Vankadara22697d32017-07-03 12:14:09 -07001861 goto num_a5_failed;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001862 }
1863
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05301864 rc = of_property_read_u32(of_node, "num-ipe", &num_dev);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301865 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001866 CAM_ERR(CAM_ICP, "getting number of ipe dev nodes failed");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001867 goto num_ipe_failed;
1868 }
1869
1870 icp_hw_mgr.devices[CAM_ICP_DEV_IPE] = kzalloc(
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05301871 sizeof(struct cam_hw_intf *) * num_dev, GFP_KERNEL);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001872 if (!icp_hw_mgr.devices[CAM_ICP_DEV_IPE]) {
1873 rc = -ENOMEM;
1874 goto num_ipe_failed;
1875 }
1876
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001877 rc = of_property_read_u32(of_node, "num-bps", &num_dev);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301878 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001879 CAM_ERR(CAM_ICP, "read num bps devices failed");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001880 goto num_bps_failed;
1881 }
1882 icp_hw_mgr.devices[CAM_ICP_DEV_BPS] = kzalloc(
1883 sizeof(struct cam_hw_intf *) * num_dev, GFP_KERNEL);
1884 if (!icp_hw_mgr.devices[CAM_ICP_DEV_BPS]) {
1885 rc = -ENOMEM;
1886 goto num_bps_failed;
1887 }
1888
Suresh Vankadara22697d32017-07-03 12:14:09 -07001889 return 0;
1890num_bps_failed:
1891 kfree(icp_hw_mgr.devices[CAM_ICP_DEV_IPE]);
1892num_ipe_failed:
1893 kfree(icp_hw_mgr.devices[CAM_ICP_DEV_A5]);
1894num_a5_failed:
1895 return rc;
1896}
1897
1898static int cam_icp_mgr_init_devs(struct device_node *of_node)
1899{
1900 int rc = 0;
1901 int count, i;
1902 const char *name = NULL;
1903 struct device_node *child_node = NULL;
1904 struct platform_device *child_pdev = NULL;
1905 struct cam_hw_intf *child_dev_intf = NULL;
1906
1907 rc = cam_icp_mgr_alloc_devs(of_node);
1908 if (rc)
1909 return rc;
1910
1911 count = of_property_count_strings(of_node, "compat-hw-name");
1912 if (!count) {
1913 CAM_ERR(CAM_ICP, "no compat hw found in dev tree, cnt = %d",
1914 count);
1915 rc = -EINVAL;
1916 goto compat_hw_name_failed;
1917 }
1918
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001919 for (i = 0; i < count; i++) {
1920 rc = of_property_read_string_index(of_node, "compat-hw-name",
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05301921 i, &name);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301922 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001923 CAM_ERR(CAM_ICP, "getting dev object name failed");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001924 goto compat_hw_name_failed;
1925 }
1926
1927 child_node = of_find_node_by_name(NULL, name);
1928 if (!child_node) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001929 CAM_ERR(CAM_ICP, "Cannot find node in dtsi %s", name);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001930 rc = -ENODEV;
1931 goto compat_hw_name_failed;
1932 }
1933
1934 child_pdev = of_find_device_by_node(child_node);
1935 if (!child_pdev) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001936 CAM_ERR(CAM_ICP, "failed to find device on bus %s",
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001937 child_node->name);
1938 rc = -ENODEV;
1939 of_node_put(child_node);
1940 goto compat_hw_name_failed;
1941 }
1942
1943 child_dev_intf = (struct cam_hw_intf *)platform_get_drvdata(
Suresh Vankadara5a1ae562017-06-03 12:59:15 +05301944 child_pdev);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001945 if (!child_dev_intf) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001946 CAM_ERR(CAM_ICP, "no child device");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001947 of_node_put(child_node);
1948 goto compat_hw_name_failed;
1949 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001950
1951 icp_hw_mgr.devices[child_dev_intf->hw_type]
1952 [child_dev_intf->hw_idx] = child_dev_intf;
1953
Suresh Vankadara6657bc22017-07-31 10:33:04 +05301954 if (!child_dev_intf->hw_ops.process_cmd)
1955 goto compat_hw_name_failed;
1956
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001957 of_node_put(child_node);
1958 }
1959
Suresh Vankadara22697d32017-07-03 12:14:09 -07001960 return 0;
1961compat_hw_name_failed:
1962 kfree(icp_hw_mgr.devices[CAM_ICP_DEV_BPS]);
1963 kfree(icp_hw_mgr.devices[CAM_ICP_DEV_IPE]);
1964 kfree(icp_hw_mgr.devices[CAM_ICP_DEV_A5]);
1965 return rc;
1966}
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001967
Suresh Vankadara22697d32017-07-03 12:14:09 -07001968static int cam_icp_mgr_create_wq(void)
1969{
1970 int rc;
1971 int i;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001972
1973 rc = cam_req_mgr_workq_create("icp_command_queue", ICP_WORKQ_NUM_TASK,
Sagar Gore9f404712017-05-22 16:57:25 -07001974 &icp_hw_mgr.cmd_work, CRM_WORKQ_USAGE_NON_IRQ);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301975 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001976 CAM_ERR(CAM_ICP, "unable to create a worker");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001977 goto cmd_work_failed;
1978 }
1979
1980 rc = cam_req_mgr_workq_create("icp_message_queue", ICP_WORKQ_NUM_TASK,
Sagar Gore9f404712017-05-22 16:57:25 -07001981 &icp_hw_mgr.msg_work, CRM_WORKQ_USAGE_IRQ);
Suresh Vankadarad8905f42017-06-04 13:33:49 +05301982 if (rc) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -07001983 CAM_ERR(CAM_ICP, "unable to create a worker");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07001984 goto msg_work_failed;
1985 }
1986
1987 icp_hw_mgr.cmd_work_data = (struct hfi_cmd_work_data *)
1988 kzalloc(sizeof(struct hfi_cmd_work_data) * ICP_WORKQ_NUM_TASK,
1989 GFP_KERNEL);
1990 if (!icp_hw_mgr.cmd_work_data)
1991 goto cmd_work_data_failed;
1992
1993 icp_hw_mgr.msg_work_data = (struct hfi_msg_work_data *)
1994 kzalloc(sizeof(struct hfi_msg_work_data) * ICP_WORKQ_NUM_TASK,
1995 GFP_KERNEL);
1996 if (!icp_hw_mgr.msg_work_data)
1997 goto msg_work_data_failed;
1998
Lakshmi Narayana Kalavala2743a0d2017-05-30 10:41:37 -07001999 rc = cam_icp_hw_mgr_create_debugfs_entry();
2000 if (rc)
2001 goto msg_work_data_failed;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002002
2003 for (i = 0; i < ICP_WORKQ_NUM_TASK; i++)
2004 icp_hw_mgr.msg_work->task.pool[i].payload =
2005 &icp_hw_mgr.msg_work_data[i];
2006
2007 for (i = 0; i < ICP_WORKQ_NUM_TASK; i++)
2008 icp_hw_mgr.cmd_work->task.pool[i].payload =
2009 &icp_hw_mgr.cmd_work_data[i];
2010
Suresh Vankadara22697d32017-07-03 12:14:09 -07002011 return 0;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002012msg_work_data_failed:
2013 kfree(icp_hw_mgr.cmd_work_data);
2014cmd_work_data_failed:
2015 cam_req_mgr_workq_destroy(&icp_hw_mgr.msg_work);
2016msg_work_failed:
2017 cam_req_mgr_workq_destroy(&icp_hw_mgr.cmd_work);
2018cmd_work_failed:
Suresh Vankadara22697d32017-07-03 12:14:09 -07002019 return rc;
2020}
2021
2022int cam_icp_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl)
2023{
2024 int i, rc = 0;
2025 struct cam_hw_mgr_intf *hw_mgr_intf;
2026
2027 hw_mgr_intf = (struct cam_hw_mgr_intf *)hw_mgr_hdl;
2028 if (!of_node || !hw_mgr_intf) {
2029 CAM_ERR(CAM_ICP, "Invalid args of_node %pK hw_mgr %pK",
2030 of_node, hw_mgr_intf);
2031 return -EINVAL;
2032 }
2033
2034 hw_mgr_intf->hw_mgr_priv = &icp_hw_mgr;
2035 hw_mgr_intf->hw_get_caps = cam_icp_mgr_get_hw_caps;
2036 hw_mgr_intf->hw_acquire = cam_icp_mgr_acquire_hw;
2037 hw_mgr_intf->hw_release = cam_icp_mgr_release_hw;
2038 hw_mgr_intf->hw_prepare_update = cam_icp_mgr_prepare_hw_update;
2039 hw_mgr_intf->hw_config = cam_icp_mgr_config_hw;
2040 hw_mgr_intf->download_fw = cam_icp_mgr_download_fw;
2041 hw_mgr_intf->hw_close = cam_icp_mgr_hw_close;
2042
2043 mutex_init(&icp_hw_mgr.hw_mgr_mutex);
2044 spin_lock_init(&icp_hw_mgr.hw_mgr_lock);
2045
2046 for (i = 0; i < CAM_ICP_CTX_MAX; i++)
2047 mutex_init(&icp_hw_mgr.ctx_data[i].ctx_mutex);
2048
2049 rc = cam_icp_mgr_init_devs(of_node);
2050 if (rc)
2051 goto dev_init_failed;
2052
2053 rc = cam_smmu_get_handle("icp", &icp_hw_mgr.iommu_hdl);
2054 if (rc) {
2055 CAM_ERR(CAM_ICP, "icp get iommu handle failed: %d", rc);
2056 goto icp_get_hdl_failed;
2057 }
2058
2059 rc = cam_smmu_ops(icp_hw_mgr.iommu_hdl, CAM_SMMU_ATTACH);
2060 if (rc) {
2061 CAM_ERR(CAM_ICP, "icp attach failed: %d", rc);
2062 goto icp_attach_failed;
2063 }
2064
2065 rc = cam_icp_mgr_create_wq();
2066 if (rc)
2067 goto icp_wq_create_failed;
2068
2069 init_completion(&icp_hw_mgr.a5_complete);
2070
2071 return rc;
2072
2073icp_wq_create_failed:
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002074 cam_smmu_ops(icp_hw_mgr.iommu_hdl, CAM_SMMU_DETACH);
2075icp_attach_failed:
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +05302076 cam_smmu_destroy_handle(icp_hw_mgr.iommu_hdl);
Suresh Vankadara22697d32017-07-03 12:14:09 -07002077 icp_hw_mgr.iommu_hdl = -1;
2078icp_get_hdl_failed:
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002079 kfree(icp_hw_mgr.devices[CAM_ICP_DEV_BPS]);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002080 kfree(icp_hw_mgr.devices[CAM_ICP_DEV_IPE]);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002081 kfree(icp_hw_mgr.devices[CAM_ICP_DEV_A5]);
Suresh Vankadara22697d32017-07-03 12:14:09 -07002082dev_init_failed:
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -07002083 mutex_destroy(&icp_hw_mgr.hw_mgr_mutex);
2084 for (i = 0; i < CAM_ICP_CTX_MAX; i++)
2085 mutex_destroy(&icp_hw_mgr.ctx_data[i].ctx_mutex);
2086
2087 return rc;
2088}