blob: 369fe5fde3774f3a6c942980f361e0cfded8a88e [file] [log] [blame]
Jing Zhoud352ed12017-03-20 23:59:56 -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
13#include <linux/debugfs.h>
14#include <linux/videodev2.h>
15#include <linux/slab.h>
16#include <linux/uaccess.h>
Jing Zhoub524a852017-05-16 15:47:30 +053017#include <linux/ratelimit.h>
Jing Zhoud352ed12017-03-20 23:59:56 -070018
19#include "cam_isp_context.h"
20#include "cam_isp_log.h"
21#include "cam_mem_mgr.h"
22#include "cam_sync_api.h"
Jing Zhoub524a852017-05-16 15:47:30 +053023#include "cam_req_mgr_dev.h"
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -060024#include "cam_trace.h"
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -070025#include "cam_debug_util.h"
Jing Zhoud352ed12017-03-20 23:59:56 -070026
Harsh Shahe9a8a9c2017-11-01 04:07:38 -070027static const char isp_dev_name[] = "isp";
28
Jing Zhou77962c52017-09-18 19:13:34 -070029static int __cam_isp_ctx_enqueue_request_in_order(
30 struct cam_context *ctx, struct cam_ctx_request *req)
31{
32 struct cam_ctx_request *req_current;
33 struct cam_ctx_request *req_prev;
34 struct list_head temp_list;
35
36 INIT_LIST_HEAD(&temp_list);
37 spin_lock_bh(&ctx->lock);
38 if (list_empty(&ctx->pending_req_list)) {
39 list_add_tail(&req->list, &ctx->pending_req_list);
40 } else {
41 list_for_each_entry_safe_reverse(
42 req_current, req_prev, &ctx->pending_req_list, list) {
43 if (req->request_id < req_current->request_id) {
44 list_del_init(&req_current->list);
45 list_add(&req_current->list, &temp_list);
46 continue;
47 } else if (req->request_id == req_current->request_id) {
48 CAM_WARN(CAM_ISP,
49 "Received duplicated request %lld",
50 req->request_id);
51 }
52 break;
53 }
54 list_add_tail(&req->list, &ctx->pending_req_list);
55
56 if (!list_empty(&temp_list)) {
57 list_for_each_entry_safe(
58 req_current, req_prev, &temp_list, list) {
59 list_del_init(&req_current->list);
60 list_add_tail(&req_current->list,
61 &ctx->pending_req_list);
62 }
63 }
64 }
65 spin_unlock_bh(&ctx->lock);
66 return 0;
67}
68
Ravikishore Pampana24f712e2017-11-13 23:09:30 +053069static int __cam_isp_ctx_enqueue_init_request(
70 struct cam_context *ctx, struct cam_ctx_request *req)
71{
72 int rc = 0;
73 struct cam_ctx_request *req_old;
74 struct cam_isp_ctx_req *req_isp_old;
75 struct cam_isp_ctx_req *req_isp_new;
76
77 spin_lock_bh(&ctx->lock);
78 if (list_empty(&ctx->pending_req_list)) {
79 list_add_tail(&req->list, &ctx->pending_req_list);
80 CAM_DBG(CAM_ISP, "INIT packet added req id= %d",
81 req->request_id);
82 goto end;
83 }
84
85 req_old = list_first_entry(&ctx->pending_req_list,
86 struct cam_ctx_request, list);
87 req_isp_old = (struct cam_isp_ctx_req *) req_old->req_priv;
88 req_isp_new = (struct cam_isp_ctx_req *) req->req_priv;
89 if (req_isp_old->packet_opcode_type == CAM_ISP_PACKET_INIT_DEV) {
90 if ((req_isp_old->num_cfg + req_isp_new->num_cfg) >=
91 CAM_ISP_CTX_CFG_MAX) {
92 CAM_WARN(CAM_ISP, "Can not merge INIT pkt");
93 rc = -ENOMEM;
94 }
95
96 if (req_isp_old->num_fence_map_out != 0 ||
97 req_isp_old->num_fence_map_in != 0) {
98 CAM_WARN(CAM_ISP, "Invalid INIT pkt sequence");
99 rc = -EINVAL;
100 }
101
102 if (!rc) {
103 memcpy(req_isp_old->fence_map_out,
104 req_isp_new->fence_map_out,
105 sizeof(req_isp_new->fence_map_out[0])*
106 req_isp_new->num_fence_map_out);
107 req_isp_old->num_fence_map_out =
108 req_isp_new->num_fence_map_out;
109
110 memcpy(req_isp_old->fence_map_in,
111 req_isp_new->fence_map_in,
112 sizeof(req_isp_new->fence_map_in[0])*
113 req_isp_new->num_fence_map_in);
114 req_isp_old->num_fence_map_in =
115 req_isp_new->num_fence_map_in;
116
117 memcpy(&req_isp_old->cfg[req_isp_old->num_cfg],
118 req_isp_new->cfg,
119 sizeof(req_isp_new->cfg[0])*
120 req_isp_new->num_cfg);
121 req_isp_old->num_cfg += req_isp_new->num_cfg;
122
123 list_add_tail(&req->list, &ctx->free_req_list);
124 }
125 } else {
126 CAM_WARN(CAM_ISP,
127 "Received Update pkt before INIT pkt. req_id= %lld",
128 req->request_id);
129 rc = -EINVAL;
130 }
131end:
132 spin_unlock_bh(&ctx->lock);
133 return rc;
134}
135
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700136static const char *__cam_isp_resource_handle_id_to_type
137 (uint32_t resource_handle)
138{
139 switch (resource_handle) {
140 case CAM_ISP_IFE_OUT_RES_FULL:
141 return "CAM_ISP_IFE_OUT_RES_FULL";
142 case CAM_ISP_IFE_OUT_RES_DS4:
143 return "CAM_ISP_IFE_OUT_RES_DS4";
144 case CAM_ISP_IFE_OUT_RES_DS16:
145 return "CAM_ISP_IFE_OUT_RES_DS16";
146 case CAM_ISP_IFE_OUT_RES_RAW_DUMP:
147 return "CAM_ISP_IFE_OUT_RES_RAW_DUMP";
148 case CAM_ISP_IFE_OUT_RES_FD:
149 return "CAM_ISP_IFE_OUT_RES_FD";
150 case CAM_ISP_IFE_OUT_RES_PDAF:
151 return "CAM_ISP_IFE_OUT_RES_PDAF";
152 case CAM_ISP_IFE_OUT_RES_RDI_0:
153 return "CAM_ISP_IFE_OUT_RES_RDI_0";
154 case CAM_ISP_IFE_OUT_RES_RDI_1:
155 return "CAM_ISP_IFE_OUT_RES_RDI_1";
156 case CAM_ISP_IFE_OUT_RES_RDI_2:
157 return "CAM_ISP_IFE_OUT_RES_RDI_2";
158 case CAM_ISP_IFE_OUT_RES_RDI_3:
159 return "CAM_ISP_IFE_OUT_RES_RDI_3";
160 case CAM_ISP_IFE_OUT_RES_STATS_HDR_BE:
161 return "CAM_ISP_IFE_OUT_RES_STATS_HDR_BE";
162 case CAM_ISP_IFE_OUT_RES_STATS_HDR_BHIST:
163 return "CAM_ISP_IFE_OUT_RES_STATS_HDR_BHIST";
164 case CAM_ISP_IFE_OUT_RES_STATS_TL_BG:
165 return "CAM_ISP_IFE_OUT_RES_STATS_TL_BG";
166 case CAM_ISP_IFE_OUT_RES_STATS_BF:
167 return "CAM_ISP_IFE_OUT_RES_STATS_BF";
168 case CAM_ISP_IFE_OUT_RES_STATS_AWB_BG:
169 return "CAM_ISP_IFE_OUT_RES_STATS_AWB_BG";
170 case CAM_ISP_IFE_OUT_RES_STATS_BHIST:
171 return "CAM_ISP_IFE_OUT_RES_STATS_BHIST";
172 case CAM_ISP_IFE_OUT_RES_STATS_RS:
173 return "CAM_ISP_IFE_OUT_RES_STATS_RS";
174 case CAM_ISP_IFE_OUT_RES_STATS_CS:
175 return "CAM_ISP_IFE_OUT_RES_STATS_CS";
176 default:
177 return "CAM_ISP_Invalid_Resource_Type";
178 }
179}
180
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -0600181static uint64_t __cam_isp_ctx_get_event_ts(uint32_t evt_id, void *evt_data)
182{
183 uint64_t ts = 0;
184
185 if (!evt_data)
186 return 0;
187
188 switch (evt_id) {
189 case CAM_ISP_HW_EVENT_ERROR:
190 ts = ((struct cam_isp_hw_error_event_data *)evt_data)->
191 timestamp;
192 break;
193 case CAM_ISP_HW_EVENT_SOF:
194 ts = ((struct cam_isp_hw_sof_event_data *)evt_data)->
195 timestamp;
196 break;
197 case CAM_ISP_HW_EVENT_REG_UPDATE:
198 ts = ((struct cam_isp_hw_reg_update_event_data *)evt_data)->
199 timestamp;
200 break;
201 case CAM_ISP_HW_EVENT_EPOCH:
202 ts = ((struct cam_isp_hw_epoch_event_data *)evt_data)->
203 timestamp;
204 break;
205 case CAM_ISP_HW_EVENT_EOF:
206 ts = ((struct cam_isp_hw_eof_event_data *)evt_data)->
207 timestamp;
208 break;
209 case CAM_ISP_HW_EVENT_DONE:
210 break;
211 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700212 CAM_DBG(CAM_ISP, "Invalid Event Type %d", evt_id);
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -0600213 }
214
215 return ts;
216}
217
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700218static void __cam_isp_ctx_handle_buf_done_fail_log(
219 struct cam_isp_ctx_req *req_isp)
220{
221 int i;
222
Harsh Shah1b8eb232017-10-09 19:20:52 -0700223 if (req_isp->num_fence_map_out >= CAM_ISP_CTX_RES_MAX) {
224 CAM_ERR_RATE_LIMIT(CAM_ISP,
225 "Num Resources exceed mMAX %d >= %d ",
226 req_isp->num_fence_map_out, CAM_ISP_CTX_RES_MAX);
227 return;
228 }
229
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700230 CAM_ERR_RATE_LIMIT(CAM_ISP,
231 "Resource Handles that fail to generate buf_done in prev frame");
232 for (i = 0; i < req_isp->num_fence_map_out; i++) {
233 if (req_isp->fence_map_out[i].sync_id != -1)
234 CAM_ERR_RATE_LIMIT(CAM_ISP,
235 "Resource_Handle: [%s] Sync_ID: [0x%x]",
236 __cam_isp_resource_handle_id_to_type(
237 req_isp->fence_map_out[i].resource_handle),
238 req_isp->fence_map_out[i].sync_id);
239 }
240}
241
Jing Zhoud352ed12017-03-20 23:59:56 -0700242static int __cam_isp_ctx_handle_buf_done_in_activated_state(
243 struct cam_isp_context *ctx_isp,
244 struct cam_isp_hw_done_event_data *done,
245 uint32_t bubble_state)
246{
247 int rc = 0;
248 int i, j;
249 struct cam_ctx_request *req;
250 struct cam_isp_ctx_req *req_isp;
251 struct cam_context *ctx = ctx_isp->base;
252
253 if (list_empty(&ctx->active_req_list)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700254 CAM_DBG(CAM_ISP, "Buf done with no active request!");
Jing Zhoud352ed12017-03-20 23:59:56 -0700255 goto end;
256 }
257
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700258 CAM_DBG(CAM_ISP, "Enter with bubble_state %d", bubble_state);
Jing Zhoud352ed12017-03-20 23:59:56 -0700259
260 req = list_first_entry(&ctx->active_req_list,
261 struct cam_ctx_request, list);
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -0600262
263 trace_cam_buf_done("ISP", ctx, req);
264
Jing Zhoud352ed12017-03-20 23:59:56 -0700265 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
266 for (i = 0; i < done->num_handles; i++) {
267 for (j = 0; j < req_isp->num_fence_map_out; j++) {
268 if (done->resource_handle[i] ==
269 req_isp->fence_map_out[j].resource_handle)
270 break;
271 }
272
273 if (j == req_isp->num_fence_map_out) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700274 CAM_ERR(CAM_ISP,
275 "Can not find matching lane handle 0x%x!",
Jing Zhoud352ed12017-03-20 23:59:56 -0700276 done->resource_handle[i]);
277 rc = -EINVAL;
278 continue;
279 }
280
Harsh Shah1b8eb232017-10-09 19:20:52 -0700281 if (req_isp->fence_map_out[j].sync_id == -1) {
282 __cam_isp_ctx_handle_buf_done_fail_log(req_isp);
283 continue;
284 }
Jing Zhoubb536a82017-05-18 15:20:38 -0700285
Jeyaprakash Soundrapandian32e5ae52017-11-17 23:44:44 -0800286 if (!bubble_state) {
vhajeri05545252017-11-10 18:43:08 -0800287 CAM_DBG(CAM_ISP,
288 "Sync with success: req %lld res 0x%x fd 0x%x",
289 req->request_id,
290 req_isp->fence_map_out[j].resource_handle,
291 req_isp->fence_map_out[j].sync_id);
292
293 rc = cam_sync_signal(req_isp->fence_map_out[j].sync_id,
294 CAM_SYNC_STATE_SIGNALED_SUCCESS);
295 if (rc)
296 CAM_DBG(CAM_ISP, "Sync failed with rc = %d",
Jeyaprakash Soundrapandian32e5ae52017-11-17 23:44:44 -0800297 rc);
298 } else if (!req_isp->bubble_report) {
299 CAM_DBG(CAM_ISP,
300 "Sync with failure: req %lld res 0x%x fd 0x%x",
301 req->request_id,
302 req_isp->fence_map_out[j].resource_handle,
303 req_isp->fence_map_out[j].sync_id);
304
305 rc = cam_sync_signal(req_isp->fence_map_out[j].sync_id,
306 CAM_SYNC_STATE_SIGNALED_ERROR);
307 if (rc)
308 CAM_ERR(CAM_ISP, "Sync failed with rc = %d",
vhajeri05545252017-11-10 18:43:08 -0800309 rc);
Jing Zhoud352ed12017-03-20 23:59:56 -0700310 } else {
311 /*
312 * Ignore the buffer done if bubble detect is on
313 * In most case, active list should be empty when
314 * bubble detects. But for safety, we just move the
315 * current active request to the pending list here.
316 */
Harsh Shah1b8eb232017-10-09 19:20:52 -0700317 CAM_DBG(CAM_ISP,
318 "buf done with bubble state %d recovery %d",
319 bubble_state, req_isp->bubble_report);
Jing Zhoud352ed12017-03-20 23:59:56 -0700320 list_del_init(&req->list);
321 list_add(&req->list, &ctx->pending_req_list);
322 continue;
323 }
324
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700325 CAM_DBG(CAM_ISP, "req %lld, reset sync id 0x%x",
Harsh Shah1b8eb232017-10-09 19:20:52 -0700326 req->request_id,
327 req_isp->fence_map_out[j].sync_id);
328 if (!rc) {
329 req_isp->num_acked++;
330 req_isp->fence_map_out[j].sync_id = -1;
331 }
Jing Zhoud352ed12017-03-20 23:59:56 -0700332 }
333
Harsh Shah1b8eb232017-10-09 19:20:52 -0700334 if (req_isp->num_acked > req_isp->num_fence_map_out) {
335 /* Should not happen */
336 CAM_ERR(CAM_ISP,
337 "WARNING: req_id %lld num_acked %d > map_out %d",
338 req->request_id, req_isp->num_acked,
339 req_isp->num_fence_map_out);
340 WARN_ON(req_isp->num_acked > req_isp->num_fence_map_out);
341 }
Jing Zhoud352ed12017-03-20 23:59:56 -0700342 if (req_isp->num_acked == req_isp->num_fence_map_out) {
343 list_del_init(&req->list);
344 list_add_tail(&req->list, &ctx->free_req_list);
Jing Zhoudedc4762017-06-19 17:45:36 +0530345 ctx_isp->active_req_cnt--;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700346 CAM_DBG(CAM_ISP,
347 "Move active request %lld to free list(cnt = %d)",
348 req->request_id, ctx_isp->active_req_cnt);
Jing Zhoud352ed12017-03-20 23:59:56 -0700349 }
350
351end:
352 return rc;
353}
354
Jing Zhoudedc4762017-06-19 17:45:36 +0530355static void __cam_isp_ctx_send_sof_timestamp(
356 struct cam_isp_context *ctx_isp, uint64_t request_id,
357 uint32_t sof_event_status)
358{
359 struct cam_req_mgr_message req_msg;
360
361 req_msg.session_hdl = ctx_isp->base->session_hdl;
362 req_msg.u.frame_msg.frame_id = ctx_isp->frame_id;
363 req_msg.u.frame_msg.request_id = request_id;
364 req_msg.u.frame_msg.timestamp = ctx_isp->sof_timestamp_val;
365 req_msg.u.frame_msg.link_hdl = ctx_isp->base->link_hdl;
366 req_msg.u.frame_msg.sof_status = sof_event_status;
367
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700368 CAM_DBG(CAM_ISP,
369 "request id:%lld frame number:%lld SOF time stamp:0x%llx",
370 request_id, ctx_isp->frame_id,
Jing Zhoudedc4762017-06-19 17:45:36 +0530371 ctx_isp->sof_timestamp_val);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700372 CAM_DBG(CAM_ISP, " sof status:%d", sof_event_status);
Jing Zhoudedc4762017-06-19 17:45:36 +0530373
Harsh Shah67fa2312017-10-30 04:03:07 -0700374 if (cam_req_mgr_notify_message(&req_msg,
Jing Zhoudedc4762017-06-19 17:45:36 +0530375 V4L_EVENT_CAM_REQ_MGR_SOF, V4L_EVENT_CAM_REQ_MGR_EVENT))
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700376 CAM_ERR(CAM_ISP,
377 "Error in notifying the sof time for req id:%lld",
378 request_id);
Jing Zhoudedc4762017-06-19 17:45:36 +0530379}
380
Jing Zhoud352ed12017-03-20 23:59:56 -0700381static int __cam_isp_ctx_reg_upd_in_activated_state(
382 struct cam_isp_context *ctx_isp, void *evt_data)
383{
384 int rc = 0;
385 struct cam_ctx_request *req;
386 struct cam_context *ctx = ctx_isp->base;
387 struct cam_isp_ctx_req *req_isp;
388
389 if (list_empty(&ctx->pending_req_list)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700390 CAM_ERR(CAM_ISP, "Reg upd ack with no pending request");
Jing Zhoud352ed12017-03-20 23:59:56 -0700391 goto end;
392 }
393 req = list_first_entry(&ctx->pending_req_list,
394 struct cam_ctx_request, list);
395 list_del_init(&req->list);
396
397 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
398 if (req_isp->num_fence_map_out != 0) {
Jing Zhoud352ed12017-03-20 23:59:56 -0700399 list_add_tail(&req->list, &ctx->active_req_list);
Jing Zhoudedc4762017-06-19 17:45:36 +0530400 ctx_isp->active_req_cnt++;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700401 CAM_DBG(CAM_ISP, "move request %lld to active list(cnt = %d)",
402 req->request_id, ctx_isp->active_req_cnt);
Jing Zhoud352ed12017-03-20 23:59:56 -0700403 } else {
404 /* no io config, so the request is completed. */
405 list_add_tail(&req->list, &ctx->free_req_list);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700406 CAM_DBG(CAM_ISP,
407 "move active request %lld to free list(cnt = %d)",
408 req->request_id, ctx_isp->active_req_cnt);
Jing Zhoud352ed12017-03-20 23:59:56 -0700409 }
410
411 /*
412 * This function only called directly from applied and bubble applied
413 * state so change substate here.
414 */
415 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_EPOCH;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700416 CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated);
Jing Zhoud352ed12017-03-20 23:59:56 -0700417
418end:
419 return rc;
420}
421
422static int __cam_isp_ctx_notify_sof_in_actived_state(
423 struct cam_isp_context *ctx_isp, void *evt_data)
424{
Junzhe Zou2df84502017-05-26 13:20:23 -0700425 int rc = 0;
426 struct cam_req_mgr_trigger_notify notify;
Jing Zhoud352ed12017-03-20 23:59:56 -0700427 struct cam_context *ctx = ctx_isp->base;
Jing Zhoudedc4762017-06-19 17:45:36 +0530428 struct cam_ctx_request *req;
429 uint64_t request_id = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -0700430
Jing Zhoudedc4762017-06-19 17:45:36 +0530431 /*
432 * notify reqmgr with sof signal. Note, due to scheduling delay
433 * we can run into situation that two active requests has already
434 * be in the active queue while we try to do the notification.
435 * In this case, we need to skip the current notification. This
436 * helps the state machine to catch up the delay.
437 */
Junzhe Zou2df84502017-05-26 13:20:23 -0700438 if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger &&
Jing Zhoudedc4762017-06-19 17:45:36 +0530439 ctx_isp->active_req_cnt <= 2) {
Junzhe Zou2df84502017-05-26 13:20:23 -0700440 if (ctx_isp->subscribe_event & CAM_TRIGGER_POINT_SOF) {
441 notify.link_hdl = ctx->link_hdl;
442 notify.dev_hdl = ctx->dev_hdl;
443 notify.frame_id = ctx_isp->frame_id;
444 notify.trigger = CAM_TRIGGER_POINT_SOF;
Jing Zhoud352ed12017-03-20 23:59:56 -0700445
Junzhe Zou2df84502017-05-26 13:20:23 -0700446 ctx->ctx_crm_intf->notify_trigger(&notify);
447 CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld",
448 ctx_isp->frame_id);
449 }
Jing Zhoudedc4762017-06-19 17:45:36 +0530450
451 list_for_each_entry(req, &ctx->active_req_list, list) {
452 if (req->request_id > ctx_isp->reported_req_id) {
453 request_id = req->request_id;
454 ctx_isp->reported_req_id = request_id;
455 break;
456 }
457 }
458
459 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
460 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
Jing Zhoud352ed12017-03-20 23:59:56 -0700461 } else {
Harsh Shahcb0072c2017-09-26 19:22:10 -0700462 CAM_ERR_RATE_LIMIT(CAM_ISP, "Can not notify SOF to CRM");
Junzhe Zou2df84502017-05-26 13:20:23 -0700463 rc = -EFAULT;
Jing Zhoud352ed12017-03-20 23:59:56 -0700464 }
465
Jing Zhoudedc4762017-06-19 17:45:36 +0530466 return 0;
Jing Zhoud352ed12017-03-20 23:59:56 -0700467}
468
Junzhe Zou2df84502017-05-26 13:20:23 -0700469static int __cam_isp_ctx_notify_eof_in_actived_state(
470 struct cam_isp_context *ctx_isp, void *evt_data)
471{
472 int rc = 0;
473 struct cam_req_mgr_trigger_notify notify;
474 struct cam_context *ctx = ctx_isp->base;
475
476 if (!(ctx_isp->subscribe_event & CAM_TRIGGER_POINT_EOF))
477 return rc;
478
479 /* notify reqmgr with eof signal */
480 if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger) {
481 notify.link_hdl = ctx->link_hdl;
482 notify.dev_hdl = ctx->dev_hdl;
483 notify.frame_id = ctx_isp->frame_id;
484 notify.trigger = CAM_TRIGGER_POINT_EOF;
485
486 ctx->ctx_crm_intf->notify_trigger(&notify);
487 CAM_DBG(CAM_ISP, "Notify CRM EOF frame %lld\n",
488 ctx_isp->frame_id);
489 } else {
490 CAM_ERR(CAM_ISP, "Can not notify EOF to CRM");
491 rc = -EFAULT;
492 }
493
494 return rc;
495}
Jing Zhoud352ed12017-03-20 23:59:56 -0700496
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +0530497static int __cam_isp_ctx_reg_upd_in_hw_error(
498 struct cam_isp_context *ctx_isp, void *evt_data)
499{
500 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
501 return 0;
502}
503
Jing Zhoudedc4762017-06-19 17:45:36 +0530504static int __cam_isp_ctx_sof_in_activated_state(
505 struct cam_isp_context *ctx_isp, void *evt_data)
Jing Zhoud352ed12017-03-20 23:59:56 -0700506{
507 int rc = 0;
Jing Zhoudedc4762017-06-19 17:45:36 +0530508 struct cam_isp_hw_sof_event_data *sof_event_data = evt_data;
Jing Zhoud352ed12017-03-20 23:59:56 -0700509
Jing Zhoudedc4762017-06-19 17:45:36 +0530510 if (!evt_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700511 CAM_ERR(CAM_ISP, "in valid sof event data");
Jing Zhoudedc4762017-06-19 17:45:36 +0530512 return -EINVAL;
513 }
514
Jing Zhoud352ed12017-03-20 23:59:56 -0700515 ctx_isp->frame_id++;
Jing Zhoudedc4762017-06-19 17:45:36 +0530516 ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700517 CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx",
Jing Zhoudedc4762017-06-19 17:45:36 +0530518 ctx_isp->frame_id, ctx_isp->sof_timestamp_val);
Jing Zhoud352ed12017-03-20 23:59:56 -0700519
520 return rc;
521}
522
523static int __cam_isp_ctx_reg_upd_in_sof(struct cam_isp_context *ctx_isp,
524 void *evt_data)
525{
526 int rc = 0;
527 struct cam_ctx_request *req;
528 struct cam_isp_ctx_req *req_isp;
529 struct cam_context *ctx = ctx_isp->base;
530
531 if (ctx->state != CAM_CTX_ACTIVATED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700532 CAM_DBG(CAM_ISP, "invalid RUP");
Jing Zhoud352ed12017-03-20 23:59:56 -0700533 goto end;
534 }
535
536 /*
537 * This is for the first update. The initial setting will
538 * cause the reg_upd in the first frame.
539 */
540 if (!list_empty(&ctx->pending_req_list)) {
541 req = list_first_entry(&ctx->pending_req_list,
542 struct cam_ctx_request, list);
543 list_del_init(&req->list);
544 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
Jing Zhoudedc4762017-06-19 17:45:36 +0530545 if (req_isp->num_fence_map_out == req_isp->num_acked) {
Jing Zhoud352ed12017-03-20 23:59:56 -0700546 list_add_tail(&req->list, &ctx->free_req_list);
Jing Zhoudedc4762017-06-19 17:45:36 +0530547 } else {
Jing Zhoud352ed12017-03-20 23:59:56 -0700548 /* need to handle the buf done */
549 list_add_tail(&req->list, &ctx->active_req_list);
Jing Zhoudedc4762017-06-19 17:45:36 +0530550 ctx_isp->active_req_cnt++;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700551 CAM_DBG(CAM_ISP,
552 "move request %lld to active list(cnt = %d)",
553 req->request_id,
Jing Zhoudedc4762017-06-19 17:45:36 +0530554 ctx_isp->active_req_cnt);
Jing Zhoud352ed12017-03-20 23:59:56 -0700555 ctx_isp->substate_activated =
556 CAM_ISP_CTX_ACTIVATED_EPOCH;
557 }
558 }
559end:
560 return rc;
561}
562
563static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
564 void *evt_data)
565{
Jing Zhoud352ed12017-03-20 23:59:56 -0700566 struct cam_ctx_request *req;
567 struct cam_isp_ctx_req *req_isp;
568 struct cam_context *ctx = ctx_isp->base;
Jing Zhoudedc4762017-06-19 17:45:36 +0530569 uint64_t request_id = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -0700570
571 if (list_empty(&ctx->pending_req_list)) {
572 /*
573 * If no pending req in epoch, this is an error case.
574 * The recovery is to go back to sof state
575 */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700576 CAM_ERR(CAM_ISP, "No pending request");
Jing Zhoud352ed12017-03-20 23:59:56 -0700577 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
Jing Zhoudedc4762017-06-19 17:45:36 +0530578
579 /* Send SOF event as empty frame*/
580 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
581 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
582
Jing Zhoud352ed12017-03-20 23:59:56 -0700583 goto end;
584 }
585
586 req = list_first_entry(&ctx->pending_req_list, struct cam_ctx_request,
587 list);
588 req_isp = (struct cam_isp_ctx_req *)req->req_priv;
589
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700590 CAM_DBG(CAM_ISP, "Report Bubble flag %d", req_isp->bubble_report);
Jing Zhoud352ed12017-03-20 23:59:56 -0700591 if (req_isp->bubble_report && ctx->ctx_crm_intf &&
592 ctx->ctx_crm_intf->notify_err) {
593 struct cam_req_mgr_error_notify notify;
594
595 notify.link_hdl = ctx->link_hdl;
596 notify.dev_hdl = ctx->dev_hdl;
597 notify.req_id = req->request_id;
598 notify.error = CRM_KMD_ERR_BUBBLE;
599 ctx->ctx_crm_intf->notify_err(&notify);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700600 CAM_DBG(CAM_ISP, "Notify CRM about Bubble frame %lld",
Jing Zhoud352ed12017-03-20 23:59:56 -0700601 ctx_isp->frame_id);
Jing Zhou45b55cc2017-05-16 17:27:18 -0700602 } else {
603 /*
604 * Since can not bubble report, always move the request to
605 * active list.
606 */
607 list_del_init(&req->list);
608 list_add_tail(&req->list, &ctx->active_req_list);
Jing Zhoudedc4762017-06-19 17:45:36 +0530609 ctx_isp->active_req_cnt++;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700610 CAM_DBG(CAM_ISP, "move request %lld to active list(cnt = %d)",
611 req->request_id, ctx_isp->active_req_cnt);
Jing Zhou45b55cc2017-05-16 17:27:18 -0700612 req_isp->bubble_report = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -0700613 }
614
Jing Zhoudedc4762017-06-19 17:45:36 +0530615 request_id = req->request_id;
616 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
617 CAM_REQ_MGR_SOF_EVENT_ERROR);
618
Jing Zhoud352ed12017-03-20 23:59:56 -0700619 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700620 CAM_DBG(CAM_ISP, "next substate %d",
Jing Zhoud352ed12017-03-20 23:59:56 -0700621 ctx_isp->substate_activated);
622end:
Jing Zhoudedc4762017-06-19 17:45:36 +0530623 return 0;
Jing Zhoud352ed12017-03-20 23:59:56 -0700624}
625
626
627static int __cam_isp_ctx_buf_done_in_applied(struct cam_isp_context *ctx_isp,
628 void *evt_data)
629{
630 int rc = 0;
631 struct cam_isp_hw_done_event_data *done =
632 (struct cam_isp_hw_done_event_data *) evt_data;
633
634 rc = __cam_isp_ctx_handle_buf_done_in_activated_state(ctx_isp, done, 0);
635 return rc;
636}
637
638
639static int __cam_isp_ctx_sof_in_epoch(struct cam_isp_context *ctx_isp,
640 void *evt_data)
641{
642 int rc = 0;
Jing Zhoudedc4762017-06-19 17:45:36 +0530643 struct cam_context *ctx = ctx_isp->base;
644 struct cam_isp_hw_sof_event_data *sof_event_data = evt_data;
Jing Zhou93b3ec12017-06-15 17:43:39 -0700645
Jing Zhoudedc4762017-06-19 17:45:36 +0530646 if (!evt_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700647 CAM_ERR(CAM_ISP, "in valid sof event data");
Jing Zhoudedc4762017-06-19 17:45:36 +0530648 return -EINVAL;
649 }
Jing Zhoud352ed12017-03-20 23:59:56 -0700650
651 ctx_isp->frame_id++;
Jing Zhoudedc4762017-06-19 17:45:36 +0530652 ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
653
Jing Zhou93b3ec12017-06-15 17:43:39 -0700654 if (list_empty(&ctx->active_req_list))
655 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
656 else
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700657 CAM_DBG(CAM_ISP, "Still need to wait for the buf done");
Jing Zhoudedc4762017-06-19 17:45:36 +0530658
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700659 CAM_DBG(CAM_ISP, "next substate %d",
Jing Zhoud352ed12017-03-20 23:59:56 -0700660 ctx_isp->substate_activated);
661
662 return rc;
663}
664
665static int __cam_isp_ctx_buf_done_in_epoch(struct cam_isp_context *ctx_isp,
666 void *evt_data)
667{
668 int rc = 0;
669 struct cam_isp_hw_done_event_data *done =
670 (struct cam_isp_hw_done_event_data *) evt_data;
671
672 rc = __cam_isp_ctx_handle_buf_done_in_activated_state(ctx_isp, done, 0);
673 return rc;
674}
675
Jing Zhoud352ed12017-03-20 23:59:56 -0700676static int __cam_isp_ctx_buf_done_in_bubble(
677 struct cam_isp_context *ctx_isp, void *evt_data)
678{
679 int rc = 0;
680 struct cam_isp_hw_done_event_data *done =
681 (struct cam_isp_hw_done_event_data *) evt_data;
682
683 rc = __cam_isp_ctx_handle_buf_done_in_activated_state(ctx_isp, done, 1);
684 return rc;
685}
686
Jing Zhoud352ed12017-03-20 23:59:56 -0700687static int __cam_isp_ctx_epoch_in_bubble_applied(
688 struct cam_isp_context *ctx_isp, void *evt_data)
689{
690 struct cam_ctx_request *req;
691 struct cam_isp_ctx_req *req_isp;
692 struct cam_context *ctx = ctx_isp->base;
Jing Zhoudedc4762017-06-19 17:45:36 +0530693 uint64_t request_id = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -0700694
695 /*
696 * This means we missed the reg upd ack. So we need to
697 * transition to BUBBLE state again.
698 */
699
700 if (list_empty(&ctx->pending_req_list)) {
701 /*
702 * If no pending req in epoch, this is an error case.
703 * Just go back to the bubble state.
704 */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700705 CAM_ERR(CAM_ISP, "No pending request.");
Jing Zhoudedc4762017-06-19 17:45:36 +0530706 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
707 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
708
Jing Zhoud352ed12017-03-20 23:59:56 -0700709 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE;
710 goto end;
711 }
712
713 req = list_first_entry(&ctx->pending_req_list, struct cam_ctx_request,
714 list);
715 req_isp = (struct cam_isp_ctx_req *)req->req_priv;
716
717 if (req_isp->bubble_report && ctx->ctx_crm_intf &&
718 ctx->ctx_crm_intf->notify_err) {
719 struct cam_req_mgr_error_notify notify;
720
721 notify.link_hdl = ctx->link_hdl;
722 notify.dev_hdl = ctx->dev_hdl;
723 notify.req_id = req->request_id;
724 notify.error = CRM_KMD_ERR_BUBBLE;
725 ctx->ctx_crm_intf->notify_err(&notify);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700726 CAM_DBG(CAM_ISP, "Notify CRM about Bubble frame %lld",
Jing Zhoud352ed12017-03-20 23:59:56 -0700727 ctx_isp->frame_id);
Jing Zhou45b55cc2017-05-16 17:27:18 -0700728 } else {
729 /*
730 * If we can not report bubble, then treat it as if no bubble
731 * report. Just move the req to active list.
732 */
733 list_del_init(&req->list);
734 list_add_tail(&req->list, &ctx->active_req_list);
Jing Zhoudedc4762017-06-19 17:45:36 +0530735 ctx_isp->active_req_cnt++;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700736 CAM_DBG(CAM_ISP, "move request %lld to active list(cnt = %d)",
737 req->request_id, ctx_isp->active_req_cnt);
Jing Zhou45b55cc2017-05-16 17:27:18 -0700738 req_isp->bubble_report = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -0700739 }
740
Jing Zhoudedc4762017-06-19 17:45:36 +0530741 request_id = req->request_id;
742 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
743 CAM_REQ_MGR_SOF_EVENT_ERROR);
744
Jing Zhoud352ed12017-03-20 23:59:56 -0700745 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700746 CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated);
Jing Zhoud352ed12017-03-20 23:59:56 -0700747end:
748 return 0;
749}
750
751static int __cam_isp_ctx_buf_done_in_bubble_applied(
752 struct cam_isp_context *ctx_isp, void *evt_data)
753{
754 int rc = 0;
755 struct cam_isp_hw_done_event_data *done =
756 (struct cam_isp_hw_done_event_data *) evt_data;
757
758 rc = __cam_isp_ctx_handle_buf_done_in_activated_state(ctx_isp, done, 1);
759 return rc;
760}
761
762static int __cam_isp_ctx_handle_error(struct cam_isp_context *ctx_isp,
763 void *evt_data)
764{
765 int rc = 0;
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +0530766 uint32_t i = 0;
767 bool found = 0;
768 struct cam_ctx_request *req = NULL;
769 struct cam_ctx_request *req_temp;
770 struct cam_isp_ctx_req *req_isp = NULL;
Jing Zhoud352ed12017-03-20 23:59:56 -0700771 struct cam_req_mgr_error_notify notify;
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +0530772 uint64_t error_request_id;
Jing Zhoud352ed12017-03-20 23:59:56 -0700773
774 struct cam_context *ctx = ctx_isp->base;
775 struct cam_isp_hw_error_event_data *error_event_data =
776 (struct cam_isp_hw_error_event_data *)evt_data;
777
778 uint32_t error_type = error_event_data->error_type;
779
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700780 CAM_DBG(CAM_ISP, "Enter error_type = %d", error_type);
Jing Zhoud352ed12017-03-20 23:59:56 -0700781 if ((error_type == CAM_ISP_HW_ERROR_OVERFLOW) ||
782 (error_type == CAM_ISP_HW_ERROR_BUSIF_OVERFLOW))
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +0530783 notify.error = CRM_KMD_ERR_OVERFLOW;
Jing Zhoud352ed12017-03-20 23:59:56 -0700784
785 /*
786 * Need to check the active req
787 * move all of them to the pending request list
788 * Note this funciton need revisit!
789 */
790
791 if (list_empty(&ctx->active_req_list)) {
Harsh Shahcb0072c2017-09-26 19:22:10 -0700792 CAM_ERR_RATE_LIMIT(CAM_ISP,
793 "handling error with no active request");
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +0530794 } else {
795 list_for_each_entry_safe(req, req_temp,
796 &ctx->active_req_list, list) {
797 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
798 if (!req_isp->bubble_report) {
799 for (i = 0; i < req_isp->num_fence_map_out;
800 i++) {
801 CAM_ERR(CAM_ISP, "req %llu, Sync fd %x",
802 req->request_id,
803 req_isp->fence_map_out[i].
804 sync_id);
805 if (req_isp->fence_map_out[i].sync_id
806 != -1) {
807 rc = cam_sync_signal(
808 req_isp->fence_map_out[i].
809 sync_id,
810 CAM_SYNC_STATE_SIGNALED_ERROR);
811 req_isp->fence_map_out[i].
812 sync_id = -1;
813 }
814 }
815 list_del_init(&req->list);
816 list_add_tail(&req->list, &ctx->free_req_list);
817 ctx_isp->active_req_cnt--;
818 } else {
819 found = 1;
820 break;
821 }
822 }
Jing Zhoud352ed12017-03-20 23:59:56 -0700823 }
824
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +0530825 if (found) {
826 list_for_each_entry_safe_reverse(req, req_temp,
827 &ctx->active_req_list, list) {
828 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
829 list_del_init(&req->list);
830 list_add(&req->list, &ctx->pending_req_list);
831 ctx_isp->active_req_cnt--;
832 }
833 }
834
835 do {
836 if (list_empty(&ctx->pending_req_list)) {
837 error_request_id = ctx_isp->last_applied_req_id + 1;
838 req_isp = NULL;
839 break;
840 }
841 req = list_first_entry(&ctx->pending_req_list,
842 struct cam_ctx_request, list);
843 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
844 error_request_id = ctx_isp->last_applied_req_id;
845
846 if (req_isp->bubble_report)
847 break;
848
849 for (i = 0; i < req_isp->num_fence_map_out; i++) {
850 if (req_isp->fence_map_out[i].sync_id != -1)
851 rc = cam_sync_signal(
852 req_isp->fence_map_out[i].sync_id,
853 CAM_SYNC_STATE_SIGNALED_ERROR);
854 req_isp->fence_map_out[i].sync_id = -1;
855 }
856 list_del_init(&req->list);
857 list_add_tail(&req->list, &ctx->free_req_list);
858
859 } while (req->request_id < ctx_isp->last_applied_req_id);
860
Jing Zhoud352ed12017-03-20 23:59:56 -0700861
862 if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_err) {
863 notify.link_hdl = ctx->link_hdl;
864 notify.dev_hdl = ctx->dev_hdl;
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +0530865 notify.req_id = error_request_id;
866
867 if (req_isp && req_isp->bubble_report)
868 notify.error = CRM_KMD_ERR_BUBBLE;
869
870 CAM_WARN(CAM_ISP, "Notify CRM: req %lld, frame %lld\n",
871 error_request_id, ctx_isp->frame_id);
Jing Zhoud352ed12017-03-20 23:59:56 -0700872
873 ctx->ctx_crm_intf->notify_err(&notify);
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +0530874 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_HW_ERROR;
Jing Zhoud352ed12017-03-20 23:59:56 -0700875 } else {
Harsh Shahcb0072c2017-09-26 19:22:10 -0700876 CAM_ERR_RATE_LIMIT(CAM_ISP, "Can not notify ERRROR to CRM");
Jing Zhoud352ed12017-03-20 23:59:56 -0700877 rc = -EFAULT;
878 }
879
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700880 CAM_DBG(CAM_ISP, "Exit");
Jing Zhoud352ed12017-03-20 23:59:56 -0700881 return rc;
882}
883
884static struct cam_isp_ctx_irq_ops
885 cam_isp_ctx_activated_state_machine_irq[CAM_ISP_CTX_ACTIVATED_MAX] = {
886 /* SOF */
887 {
888 .irq_ops = {
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +0530889 __cam_isp_ctx_handle_error,
Jing Zhoudedc4762017-06-19 17:45:36 +0530890 __cam_isp_ctx_sof_in_activated_state,
Jing Zhoud352ed12017-03-20 23:59:56 -0700891 __cam_isp_ctx_reg_upd_in_sof,
892 __cam_isp_ctx_notify_sof_in_actived_state,
Junzhe Zou2df84502017-05-26 13:20:23 -0700893 __cam_isp_ctx_notify_eof_in_actived_state,
Jing Zhoud352ed12017-03-20 23:59:56 -0700894 NULL,
895 },
896 },
897 /* APPLIED */
898 {
899 .irq_ops = {
900 __cam_isp_ctx_handle_error,
Jing Zhoudedc4762017-06-19 17:45:36 +0530901 __cam_isp_ctx_sof_in_activated_state,
Jing Zhoud352ed12017-03-20 23:59:56 -0700902 __cam_isp_ctx_reg_upd_in_activated_state,
903 __cam_isp_ctx_epoch_in_applied,
Junzhe Zou2df84502017-05-26 13:20:23 -0700904 __cam_isp_ctx_notify_eof_in_actived_state,
Jing Zhoud352ed12017-03-20 23:59:56 -0700905 __cam_isp_ctx_buf_done_in_applied,
906 },
907 },
908 /* EPOCH */
909 {
910 .irq_ops = {
911 __cam_isp_ctx_handle_error,
912 __cam_isp_ctx_sof_in_epoch,
913 NULL,
914 __cam_isp_ctx_notify_sof_in_actived_state,
Junzhe Zou2df84502017-05-26 13:20:23 -0700915 __cam_isp_ctx_notify_eof_in_actived_state,
Jing Zhoud352ed12017-03-20 23:59:56 -0700916 __cam_isp_ctx_buf_done_in_epoch,
917 },
918 },
919 /* BUBBLE */
920 {
921 .irq_ops = {
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +0530922 __cam_isp_ctx_handle_error,
Jing Zhoudedc4762017-06-19 17:45:36 +0530923 __cam_isp_ctx_sof_in_activated_state,
Jing Zhoud352ed12017-03-20 23:59:56 -0700924 NULL,
925 __cam_isp_ctx_notify_sof_in_actived_state,
Junzhe Zou2df84502017-05-26 13:20:23 -0700926 __cam_isp_ctx_notify_eof_in_actived_state,
Jing Zhoud352ed12017-03-20 23:59:56 -0700927 __cam_isp_ctx_buf_done_in_bubble,
928 },
929 },
930 /* Bubble Applied */
931 {
932 .irq_ops = {
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +0530933 __cam_isp_ctx_handle_error,
Jing Zhoudedc4762017-06-19 17:45:36 +0530934 __cam_isp_ctx_sof_in_activated_state,
Jing Zhoud352ed12017-03-20 23:59:56 -0700935 __cam_isp_ctx_reg_upd_in_activated_state,
936 __cam_isp_ctx_epoch_in_bubble_applied,
937 NULL,
938 __cam_isp_ctx_buf_done_in_bubble_applied,
939 },
940 },
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +0530941 /* HW ERROR */
942 {
943 .irq_ops = {
944 NULL,
945 __cam_isp_ctx_sof_in_activated_state,
946 __cam_isp_ctx_reg_upd_in_hw_error,
947 NULL,
948 NULL,
949 NULL,
950 },
951 },
Jing Zhoud352ed12017-03-20 23:59:56 -0700952 /* HALT */
953 {
954 },
955};
956
957static int __cam_isp_ctx_apply_req_in_activated_state(
958 struct cam_context *ctx, struct cam_req_mgr_apply_request *apply,
959 uint32_t next_state)
960{
961 int rc = 0;
962 struct cam_ctx_request *req;
Harsh Shah1b8eb232017-10-09 19:20:52 -0700963 struct cam_ctx_request *active_req;
Jing Zhoud352ed12017-03-20 23:59:56 -0700964 struct cam_isp_ctx_req *req_isp;
Harsh Shah1b8eb232017-10-09 19:20:52 -0700965 struct cam_isp_ctx_req *active_req_isp;
Jing Zhoud352ed12017-03-20 23:59:56 -0700966 struct cam_isp_context *ctx_isp;
967 struct cam_hw_config_args cfg;
968
969 if (list_empty(&ctx->pending_req_list)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700970 CAM_ERR(CAM_ISP, "No available request for Apply id %lld",
971 apply->request_id);
Jing Zhoud352ed12017-03-20 23:59:56 -0700972 rc = -EFAULT;
973 goto end;
974 }
Jing Zhou9eabf472017-05-16 11:59:41 -0700975
976 /*
977 * When the pipeline has issue, the requests can be queued up in the
978 * pipeline. In this case, we should reject the additional request.
979 * The maximum number of request allowed to be outstanding is 2.
980 *
981 */
Jing Zhoudedc4762017-06-19 17:45:36 +0530982 ctx_isp = (struct cam_isp_context *) ctx->ctx_priv;
Jing Zhoud352ed12017-03-20 23:59:56 -0700983 req = list_first_entry(&ctx->pending_req_list, struct cam_ctx_request,
984 list);
985
986 /*
987 * Check whehter the request id is matching the tip, if not, this means
988 * we are in the middle of the error handling. Need to reject this apply
989 */
990 if (req->request_id != apply->request_id) {
Harsh Shahf7136392017-08-29 12:42:52 -0700991 CAM_ERR_RATE_LIMIT(CAM_ISP,
992 "Invalid Request Id asking %llu existing %llu",
993 apply->request_id, req->request_id);
Jing Zhoud352ed12017-03-20 23:59:56 -0700994 rc = -EFAULT;
995 goto end;
996 }
997
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700998 CAM_DBG(CAM_ISP, "Apply request %lld", req->request_id);
Jing Zhoud352ed12017-03-20 23:59:56 -0700999 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
Jing Zhoud352ed12017-03-20 23:59:56 -07001000
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -07001001 if (ctx_isp->active_req_cnt >= 2) {
1002 CAM_ERR_RATE_LIMIT(CAM_ISP,
Harsh Shah1b8eb232017-10-09 19:20:52 -07001003 "Reject apply request (id %lld) due to congestion(cnt = %d)",
1004 req->request_id,
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -07001005 ctx_isp->active_req_cnt);
Harsh Shah1b8eb232017-10-09 19:20:52 -07001006 if (!list_empty(&ctx->active_req_list)) {
1007 active_req = list_first_entry(&ctx->active_req_list,
1008 struct cam_ctx_request, list);
1009 active_req_isp =
1010 (struct cam_isp_ctx_req *) active_req->req_priv;
1011 __cam_isp_ctx_handle_buf_done_fail_log(active_req_isp);
1012 } else {
1013 CAM_ERR_RATE_LIMIT(CAM_ISP,
1014 "WARNING: should not happen (cnt = %d) but active_list empty",
1015 ctx_isp->active_req_cnt);
1016 }
1017 rc = -EFAULT;
1018 goto end;
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -07001019 }
Jing Zhoud352ed12017-03-20 23:59:56 -07001020 req_isp->bubble_report = apply->report_if_bubble;
1021
1022 cfg.ctxt_to_hw_map = ctx_isp->hw_ctx;
1023 cfg.hw_update_entries = req_isp->cfg;
1024 cfg.num_hw_update_entries = req_isp->num_cfg;
1025
1026 rc = ctx->hw_mgr_intf->hw_config(ctx->hw_mgr_intf->hw_mgr_priv, &cfg);
1027 if (rc) {
Harsh Shahcb0072c2017-09-26 19:22:10 -07001028 CAM_ERR_RATE_LIMIT(CAM_ISP, "Can not apply the configuration");
Jing Zhoud352ed12017-03-20 23:59:56 -07001029 } else {
Jing Zhou93b3ec12017-06-15 17:43:39 -07001030 spin_lock_bh(&ctx->lock);
Jing Zhoud352ed12017-03-20 23:59:56 -07001031 ctx_isp->substate_activated = next_state;
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +05301032 ctx_isp->last_applied_req_id = apply->request_id;
1033 CAM_DBG(CAM_ISP, "new substate state %d, applied req %lld",
1034 next_state, ctx_isp->last_applied_req_id);
Jing Zhou93b3ec12017-06-15 17:43:39 -07001035 spin_unlock_bh(&ctx->lock);
Jing Zhoud352ed12017-03-20 23:59:56 -07001036 }
1037end:
1038 return rc;
1039}
1040
1041static int __cam_isp_ctx_apply_req_in_sof(
1042 struct cam_context *ctx, struct cam_req_mgr_apply_request *apply)
1043{
1044 int rc = 0;
1045 struct cam_isp_context *ctx_isp =
1046 (struct cam_isp_context *) ctx->ctx_priv;
1047
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001048 CAM_DBG(CAM_ISP, "current substate %d",
Jing Zhoud352ed12017-03-20 23:59:56 -07001049 ctx_isp->substate_activated);
1050 rc = __cam_isp_ctx_apply_req_in_activated_state(ctx, apply,
1051 CAM_ISP_CTX_ACTIVATED_APPLIED);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001052 CAM_DBG(CAM_ISP, "new substate %d", ctx_isp->substate_activated);
Jing Zhoud352ed12017-03-20 23:59:56 -07001053
1054 return rc;
1055}
1056
1057static int __cam_isp_ctx_apply_req_in_epoch(
1058 struct cam_context *ctx, struct cam_req_mgr_apply_request *apply)
1059{
1060 int rc = 0;
1061 struct cam_isp_context *ctx_isp =
1062 (struct cam_isp_context *) ctx->ctx_priv;
1063
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001064 CAM_DBG(CAM_ISP, "current substate %d",
Jing Zhoud352ed12017-03-20 23:59:56 -07001065 ctx_isp->substate_activated);
1066 rc = __cam_isp_ctx_apply_req_in_activated_state(ctx, apply,
1067 CAM_ISP_CTX_ACTIVATED_APPLIED);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001068 CAM_DBG(CAM_ISP, "new substate %d", ctx_isp->substate_activated);
Jing Zhoud352ed12017-03-20 23:59:56 -07001069
1070 return rc;
1071}
1072
1073static int __cam_isp_ctx_apply_req_in_bubble(
1074 struct cam_context *ctx, struct cam_req_mgr_apply_request *apply)
1075{
1076 int rc = 0;
1077 struct cam_isp_context *ctx_isp =
1078 (struct cam_isp_context *) ctx->ctx_priv;
1079
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001080 CAM_DBG(CAM_ISP, "current substate %d",
Jing Zhoud352ed12017-03-20 23:59:56 -07001081 ctx_isp->substate_activated);
1082 rc = __cam_isp_ctx_apply_req_in_activated_state(ctx, apply,
1083 CAM_ISP_CTX_ACTIVATED_BUBBLE_APPLIED);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001084 CAM_DBG(CAM_ISP, "new substate %d", ctx_isp->substate_activated);
Jing Zhoud352ed12017-03-20 23:59:56 -07001085
1086 return rc;
1087}
1088
Jing Zhoub524a852017-05-16 15:47:30 +05301089static int __cam_isp_ctx_flush_req(struct cam_context *ctx,
1090 struct list_head *req_list, struct cam_req_mgr_flush_request *flush_req)
1091{
1092 int i, rc;
1093 uint32_t cancel_req_id_found = 0;
1094 struct cam_ctx_request *req;
1095 struct cam_ctx_request *req_temp;
1096 struct cam_isp_ctx_req *req_isp;
1097
1098 spin_lock(&ctx->lock);
1099 if (list_empty(req_list)) {
1100 spin_unlock(&ctx->lock);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001101 CAM_DBG(CAM_ISP, "request list is empty");
Jing Zhoub524a852017-05-16 15:47:30 +05301102 return 0;
1103 }
1104
1105 list_for_each_entry_safe(req, req_temp, req_list, list) {
1106 if ((flush_req->type == CAM_REQ_MGR_FLUSH_TYPE_CANCEL_REQ)
1107 && (req->request_id != flush_req->req_id))
1108 continue;
1109
1110 list_del_init(&req->list);
1111 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
1112 for (i = 0; i < req_isp->num_fence_map_out; i++) {
1113 if (req_isp->fence_map_out[i].sync_id != -1) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001114 CAM_DBG(CAM_ISP, "Flush req 0x%llx, fence %d",
1115 req->request_id,
Jing Zhoub524a852017-05-16 15:47:30 +05301116 req_isp->fence_map_out[i].sync_id);
1117 rc = cam_sync_signal(
1118 req_isp->fence_map_out[i].sync_id,
1119 CAM_SYNC_STATE_SIGNALED_ERROR);
1120 if (rc)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001121 CAM_ERR_RATE_LIMIT(CAM_ISP,
1122 "signal fence failed\n");
Jing Zhoub524a852017-05-16 15:47:30 +05301123 req_isp->fence_map_out[i].sync_id = -1;
1124 }
1125 }
1126 list_add_tail(&req->list, &ctx->free_req_list);
1127
1128 /* If flush request id found, exit the loop */
1129 if (flush_req->type == CAM_REQ_MGR_FLUSH_TYPE_CANCEL_REQ) {
1130 cancel_req_id_found = 1;
1131 break;
1132 }
1133 }
1134 spin_unlock(&ctx->lock);
1135
1136 if (flush_req->type == CAM_REQ_MGR_FLUSH_TYPE_CANCEL_REQ &&
1137 !cancel_req_id_found)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001138 CAM_DBG(CAM_ISP,
1139 "Flush request id:%lld is not found in the list",
1140 flush_req->req_id);
Jing Zhoub524a852017-05-16 15:47:30 +05301141
1142 return 0;
1143}
1144
1145static int __cam_isp_ctx_flush_req_in_top_state(
1146 struct cam_context *ctx,
1147 struct cam_req_mgr_flush_request *flush_req)
1148{
1149 int rc = 0;
1150
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001151 CAM_DBG(CAM_ISP, "try to flush pending list");
Jing Zhoub524a852017-05-16 15:47:30 +05301152 rc = __cam_isp_ctx_flush_req(ctx, &ctx->pending_req_list, flush_req);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001153 CAM_DBG(CAM_ISP, "Flush request in top state %d",
1154 ctx->state);
Jing Zhoub524a852017-05-16 15:47:30 +05301155 return rc;
1156}
1157
1158static int __cam_isp_ctx_flush_req_in_ready(
1159 struct cam_context *ctx,
1160 struct cam_req_mgr_flush_request *flush_req)
1161{
1162 int rc = 0;
1163
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001164 CAM_DBG(CAM_ISP, "try to flush pending list");
Jing Zhoub524a852017-05-16 15:47:30 +05301165 rc = __cam_isp_ctx_flush_req(ctx, &ctx->pending_req_list, flush_req);
1166
1167 /* if nothing is in pending req list, change state to acquire*/
1168 spin_lock(&ctx->lock);
1169 if (list_empty(&ctx->pending_req_list))
1170 ctx->state = CAM_CTX_ACQUIRED;
1171 spin_unlock(&ctx->lock);
1172
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06001173 trace_cam_context_state("ISP", ctx);
1174
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001175 CAM_DBG(CAM_ISP, "Flush request in ready state. next state %d",
1176 ctx->state);
Jing Zhoub524a852017-05-16 15:47:30 +05301177 return rc;
1178}
1179
Jing Zhoud352ed12017-03-20 23:59:56 -07001180static struct cam_ctx_ops
1181 cam_isp_ctx_activated_state_machine[CAM_ISP_CTX_ACTIVATED_MAX] = {
1182 /* SOF */
1183 {
1184 .ioctl_ops = {},
1185 .crm_ops = {
1186 .apply_req = __cam_isp_ctx_apply_req_in_sof,
1187 },
1188 .irq_ops = NULL,
1189 },
1190 /* APPLIED */
1191 {
1192 .ioctl_ops = {},
1193 .crm_ops = {},
1194 .irq_ops = NULL,
1195 },
1196 /* EPOCH */
1197 {
1198 .ioctl_ops = {},
1199 .crm_ops = {
1200 .apply_req = __cam_isp_ctx_apply_req_in_epoch,
1201 },
1202 .irq_ops = NULL,
1203 },
1204 /* BUBBLE */
1205 {
1206 .ioctl_ops = {},
1207 .crm_ops = {
1208 .apply_req = __cam_isp_ctx_apply_req_in_bubble,
1209 },
1210 .irq_ops = NULL,
1211 },
1212 /* Bubble Applied */
1213 {
1214 .ioctl_ops = {},
1215 .crm_ops = {},
1216 .irq_ops = NULL,
1217 },
1218 /* HALT */
1219 {
1220 .ioctl_ops = {},
1221 .crm_ops = {},
1222 .irq_ops = NULL,
1223 },
1224};
1225
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301226static int __cam_isp_ctx_rdi_only_sof_in_top_state(
1227 struct cam_isp_context *ctx_isp, void *evt_data)
1228{
1229 int rc = 0;
1230 struct cam_context *ctx = ctx_isp->base;
Junzhe Zou2df84502017-05-26 13:20:23 -07001231 struct cam_req_mgr_trigger_notify notify;
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301232 struct cam_isp_hw_sof_event_data *sof_event_data = evt_data;
1233 uint64_t request_id = 0;
1234
1235 if (!evt_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001236 CAM_ERR(CAM_ISP, "in valid sof event data");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301237 return -EINVAL;
1238 }
1239
1240 ctx_isp->frame_id++;
1241 ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001242 CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301243 ctx_isp->frame_id, ctx_isp->sof_timestamp_val);
1244
1245 /*
1246 * notify reqmgr with sof signal. Note, due to scheduling delay
1247 * we can run into situation that two active requests has already
1248 * be in the active queue while we try to do the notification.
1249 * In this case, we need to skip the current notification. This
1250 * helps the state machine to catch up the delay.
1251 */
Junzhe Zou2df84502017-05-26 13:20:23 -07001252 if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger &&
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301253 ctx_isp->active_req_cnt <= 2) {
1254 notify.link_hdl = ctx->link_hdl;
1255 notify.dev_hdl = ctx->dev_hdl;
1256 notify.frame_id = ctx_isp->frame_id;
Junzhe Zou2df84502017-05-26 13:20:23 -07001257 notify.trigger = CAM_TRIGGER_POINT_SOF;
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301258
Junzhe Zou2df84502017-05-26 13:20:23 -07001259 ctx->ctx_crm_intf->notify_trigger(&notify);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001260 CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301261 ctx_isp->frame_id);
1262
1263 /*
1264 * It is idle frame with out any applied request id, send
1265 * request id as zero
1266 */
1267 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
1268 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
1269 } else {
Harsh Shahcb0072c2017-09-26 19:22:10 -07001270 CAM_ERR_RATE_LIMIT(CAM_ISP, "Can not notify SOF to CRM");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301271 }
1272
1273 if (list_empty(&ctx->active_req_list))
1274 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
1275 else
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001276 CAM_DBG(CAM_ISP, "Still need to wait for the buf done");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301277
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001278 CAM_DBG(CAM_ISP, "next substate %d",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301279 ctx_isp->substate_activated);
1280 return rc;
1281}
1282
1283static int __cam_isp_ctx_rdi_only_sof_in_applied_state(
1284 struct cam_isp_context *ctx_isp, void *evt_data)
1285{
1286 struct cam_isp_hw_sof_event_data *sof_event_data = evt_data;
1287
1288 if (!evt_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001289 CAM_ERR(CAM_ISP, "in valid sof event data");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301290 return -EINVAL;
1291 }
1292
1293 ctx_isp->frame_id++;
1294 ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001295 CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301296 ctx_isp->frame_id, ctx_isp->sof_timestamp_val);
1297
1298 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE_APPLIED;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001299 CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301300
1301 return 0;
1302}
1303
1304static int __cam_isp_ctx_rdi_only_sof_in_bubble_applied(
1305 struct cam_isp_context *ctx_isp, void *evt_data)
1306{
1307 struct cam_ctx_request *req;
1308 struct cam_isp_ctx_req *req_isp;
1309 struct cam_context *ctx = ctx_isp->base;
1310 struct cam_isp_hw_sof_event_data *sof_event_data = evt_data;
1311 uint64_t request_id = 0;
1312
1313 ctx_isp->frame_id++;
1314 ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001315 CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301316 ctx_isp->frame_id, ctx_isp->sof_timestamp_val);
1317
1318 if (list_empty(&ctx->pending_req_list)) {
1319 /*
1320 * If no pending req in epoch, this is an error case.
1321 * The recovery is to go back to sof state
1322 */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001323 CAM_ERR(CAM_ISP, "No pending request");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301324 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
1325
1326 /* Send SOF event as empty frame*/
1327 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
1328 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
1329
1330 goto end;
1331 }
1332
1333 req = list_first_entry(&ctx->pending_req_list, struct cam_ctx_request,
1334 list);
1335 req_isp = (struct cam_isp_ctx_req *)req->req_priv;
1336
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001337 CAM_DBG(CAM_ISP, "Report Bubble flag %d", req_isp->bubble_report);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301338 if (req_isp->bubble_report && ctx->ctx_crm_intf &&
1339 ctx->ctx_crm_intf->notify_err) {
1340 struct cam_req_mgr_error_notify notify;
1341
1342 notify.link_hdl = ctx->link_hdl;
1343 notify.dev_hdl = ctx->dev_hdl;
1344 notify.req_id = req->request_id;
1345 notify.error = CRM_KMD_ERR_BUBBLE;
1346 ctx->ctx_crm_intf->notify_err(&notify);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001347 CAM_DBG(CAM_ISP, "Notify CRM about Bubble frame %lld",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301348 ctx_isp->frame_id);
1349 } else {
1350 /*
1351 * Since can not bubble report, always move the request to
1352 * active list.
1353 */
1354 list_del_init(&req->list);
1355 list_add_tail(&req->list, &ctx->active_req_list);
1356 ctx_isp->active_req_cnt++;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001357 CAM_DBG(CAM_ISP, "move request %lld to active list(cnt = %d)",
1358 req->request_id, ctx_isp->active_req_cnt);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301359 req_isp->bubble_report = 0;
1360 }
1361
1362 request_id = req->request_id;
1363 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
1364 CAM_REQ_MGR_SOF_EVENT_ERROR);
1365
1366 /* change the state to bubble, as reg update has not come */
1367 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001368 CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301369end:
1370 return 0;
1371}
1372
1373static int __cam_isp_ctx_rdi_only_sof_in_bubble_state(
1374 struct cam_isp_context *ctx_isp, void *evt_data)
1375{
1376 uint32_t i;
1377 struct cam_ctx_request *req;
1378 struct cam_context *ctx = ctx_isp->base;
Junzhe Zou2df84502017-05-26 13:20:23 -07001379 struct cam_req_mgr_trigger_notify notify;
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301380 struct cam_isp_hw_sof_event_data *sof_event_data = evt_data;
1381 struct cam_isp_ctx_req *req_isp;
1382 uint64_t request_id = 0;
1383
1384 if (!evt_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001385 CAM_ERR(CAM_ISP, "in valid sof event data");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301386 return -EINVAL;
1387 }
1388
1389 ctx_isp->frame_id++;
1390 ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001391 CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301392 ctx_isp->frame_id, ctx_isp->sof_timestamp_val);
1393 /*
1394 * Signal all active requests with error and move the all the active
1395 * requests to free list
1396 */
1397 while (!list_empty(&ctx->active_req_list)) {
1398 req = list_first_entry(&ctx->active_req_list,
1399 struct cam_ctx_request, list);
1400 list_del_init(&req->list);
1401 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001402 CAM_DBG(CAM_ISP, "signal fence in active list. fence num %d",
1403 req_isp->num_fence_map_out);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301404 for (i = 0; i < req_isp->num_fence_map_out; i++)
1405 if (req_isp->fence_map_out[i].sync_id != -1) {
1406 cam_sync_signal(
1407 req_isp->fence_map_out[i].sync_id,
1408 CAM_SYNC_STATE_SIGNALED_ERROR);
1409 }
1410 list_add_tail(&req->list, &ctx->free_req_list);
Harsh Shah1b8eb232017-10-09 19:20:52 -07001411 ctx_isp->active_req_cnt--;
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301412 }
1413
1414 /* notify reqmgr with sof signal */
Junzhe Zou2df84502017-05-26 13:20:23 -07001415 if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger) {
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301416 notify.link_hdl = ctx->link_hdl;
1417 notify.dev_hdl = ctx->dev_hdl;
1418 notify.frame_id = ctx_isp->frame_id;
Junzhe Zou2df84502017-05-26 13:20:23 -07001419 notify.trigger = CAM_TRIGGER_POINT_SOF;
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301420
Junzhe Zou2df84502017-05-26 13:20:23 -07001421 ctx->ctx_crm_intf->notify_trigger(&notify);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001422 CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301423 ctx_isp->frame_id);
1424
1425 } else {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001426 CAM_ERR(CAM_ISP, "Can not notify SOF to CRM");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301427 }
1428
1429 /*
1430 * It is idle frame with out any applied request id, send
1431 * request id as zero
1432 */
1433 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
1434 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
1435
1436 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
1437
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001438 CAM_DBG(CAM_ISP, "next substate %d",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301439 ctx_isp->substate_activated);
1440
1441 return 0;
1442}
1443
1444static int __cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state(
1445 struct cam_isp_context *ctx_isp, void *evt_data)
1446{
1447 struct cam_ctx_request *req;
1448 struct cam_context *ctx = ctx_isp->base;
1449 struct cam_isp_ctx_req *req_isp;
Junzhe Zou2df84502017-05-26 13:20:23 -07001450 struct cam_req_mgr_trigger_notify notify;
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301451 uint64_t request_id = 0;
1452
1453 /* notify reqmgr with sof signal*/
Junzhe Zou2df84502017-05-26 13:20:23 -07001454 if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger) {
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301455 if (list_empty(&ctx->pending_req_list)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001456 CAM_ERR(CAM_ISP, "Reg upd ack with no pending request");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301457 goto error;
1458 }
1459 req = list_first_entry(&ctx->pending_req_list,
1460 struct cam_ctx_request, list);
1461 list_del_init(&req->list);
1462
1463 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
1464 request_id = req->request_id;
1465 if (req_isp->num_fence_map_out != 0) {
1466 list_add_tail(&req->list, &ctx->active_req_list);
1467 ctx_isp->active_req_cnt++;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001468 CAM_DBG(CAM_ISP,
1469 "move request %lld to active list(cnt = %d)",
1470 req->request_id, ctx_isp->active_req_cnt);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301471 } else {
1472 /* no io config, so the request is completed. */
1473 list_add_tail(&req->list, &ctx->free_req_list);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001474 CAM_DBG(CAM_ISP,
1475 "move active req %lld to free list(cnt=%d)",
1476 req->request_id, ctx_isp->active_req_cnt);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301477 }
1478
1479 notify.link_hdl = ctx->link_hdl;
1480 notify.dev_hdl = ctx->dev_hdl;
1481 notify.frame_id = ctx_isp->frame_id;
Junzhe Zou2df84502017-05-26 13:20:23 -07001482 notify.trigger = CAM_TRIGGER_POINT_SOF;
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301483
Junzhe Zou2df84502017-05-26 13:20:23 -07001484 ctx->ctx_crm_intf->notify_trigger(&notify);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001485 CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301486 ctx_isp->frame_id);
1487 } else {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001488 CAM_ERR(CAM_ISP, "Can not notify SOF to CRM");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301489 }
1490 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
1491 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
1492
1493 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_EPOCH;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001494 CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301495
1496 return 0;
1497error:
1498 /* Send SOF event as idle frame*/
1499 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
1500 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
1501
1502 /*
1503 * There is no request in the pending list, move the sub state machine
1504 * to SOF sub state
1505 */
1506 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
1507
1508 return 0;
1509}
1510
1511static struct cam_isp_ctx_irq_ops
1512 cam_isp_ctx_rdi_only_activated_state_machine_irq
1513 [CAM_ISP_CTX_ACTIVATED_MAX] = {
1514 /* SOF */
1515 {
1516 .irq_ops = {
1517 NULL,
1518 __cam_isp_ctx_rdi_only_sof_in_top_state,
1519 __cam_isp_ctx_reg_upd_in_sof,
1520 NULL,
1521 NULL,
1522 NULL,
1523 },
1524 },
1525 /* APPLIED */
1526 {
1527 .irq_ops = {
1528 __cam_isp_ctx_handle_error,
1529 __cam_isp_ctx_rdi_only_sof_in_applied_state,
1530 NULL,
1531 NULL,
1532 NULL,
1533 __cam_isp_ctx_buf_done_in_applied,
1534 },
1535 },
1536 /* EPOCH */
1537 {
1538 .irq_ops = {
1539 __cam_isp_ctx_handle_error,
1540 __cam_isp_ctx_rdi_only_sof_in_top_state,
1541 NULL,
1542 NULL,
1543 NULL,
1544 __cam_isp_ctx_buf_done_in_epoch,
1545 },
1546 },
1547 /* BUBBLE*/
1548 {
1549 .irq_ops = {
1550 __cam_isp_ctx_handle_error,
1551 __cam_isp_ctx_rdi_only_sof_in_bubble_state,
1552 NULL,
1553 NULL,
1554 NULL,
1555 __cam_isp_ctx_buf_done_in_bubble,
1556 },
1557 },
1558 /* BUBBLE APPLIED ie PRE_BUBBLE */
1559 {
1560 .irq_ops = {
1561 __cam_isp_ctx_handle_error,
1562 __cam_isp_ctx_rdi_only_sof_in_bubble_applied,
1563 __cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state,
1564 NULL,
1565 NULL,
1566 __cam_isp_ctx_buf_done_in_bubble_applied,
1567 },
1568 },
1569
1570 /* HALT */
1571 {
1572 },
1573};
1574
1575static int __cam_isp_ctx_rdi_only_apply_req_top_state(
1576 struct cam_context *ctx, struct cam_req_mgr_apply_request *apply)
1577{
1578 int rc = 0;
1579 struct cam_isp_context *ctx_isp =
1580 (struct cam_isp_context *) ctx->ctx_priv;
1581
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001582 CAM_DBG(CAM_ISP, "current substate %d",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301583 ctx_isp->substate_activated);
1584 rc = __cam_isp_ctx_apply_req_in_activated_state(ctx, apply,
1585 CAM_ISP_CTX_ACTIVATED_APPLIED);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001586 CAM_DBG(CAM_ISP, "new substate %d", ctx_isp->substate_activated);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301587
1588 return rc;
1589}
1590
1591static struct cam_ctx_ops
1592 cam_isp_ctx_rdi_only_activated_state_machine
1593 [CAM_ISP_CTX_ACTIVATED_MAX] = {
1594 /* SOF */
1595 {
1596 .ioctl_ops = {},
1597 .crm_ops = {
1598 .apply_req = __cam_isp_ctx_rdi_only_apply_req_top_state,
1599 },
1600 .irq_ops = NULL,
1601 },
1602 /* APPLIED */
1603 {
1604 .ioctl_ops = {},
1605 .crm_ops = {},
1606 .irq_ops = NULL,
1607 },
1608 /* EPOCH */
1609 {
1610 .ioctl_ops = {},
1611 .crm_ops = {
1612 .apply_req = __cam_isp_ctx_rdi_only_apply_req_top_state,
1613 },
1614 .irq_ops = NULL,
1615 },
1616 /* PRE BUBBLE */
1617 {
1618 .ioctl_ops = {},
1619 .crm_ops = {},
1620 .irq_ops = NULL,
1621 },
1622 /* BUBBLE */
1623 {
1624 .ioctl_ops = {},
1625 .crm_ops = {},
1626 .irq_ops = NULL,
1627 },
1628 /* HALT */
1629 {
1630 .ioctl_ops = {},
1631 .crm_ops = {},
1632 .irq_ops = NULL,
1633 },
1634};
1635
Jing Zhoud352ed12017-03-20 23:59:56 -07001636
1637/* top level state machine */
1638static int __cam_isp_ctx_release_dev_in_top_state(struct cam_context *ctx,
1639 struct cam_release_dev_cmd *cmd)
1640{
1641 int rc = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -07001642 struct cam_hw_release_args rel_arg;
Jing Zhoud352ed12017-03-20 23:59:56 -07001643 struct cam_isp_context *ctx_isp =
1644 (struct cam_isp_context *) ctx->ctx_priv;
Jing Zhoub524a852017-05-16 15:47:30 +05301645 struct cam_req_mgr_flush_request flush_req;
Jing Zhoud352ed12017-03-20 23:59:56 -07001646
1647 if (ctx_isp->hw_ctx) {
1648 rel_arg.ctxt_to_hw_map = ctx_isp->hw_ctx;
1649 ctx->hw_mgr_intf->hw_release(ctx->hw_mgr_intf->hw_mgr_priv,
1650 &rel_arg);
1651 ctx_isp->hw_ctx = NULL;
1652 }
1653
Soundrapandian Jeyaprakash8d16e272017-10-12 11:05:37 -07001654 ctx->session_hdl = -1;
1655 ctx->dev_hdl = -1;
1656 ctx->link_hdl = -1;
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001657 ctx->ctx_crm_intf = NULL;
Jing Zhoud352ed12017-03-20 23:59:56 -07001658 ctx_isp->frame_id = 0;
Jing Zhoudedc4762017-06-19 17:45:36 +05301659 ctx_isp->active_req_cnt = 0;
1660 ctx_isp->reported_req_id = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -07001661
1662 /*
1663 * Ideally, we should never have any active request here.
1664 * But we still add some sanity check code here to help the debug
1665 */
1666 if (!list_empty(&ctx->active_req_list))
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001667 CAM_ERR(CAM_ISP, "Active list is not empty");
Jing Zhoud352ed12017-03-20 23:59:56 -07001668
Jing Zhoub524a852017-05-16 15:47:30 +05301669 /* Flush all the pending request list */
1670 flush_req.type = CAM_REQ_MGR_FLUSH_TYPE_ALL;
1671 flush_req.link_hdl = ctx->link_hdl;
1672 flush_req.dev_hdl = ctx->dev_hdl;
1673
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001674 CAM_DBG(CAM_ISP, "try to flush pending list");
Jing Zhoub524a852017-05-16 15:47:30 +05301675 rc = __cam_isp_ctx_flush_req(ctx, &ctx->pending_req_list, &flush_req);
1676
Jing Zhoud352ed12017-03-20 23:59:56 -07001677 ctx->state = CAM_CTX_AVAILABLE;
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06001678
1679 trace_cam_context_state("ISP", ctx);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001680 CAM_DBG(CAM_ISP, "next state %d", ctx->state);
Jing Zhoud352ed12017-03-20 23:59:56 -07001681 return rc;
1682}
1683
1684static int __cam_isp_ctx_config_dev_in_top_state(
1685 struct cam_context *ctx, struct cam_config_dev_cmd *cmd)
1686{
1687 int rc = 0;
1688 struct cam_ctx_request *req = NULL;
1689 struct cam_isp_ctx_req *req_isp;
1690 uint64_t packet_addr;
1691 struct cam_packet *packet;
1692 size_t len = 0;
1693 struct cam_hw_prepare_update_args cfg;
1694 struct cam_req_mgr_add_request add_req;
1695 struct cam_isp_context *ctx_isp =
1696 (struct cam_isp_context *) ctx->ctx_priv;
Ravikishore Pampana24f712e2017-11-13 23:09:30 +05301697 struct cam_isp_prepare_hw_update_data hw_update_data;
Jing Zhoud352ed12017-03-20 23:59:56 -07001698
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001699 CAM_DBG(CAM_ISP, "get free request object......");
Jing Zhoud352ed12017-03-20 23:59:56 -07001700
1701 /* get free request */
Jing Zhou93b3ec12017-06-15 17:43:39 -07001702 spin_lock_bh(&ctx->lock);
Jing Zhoud352ed12017-03-20 23:59:56 -07001703 if (!list_empty(&ctx->free_req_list)) {
1704 req = list_first_entry(&ctx->free_req_list,
1705 struct cam_ctx_request, list);
1706 list_del_init(&req->list);
1707 }
Jing Zhou93b3ec12017-06-15 17:43:39 -07001708 spin_unlock_bh(&ctx->lock);
Jing Zhoud352ed12017-03-20 23:59:56 -07001709
1710 if (!req) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001711 CAM_ERR(CAM_ISP, "No more request obj free");
Jing Zhoud352ed12017-03-20 23:59:56 -07001712 rc = -ENOMEM;
1713 goto end;
1714 }
1715
1716 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
1717
1718 /* for config dev, only memory handle is supported */
1719 /* map packet from the memhandle */
1720 rc = cam_mem_get_cpu_buf((int32_t) cmd->packet_handle,
1721 (uint64_t *) &packet_addr, &len);
1722 if (rc != 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001723 CAM_ERR(CAM_ISP, "Can not get packet address");
Jing Zhoud352ed12017-03-20 23:59:56 -07001724 rc = -EINVAL;
1725 goto free_req;
1726 }
1727
1728 packet = (struct cam_packet *) (packet_addr + cmd->offset);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001729 CAM_DBG(CAM_ISP, "pack_handle %llx", cmd->packet_handle);
1730 CAM_DBG(CAM_ISP, "packet address is 0x%llx", packet_addr);
1731 CAM_DBG(CAM_ISP, "packet with length %zu, offset 0x%llx",
Jing Zhoud352ed12017-03-20 23:59:56 -07001732 len, cmd->offset);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001733 CAM_DBG(CAM_ISP, "Packet request id %lld",
Jing Zhoud352ed12017-03-20 23:59:56 -07001734 packet->header.request_id);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001735 CAM_DBG(CAM_ISP, "Packet size 0x%x", packet->header.size);
1736 CAM_DBG(CAM_ISP, "packet op %d", packet->header.op_code);
Jing Zhoud352ed12017-03-20 23:59:56 -07001737
1738 /* preprocess the configuration */
1739 memset(&cfg, 0, sizeof(cfg));
1740 cfg.packet = packet;
1741 cfg.ctxt_to_hw_map = ctx_isp->hw_ctx;
1742 cfg.max_hw_update_entries = CAM_ISP_CTX_CFG_MAX;
1743 cfg.hw_update_entries = req_isp->cfg;
1744 cfg.max_out_map_entries = CAM_ISP_CTX_RES_MAX;
1745 cfg.max_in_map_entries = CAM_ISP_CTX_RES_MAX;
1746 cfg.out_map_entries = req_isp->fence_map_out;
1747 cfg.in_map_entries = req_isp->fence_map_in;
Ravikishore Pampana24f712e2017-11-13 23:09:30 +05301748 cfg.priv = &hw_update_data;
Jing Zhoud352ed12017-03-20 23:59:56 -07001749
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001750 CAM_DBG(CAM_ISP, "try to prepare config packet......");
Jing Zhoud352ed12017-03-20 23:59:56 -07001751
1752 rc = ctx->hw_mgr_intf->hw_prepare_update(
1753 ctx->hw_mgr_intf->hw_mgr_priv, &cfg);
1754 if (rc != 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001755 CAM_ERR(CAM_ISP, "Prepare config packet failed in HW layer");
Jing Zhoud352ed12017-03-20 23:59:56 -07001756 rc = -EFAULT;
1757 goto free_req;
1758 }
1759 req_isp->num_cfg = cfg.num_hw_update_entries;
1760 req_isp->num_fence_map_out = cfg.num_out_map_entries;
1761 req_isp->num_fence_map_in = cfg.num_in_map_entries;
1762 req_isp->num_acked = 0;
Ravikishore Pampana24f712e2017-11-13 23:09:30 +05301763 req_isp->packet_opcode_type = hw_update_data.packet_opcode_type;
Jing Zhoud352ed12017-03-20 23:59:56 -07001764
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001765 CAM_DBG(CAM_ISP, "num_entry: %d, num fence out: %d, num fence in: %d",
Ravikishore Pampana24f712e2017-11-13 23:09:30 +05301766 req_isp->num_cfg, req_isp->num_fence_map_out,
Jing Zhoud352ed12017-03-20 23:59:56 -07001767 req_isp->num_fence_map_in);
1768
1769 req->request_id = packet->header.request_id;
1770 req->status = 1;
1771
Ravikishore Pampana24f712e2017-11-13 23:09:30 +05301772 CAM_DBG(CAM_ISP, "Packet request id 0x%llx packet opcode:%d",
1773 packet->header.request_id, req_isp->packet_opcode_type);
1774
1775 if (req_isp->packet_opcode_type == CAM_ISP_PACKET_INIT_DEV) {
1776 if (ctx->state < CAM_CTX_ACTIVATED) {
1777 rc = __cam_isp_ctx_enqueue_init_request(ctx, req);
1778 if (rc)
1779 CAM_ERR(CAM_ISP, "Enqueue INIT pkt failed");
1780 } else {
1781 rc = -EINVAL;
1782 CAM_ERR(CAM_ISP, "Recevied INIT pkt in wrong state");
1783 }
1784 } else {
1785 if (ctx->state >= CAM_CTX_READY && ctx->ctx_crm_intf->add_req) {
1786 add_req.link_hdl = ctx->link_hdl;
1787 add_req.dev_hdl = ctx->dev_hdl;
1788 add_req.req_id = req->request_id;
1789 add_req.skip_before_applying = 0;
1790 rc = ctx->ctx_crm_intf->add_req(&add_req);
1791 if (rc) {
1792 CAM_ERR(CAM_ISP, "Add req failed: req id=%llu",
1793 req->request_id);
1794 } else {
1795 __cam_isp_ctx_enqueue_request_in_order(
1796 ctx, req);
1797 }
1798 } else {
1799 rc = -EINVAL;
1800 CAM_ERR(CAM_ISP, "Recevied Update in wrong state");
Jing Zhoud352ed12017-03-20 23:59:56 -07001801 }
1802 }
Ravikishore Pampana24f712e2017-11-13 23:09:30 +05301803 if (rc)
1804 goto free_req;
Jing Zhoud352ed12017-03-20 23:59:56 -07001805
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001806 CAM_DBG(CAM_ISP, "Preprocessing Config %lld successful",
Jing Zhoud352ed12017-03-20 23:59:56 -07001807 req->request_id);
1808
1809 return rc;
1810
1811free_req:
Jing Zhou93b3ec12017-06-15 17:43:39 -07001812 spin_lock_bh(&ctx->lock);
Jing Zhoud352ed12017-03-20 23:59:56 -07001813 list_add_tail(&req->list, &ctx->free_req_list);
Jing Zhou93b3ec12017-06-15 17:43:39 -07001814 spin_unlock_bh(&ctx->lock);
Jing Zhoud352ed12017-03-20 23:59:56 -07001815end:
1816 return rc;
1817}
1818
1819static int __cam_isp_ctx_acquire_dev_in_available(struct cam_context *ctx,
1820 struct cam_acquire_dev_cmd *cmd)
1821{
1822 int rc = 0;
1823 struct cam_hw_acquire_args param;
1824 struct cam_isp_resource *isp_res = NULL;
1825 struct cam_create_dev_hdl req_hdl_param;
1826 struct cam_hw_release_args release;
1827 struct cam_isp_context *ctx_isp =
1828 (struct cam_isp_context *) ctx->ctx_priv;
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301829 struct cam_isp_hw_cmd_args hw_cmd_args;
Jing Zhoud352ed12017-03-20 23:59:56 -07001830
1831 if (!ctx->hw_mgr_intf) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001832 CAM_ERR(CAM_ISP, "HW interface is not ready");
Jing Zhoud352ed12017-03-20 23:59:56 -07001833 rc = -EFAULT;
1834 goto end;
1835 }
1836
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001837 CAM_DBG(CAM_ISP,
1838 "session_hdl 0x%x, num_resources %d, hdl type %d, res %lld",
1839 cmd->session_handle, cmd->num_resources,
Jing Zhoud352ed12017-03-20 23:59:56 -07001840 cmd->handle_type, cmd->resource_hdl);
1841
1842 if (cmd->num_resources > CAM_ISP_CTX_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001843 CAM_ERR(CAM_ISP, "Too much resources in the acquire");
Jing Zhoud352ed12017-03-20 23:59:56 -07001844 rc = -ENOMEM;
1845 goto end;
1846 }
1847
1848 /* for now we only support user pointer */
1849 if (cmd->handle_type != 1) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001850 CAM_ERR(CAM_ISP, "Only user pointer is supported");
Jing Zhoud352ed12017-03-20 23:59:56 -07001851 rc = -EINVAL;
1852 goto end;
1853 }
1854
1855 isp_res = kzalloc(
1856 sizeof(*isp_res)*cmd->num_resources, GFP_KERNEL);
1857 if (!isp_res) {
1858 rc = -ENOMEM;
1859 goto end;
1860 }
1861
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001862 CAM_DBG(CAM_ISP, "start copy %d resources from user",
1863 cmd->num_resources);
Jing Zhoud352ed12017-03-20 23:59:56 -07001864
1865 if (copy_from_user(isp_res, (void __user *)cmd->resource_hdl,
1866 sizeof(*isp_res)*cmd->num_resources)) {
1867 rc = -EFAULT;
1868 goto free_res;
1869 }
1870
1871 param.context_data = ctx;
1872 param.event_cb = ctx->irq_cb_intf;
1873 param.num_acq = cmd->num_resources;
1874 param.acquire_info = (uint64_t) isp_res;
1875
1876 /* call HW manager to reserve the resource */
1877 rc = ctx->hw_mgr_intf->hw_acquire(ctx->hw_mgr_intf->hw_mgr_priv,
1878 &param);
1879 if (rc != 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001880 CAM_ERR(CAM_ISP, "Acquire device failed");
Jing Zhoud352ed12017-03-20 23:59:56 -07001881 goto free_res;
1882 }
1883
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301884 /* Query the context has rdi only resource */
1885 hw_cmd_args.ctxt_to_hw_map = param.ctxt_to_hw_map;
1886 hw_cmd_args.cmd_type = CAM_ISP_HW_MGR_CMD_IS_RDI_ONLY_CONTEXT;
1887 rc = ctx->hw_mgr_intf->hw_cmd(ctx->hw_mgr_intf->hw_mgr_priv,
1888 &hw_cmd_args);
1889 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001890 CAM_ERR(CAM_ISP, "HW command failed");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301891 goto free_hw;
1892 }
1893
1894 if (hw_cmd_args.u.is_rdi_only_context) {
1895 /*
1896 * this context has rdi only resource assign rdi only
1897 * state machine
1898 */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001899 CAM_DBG(CAM_ISP, "RDI only session Context");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301900
1901 ctx_isp->substate_machine_irq =
1902 cam_isp_ctx_rdi_only_activated_state_machine_irq;
1903 ctx_isp->substate_machine =
1904 cam_isp_ctx_rdi_only_activated_state_machine;
1905 } else {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001906 CAM_DBG(CAM_ISP, "Session has PIX or PIX and RDI resources");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301907 ctx_isp->substate_machine_irq =
1908 cam_isp_ctx_activated_state_machine_irq;
1909 ctx_isp->substate_machine =
1910 cam_isp_ctx_activated_state_machine;
1911 }
1912
Jing Zhoud352ed12017-03-20 23:59:56 -07001913 ctx_isp->hw_ctx = param.ctxt_to_hw_map;
1914
1915 req_hdl_param.session_hdl = cmd->session_handle;
1916 /* bridge is not ready for these flags. so false for now */
1917 req_hdl_param.v4l2_sub_dev_flag = 0;
1918 req_hdl_param.media_entity_flag = 0;
1919 req_hdl_param.ops = ctx->crm_ctx_intf;
1920 req_hdl_param.priv = ctx;
1921
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001922 CAM_DBG(CAM_ISP, "get device handle form bridge");
Jing Zhoud352ed12017-03-20 23:59:56 -07001923 ctx->dev_hdl = cam_create_device_hdl(&req_hdl_param);
1924 if (ctx->dev_hdl <= 0) {
1925 rc = -EFAULT;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001926 CAM_ERR(CAM_ISP, "Can not create device handle");
Jing Zhoud352ed12017-03-20 23:59:56 -07001927 goto free_hw;
1928 }
1929 cmd->dev_handle = ctx->dev_hdl;
1930
1931 /* store session information */
1932 ctx->session_hdl = cmd->session_handle;
1933
1934 ctx->state = CAM_CTX_ACQUIRED;
1935
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06001936 trace_cam_context_state("ISP", ctx);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001937 CAM_DBG(CAM_ISP, "Acquire success.");
Jing Zhoud352ed12017-03-20 23:59:56 -07001938 kfree(isp_res);
1939 return rc;
1940
1941free_hw:
1942 release.ctxt_to_hw_map = ctx_isp->hw_ctx;
1943 ctx->hw_mgr_intf->hw_release(ctx->hw_mgr_intf->hw_mgr_priv, &release);
1944 ctx_isp->hw_ctx = NULL;
1945free_res:
1946 kfree(isp_res);
1947end:
1948 return rc;
1949}
1950
1951static int __cam_isp_ctx_config_dev_in_acquired(struct cam_context *ctx,
1952 struct cam_config_dev_cmd *cmd)
1953{
1954 int rc = 0;
1955
1956 rc = __cam_isp_ctx_config_dev_in_top_state(ctx, cmd);
1957
Karthik Anantha Ram34dc2652017-10-20 15:49:54 -07001958 if (!rc && (ctx->link_hdl >= 0)) {
Jing Zhoud352ed12017-03-20 23:59:56 -07001959 ctx->state = CAM_CTX_READY;
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06001960 trace_cam_context_state("ISP", ctx);
1961 }
Jing Zhoud352ed12017-03-20 23:59:56 -07001962
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001963 CAM_DBG(CAM_ISP, "next state %d", ctx->state);
Jing Zhoud352ed12017-03-20 23:59:56 -07001964 return rc;
1965}
1966
1967static int __cam_isp_ctx_link_in_acquired(struct cam_context *ctx,
1968 struct cam_req_mgr_core_dev_link_setup *link)
1969{
1970 int rc = 0;
Junzhe Zou2df84502017-05-26 13:20:23 -07001971 struct cam_isp_context *ctx_isp =
1972 (struct cam_isp_context *) ctx->ctx_priv;
Jing Zhoud352ed12017-03-20 23:59:56 -07001973
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001974 CAM_DBG(CAM_ISP, "Enter.........");
Jing Zhoud352ed12017-03-20 23:59:56 -07001975
1976 ctx->link_hdl = link->link_hdl;
1977 ctx->ctx_crm_intf = link->crm_cb;
Junzhe Zou2df84502017-05-26 13:20:23 -07001978 ctx_isp->subscribe_event = link->subscribe_event;
Jing Zhoud352ed12017-03-20 23:59:56 -07001979
1980 /* change state only if we had the init config */
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06001981 if (!list_empty(&ctx->pending_req_list)) {
Jing Zhoud352ed12017-03-20 23:59:56 -07001982 ctx->state = CAM_CTX_READY;
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06001983 trace_cam_context_state("ISP", ctx);
1984 }
Jing Zhoud352ed12017-03-20 23:59:56 -07001985
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001986 CAM_DBG(CAM_ISP, "next state %d", ctx->state);
Jing Zhoud352ed12017-03-20 23:59:56 -07001987
1988 return rc;
1989}
1990
1991static int __cam_isp_ctx_unlink_in_acquired(struct cam_context *ctx,
1992 struct cam_req_mgr_core_dev_link_setup *unlink)
1993{
1994 int rc = 0;
1995
Karthik Anantha Ram34dc2652017-10-20 15:49:54 -07001996 ctx->link_hdl = -1;
Jing Zhoud352ed12017-03-20 23:59:56 -07001997 ctx->ctx_crm_intf = NULL;
1998
1999 return rc;
2000}
2001
2002static int __cam_isp_ctx_get_dev_info_in_acquired(struct cam_context *ctx,
2003 struct cam_req_mgr_device_info *dev_info)
2004{
2005 int rc = 0;
2006
2007 dev_info->dev_hdl = ctx->dev_hdl;
2008 strlcpy(dev_info->name, CAM_ISP_DEV_NAME, sizeof(dev_info->name));
2009 dev_info->dev_id = CAM_REQ_MGR_DEVICE_IFE;
2010 dev_info->p_delay = 1;
Junzhe Zou2df84502017-05-26 13:20:23 -07002011 dev_info->trigger = CAM_TRIGGER_POINT_SOF;
Jing Zhoud352ed12017-03-20 23:59:56 -07002012
2013 return rc;
2014}
2015
2016static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx,
2017 struct cam_start_stop_dev_cmd *cmd)
2018{
2019 int rc = 0;
2020 struct cam_hw_start_args arg;
2021 struct cam_ctx_request *req;
2022 struct cam_isp_ctx_req *req_isp;
2023 struct cam_isp_context *ctx_isp =
2024 (struct cam_isp_context *) ctx->ctx_priv;
2025
2026 if (cmd->session_handle != ctx->session_hdl ||
2027 cmd->dev_handle != ctx->dev_hdl) {
2028 rc = -EPERM;
2029 goto end;
2030 }
2031
2032 if (list_empty(&ctx->pending_req_list)) {
2033 /* should never happen */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002034 CAM_ERR(CAM_ISP, "Start device with empty configuration");
Jing Zhoud352ed12017-03-20 23:59:56 -07002035 rc = -EFAULT;
2036 goto end;
2037 } else {
2038 req = list_first_entry(&ctx->pending_req_list,
2039 struct cam_ctx_request, list);
2040 }
2041 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
2042
2043 if (!ctx_isp->hw_ctx) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002044 CAM_ERR(CAM_ISP, "Wrong hw context pointer.");
Jing Zhoud352ed12017-03-20 23:59:56 -07002045 rc = -EFAULT;
2046 goto end;
2047 }
2048 arg.ctxt_to_hw_map = ctx_isp->hw_ctx;
2049 arg.hw_update_entries = req_isp->cfg;
2050 arg.num_hw_update_entries = req_isp->num_cfg;
2051
2052 ctx_isp->frame_id = 0;
Jing Zhoudedc4762017-06-19 17:45:36 +05302053 ctx_isp->active_req_cnt = 0;
2054 ctx_isp->reported_req_id = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -07002055 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
2056
2057 /*
2058 * Only place to change state before calling the hw due to
2059 * hardware tasklet has higher priority that can cause the
2060 * irq handling comes early
2061 */
2062 ctx->state = CAM_CTX_ACTIVATED;
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06002063 trace_cam_context_state("ISP", ctx);
Jing Zhoud352ed12017-03-20 23:59:56 -07002064 rc = ctx->hw_mgr_intf->hw_start(ctx->hw_mgr_intf->hw_mgr_priv, &arg);
2065 if (rc) {
2066 /* HW failure. user need to clean up the resource */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002067 CAM_ERR(CAM_ISP, "Start HW failed");
Jing Zhoud352ed12017-03-20 23:59:56 -07002068 ctx->state = CAM_CTX_READY;
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06002069 trace_cam_context_state("ISP", ctx);
Jing Zhoud352ed12017-03-20 23:59:56 -07002070 goto end;
2071 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002072 CAM_DBG(CAM_ISP, "start device success");
Jing Zhoud352ed12017-03-20 23:59:56 -07002073end:
2074 return rc;
2075}
2076
2077static int __cam_isp_ctx_unlink_in_ready(struct cam_context *ctx,
2078 struct cam_req_mgr_core_dev_link_setup *unlink)
2079{
2080 int rc = 0;
2081
Karthik Anantha Ram34dc2652017-10-20 15:49:54 -07002082 ctx->link_hdl = -1;
Jing Zhoud352ed12017-03-20 23:59:56 -07002083 ctx->ctx_crm_intf = NULL;
2084 ctx->state = CAM_CTX_ACQUIRED;
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06002085 trace_cam_context_state("ISP", ctx);
Jing Zhoud352ed12017-03-20 23:59:56 -07002086
2087 return rc;
2088}
2089
2090static int __cam_isp_ctx_stop_dev_in_activated_unlock(
2091 struct cam_context *ctx)
2092{
2093 int rc = 0;
2094 uint32_t i;
2095 struct cam_hw_stop_args stop;
2096 struct cam_ctx_request *req;
2097 struct cam_isp_ctx_req *req_isp;
2098 struct cam_isp_context *ctx_isp =
2099 (struct cam_isp_context *) ctx->ctx_priv;
2100
2101 /* Mask off all the incoming hardware events */
Jing Zhou93b3ec12017-06-15 17:43:39 -07002102 spin_lock_bh(&ctx->lock);
Jing Zhoud352ed12017-03-20 23:59:56 -07002103 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_HALT;
Jing Zhou93b3ec12017-06-15 17:43:39 -07002104 spin_unlock_bh(&ctx->lock);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002105 CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated);
Jing Zhoud352ed12017-03-20 23:59:56 -07002106
2107 /* stop hw first */
2108 if (ctx_isp->hw_ctx) {
2109 stop.ctxt_to_hw_map = ctx_isp->hw_ctx;
2110 ctx->hw_mgr_intf->hw_stop(ctx->hw_mgr_intf->hw_mgr_priv,
2111 &stop);
2112 }
2113
2114 while (!list_empty(&ctx->pending_req_list)) {
2115 req = list_first_entry(&ctx->pending_req_list,
2116 struct cam_ctx_request, list);
2117 list_del_init(&req->list);
2118 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002119 CAM_DBG(CAM_ISP, "signal fence in pending list. fence num %d",
2120 req_isp->num_fence_map_out);
Jing Zhoud352ed12017-03-20 23:59:56 -07002121 for (i = 0; i < req_isp->num_fence_map_out; i++)
2122 if (req_isp->fence_map_out[i].sync_id != -1) {
2123 cam_sync_signal(
2124 req_isp->fence_map_out[i].sync_id,
2125 CAM_SYNC_STATE_SIGNALED_ERROR);
2126 }
2127 list_add_tail(&req->list, &ctx->free_req_list);
2128 }
2129
2130 while (!list_empty(&ctx->active_req_list)) {
2131 req = list_first_entry(&ctx->active_req_list,
2132 struct cam_ctx_request, list);
2133 list_del_init(&req->list);
2134 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002135 CAM_DBG(CAM_ISP, "signal fence in active list. fence num %d",
2136 req_isp->num_fence_map_out);
Jing Zhoud352ed12017-03-20 23:59:56 -07002137 for (i = 0; i < req_isp->num_fence_map_out; i++)
2138 if (req_isp->fence_map_out[i].sync_id != -1) {
2139 cam_sync_signal(
2140 req_isp->fence_map_out[i].sync_id,
2141 CAM_SYNC_STATE_SIGNALED_ERROR);
2142 }
2143 list_add_tail(&req->list, &ctx->free_req_list);
2144 }
2145 ctx_isp->frame_id = 0;
Jing Zhoudedc4762017-06-19 17:45:36 +05302146 ctx_isp->active_req_cnt = 0;
2147 ctx_isp->reported_req_id = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -07002148
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002149 CAM_DBG(CAM_ISP, "next state %d", ctx->state);
Jing Zhoud352ed12017-03-20 23:59:56 -07002150 return rc;
2151}
2152
2153static int __cam_isp_ctx_stop_dev_in_activated(struct cam_context *ctx,
2154 struct cam_start_stop_dev_cmd *cmd)
2155{
2156 int rc = 0;
2157
2158 __cam_isp_ctx_stop_dev_in_activated_unlock(ctx);
2159 ctx->state = CAM_CTX_ACQUIRED;
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06002160 trace_cam_context_state("ISP", ctx);
Jing Zhoud352ed12017-03-20 23:59:56 -07002161 return rc;
2162}
2163
2164static int __cam_isp_ctx_release_dev_in_activated(struct cam_context *ctx,
2165 struct cam_release_dev_cmd *cmd)
2166{
2167 int rc = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -07002168
Harsh Shah2d96c5e2017-09-29 11:58:45 -07002169 rc = __cam_isp_ctx_stop_dev_in_activated_unlock(ctx);
2170 if (rc)
2171 CAM_ERR(CAM_ISP, "Stop device failed rc=%d", rc);
Jing Zhoud352ed12017-03-20 23:59:56 -07002172
Harsh Shah2d96c5e2017-09-29 11:58:45 -07002173 rc = __cam_isp_ctx_release_dev_in_top_state(ctx, cmd);
2174 if (rc)
2175 CAM_ERR(CAM_ISP, "Release device failed rc=%d", rc);
Jing Zhoud352ed12017-03-20 23:59:56 -07002176
2177 return rc;
2178}
2179
Harsh Shah6e4bc932017-11-07 06:15:12 -08002180static int __cam_isp_ctx_unlink_in_activated(struct cam_context *ctx,
2181 struct cam_req_mgr_core_dev_link_setup *unlink)
2182{
2183 int rc = 0;
2184
2185 CAM_WARN(CAM_ISP,
2186 "Received unlink in activated state. It's unexpected");
2187 rc = __cam_isp_ctx_stop_dev_in_activated_unlock(ctx);
2188 if (rc)
2189 CAM_WARN(CAM_ISP, "Stop device failed rc=%d", rc);
2190
2191 rc = __cam_isp_ctx_unlink_in_ready(ctx, unlink);
2192 if (rc)
2193 CAM_ERR(CAM_ISP, "Unlink failed rc=%d", rc);
2194
2195 return rc;
2196}
2197
Jing Zhoud352ed12017-03-20 23:59:56 -07002198static int __cam_isp_ctx_apply_req(struct cam_context *ctx,
2199 struct cam_req_mgr_apply_request *apply)
2200{
2201 int rc = 0;
2202 struct cam_isp_context *ctx_isp =
2203 (struct cam_isp_context *) ctx->ctx_priv;
2204
Junzhe Zou5fa08b12017-08-15 10:08:12 -07002205 trace_cam_apply_req("ISP", apply->request_id);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002206 CAM_DBG(CAM_ISP, "Enter: apply req in Substate %d request _id:%lld",
2207 ctx_isp->substate_activated, apply->request_id);
Jing Zhoud352ed12017-03-20 23:59:56 -07002208 if (ctx_isp->substate_machine[ctx_isp->substate_activated].
2209 crm_ops.apply_req) {
2210 rc = ctx_isp->substate_machine[ctx_isp->substate_activated].
2211 crm_ops.apply_req(ctx, apply);
2212 } else {
Harsh Shahcb0072c2017-09-26 19:22:10 -07002213 CAM_ERR_RATE_LIMIT(CAM_ISP,
2214 "No handle function in activated substate %d",
2215 ctx_isp->substate_activated);
Jing Zhoud352ed12017-03-20 23:59:56 -07002216 rc = -EFAULT;
2217 }
2218
2219 if (rc)
Harsh Shahcb0072c2017-09-26 19:22:10 -07002220 CAM_ERR_RATE_LIMIT(CAM_ISP,
2221 "Apply failed in active substate %d",
2222 ctx_isp->substate_activated);
Jing Zhoud352ed12017-03-20 23:59:56 -07002223 return rc;
2224}
2225
2226
2227
2228static int __cam_isp_ctx_handle_irq_in_activated(void *context,
2229 uint32_t evt_id, void *evt_data)
2230{
2231 int rc = 0;
2232 struct cam_context *ctx = (struct cam_context *)context;
2233 struct cam_isp_context *ctx_isp =
2234 (struct cam_isp_context *)ctx->ctx_priv;
2235
Jing Zhou93b3ec12017-06-15 17:43:39 -07002236 spin_lock_bh(&ctx->lock);
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06002237
2238 trace_cam_isp_activated_irq(ctx, ctx_isp->substate_activated, evt_id,
2239 __cam_isp_ctx_get_event_ts(evt_id, evt_data));
2240
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002241 CAM_DBG(CAM_ISP, "Enter: State %d, Substate %d, evt id %d",
2242 ctx->state, ctx_isp->substate_activated, evt_id);
Jing Zhoud352ed12017-03-20 23:59:56 -07002243 if (ctx_isp->substate_machine_irq[ctx_isp->substate_activated].
2244 irq_ops[evt_id]) {
2245 rc = ctx_isp->substate_machine_irq[ctx_isp->substate_activated].
2246 irq_ops[evt_id](ctx_isp, evt_data);
2247 } else {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002248 CAM_DBG(CAM_ISP, "No handle function for substate %d",
Jing Zhoud352ed12017-03-20 23:59:56 -07002249 ctx_isp->substate_activated);
2250 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002251 CAM_DBG(CAM_ISP, "Exit: State %d Substate %d",
2252 ctx->state, ctx_isp->substate_activated);
Jing Zhou93b3ec12017-06-15 17:43:39 -07002253 spin_unlock_bh(&ctx->lock);
Jing Zhoud352ed12017-03-20 23:59:56 -07002254 return rc;
2255}
2256
2257/* top state machine */
2258static struct cam_ctx_ops
2259 cam_isp_ctx_top_state_machine[CAM_CTX_STATE_MAX] = {
2260 /* Uninit */
2261 {
2262 .ioctl_ops = {},
2263 .crm_ops = {},
2264 .irq_ops = NULL,
2265 },
2266 /* Available */
2267 {
2268 .ioctl_ops = {
2269 .acquire_dev = __cam_isp_ctx_acquire_dev_in_available,
2270 },
2271 .crm_ops = {},
2272 .irq_ops = NULL,
2273 },
2274 /* Acquired */
2275 {
2276 .ioctl_ops = {
2277 .release_dev = __cam_isp_ctx_release_dev_in_top_state,
2278 .config_dev = __cam_isp_ctx_config_dev_in_acquired,
2279 },
2280 .crm_ops = {
2281 .link = __cam_isp_ctx_link_in_acquired,
2282 .unlink = __cam_isp_ctx_unlink_in_acquired,
2283 .get_dev_info = __cam_isp_ctx_get_dev_info_in_acquired,
Jing Zhoub524a852017-05-16 15:47:30 +05302284 .flush_req = __cam_isp_ctx_flush_req_in_top_state,
Jing Zhoud352ed12017-03-20 23:59:56 -07002285 },
2286 .irq_ops = NULL,
2287 },
2288 /* Ready */
2289 {
2290 .ioctl_ops = {
2291 .start_dev = __cam_isp_ctx_start_dev_in_ready,
2292 .release_dev = __cam_isp_ctx_release_dev_in_top_state,
2293 .config_dev = __cam_isp_ctx_config_dev_in_top_state,
2294 },
2295 .crm_ops = {
2296 .unlink = __cam_isp_ctx_unlink_in_ready,
Jing Zhoub524a852017-05-16 15:47:30 +05302297 .flush_req = __cam_isp_ctx_flush_req_in_ready,
Jing Zhoud352ed12017-03-20 23:59:56 -07002298 },
2299 .irq_ops = NULL,
2300 },
2301 /* Activated */
2302 {
2303 .ioctl_ops = {
2304 .stop_dev = __cam_isp_ctx_stop_dev_in_activated,
2305 .release_dev = __cam_isp_ctx_release_dev_in_activated,
2306 .config_dev = __cam_isp_ctx_config_dev_in_top_state,
2307 },
2308 .crm_ops = {
Harsh Shah6e4bc932017-11-07 06:15:12 -08002309 .unlink = __cam_isp_ctx_unlink_in_activated,
Jing Zhoud352ed12017-03-20 23:59:56 -07002310 .apply_req = __cam_isp_ctx_apply_req,
Jing Zhoub524a852017-05-16 15:47:30 +05302311 .flush_req = __cam_isp_ctx_flush_req_in_top_state,
Jing Zhoud352ed12017-03-20 23:59:56 -07002312 },
2313 .irq_ops = __cam_isp_ctx_handle_irq_in_activated,
2314 },
2315};
2316
2317
2318int cam_isp_context_init(struct cam_isp_context *ctx,
2319 struct cam_context *ctx_base,
2320 struct cam_req_mgr_kmd_ops *crm_node_intf,
2321 struct cam_hw_mgr_intf *hw_intf)
2322
2323{
2324 int rc = -1;
2325 int i;
2326
2327 if (!ctx || !ctx_base) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002328 CAM_ERR(CAM_ISP, "Invalid Context");
Jing Zhoud352ed12017-03-20 23:59:56 -07002329 goto err;
2330 }
2331
2332 /* ISP context setup */
2333 memset(ctx, 0, sizeof(*ctx));
2334
2335 ctx->base = ctx_base;
2336 ctx->frame_id = 0;
Jing Zhoudedc4762017-06-19 17:45:36 +05302337 ctx->active_req_cnt = 0;
2338 ctx->reported_req_id = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -07002339 ctx->hw_ctx = NULL;
2340 ctx->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
2341 ctx->substate_machine = cam_isp_ctx_activated_state_machine;
2342 ctx->substate_machine_irq = cam_isp_ctx_activated_state_machine_irq;
2343
2344 for (i = 0; i < CAM_CTX_REQ_MAX; i++) {
2345 ctx->req_base[i].req_priv = &ctx->req_isp[i];
2346 ctx->req_isp[i].base = &ctx->req_base[i];
2347 }
2348
2349 /* camera context setup */
Harsh Shahe9a8a9c2017-11-01 04:07:38 -07002350 rc = cam_context_init(ctx_base, isp_dev_name, crm_node_intf, hw_intf,
2351 ctx->req_base, CAM_CTX_REQ_MAX);
Jing Zhoud352ed12017-03-20 23:59:56 -07002352 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002353 CAM_ERR(CAM_ISP, "Camera Context Base init failed");
Jing Zhoud352ed12017-03-20 23:59:56 -07002354 goto err;
2355 }
2356
2357 /* link camera context with isp context */
2358 ctx_base->state_machine = cam_isp_ctx_top_state_machine;
2359 ctx_base->ctx_priv = ctx;
2360
2361err:
2362 return rc;
2363}
2364
2365int cam_isp_context_deinit(struct cam_isp_context *ctx)
2366{
2367 int rc = 0;
2368
2369 if (ctx->base)
2370 cam_context_deinit(ctx->base);
2371
2372 if (ctx->substate_activated != CAM_ISP_CTX_ACTIVATED_SOF)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002373 CAM_ERR(CAM_ISP, "ISP context substate is invalid");
Jing Zhoud352ed12017-03-20 23:59:56 -07002374
2375 memset(ctx, 0, sizeof(*ctx));
2376 return rc;
2377}