blob: 32f65720655fac22f6437a830db38addd2e65ca9 [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/debugfs.h>
14#include <linux/videodev2.h>
15#include <linux/slab.h>
16#include <linux/uaccess.h>
17#include <media/cam_sync.h>
18#include <media/cam_defs.h>
19
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -060020#include "cam_context.h"
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -070021#include "cam_context_utils.h"
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -070022#include "cam_mem_mgr.h"
23#include "cam_node.h"
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -060024#include "cam_req_mgr_util.h"
25#include "cam_sync_api.h"
26#include "cam_trace.h"
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -070027#include "cam_debug_util.h"
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -070028
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -070029static inline int cam_context_validate_thread(void)
30{
31 if (in_interrupt()) {
32 WARN(1, "Invalid execution context\n");
33 return -EINVAL;
34 }
35 return 0;
36}
37
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -070038int cam_context_buf_done_from_hw(struct cam_context *ctx,
39 void *done_event_data, uint32_t bubble_state)
40{
Sagar Gorecdd6a5e2017-05-17 19:06:59 -070041 int j;
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +053042 int result;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -070043 struct cam_ctx_request *req;
44 struct cam_hw_done_event_data *done =
45 (struct cam_hw_done_event_data *)done_event_data;
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -070046 int rc;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -070047
Pavan Kumar Chilamkurthica2295d2017-07-30 01:50:59 -070048 if (!ctx || !done) {
49 CAM_ERR(CAM_CTXT, "Invalid input params %pK %pK", ctx, done);
50 return -EINVAL;
51 }
52
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -070053 rc = cam_context_validate_thread();
54 if (rc)
55 return rc;
56
57 spin_lock(&ctx->lock);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -070058 if (list_empty(&ctx->active_req_list)) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -070059 CAM_ERR(CAM_CTXT, "no active request");
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -070060 spin_unlock(&ctx->lock);
Sagar Gorecdd6a5e2017-05-17 19:06:59 -070061 return -EIO;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -070062 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -070063 req = list_first_entry(&ctx->active_req_list,
64 struct cam_ctx_request, list);
65
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -060066 trace_cam_buf_done("UTILS", ctx, req);
67
Sagar Gorecdd6a5e2017-05-17 19:06:59 -070068 if (done->request_id != req->request_id) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -070069 CAM_ERR(CAM_CTXT, "mismatch: done req[%lld], active req[%lld]",
Sagar Gorecdd6a5e2017-05-17 19:06:59 -070070 done->request_id, req->request_id);
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -070071 spin_unlock(&ctx->lock);
Sagar Gorecdd6a5e2017-05-17 19:06:59 -070072 return -EIO;
73 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -070074
Sagar Gorecdd6a5e2017-05-17 19:06:59 -070075 if (!req->num_out_map_entries) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -070076 CAM_ERR(CAM_CTXT, "no output fence to signal");
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -070077 spin_unlock(&ctx->lock);
Sagar Gorecdd6a5e2017-05-17 19:06:59 -070078 return -EIO;
79 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -070080
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -070081 /*
82 * since another thread may be adding/removing from active
83 * list, so hold the lock
84 */
Sagar Gorecdd6a5e2017-05-17 19:06:59 -070085 list_del_init(&req->list);
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -070086 spin_unlock(&ctx->lock);
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +053087 if (!bubble_state)
88 result = CAM_SYNC_STATE_SIGNALED_SUCCESS;
89 else
90 result = CAM_SYNC_STATE_SIGNALED_ERROR;
91
Sagar Gorecdd6a5e2017-05-17 19:06:59 -070092 for (j = 0; j < req->num_out_map_entries; j++) {
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +053093 cam_sync_signal(req->out_map_entries[j].sync_id, result);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -070094 req->out_map_entries[j].sync_id = -1;
95 }
96
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -070097 /*
98 * another thread may be adding/removing from free list,
99 * so hold the lock
100 */
101 spin_lock(&ctx->lock);
Sagar Gorecdd6a5e2017-05-17 19:06:59 -0700102 list_add_tail(&req->list, &ctx->free_req_list);
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -0700103 req->ctx = NULL;
104 spin_unlock(&ctx->lock);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700105
Sagar Gorecdd6a5e2017-05-17 19:06:59 -0700106 return 0;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700107}
108
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -0700109static int cam_context_apply_req_to_hw(struct cam_ctx_request *req,
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700110 struct cam_req_mgr_apply_request *apply)
111{
112 int rc = 0;
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -0700113 struct cam_context *ctx = req->ctx;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700114 struct cam_hw_config_args cfg;
115
116 if (!ctx->hw_mgr_intf) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700117 CAM_ERR(CAM_CTXT, "HW interface is not ready");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700118 rc = -EFAULT;
119 goto end;
120 }
121
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700122 spin_lock(&ctx->lock);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700123 list_del_init(&req->list);
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -0700124 list_add_tail(&req->list, &ctx->active_req_list);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700125 spin_unlock(&ctx->lock);
126
127 cfg.ctxt_to_hw_map = ctx->ctxt_to_hw_map;
128 cfg.hw_update_entries = req->hw_update_entries;
129 cfg.num_hw_update_entries = req->num_hw_update_entries;
130 cfg.out_map_entries = req->out_map_entries;
131 cfg.num_out_map_entries = req->num_out_map_entries;
Pavan Kumar Chilamkurthieb8833c2017-07-15 19:44:13 -0700132 cfg.priv = req->req_priv;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700133
134 rc = ctx->hw_mgr_intf->hw_config(ctx->hw_mgr_intf->hw_mgr_priv, &cfg);
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -0700135 if (rc) {
136 spin_lock(&ctx->lock);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700137 list_del_init(&req->list);
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -0700138 spin_unlock(&ctx->lock);
139 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700140
141end:
142 return rc;
143}
144
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +0530145static void cam_context_sync_callback(int32_t sync_obj, int status, void *data)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700146{
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -0700147 struct cam_ctx_request *req = data;
148 struct cam_context *ctx = NULL;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700149 struct cam_req_mgr_apply_request apply;
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -0700150 int rc;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700151
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -0700152 if (!req) {
Pavan Kumar Chilamkurthica2295d2017-07-30 01:50:59 -0700153 CAM_ERR(CAM_CTXT, "Invalid input param");
154 return;
155 }
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -0700156 rc = cam_context_validate_thread();
157 if (rc)
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700158 return;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700159
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -0700160 ctx = req->ctx;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700161 req->num_in_acked++;
162 if (req->num_in_acked == req->num_in_map_entries) {
163 apply.request_id = req->request_id;
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -0700164 /*
165 * take mutex to ensure that another thread does
166 * not flush the request while this
167 * thread is submitting it to h/w. The submit to
168 * h/w and adding to the active list should happen
169 * in a critical section which is provided by this
170 * mutex.
171 */
172 mutex_lock(&ctx->sync_mutex);
173 if (!req->flushed) {
174 cam_context_apply_req_to_hw(req, &apply);
175 mutex_unlock(&ctx->sync_mutex);
176 } else {
177 mutex_unlock(&ctx->sync_mutex);
178 req->ctx = NULL;
179 req->flushed = 0;
180 spin_lock(&ctx->lock);
181 list_add_tail(&req->list, &ctx->free_req_list);
182 spin_unlock(&ctx->lock);
183 }
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700184 }
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -0700185 cam_context_putref(ctx);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700186}
187
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +0530188int32_t cam_context_release_dev_to_hw(struct cam_context *ctx,
189 struct cam_release_dev_cmd *cmd)
190{
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +0530191 struct cam_hw_release_args arg;
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +0530192
Pavan Kumar Chilamkurthica2295d2017-07-30 01:50:59 -0700193 if (!ctx) {
194 CAM_ERR(CAM_CTXT, "Invalid input param");
195 return -EINVAL;
196 }
197
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530198 if ((!ctx->hw_mgr_intf) || (!ctx->hw_mgr_intf->hw_release)) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700199 CAM_ERR(CAM_CTXT, "HW interface is not ready");
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530200 return -EINVAL;
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +0530201 }
202
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530203 arg.ctxt_to_hw_map = ctx->ctxt_to_hw_map;
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -0700204 arg.active_req = false;
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +0530205
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530206 ctx->hw_mgr_intf->hw_release(ctx->hw_mgr_intf->hw_mgr_priv, &arg);
207 ctx->ctxt_to_hw_map = NULL;
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +0530208
Soundrapandian Jeyaprakash8d16e272017-10-12 11:05:37 -0700209 ctx->session_hdl = -1;
210 ctx->dev_hdl = -1;
211 ctx->link_hdl = -1;
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +0530212
Suresh Vankadarad8905f42017-06-04 13:33:49 +0530213 return 0;
Suresh Vankadara8e06cfb2017-06-13 16:27:08 +0530214}
215
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700216int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx,
217 struct cam_config_dev_cmd *cmd)
218{
219 int rc = 0;
220 struct cam_ctx_request *req = NULL;
221 struct cam_hw_prepare_update_args cfg;
222 uint64_t packet_addr;
223 struct cam_packet *packet;
224 size_t len = 0;
225 int32_t i = 0;
226
Pavan Kumar Chilamkurthica2295d2017-07-30 01:50:59 -0700227 if (!ctx || !cmd) {
228 CAM_ERR(CAM_CTXT, "Invalid input params %pK %pK", ctx, cmd);
229 rc = -EINVAL;
230 goto end;
231 }
232
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700233 if (!ctx->hw_mgr_intf) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700234 CAM_ERR(CAM_CTXT, "HW interface is not ready");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700235 rc = -EFAULT;
236 goto end;
237 }
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -0700238 rc = cam_context_validate_thread();
239 if (rc)
240 return rc;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700241
242 spin_lock(&ctx->lock);
243 if (!list_empty(&ctx->free_req_list)) {
244 req = list_first_entry(&ctx->free_req_list,
245 struct cam_ctx_request, list);
246 list_del_init(&req->list);
247 }
248 spin_unlock(&ctx->lock);
249
250 if (!req) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700251 CAM_ERR(CAM_CTXT, "No more request obj free");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700252 rc = -ENOMEM;
253 goto end;
254 }
255
256 memset(req, 0, sizeof(*req));
257 INIT_LIST_HEAD(&req->list);
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -0700258 req->ctx = ctx;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700259
260 /* for config dev, only memory handle is supported */
261 /* map packet from the memhandle */
262 rc = cam_mem_get_cpu_buf((int32_t) cmd->packet_handle,
263 (uint64_t *) &packet_addr,
264 &len);
265 if (rc != 0) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700266 CAM_ERR(CAM_CTXT, "Can not get packet address");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700267 rc = -EINVAL;
268 goto free_req;
269 }
270
271 packet = (struct cam_packet *) (packet_addr + cmd->offset);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700272
273 /* preprocess the configuration */
274 memset(&cfg, 0, sizeof(cfg));
275 cfg.packet = packet;
276 cfg.ctxt_to_hw_map = ctx->ctxt_to_hw_map;
277 cfg.max_hw_update_entries = CAM_CTX_CFG_MAX;
278 cfg.num_hw_update_entries = req->num_hw_update_entries;
279 cfg.hw_update_entries = req->hw_update_entries;
280 cfg.max_out_map_entries = CAM_CTX_CFG_MAX;
281 cfg.out_map_entries = req->out_map_entries;
282 cfg.max_in_map_entries = CAM_CTX_CFG_MAX;
283 cfg.in_map_entries = req->in_map_entries;
284
285 rc = ctx->hw_mgr_intf->hw_prepare_update(
286 ctx->hw_mgr_intf->hw_mgr_priv, &cfg);
287 if (rc != 0) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700288 CAM_ERR(CAM_CTXT, "Prepare config packet failed in HW layer");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700289 rc = -EFAULT;
290 goto free_req;
291 }
292 req->num_hw_update_entries = cfg.num_hw_update_entries;
293 req->num_out_map_entries = cfg.num_out_map_entries;
294 req->num_in_map_entries = cfg.num_in_map_entries;
295 req->request_id = packet->header.request_id;
296 req->status = 1;
297 req->req_priv = cfg.priv;
298
299 if (req->num_in_map_entries > 0) {
300 spin_lock(&ctx->lock);
301 list_add_tail(&req->list, &ctx->pending_req_list);
302 spin_unlock(&ctx->lock);
303 for (i = 0; i < req->num_in_map_entries; i++) {
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -0700304 cam_context_getref(ctx);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700305 rc = cam_sync_register_callback(
306 cam_context_sync_callback,
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -0700307 (void *)req,
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700308 req->in_map_entries[i].sync_id);
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -0700309 if (rc) {
310 CAM_ERR(CAM_CTXT,
311 "Failed register fence cb: %d ret = %d",
312 req->in_map_entries[i].sync_id, rc);
313 cam_context_putref(ctx);
314 goto free_req;
315 }
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700316 CAM_DBG(CAM_CTXT, "register in fence cb: %d ret = %d",
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700317 req->in_map_entries[i].sync_id, rc);
318 }
319 goto end;
320 }
321
322 return rc;
323
324free_req:
325 spin_lock(&ctx->lock);
326 list_add_tail(&req->list, &ctx->free_req_list);
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -0700327 req->ctx = NULL;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700328 spin_unlock(&ctx->lock);
329end:
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700330 return rc;
331}
332
333int32_t cam_context_acquire_dev_to_hw(struct cam_context *ctx,
334 struct cam_acquire_dev_cmd *cmd)
335{
336 int rc;
337 struct cam_hw_acquire_args param;
338 struct cam_create_dev_hdl req_hdl_param;
339 struct cam_hw_release_args release;
340
Pavan Kumar Chilamkurthica2295d2017-07-30 01:50:59 -0700341 if (!ctx || !cmd) {
342 CAM_ERR(CAM_CTXT, "Invalid input params %pK %pK", ctx, cmd);
343 rc = -EINVAL;
344 goto end;
345 }
346
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700347 if (!ctx->hw_mgr_intf) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700348 CAM_ERR(CAM_CTXT, "HW interface is not ready");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700349 rc = -EFAULT;
350 goto end;
351 }
352
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700353 CAM_DBG(CAM_CTXT, "ses hdl: %x, num_res: %d, type: %d, res: %lld",
354 cmd->session_handle, cmd->num_resources, cmd->handle_type,
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700355 cmd->resource_hdl);
356
357 if (cmd->num_resources > CAM_CTX_RES_MAX) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700358 CAM_ERR(CAM_CTXT, "resource limit exceeded");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700359 rc = -ENOMEM;
360 goto end;
361 }
362
363 /* for now we only support user pointer */
364 if (cmd->handle_type != 1) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700365 CAM_ERR(CAM_CTXT, "Only user pointer is supported");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700366 rc = -EINVAL;
367 goto end;
368 }
369
370 /* fill in parameters */
371 param.context_data = ctx;
372 param.event_cb = ctx->irq_cb_intf;
373 param.num_acq = cmd->num_resources;
374 param.acquire_info = cmd->resource_hdl;
375
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700376 /* call HW manager to reserve the resource */
377 rc = ctx->hw_mgr_intf->hw_acquire(ctx->hw_mgr_intf->hw_mgr_priv,
378 &param);
379 if (rc != 0) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700380 CAM_ERR(CAM_CTXT, "Acquire device failed");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700381 goto end;
382 }
383
384 ctx->ctxt_to_hw_map = param.ctxt_to_hw_map;
385
386 /* if hw resource acquire successful, acquire dev handle */
387 req_hdl_param.session_hdl = cmd->session_handle;
388 /* bridge is not ready for these flags. so false for now */
389 req_hdl_param.v4l2_sub_dev_flag = 0;
390 req_hdl_param.media_entity_flag = 0;
391 req_hdl_param.priv = ctx;
Soundrapandian Jeyaprakasheb64e8e2017-08-11 18:44:14 -0700392 req_hdl_param.ops = ctx->crm_ctx_intf;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700393
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700394 ctx->dev_hdl = cam_create_device_hdl(&req_hdl_param);
395 if (ctx->dev_hdl <= 0) {
396 rc = -EFAULT;
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700397 CAM_ERR(CAM_CTXT, "Can not create device handle");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700398 goto free_hw;
399 }
400 cmd->dev_handle = ctx->dev_hdl;
401
402 /* store session information */
403 ctx->session_hdl = cmd->session_handle;
404
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700405 return rc;
406
407free_hw:
408 release.ctxt_to_hw_map = ctx->ctxt_to_hw_map;
409 ctx->hw_mgr_intf->hw_release(ctx->hw_mgr_intf->hw_mgr_priv, &release);
410 ctx->ctxt_to_hw_map = NULL;
411end:
412 return rc;
413}
414
415int32_t cam_context_start_dev_to_hw(struct cam_context *ctx,
416 struct cam_start_stop_dev_cmd *cmd)
417{
418 int rc = 0;
419 struct cam_hw_start_args arg;
420
Pavan Kumar Chilamkurthica2295d2017-07-30 01:50:59 -0700421 if (!ctx || !cmd) {
422 CAM_ERR(CAM_CTXT, "Invalid input params %pK %pK", ctx, cmd);
423 rc = -EINVAL;
424 goto end;
425 }
426
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700427 if (!ctx->hw_mgr_intf) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700428 CAM_ERR(CAM_CTXT, "HW interface is not ready");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700429 rc = -EFAULT;
430 goto end;
431 }
432
433 if ((cmd->session_handle != ctx->session_hdl) ||
434 (cmd->dev_handle != ctx->dev_hdl)) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700435 CAM_ERR(CAM_CTXT, "Invalid session hdl[%d], dev_handle[%d]",
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700436 cmd->session_handle, cmd->dev_handle);
437 rc = -EPERM;
438 goto end;
439 }
440
441 if (ctx->hw_mgr_intf->hw_start) {
Pavan Kumar Chilamkurthica2295d2017-07-30 01:50:59 -0700442 arg.ctxt_to_hw_map = ctx->ctxt_to_hw_map;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700443 rc = ctx->hw_mgr_intf->hw_start(ctx->hw_mgr_intf->hw_mgr_priv,
444 &arg);
445 if (rc) {
446 /* HW failure. user need to clean up the resource */
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700447 CAM_ERR(CAM_CTXT, "Start HW failed");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700448 goto end;
449 }
450 }
451
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700452end:
453 return rc;
454}
455
456int32_t cam_context_stop_dev_to_hw(struct cam_context *ctx)
457{
458 int rc = 0;
459 uint32_t i;
460 struct cam_hw_stop_args stop;
461 struct cam_ctx_request *req;
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -0700462 struct list_head temp_list;
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700463
Pavan Kumar Chilamkurthica2295d2017-07-30 01:50:59 -0700464 if (!ctx) {
465 CAM_ERR(CAM_CTXT, "Invalid input param");
466 rc = -EINVAL;
467 goto end;
468 }
469
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700470 if (!ctx->hw_mgr_intf) {
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700471 CAM_ERR(CAM_CTXT, "HW interface is not ready");
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700472 rc = -EFAULT;
473 goto end;
474 }
475
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -0700476 rc = cam_context_validate_thread();
477 if (rc)
478 goto end;
479
480 /*
481 * flush pending requests, take the sync lock to synchronize with the
482 * sync callback thread so that the sync cb thread does not try to
483 * submit request to h/w while the request is being flushed
484 */
485 mutex_lock(&ctx->sync_mutex);
486 INIT_LIST_HEAD(&temp_list);
487 spin_lock(&ctx->lock);
488 list_splice_init(&ctx->pending_req_list, &temp_list);
489 spin_unlock(&ctx->lock);
490 while (!list_empty(&temp_list)) {
491 req = list_first_entry(&temp_list,
492 struct cam_ctx_request, list);
493 list_del_init(&req->list);
494 req->flushed = 1;
495 for (i = 0; i < req->num_out_map_entries; i++)
496 if (req->out_map_entries[i].sync_id != -1)
497 cam_sync_signal(req->out_map_entries[i].sync_id,
498 CAM_SYNC_STATE_SIGNALED_ERROR);
499 }
500 mutex_unlock(&ctx->sync_mutex);
501
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700502 /* stop hw first */
503 if (ctx->ctxt_to_hw_map) {
504 stop.ctxt_to_hw_map = ctx->ctxt_to_hw_map;
505 if (ctx->hw_mgr_intf->hw_stop)
506 ctx->hw_mgr_intf->hw_stop(ctx->hw_mgr_intf->hw_mgr_priv,
507 &stop);
508 }
509
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -0700510 /*
511 * flush active queue, at this point h/w layer below does not have any
512 * reference to requests in active queue.
513 */
514 INIT_LIST_HEAD(&temp_list);
515 spin_lock(&ctx->lock);
516 list_splice_init(&ctx->active_req_list, &temp_list);
517 spin_unlock(&ctx->lock);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700518
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -0700519 while (!list_empty(&temp_list)) {
520 req = list_first_entry(&temp_list,
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700521 struct cam_ctx_request, list);
522 list_del_init(&req->list);
Lakshmi Narayana Kalavalaadc6ce32017-07-17 17:19:11 -0700523 CAM_DBG(CAM_CTXT, "signal fence in active list. fence num %d",
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700524 req->num_out_map_entries);
525 for (i = 0; i < req->num_out_map_entries; i++)
526 if (req->out_map_entries[i].sync_id != -1)
527 cam_sync_signal(req->out_map_entries[i].sync_id,
528 CAM_SYNC_STATE_SIGNALED_ERROR);
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -0700529 /*
530 * The spin lock should be taken here to guard the free list,
531 * as sync cb thread could be adding a pending req to free list
532 */
533 spin_lock(&ctx->lock);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700534 list_add_tail(&req->list, &ctx->free_req_list);
Shubhraprakash Das45ca2fe2017-10-07 14:29:30 -0700535 req->ctx = NULL;
536 spin_unlock(&ctx->lock);
Lakshmi Narayana Kalavala85c40352017-05-15 16:19:13 -0700537 }
538
539end:
540 return rc;
541}
542