blob: 1106453b7e59550e8720816fdc4850ede29173ff [file] [log] [blame]
Jing Zhou4d4f03e2018-01-16 18:10:31 -08001/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
Jing Zhoud352ed12017-03-20 23:59:56 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
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
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -070029#define INC_STATE_MONITOR_HEAD(head) \
30 (atomic64_add_return(1, head) % \
31 CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES)
32
33static void __cam_isp_ctx_update_state_monitor_array(
34 struct cam_isp_context *ctx_isp,
35 enum cam_isp_state_change_trigger trigger_type,
36 uint32_t req_id)
37{
38 int iterator = 0;
39
40 iterator = INC_STATE_MONITOR_HEAD(&ctx_isp->state_monitor_head);
41 ctx_isp->cam_isp_ctx_state_monitor[iterator].curr_state =
42 ctx_isp->substate_activated;
43 ctx_isp->cam_isp_ctx_state_monitor[iterator].trigger =
44 trigger_type;
45 ctx_isp->cam_isp_ctx_state_monitor[iterator].req_id =
46 req_id;
47 ctx_isp->cam_isp_ctx_state_monitor[iterator].evt_time_stamp =
48 jiffies_to_msecs(jiffies);
49}
50
51static const char *__cam_isp_ctx_substate_val_to_type(
52 uint32_t type)
53{
54 switch (type) {
55 case CAM_ISP_CTX_ACTIVATED_SOF:
56 return "SOF";
57 case CAM_ISP_CTX_ACTIVATED_APPLIED:
58 return "APPLIED";
59 case CAM_ISP_CTX_ACTIVATED_EPOCH:
60 return "EPOCH";
61 case CAM_ISP_CTX_ACTIVATED_BUBBLE:
62 return "BUBBLE";
63 case CAM_ISP_CTX_ACTIVATED_BUBBLE_APPLIED:
64 return "BUBBLE_APPLIED";
65 case CAM_ISP_CTX_ACTIVATED_HALT:
66 return "HALT";
67 default:
68 return "CAM_ISP_CTX_INVALID_STATE";
69 }
70}
71
72static const char *__cam_isp_hw_evt_val_to_type(
73 uint32_t evt_id)
74{
75 switch (evt_id) {
76 case CAM_ISP_STATE_CHANGE_TRIGGER_ERROR:
77 return "ERROR";
78 case CAM_ISP_STATE_CHANGE_TRIGGER_SOF:
79 return "SOF";
80 case CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE:
81 return "REG_UPDATE";
82 case CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH:
83 return "EPOCH";
84 case CAM_ISP_STATE_CHANGE_TRIGGER_EOF:
85 return "EOF";
86 case CAM_ISP_STATE_CHANGE_TRIGGER_DONE:
87 return "DONE";
88 default:
89 return "CAM_ISP_EVENT_INVALID";
90 }
91}
92
93static void __cam_isp_ctx_dump_state_monitor_array(
94 struct cam_isp_context *ctx_isp)
95{
96 int i = 0;
97 uint64_t state_head = 0;
98 uint64_t index;
99
100 state_head = atomic64_read(&ctx_isp->state_monitor_head);
101 CAM_ERR_RATE_LIMIT(CAM_ISP,
102 "Dumping state information for preceding requests");
103
104 for (i = CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES - 1; i >= 0;
105 i--) {
106 index = (((state_head - i) +
107 CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES) %
108 CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES);
109 CAM_ERR_RATE_LIMIT(CAM_ISP,
110 "time[0x%llx] req_id[%u] state[%s] evt_type[%s]",
111 ctx_isp->cam_isp_ctx_state_monitor[index].evt_time_stamp,
112 ctx_isp->cam_isp_ctx_state_monitor[index].req_id,
113 __cam_isp_ctx_substate_val_to_type(
114 ctx_isp->cam_isp_ctx_state_monitor[index].curr_state),
115 __cam_isp_hw_evt_val_to_type(
116 ctx_isp->cam_isp_ctx_state_monitor[index].trigger));
117 }
118}
119
Jing Zhou77962c52017-09-18 19:13:34 -0700120static int __cam_isp_ctx_enqueue_request_in_order(
121 struct cam_context *ctx, struct cam_ctx_request *req)
122{
123 struct cam_ctx_request *req_current;
124 struct cam_ctx_request *req_prev;
125 struct list_head temp_list;
126
127 INIT_LIST_HEAD(&temp_list);
128 spin_lock_bh(&ctx->lock);
129 if (list_empty(&ctx->pending_req_list)) {
130 list_add_tail(&req->list, &ctx->pending_req_list);
131 } else {
132 list_for_each_entry_safe_reverse(
133 req_current, req_prev, &ctx->pending_req_list, list) {
134 if (req->request_id < req_current->request_id) {
135 list_del_init(&req_current->list);
136 list_add(&req_current->list, &temp_list);
137 continue;
138 } else if (req->request_id == req_current->request_id) {
139 CAM_WARN(CAM_ISP,
140 "Received duplicated request %lld",
141 req->request_id);
142 }
143 break;
144 }
145 list_add_tail(&req->list, &ctx->pending_req_list);
146
147 if (!list_empty(&temp_list)) {
148 list_for_each_entry_safe(
149 req_current, req_prev, &temp_list, list) {
150 list_del_init(&req_current->list);
151 list_add_tail(&req_current->list,
152 &ctx->pending_req_list);
153 }
154 }
155 }
156 spin_unlock_bh(&ctx->lock);
157 return 0;
158}
159
Ravikishore Pampana24f712e2017-11-13 23:09:30 +0530160static int __cam_isp_ctx_enqueue_init_request(
161 struct cam_context *ctx, struct cam_ctx_request *req)
162{
163 int rc = 0;
164 struct cam_ctx_request *req_old;
165 struct cam_isp_ctx_req *req_isp_old;
166 struct cam_isp_ctx_req *req_isp_new;
167
168 spin_lock_bh(&ctx->lock);
169 if (list_empty(&ctx->pending_req_list)) {
170 list_add_tail(&req->list, &ctx->pending_req_list);
171 CAM_DBG(CAM_ISP, "INIT packet added req id= %d",
172 req->request_id);
173 goto end;
174 }
175
176 req_old = list_first_entry(&ctx->pending_req_list,
177 struct cam_ctx_request, list);
178 req_isp_old = (struct cam_isp_ctx_req *) req_old->req_priv;
179 req_isp_new = (struct cam_isp_ctx_req *) req->req_priv;
Vishalsingh Hajerie5450be2018-01-18 20:31:19 -0800180 if (req_isp_old->hw_update_data.packet_opcode_type ==
181 CAM_ISP_PACKET_INIT_DEV) {
Ravikishore Pampana24f712e2017-11-13 23:09:30 +0530182 if ((req_isp_old->num_cfg + req_isp_new->num_cfg) >=
183 CAM_ISP_CTX_CFG_MAX) {
184 CAM_WARN(CAM_ISP, "Can not merge INIT pkt");
185 rc = -ENOMEM;
186 }
187
188 if (req_isp_old->num_fence_map_out != 0 ||
189 req_isp_old->num_fence_map_in != 0) {
190 CAM_WARN(CAM_ISP, "Invalid INIT pkt sequence");
191 rc = -EINVAL;
192 }
193
194 if (!rc) {
195 memcpy(req_isp_old->fence_map_out,
196 req_isp_new->fence_map_out,
197 sizeof(req_isp_new->fence_map_out[0])*
198 req_isp_new->num_fence_map_out);
199 req_isp_old->num_fence_map_out =
200 req_isp_new->num_fence_map_out;
201
202 memcpy(req_isp_old->fence_map_in,
203 req_isp_new->fence_map_in,
204 sizeof(req_isp_new->fence_map_in[0])*
205 req_isp_new->num_fence_map_in);
206 req_isp_old->num_fence_map_in =
207 req_isp_new->num_fence_map_in;
208
209 memcpy(&req_isp_old->cfg[req_isp_old->num_cfg],
210 req_isp_new->cfg,
211 sizeof(req_isp_new->cfg[0])*
212 req_isp_new->num_cfg);
213 req_isp_old->num_cfg += req_isp_new->num_cfg;
214
215 list_add_tail(&req->list, &ctx->free_req_list);
216 }
217 } else {
218 CAM_WARN(CAM_ISP,
219 "Received Update pkt before INIT pkt. req_id= %lld",
220 req->request_id);
221 rc = -EINVAL;
222 }
223end:
224 spin_unlock_bh(&ctx->lock);
225 return rc;
226}
227
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700228static const char *__cam_isp_resource_handle_id_to_type(
229 uint32_t resource_handle)
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700230{
231 switch (resource_handle) {
232 case CAM_ISP_IFE_OUT_RES_FULL:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700233 return "FULL";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700234 case CAM_ISP_IFE_OUT_RES_DS4:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700235 return "DS4";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700236 case CAM_ISP_IFE_OUT_RES_DS16:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700237 return "DS16";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700238 case CAM_ISP_IFE_OUT_RES_RAW_DUMP:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700239 return "RAW_DUMP";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700240 case CAM_ISP_IFE_OUT_RES_FD:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700241 return "FD";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700242 case CAM_ISP_IFE_OUT_RES_PDAF:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700243 return "PDAF";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700244 case CAM_ISP_IFE_OUT_RES_RDI_0:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700245 return "RDI_0";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700246 case CAM_ISP_IFE_OUT_RES_RDI_1:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700247 return "RDI_1";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700248 case CAM_ISP_IFE_OUT_RES_RDI_2:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700249 return "RDI_2";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700250 case CAM_ISP_IFE_OUT_RES_RDI_3:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700251 return "RDI_3";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700252 case CAM_ISP_IFE_OUT_RES_STATS_HDR_BE:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700253 return "STATS_HDR_BE";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700254 case CAM_ISP_IFE_OUT_RES_STATS_HDR_BHIST:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700255 return "STATS_HDR_BHIST";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700256 case CAM_ISP_IFE_OUT_RES_STATS_TL_BG:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700257 return "STATS_TL_BG";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700258 case CAM_ISP_IFE_OUT_RES_STATS_BF:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700259 return "STATS_BF";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700260 case CAM_ISP_IFE_OUT_RES_STATS_AWB_BG:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700261 return "STATS_AWB_BG";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700262 case CAM_ISP_IFE_OUT_RES_STATS_BHIST:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700263 return "STATS_BHIST";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700264 case CAM_ISP_IFE_OUT_RES_STATS_RS:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700265 return "STATS_RS";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700266 case CAM_ISP_IFE_OUT_RES_STATS_CS:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700267 return "STATS_CS";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700268 default:
269 return "CAM_ISP_Invalid_Resource_Type";
270 }
271}
272
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -0600273static uint64_t __cam_isp_ctx_get_event_ts(uint32_t evt_id, void *evt_data)
274{
275 uint64_t ts = 0;
276
277 if (!evt_data)
278 return 0;
279
280 switch (evt_id) {
281 case CAM_ISP_HW_EVENT_ERROR:
282 ts = ((struct cam_isp_hw_error_event_data *)evt_data)->
283 timestamp;
284 break;
285 case CAM_ISP_HW_EVENT_SOF:
286 ts = ((struct cam_isp_hw_sof_event_data *)evt_data)->
287 timestamp;
288 break;
289 case CAM_ISP_HW_EVENT_REG_UPDATE:
290 ts = ((struct cam_isp_hw_reg_update_event_data *)evt_data)->
291 timestamp;
292 break;
293 case CAM_ISP_HW_EVENT_EPOCH:
294 ts = ((struct cam_isp_hw_epoch_event_data *)evt_data)->
295 timestamp;
296 break;
297 case CAM_ISP_HW_EVENT_EOF:
298 ts = ((struct cam_isp_hw_eof_event_data *)evt_data)->
299 timestamp;
300 break;
301 case CAM_ISP_HW_EVENT_DONE:
302 break;
303 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700304 CAM_DBG(CAM_ISP, "Invalid Event Type %d", evt_id);
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -0600305 }
306
307 return ts;
308}
309
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700310static void __cam_isp_ctx_handle_buf_done_fail_log(
311 struct cam_isp_ctx_req *req_isp)
312{
313 int i;
314
Harsh Shah1b8eb232017-10-09 19:20:52 -0700315 if (req_isp->num_fence_map_out >= CAM_ISP_CTX_RES_MAX) {
316 CAM_ERR_RATE_LIMIT(CAM_ISP,
317 "Num Resources exceed mMAX %d >= %d ",
318 req_isp->num_fence_map_out, CAM_ISP_CTX_RES_MAX);
319 return;
320 }
321
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700322 CAM_ERR_RATE_LIMIT(CAM_ISP,
323 "Resource Handles that fail to generate buf_done in prev frame");
324 for (i = 0; i < req_isp->num_fence_map_out; i++) {
325 if (req_isp->fence_map_out[i].sync_id != -1)
326 CAM_ERR_RATE_LIMIT(CAM_ISP,
327 "Resource_Handle: [%s] Sync_ID: [0x%x]",
328 __cam_isp_resource_handle_id_to_type(
329 req_isp->fence_map_out[i].resource_handle),
330 req_isp->fence_map_out[i].sync_id);
331 }
332}
333
Jing Zhoud352ed12017-03-20 23:59:56 -0700334static int __cam_isp_ctx_handle_buf_done_in_activated_state(
335 struct cam_isp_context *ctx_isp,
336 struct cam_isp_hw_done_event_data *done,
337 uint32_t bubble_state)
338{
339 int rc = 0;
340 int i, j;
341 struct cam_ctx_request *req;
342 struct cam_isp_ctx_req *req_isp;
343 struct cam_context *ctx = ctx_isp->base;
344
345 if (list_empty(&ctx->active_req_list)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700346 CAM_DBG(CAM_ISP, "Buf done with no active request!");
Jing Zhoud352ed12017-03-20 23:59:56 -0700347 goto end;
348 }
349
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700350 CAM_DBG(CAM_ISP, "Enter with bubble_state %d", bubble_state);
Jing Zhoud352ed12017-03-20 23:59:56 -0700351
352 req = list_first_entry(&ctx->active_req_list,
353 struct cam_ctx_request, list);
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -0600354
355 trace_cam_buf_done("ISP", ctx, req);
356
Jing Zhoud352ed12017-03-20 23:59:56 -0700357 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
358 for (i = 0; i < done->num_handles; i++) {
359 for (j = 0; j < req_isp->num_fence_map_out; j++) {
360 if (done->resource_handle[i] ==
361 req_isp->fence_map_out[j].resource_handle)
362 break;
363 }
364
365 if (j == req_isp->num_fence_map_out) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700366 CAM_ERR(CAM_ISP,
367 "Can not find matching lane handle 0x%x!",
Jing Zhoud352ed12017-03-20 23:59:56 -0700368 done->resource_handle[i]);
369 rc = -EINVAL;
370 continue;
371 }
372
Harsh Shah1b8eb232017-10-09 19:20:52 -0700373 if (req_isp->fence_map_out[j].sync_id == -1) {
374 __cam_isp_ctx_handle_buf_done_fail_log(req_isp);
375 continue;
376 }
Jing Zhoubb536a82017-05-18 15:20:38 -0700377
Jeyaprakash Soundrapandian32e5ae52017-11-17 23:44:44 -0800378 if (!bubble_state) {
vhajeri05545252017-11-10 18:43:08 -0800379 CAM_DBG(CAM_ISP,
380 "Sync with success: req %lld res 0x%x fd 0x%x",
381 req->request_id,
382 req_isp->fence_map_out[j].resource_handle,
383 req_isp->fence_map_out[j].sync_id);
384
385 rc = cam_sync_signal(req_isp->fence_map_out[j].sync_id,
386 CAM_SYNC_STATE_SIGNALED_SUCCESS);
387 if (rc)
388 CAM_DBG(CAM_ISP, "Sync failed with rc = %d",
Jeyaprakash Soundrapandian32e5ae52017-11-17 23:44:44 -0800389 rc);
390 } else if (!req_isp->bubble_report) {
391 CAM_DBG(CAM_ISP,
392 "Sync with failure: req %lld res 0x%x fd 0x%x",
393 req->request_id,
394 req_isp->fence_map_out[j].resource_handle,
395 req_isp->fence_map_out[j].sync_id);
396
397 rc = cam_sync_signal(req_isp->fence_map_out[j].sync_id,
398 CAM_SYNC_STATE_SIGNALED_ERROR);
399 if (rc)
400 CAM_ERR(CAM_ISP, "Sync failed with rc = %d",
vhajeri05545252017-11-10 18:43:08 -0800401 rc);
Jing Zhoud352ed12017-03-20 23:59:56 -0700402 } else {
403 /*
404 * Ignore the buffer done if bubble detect is on
405 * In most case, active list should be empty when
406 * bubble detects. But for safety, we just move the
407 * current active request to the pending list here.
408 */
Harsh Shah1b8eb232017-10-09 19:20:52 -0700409 CAM_DBG(CAM_ISP,
410 "buf done with bubble state %d recovery %d",
411 bubble_state, req_isp->bubble_report);
Jing Zhoud352ed12017-03-20 23:59:56 -0700412 list_del_init(&req->list);
413 list_add(&req->list, &ctx->pending_req_list);
414 continue;
415 }
416
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700417 CAM_DBG(CAM_ISP, "req %lld, reset sync id 0x%x",
Harsh Shah1b8eb232017-10-09 19:20:52 -0700418 req->request_id,
419 req_isp->fence_map_out[j].sync_id);
420 if (!rc) {
421 req_isp->num_acked++;
422 req_isp->fence_map_out[j].sync_id = -1;
423 }
Jing Zhoud352ed12017-03-20 23:59:56 -0700424 }
425
Harsh Shah1b8eb232017-10-09 19:20:52 -0700426 if (req_isp->num_acked > req_isp->num_fence_map_out) {
427 /* Should not happen */
428 CAM_ERR(CAM_ISP,
429 "WARNING: req_id %lld num_acked %d > map_out %d",
430 req->request_id, req_isp->num_acked,
431 req_isp->num_fence_map_out);
432 WARN_ON(req_isp->num_acked > req_isp->num_fence_map_out);
433 }
Jing Zhoud352ed12017-03-20 23:59:56 -0700434 if (req_isp->num_acked == req_isp->num_fence_map_out) {
435 list_del_init(&req->list);
436 list_add_tail(&req->list, &ctx->free_req_list);
Jing Zhoudedc4762017-06-19 17:45:36 +0530437 ctx_isp->active_req_cnt--;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700438 CAM_DBG(CAM_ISP,
439 "Move active request %lld to free list(cnt = %d)",
440 req->request_id, ctx_isp->active_req_cnt);
Jing Zhoud352ed12017-03-20 23:59:56 -0700441 }
442
443end:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700444 __cam_isp_ctx_update_state_monitor_array(ctx_isp,
445 CAM_ISP_STATE_CHANGE_TRIGGER_DONE,
446 ctx_isp->base->req_list->request_id);
Jing Zhoud352ed12017-03-20 23:59:56 -0700447 return rc;
448}
449
Jing Zhoudedc4762017-06-19 17:45:36 +0530450static void __cam_isp_ctx_send_sof_timestamp(
451 struct cam_isp_context *ctx_isp, uint64_t request_id,
452 uint32_t sof_event_status)
453{
454 struct cam_req_mgr_message req_msg;
455
456 req_msg.session_hdl = ctx_isp->base->session_hdl;
457 req_msg.u.frame_msg.frame_id = ctx_isp->frame_id;
458 req_msg.u.frame_msg.request_id = request_id;
459 req_msg.u.frame_msg.timestamp = ctx_isp->sof_timestamp_val;
460 req_msg.u.frame_msg.link_hdl = ctx_isp->base->link_hdl;
461 req_msg.u.frame_msg.sof_status = sof_event_status;
462
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700463 CAM_DBG(CAM_ISP,
464 "request id:%lld frame number:%lld SOF time stamp:0x%llx",
465 request_id, ctx_isp->frame_id,
Jing Zhoudedc4762017-06-19 17:45:36 +0530466 ctx_isp->sof_timestamp_val);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700467 CAM_DBG(CAM_ISP, " sof status:%d", sof_event_status);
Jing Zhoudedc4762017-06-19 17:45:36 +0530468
Harsh Shah67fa2312017-10-30 04:03:07 -0700469 if (cam_req_mgr_notify_message(&req_msg,
Jing Zhoudedc4762017-06-19 17:45:36 +0530470 V4L_EVENT_CAM_REQ_MGR_SOF, V4L_EVENT_CAM_REQ_MGR_EVENT))
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700471 CAM_ERR(CAM_ISP,
472 "Error in notifying the sof time for req id:%lld",
473 request_id);
Jing Zhoudedc4762017-06-19 17:45:36 +0530474}
475
Jing Zhoud352ed12017-03-20 23:59:56 -0700476static int __cam_isp_ctx_reg_upd_in_activated_state(
477 struct cam_isp_context *ctx_isp, void *evt_data)
478{
479 int rc = 0;
480 struct cam_ctx_request *req;
481 struct cam_context *ctx = ctx_isp->base;
482 struct cam_isp_ctx_req *req_isp;
483
484 if (list_empty(&ctx->pending_req_list)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700485 CAM_ERR(CAM_ISP, "Reg upd ack with no pending request");
Jing Zhoud352ed12017-03-20 23:59:56 -0700486 goto end;
487 }
488 req = list_first_entry(&ctx->pending_req_list,
489 struct cam_ctx_request, list);
490 list_del_init(&req->list);
491
492 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
493 if (req_isp->num_fence_map_out != 0) {
Jing Zhoud352ed12017-03-20 23:59:56 -0700494 list_add_tail(&req->list, &ctx->active_req_list);
Jing Zhoudedc4762017-06-19 17:45:36 +0530495 ctx_isp->active_req_cnt++;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700496 CAM_DBG(CAM_ISP, "move request %lld to active list(cnt = %d)",
497 req->request_id, ctx_isp->active_req_cnt);
Jing Zhoud352ed12017-03-20 23:59:56 -0700498 } else {
499 /* no io config, so the request is completed. */
500 list_add_tail(&req->list, &ctx->free_req_list);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700501 CAM_DBG(CAM_ISP,
502 "move active request %lld to free list(cnt = %d)",
503 req->request_id, ctx_isp->active_req_cnt);
Jing Zhoud352ed12017-03-20 23:59:56 -0700504 }
505
506 /*
507 * This function only called directly from applied and bubble applied
508 * state so change substate here.
509 */
510 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_EPOCH;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700511 CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated);
Jing Zhoud352ed12017-03-20 23:59:56 -0700512
513end:
514 return rc;
515}
516
517static int __cam_isp_ctx_notify_sof_in_actived_state(
518 struct cam_isp_context *ctx_isp, void *evt_data)
519{
Junzhe Zou2df84502017-05-26 13:20:23 -0700520 int rc = 0;
521 struct cam_req_mgr_trigger_notify notify;
Jing Zhoud352ed12017-03-20 23:59:56 -0700522 struct cam_context *ctx = ctx_isp->base;
Jing Zhoudedc4762017-06-19 17:45:36 +0530523 struct cam_ctx_request *req;
524 uint64_t request_id = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -0700525
Jing Zhoudedc4762017-06-19 17:45:36 +0530526 /*
527 * notify reqmgr with sof signal. Note, due to scheduling delay
528 * we can run into situation that two active requests has already
529 * be in the active queue while we try to do the notification.
530 * In this case, we need to skip the current notification. This
531 * helps the state machine to catch up the delay.
532 */
Junzhe Zou2df84502017-05-26 13:20:23 -0700533 if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger &&
Jing Zhoudedc4762017-06-19 17:45:36 +0530534 ctx_isp->active_req_cnt <= 2) {
Junzhe Zou2df84502017-05-26 13:20:23 -0700535 if (ctx_isp->subscribe_event & CAM_TRIGGER_POINT_SOF) {
536 notify.link_hdl = ctx->link_hdl;
537 notify.dev_hdl = ctx->dev_hdl;
538 notify.frame_id = ctx_isp->frame_id;
539 notify.trigger = CAM_TRIGGER_POINT_SOF;
Jing Zhoud352ed12017-03-20 23:59:56 -0700540
Junzhe Zou2df84502017-05-26 13:20:23 -0700541 ctx->ctx_crm_intf->notify_trigger(&notify);
542 CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld",
543 ctx_isp->frame_id);
544 }
Jing Zhoudedc4762017-06-19 17:45:36 +0530545
546 list_for_each_entry(req, &ctx->active_req_list, list) {
547 if (req->request_id > ctx_isp->reported_req_id) {
548 request_id = req->request_id;
549 ctx_isp->reported_req_id = request_id;
550 break;
551 }
552 }
553
Ravikishore Pampana6648f172017-12-08 20:29:11 +0530554 if (ctx_isp->substate_activated == CAM_ISP_CTX_ACTIVATED_BUBBLE)
555 request_id = 0;
556
Jing Zhoudedc4762017-06-19 17:45:36 +0530557 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
558 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
Jing Zhoud352ed12017-03-20 23:59:56 -0700559 } else {
Harsh Shahcb0072c2017-09-26 19:22:10 -0700560 CAM_ERR_RATE_LIMIT(CAM_ISP, "Can not notify SOF to CRM");
Junzhe Zou2df84502017-05-26 13:20:23 -0700561 rc = -EFAULT;
Jing Zhoud352ed12017-03-20 23:59:56 -0700562 }
563
Jing Zhoudedc4762017-06-19 17:45:36 +0530564 return 0;
Jing Zhoud352ed12017-03-20 23:59:56 -0700565}
566
Junzhe Zou2df84502017-05-26 13:20:23 -0700567static int __cam_isp_ctx_notify_eof_in_actived_state(
568 struct cam_isp_context *ctx_isp, void *evt_data)
569{
570 int rc = 0;
571 struct cam_req_mgr_trigger_notify notify;
572 struct cam_context *ctx = ctx_isp->base;
573
574 if (!(ctx_isp->subscribe_event & CAM_TRIGGER_POINT_EOF))
575 return rc;
576
577 /* notify reqmgr with eof signal */
578 if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger) {
579 notify.link_hdl = ctx->link_hdl;
580 notify.dev_hdl = ctx->dev_hdl;
581 notify.frame_id = ctx_isp->frame_id;
582 notify.trigger = CAM_TRIGGER_POINT_EOF;
583
584 ctx->ctx_crm_intf->notify_trigger(&notify);
585 CAM_DBG(CAM_ISP, "Notify CRM EOF frame %lld\n",
586 ctx_isp->frame_id);
587 } else {
588 CAM_ERR(CAM_ISP, "Can not notify EOF to CRM");
589 rc = -EFAULT;
590 }
591
592 return rc;
593}
Jing Zhoud352ed12017-03-20 23:59:56 -0700594
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +0530595static int __cam_isp_ctx_reg_upd_in_hw_error(
596 struct cam_isp_context *ctx_isp, void *evt_data)
597{
598 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
599 return 0;
600}
601
Jing Zhoudedc4762017-06-19 17:45:36 +0530602static int __cam_isp_ctx_sof_in_activated_state(
603 struct cam_isp_context *ctx_isp, void *evt_data)
Jing Zhoud352ed12017-03-20 23:59:56 -0700604{
605 int rc = 0;
Jing Zhoudedc4762017-06-19 17:45:36 +0530606 struct cam_isp_hw_sof_event_data *sof_event_data = evt_data;
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700607 struct cam_ctx_request *req;
608 struct cam_context *ctx = ctx_isp->base;
609
610 req = list_last_entry(&ctx->pending_req_list,
611 struct cam_ctx_request, list);
Jing Zhoud352ed12017-03-20 23:59:56 -0700612
Jing Zhoudedc4762017-06-19 17:45:36 +0530613 if (!evt_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700614 CAM_ERR(CAM_ISP, "in valid sof event data");
Jing Zhoudedc4762017-06-19 17:45:36 +0530615 return -EINVAL;
616 }
617
Jing Zhoud352ed12017-03-20 23:59:56 -0700618 ctx_isp->frame_id++;
Jing Zhoudedc4762017-06-19 17:45:36 +0530619 ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700620 __cam_isp_ctx_update_state_monitor_array(ctx_isp,
621 CAM_ISP_STATE_CHANGE_TRIGGER_SOF, req->request_id);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700622 CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx",
Jing Zhoudedc4762017-06-19 17:45:36 +0530623 ctx_isp->frame_id, ctx_isp->sof_timestamp_val);
Jing Zhoud352ed12017-03-20 23:59:56 -0700624
625 return rc;
626}
627
628static int __cam_isp_ctx_reg_upd_in_sof(struct cam_isp_context *ctx_isp,
629 void *evt_data)
630{
631 int rc = 0;
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700632 struct cam_ctx_request *req = NULL;
Jing Zhoud352ed12017-03-20 23:59:56 -0700633 struct cam_isp_ctx_req *req_isp;
634 struct cam_context *ctx = ctx_isp->base;
635
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700636 if (ctx->state != CAM_CTX_ACTIVATED && ctx_isp->frame_id > 1) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700637 CAM_DBG(CAM_ISP, "invalid RUP");
Jing Zhoud352ed12017-03-20 23:59:56 -0700638 goto end;
639 }
640
641 /*
642 * This is for the first update. The initial setting will
643 * cause the reg_upd in the first frame.
644 */
645 if (!list_empty(&ctx->pending_req_list)) {
646 req = list_first_entry(&ctx->pending_req_list,
647 struct cam_ctx_request, list);
648 list_del_init(&req->list);
649 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
Jing Zhoudedc4762017-06-19 17:45:36 +0530650 if (req_isp->num_fence_map_out == req_isp->num_acked) {
Jing Zhoud352ed12017-03-20 23:59:56 -0700651 list_add_tail(&req->list, &ctx->free_req_list);
Jing Zhoudedc4762017-06-19 17:45:36 +0530652 } else {
Jing Zhoud352ed12017-03-20 23:59:56 -0700653 /* need to handle the buf done */
654 list_add_tail(&req->list, &ctx->active_req_list);
Jing Zhoudedc4762017-06-19 17:45:36 +0530655 ctx_isp->active_req_cnt++;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700656 CAM_DBG(CAM_ISP,
657 "move request %lld to active list(cnt = %d)",
658 req->request_id,
Jing Zhoudedc4762017-06-19 17:45:36 +0530659 ctx_isp->active_req_cnt);
Jing Zhoud352ed12017-03-20 23:59:56 -0700660 ctx_isp->substate_activated =
661 CAM_ISP_CTX_ACTIVATED_EPOCH;
662 }
663 }
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700664 if (req != NULL) {
665 __cam_isp_ctx_update_state_monitor_array(ctx_isp,
666 CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE,
667 req->request_id);
668 }
Jing Zhoud352ed12017-03-20 23:59:56 -0700669end:
670 return rc;
671}
672
673static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
674 void *evt_data)
675{
Jing Zhoud352ed12017-03-20 23:59:56 -0700676 struct cam_ctx_request *req;
677 struct cam_isp_ctx_req *req_isp;
678 struct cam_context *ctx = ctx_isp->base;
Jing Zhoudedc4762017-06-19 17:45:36 +0530679 uint64_t request_id = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -0700680
681 if (list_empty(&ctx->pending_req_list)) {
682 /*
683 * If no pending req in epoch, this is an error case.
684 * The recovery is to go back to sof state
685 */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700686 CAM_ERR(CAM_ISP, "No pending request");
Jing Zhoud352ed12017-03-20 23:59:56 -0700687 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
Jing Zhoudedc4762017-06-19 17:45:36 +0530688
689 /* Send SOF event as empty frame*/
690 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
691 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
692
Jing Zhoud352ed12017-03-20 23:59:56 -0700693 goto end;
694 }
695
696 req = list_first_entry(&ctx->pending_req_list, struct cam_ctx_request,
697 list);
698 req_isp = (struct cam_isp_ctx_req *)req->req_priv;
699
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700700 CAM_DBG(CAM_ISP, "Report Bubble flag %d", req_isp->bubble_report);
Jing Zhoud352ed12017-03-20 23:59:56 -0700701 if (req_isp->bubble_report && ctx->ctx_crm_intf &&
702 ctx->ctx_crm_intf->notify_err) {
703 struct cam_req_mgr_error_notify notify;
704
705 notify.link_hdl = ctx->link_hdl;
706 notify.dev_hdl = ctx->dev_hdl;
707 notify.req_id = req->request_id;
708 notify.error = CRM_KMD_ERR_BUBBLE;
709 ctx->ctx_crm_intf->notify_err(&notify);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700710 CAM_DBG(CAM_ISP, "Notify CRM about Bubble frame %lld",
Jing Zhoud352ed12017-03-20 23:59:56 -0700711 ctx_isp->frame_id);
Jing Zhou45b55cc2017-05-16 17:27:18 -0700712 } else {
713 /*
714 * Since can not bubble report, always move the request to
715 * active list.
716 */
717 list_del_init(&req->list);
718 list_add_tail(&req->list, &ctx->active_req_list);
Jing Zhoudedc4762017-06-19 17:45:36 +0530719 ctx_isp->active_req_cnt++;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700720 CAM_DBG(CAM_ISP, "move request %lld to active list(cnt = %d)",
721 req->request_id, ctx_isp->active_req_cnt);
Jing Zhou45b55cc2017-05-16 17:27:18 -0700722 req_isp->bubble_report = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -0700723 }
724
Ravikishore Pampana6648f172017-12-08 20:29:11 +0530725 if (req->request_id > ctx_isp->reported_req_id) {
726 request_id = req->request_id;
727 ctx_isp->reported_req_id = request_id;
728 }
Jing Zhoudedc4762017-06-19 17:45:36 +0530729 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
730 CAM_REQ_MGR_SOF_EVENT_ERROR);
731
Jing Zhoud352ed12017-03-20 23:59:56 -0700732 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700733 CAM_DBG(CAM_ISP, "next substate %d",
Jing Zhoud352ed12017-03-20 23:59:56 -0700734 ctx_isp->substate_activated);
735end:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700736 if (request_id == 0) {
737 req = list_last_entry(&ctx->active_req_list,
738 struct cam_ctx_request, list);
739 __cam_isp_ctx_update_state_monitor_array(ctx_isp,
740 CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, req->request_id);
741 } else {
742 __cam_isp_ctx_update_state_monitor_array(ctx_isp,
743 CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, request_id);
744 }
Jing Zhoudedc4762017-06-19 17:45:36 +0530745 return 0;
Jing Zhoud352ed12017-03-20 23:59:56 -0700746}
747
748
749static int __cam_isp_ctx_buf_done_in_applied(struct cam_isp_context *ctx_isp,
750 void *evt_data)
751{
752 int rc = 0;
753 struct cam_isp_hw_done_event_data *done =
754 (struct cam_isp_hw_done_event_data *) evt_data;
755
756 rc = __cam_isp_ctx_handle_buf_done_in_activated_state(ctx_isp, done, 0);
757 return rc;
758}
759
760
761static int __cam_isp_ctx_sof_in_epoch(struct cam_isp_context *ctx_isp,
762 void *evt_data)
763{
764 int rc = 0;
Jing Zhoudedc4762017-06-19 17:45:36 +0530765 struct cam_context *ctx = ctx_isp->base;
766 struct cam_isp_hw_sof_event_data *sof_event_data = evt_data;
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700767 struct cam_ctx_request *req;
Jing Zhou93b3ec12017-06-15 17:43:39 -0700768
Jing Zhoudedc4762017-06-19 17:45:36 +0530769 if (!evt_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700770 CAM_ERR(CAM_ISP, "in valid sof event data");
Jing Zhoudedc4762017-06-19 17:45:36 +0530771 return -EINVAL;
772 }
Jing Zhoud352ed12017-03-20 23:59:56 -0700773
774 ctx_isp->frame_id++;
Jing Zhoudedc4762017-06-19 17:45:36 +0530775 ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
776
Jing Zhou93b3ec12017-06-15 17:43:39 -0700777 if (list_empty(&ctx->active_req_list))
778 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
779 else
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700780 CAM_DBG(CAM_ISP, "Still need to wait for the buf done");
Jing Zhoudedc4762017-06-19 17:45:36 +0530781
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700782 req = list_last_entry(&ctx->active_req_list,
783 struct cam_ctx_request, list);
784 __cam_isp_ctx_update_state_monitor_array(ctx_isp,
785 CAM_ISP_STATE_CHANGE_TRIGGER_SOF, ctx->req_list->request_id);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700786 CAM_DBG(CAM_ISP, "next substate %d",
Jing Zhoud352ed12017-03-20 23:59:56 -0700787 ctx_isp->substate_activated);
788
789 return rc;
790}
791
792static int __cam_isp_ctx_buf_done_in_epoch(struct cam_isp_context *ctx_isp,
793 void *evt_data)
794{
795 int rc = 0;
796 struct cam_isp_hw_done_event_data *done =
797 (struct cam_isp_hw_done_event_data *) evt_data;
798
799 rc = __cam_isp_ctx_handle_buf_done_in_activated_state(ctx_isp, done, 0);
800 return rc;
801}
802
Jing Zhoud352ed12017-03-20 23:59:56 -0700803static int __cam_isp_ctx_buf_done_in_bubble(
804 struct cam_isp_context *ctx_isp, void *evt_data)
805{
806 int rc = 0;
807 struct cam_isp_hw_done_event_data *done =
808 (struct cam_isp_hw_done_event_data *) evt_data;
809
810 rc = __cam_isp_ctx_handle_buf_done_in_activated_state(ctx_isp, done, 1);
811 return rc;
812}
813
Jing Zhoud352ed12017-03-20 23:59:56 -0700814static int __cam_isp_ctx_epoch_in_bubble_applied(
815 struct cam_isp_context *ctx_isp, void *evt_data)
816{
817 struct cam_ctx_request *req;
818 struct cam_isp_ctx_req *req_isp;
819 struct cam_context *ctx = ctx_isp->base;
Jing Zhoudedc4762017-06-19 17:45:36 +0530820 uint64_t request_id = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -0700821
822 /*
823 * This means we missed the reg upd ack. So we need to
824 * transition to BUBBLE state again.
825 */
826
827 if (list_empty(&ctx->pending_req_list)) {
828 /*
829 * If no pending req in epoch, this is an error case.
830 * Just go back to the bubble state.
831 */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700832 CAM_ERR(CAM_ISP, "No pending request.");
Jing Zhoudedc4762017-06-19 17:45:36 +0530833 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
834 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
835
Jing Zhoud352ed12017-03-20 23:59:56 -0700836 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE;
837 goto end;
838 }
839
840 req = list_first_entry(&ctx->pending_req_list, struct cam_ctx_request,
841 list);
842 req_isp = (struct cam_isp_ctx_req *)req->req_priv;
843
844 if (req_isp->bubble_report && ctx->ctx_crm_intf &&
845 ctx->ctx_crm_intf->notify_err) {
846 struct cam_req_mgr_error_notify notify;
847
848 notify.link_hdl = ctx->link_hdl;
849 notify.dev_hdl = ctx->dev_hdl;
850 notify.req_id = req->request_id;
851 notify.error = CRM_KMD_ERR_BUBBLE;
852 ctx->ctx_crm_intf->notify_err(&notify);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700853 CAM_DBG(CAM_ISP, "Notify CRM about Bubble frame %lld",
Jing Zhoud352ed12017-03-20 23:59:56 -0700854 ctx_isp->frame_id);
Jing Zhou45b55cc2017-05-16 17:27:18 -0700855 } else {
856 /*
857 * If we can not report bubble, then treat it as if no bubble
858 * report. Just move the req to active list.
859 */
860 list_del_init(&req->list);
861 list_add_tail(&req->list, &ctx->active_req_list);
Jing Zhoudedc4762017-06-19 17:45:36 +0530862 ctx_isp->active_req_cnt++;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700863 CAM_DBG(CAM_ISP, "move request %lld to active list(cnt = %d)",
864 req->request_id, ctx_isp->active_req_cnt);
Jing Zhou45b55cc2017-05-16 17:27:18 -0700865 req_isp->bubble_report = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -0700866 }
867
Ravikishore Pampana6648f172017-12-08 20:29:11 +0530868 if (!req_isp->bubble_report) {
869 if (req->request_id > ctx_isp->reported_req_id) {
870 request_id = req->request_id;
871 ctx_isp->reported_req_id = request_id;
872 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
873 CAM_REQ_MGR_SOF_EVENT_ERROR);
874 } else
875 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
876 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
877 } else
878 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
879 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
Jing Zhoudedc4762017-06-19 17:45:36 +0530880
Jing Zhoud352ed12017-03-20 23:59:56 -0700881 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700882 CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated);
Jing Zhoud352ed12017-03-20 23:59:56 -0700883end:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700884 req = list_last_entry(&ctx->active_req_list, struct cam_ctx_request,
885 list);
886 __cam_isp_ctx_update_state_monitor_array(ctx_isp,
887 CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, req->request_id);
Jing Zhoud352ed12017-03-20 23:59:56 -0700888 return 0;
889}
890
891static int __cam_isp_ctx_buf_done_in_bubble_applied(
892 struct cam_isp_context *ctx_isp, void *evt_data)
893{
894 int rc = 0;
895 struct cam_isp_hw_done_event_data *done =
896 (struct cam_isp_hw_done_event_data *) evt_data;
897
898 rc = __cam_isp_ctx_handle_buf_done_in_activated_state(ctx_isp, done, 1);
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700899 __cam_isp_ctx_update_state_monitor_array(ctx_isp,
900 CAM_ISP_STATE_CHANGE_TRIGGER_DONE,
901 ctx_isp->base->req_list->request_id);
Jing Zhoud352ed12017-03-20 23:59:56 -0700902 return rc;
903}
904
905static int __cam_isp_ctx_handle_error(struct cam_isp_context *ctx_isp,
906 void *evt_data)
907{
908 int rc = 0;
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +0530909 uint32_t i = 0;
910 bool found = 0;
911 struct cam_ctx_request *req = NULL;
912 struct cam_ctx_request *req_temp;
913 struct cam_isp_ctx_req *req_isp = NULL;
Jing Zhoud352ed12017-03-20 23:59:56 -0700914 struct cam_req_mgr_error_notify notify;
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +0530915 uint64_t error_request_id;
Vishalsingh Hajeri7a431b72018-03-01 14:07:24 -0800916 struct cam_hw_fence_map_entry *fence_map_out = NULL;
Jing Zhoud352ed12017-03-20 23:59:56 -0700917
918 struct cam_context *ctx = ctx_isp->base;
919 struct cam_isp_hw_error_event_data *error_event_data =
920 (struct cam_isp_hw_error_event_data *)evt_data;
921
922 uint32_t error_type = error_event_data->error_type;
923
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700924 CAM_DBG(CAM_ISP, "Enter error_type = %d", error_type);
Jing Zhoud352ed12017-03-20 23:59:56 -0700925 if ((error_type == CAM_ISP_HW_ERROR_OVERFLOW) ||
926 (error_type == CAM_ISP_HW_ERROR_BUSIF_OVERFLOW))
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +0530927 notify.error = CRM_KMD_ERR_OVERFLOW;
Jing Zhoud352ed12017-03-20 23:59:56 -0700928
929 /*
930 * Need to check the active req
931 * move all of them to the pending request list
932 * Note this funciton need revisit!
933 */
934
935 if (list_empty(&ctx->active_req_list)) {
Harsh Shahcb0072c2017-09-26 19:22:10 -0700936 CAM_ERR_RATE_LIMIT(CAM_ISP,
937 "handling error with no active request");
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +0530938 } else {
939 list_for_each_entry_safe(req, req_temp,
940 &ctx->active_req_list, list) {
941 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
942 if (!req_isp->bubble_report) {
943 for (i = 0; i < req_isp->num_fence_map_out;
944 i++) {
Vishalsingh Hajeri7a431b72018-03-01 14:07:24 -0800945 fence_map_out =
946 &req_isp->fence_map_out[i];
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +0530947 CAM_ERR(CAM_ISP, "req %llu, Sync fd %x",
Vishalsingh Hajeri7a431b72018-03-01 14:07:24 -0800948 req->request_id,
949 req_isp->fence_map_out[i].sync_id);
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +0530950 if (req_isp->fence_map_out[i].sync_id
951 != -1) {
952 rc = cam_sync_signal(
Vishalsingh Hajeri7a431b72018-03-01 14:07:24 -0800953 fence_map_out->sync_id,
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +0530954 CAM_SYNC_STATE_SIGNALED_ERROR);
Vishalsingh Hajeri7a431b72018-03-01 14:07:24 -0800955 fence_map_out->sync_id =
956 -1;
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +0530957 }
958 }
959 list_del_init(&req->list);
960 list_add_tail(&req->list, &ctx->free_req_list);
961 ctx_isp->active_req_cnt--;
962 } else {
963 found = 1;
964 break;
965 }
966 }
Jing Zhoud352ed12017-03-20 23:59:56 -0700967 }
968
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +0530969 if (found) {
970 list_for_each_entry_safe_reverse(req, req_temp,
971 &ctx->active_req_list, list) {
972 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
973 list_del_init(&req->list);
974 list_add(&req->list, &ctx->pending_req_list);
975 ctx_isp->active_req_cnt--;
976 }
977 }
978
979 do {
980 if (list_empty(&ctx->pending_req_list)) {
981 error_request_id = ctx_isp->last_applied_req_id + 1;
982 req_isp = NULL;
983 break;
984 }
985 req = list_first_entry(&ctx->pending_req_list,
986 struct cam_ctx_request, list);
987 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
988 error_request_id = ctx_isp->last_applied_req_id;
989
990 if (req_isp->bubble_report)
991 break;
992
993 for (i = 0; i < req_isp->num_fence_map_out; i++) {
994 if (req_isp->fence_map_out[i].sync_id != -1)
995 rc = cam_sync_signal(
996 req_isp->fence_map_out[i].sync_id,
997 CAM_SYNC_STATE_SIGNALED_ERROR);
998 req_isp->fence_map_out[i].sync_id = -1;
999 }
1000 list_del_init(&req->list);
1001 list_add_tail(&req->list, &ctx->free_req_list);
1002
1003 } while (req->request_id < ctx_isp->last_applied_req_id);
1004
Jing Zhoud352ed12017-03-20 23:59:56 -07001005
1006 if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_err) {
1007 notify.link_hdl = ctx->link_hdl;
1008 notify.dev_hdl = ctx->dev_hdl;
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +05301009 notify.req_id = error_request_id;
1010
1011 if (req_isp && req_isp->bubble_report)
1012 notify.error = CRM_KMD_ERR_BUBBLE;
1013
1014 CAM_WARN(CAM_ISP, "Notify CRM: req %lld, frame %lld\n",
1015 error_request_id, ctx_isp->frame_id);
Jing Zhoud352ed12017-03-20 23:59:56 -07001016
1017 ctx->ctx_crm_intf->notify_err(&notify);
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +05301018 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_HW_ERROR;
Jing Zhoud352ed12017-03-20 23:59:56 -07001019 } else {
Harsh Shahcb0072c2017-09-26 19:22:10 -07001020 CAM_ERR_RATE_LIMIT(CAM_ISP, "Can not notify ERRROR to CRM");
Jing Zhoud352ed12017-03-20 23:59:56 -07001021 rc = -EFAULT;
1022 }
1023
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -07001024
1025 list_del_init(&req->list);
1026 list_add(&req->list, &ctx->pending_req_list);
1027 /* might need to check if active list is empty */
1028 if (req != NULL) {
1029 __cam_isp_ctx_update_state_monitor_array(ctx_isp,
1030 CAM_ISP_STATE_CHANGE_TRIGGER_ERROR, req->request_id);
1031 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001032 CAM_DBG(CAM_ISP, "Exit");
Jing Zhoud352ed12017-03-20 23:59:56 -07001033 return rc;
1034}
1035
Jing Zhou4d4f03e2018-01-16 18:10:31 -08001036static int __cam_isp_ctx_sof_in_flush(
1037 struct cam_isp_context *ctx_isp, void *evt_data)
1038{
1039 int rc = 0;
1040 struct cam_isp_hw_sof_event_data *sof_event_data = evt_data;
1041
1042 if (!evt_data) {
1043 CAM_ERR(CAM_ISP, "in valid sof event data");
1044 return -EINVAL;
1045 }
1046 ctx_isp->frame_id++;
1047 ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
1048 CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx",
1049 ctx_isp->frame_id, ctx_isp->sof_timestamp_val);
1050
1051 if (--ctx_isp->frame_skip_count == 0)
1052 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
1053 else
1054 CAM_ERR(CAM_ISP, "Skip currect SOF");
1055
1056 return rc;
1057}
1058
Jing Zhoud352ed12017-03-20 23:59:56 -07001059static struct cam_isp_ctx_irq_ops
1060 cam_isp_ctx_activated_state_machine_irq[CAM_ISP_CTX_ACTIVATED_MAX] = {
1061 /* SOF */
1062 {
1063 .irq_ops = {
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +05301064 __cam_isp_ctx_handle_error,
Jing Zhoudedc4762017-06-19 17:45:36 +05301065 __cam_isp_ctx_sof_in_activated_state,
Jing Zhoud352ed12017-03-20 23:59:56 -07001066 __cam_isp_ctx_reg_upd_in_sof,
1067 __cam_isp_ctx_notify_sof_in_actived_state,
Junzhe Zou2df84502017-05-26 13:20:23 -07001068 __cam_isp_ctx_notify_eof_in_actived_state,
Jing Zhoud352ed12017-03-20 23:59:56 -07001069 NULL,
1070 },
1071 },
1072 /* APPLIED */
1073 {
1074 .irq_ops = {
1075 __cam_isp_ctx_handle_error,
Jing Zhoudedc4762017-06-19 17:45:36 +05301076 __cam_isp_ctx_sof_in_activated_state,
Jing Zhoud352ed12017-03-20 23:59:56 -07001077 __cam_isp_ctx_reg_upd_in_activated_state,
1078 __cam_isp_ctx_epoch_in_applied,
Junzhe Zou2df84502017-05-26 13:20:23 -07001079 __cam_isp_ctx_notify_eof_in_actived_state,
Jing Zhoud352ed12017-03-20 23:59:56 -07001080 __cam_isp_ctx_buf_done_in_applied,
1081 },
1082 },
1083 /* EPOCH */
1084 {
1085 .irq_ops = {
1086 __cam_isp_ctx_handle_error,
1087 __cam_isp_ctx_sof_in_epoch,
1088 NULL,
1089 __cam_isp_ctx_notify_sof_in_actived_state,
Junzhe Zou2df84502017-05-26 13:20:23 -07001090 __cam_isp_ctx_notify_eof_in_actived_state,
Jing Zhoud352ed12017-03-20 23:59:56 -07001091 __cam_isp_ctx_buf_done_in_epoch,
1092 },
1093 },
1094 /* BUBBLE */
1095 {
1096 .irq_ops = {
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +05301097 __cam_isp_ctx_handle_error,
Jing Zhoudedc4762017-06-19 17:45:36 +05301098 __cam_isp_ctx_sof_in_activated_state,
Jing Zhoud352ed12017-03-20 23:59:56 -07001099 NULL,
1100 __cam_isp_ctx_notify_sof_in_actived_state,
Junzhe Zou2df84502017-05-26 13:20:23 -07001101 __cam_isp_ctx_notify_eof_in_actived_state,
Jing Zhoud352ed12017-03-20 23:59:56 -07001102 __cam_isp_ctx_buf_done_in_bubble,
1103 },
1104 },
1105 /* Bubble Applied */
1106 {
1107 .irq_ops = {
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +05301108 __cam_isp_ctx_handle_error,
Jing Zhoudedc4762017-06-19 17:45:36 +05301109 __cam_isp_ctx_sof_in_activated_state,
Jing Zhoud352ed12017-03-20 23:59:56 -07001110 __cam_isp_ctx_reg_upd_in_activated_state,
1111 __cam_isp_ctx_epoch_in_bubble_applied,
1112 NULL,
1113 __cam_isp_ctx_buf_done_in_bubble_applied,
1114 },
1115 },
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +05301116 /* HW ERROR */
1117 {
1118 .irq_ops = {
1119 NULL,
1120 __cam_isp_ctx_sof_in_activated_state,
1121 __cam_isp_ctx_reg_upd_in_hw_error,
1122 NULL,
1123 NULL,
1124 NULL,
1125 },
1126 },
Jing Zhoud352ed12017-03-20 23:59:56 -07001127 /* HALT */
1128 {
1129 },
Jing Zhou4d4f03e2018-01-16 18:10:31 -08001130 /* FLUSH */
1131 {
1132 .irq_ops = {
1133 NULL,
1134 __cam_isp_ctx_sof_in_flush,
1135 NULL,
1136 NULL,
1137 NULL,
1138 __cam_isp_ctx_buf_done_in_applied,
1139 },
1140 },
Jing Zhoud352ed12017-03-20 23:59:56 -07001141};
1142
1143static int __cam_isp_ctx_apply_req_in_activated_state(
1144 struct cam_context *ctx, struct cam_req_mgr_apply_request *apply,
1145 uint32_t next_state)
1146{
1147 int rc = 0;
1148 struct cam_ctx_request *req;
Harsh Shah1b8eb232017-10-09 19:20:52 -07001149 struct cam_ctx_request *active_req;
Jing Zhoud352ed12017-03-20 23:59:56 -07001150 struct cam_isp_ctx_req *req_isp;
Harsh Shah1b8eb232017-10-09 19:20:52 -07001151 struct cam_isp_ctx_req *active_req_isp;
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -07001152 struct cam_isp_context *ctx_isp = NULL;
Jing Zhoud352ed12017-03-20 23:59:56 -07001153 struct cam_hw_config_args cfg;
1154
1155 if (list_empty(&ctx->pending_req_list)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001156 CAM_ERR(CAM_ISP, "No available request for Apply id %lld",
1157 apply->request_id);
Jing Zhoud352ed12017-03-20 23:59:56 -07001158 rc = -EFAULT;
1159 goto end;
1160 }
Jing Zhou9eabf472017-05-16 11:59:41 -07001161
1162 /*
1163 * When the pipeline has issue, the requests can be queued up in the
1164 * pipeline. In this case, we should reject the additional request.
1165 * The maximum number of request allowed to be outstanding is 2.
1166 *
1167 */
Jing Zhoudedc4762017-06-19 17:45:36 +05301168 ctx_isp = (struct cam_isp_context *) ctx->ctx_priv;
Jing Zhoud352ed12017-03-20 23:59:56 -07001169 req = list_first_entry(&ctx->pending_req_list, struct cam_ctx_request,
1170 list);
1171
1172 /*
1173 * Check whehter the request id is matching the tip, if not, this means
1174 * we are in the middle of the error handling. Need to reject this apply
1175 */
1176 if (req->request_id != apply->request_id) {
Harsh Shahf7136392017-08-29 12:42:52 -07001177 CAM_ERR_RATE_LIMIT(CAM_ISP,
1178 "Invalid Request Id asking %llu existing %llu",
1179 apply->request_id, req->request_id);
Jing Zhoud352ed12017-03-20 23:59:56 -07001180 rc = -EFAULT;
1181 goto end;
1182 }
1183
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001184 CAM_DBG(CAM_ISP, "Apply request %lld", req->request_id);
Jing Zhoud352ed12017-03-20 23:59:56 -07001185 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
Jing Zhoud352ed12017-03-20 23:59:56 -07001186
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -07001187 if (ctx_isp->active_req_cnt >= 2) {
1188 CAM_ERR_RATE_LIMIT(CAM_ISP,
Harsh Shah1b8eb232017-10-09 19:20:52 -07001189 "Reject apply request (id %lld) due to congestion(cnt = %d)",
1190 req->request_id,
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -07001191 ctx_isp->active_req_cnt);
Harsh Shah1b8eb232017-10-09 19:20:52 -07001192 if (!list_empty(&ctx->active_req_list)) {
1193 active_req = list_first_entry(&ctx->active_req_list,
1194 struct cam_ctx_request, list);
1195 active_req_isp =
1196 (struct cam_isp_ctx_req *) active_req->req_priv;
1197 __cam_isp_ctx_handle_buf_done_fail_log(active_req_isp);
1198 } else {
1199 CAM_ERR_RATE_LIMIT(CAM_ISP,
1200 "WARNING: should not happen (cnt = %d) but active_list empty",
1201 ctx_isp->active_req_cnt);
1202 }
1203 rc = -EFAULT;
1204 goto end;
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -07001205 }
Jing Zhoud352ed12017-03-20 23:59:56 -07001206 req_isp->bubble_report = apply->report_if_bubble;
1207
1208 cfg.ctxt_to_hw_map = ctx_isp->hw_ctx;
Venkat Chintad983df82018-03-14 12:54:40 -07001209 cfg.request_id = req->request_id;
Jing Zhoud352ed12017-03-20 23:59:56 -07001210 cfg.hw_update_entries = req_isp->cfg;
1211 cfg.num_hw_update_entries = req_isp->num_cfg;
Vishalsingh Hajerie5450be2018-01-18 20:31:19 -08001212 cfg.priv = &req_isp->hw_update_data;
Jing Zhoud352ed12017-03-20 23:59:56 -07001213
1214 rc = ctx->hw_mgr_intf->hw_config(ctx->hw_mgr_intf->hw_mgr_priv, &cfg);
1215 if (rc) {
Harsh Shahcb0072c2017-09-26 19:22:10 -07001216 CAM_ERR_RATE_LIMIT(CAM_ISP, "Can not apply the configuration");
Jing Zhoud352ed12017-03-20 23:59:56 -07001217 } else {
Jing Zhou93b3ec12017-06-15 17:43:39 -07001218 spin_lock_bh(&ctx->lock);
Jing Zhoud352ed12017-03-20 23:59:56 -07001219 ctx_isp->substate_activated = next_state;
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +05301220 ctx_isp->last_applied_req_id = apply->request_id;
1221 CAM_DBG(CAM_ISP, "new substate state %d, applied req %lld",
1222 next_state, ctx_isp->last_applied_req_id);
Jing Zhou93b3ec12017-06-15 17:43:39 -07001223 spin_unlock_bh(&ctx->lock);
Jing Zhoud352ed12017-03-20 23:59:56 -07001224 }
1225end:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -07001226 if (ctx_isp != NULL) {
1227 __cam_isp_ctx_update_state_monitor_array(ctx_isp,
1228 CAM_ISP_STATE_CHANGE_TRIGGER_SOF,
1229 ctx->req_list->request_id);
1230 }
Jing Zhoud352ed12017-03-20 23:59:56 -07001231 return rc;
1232}
1233
1234static int __cam_isp_ctx_apply_req_in_sof(
1235 struct cam_context *ctx, struct cam_req_mgr_apply_request *apply)
1236{
1237 int rc = 0;
1238 struct cam_isp_context *ctx_isp =
1239 (struct cam_isp_context *) ctx->ctx_priv;
1240
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001241 CAM_DBG(CAM_ISP, "current substate %d",
Jing Zhoud352ed12017-03-20 23:59:56 -07001242 ctx_isp->substate_activated);
1243 rc = __cam_isp_ctx_apply_req_in_activated_state(ctx, apply,
1244 CAM_ISP_CTX_ACTIVATED_APPLIED);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001245 CAM_DBG(CAM_ISP, "new substate %d", ctx_isp->substate_activated);
Jing Zhoud352ed12017-03-20 23:59:56 -07001246
1247 return rc;
1248}
1249
1250static int __cam_isp_ctx_apply_req_in_epoch(
1251 struct cam_context *ctx, struct cam_req_mgr_apply_request *apply)
1252{
1253 int rc = 0;
1254 struct cam_isp_context *ctx_isp =
1255 (struct cam_isp_context *) ctx->ctx_priv;
1256
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001257 CAM_DBG(CAM_ISP, "current substate %d",
Jing Zhoud352ed12017-03-20 23:59:56 -07001258 ctx_isp->substate_activated);
1259 rc = __cam_isp_ctx_apply_req_in_activated_state(ctx, apply,
1260 CAM_ISP_CTX_ACTIVATED_APPLIED);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001261 CAM_DBG(CAM_ISP, "new substate %d", ctx_isp->substate_activated);
Jing Zhoud352ed12017-03-20 23:59:56 -07001262
1263 return rc;
1264}
1265
1266static int __cam_isp_ctx_apply_req_in_bubble(
1267 struct cam_context *ctx, struct cam_req_mgr_apply_request *apply)
1268{
1269 int rc = 0;
1270 struct cam_isp_context *ctx_isp =
1271 (struct cam_isp_context *) ctx->ctx_priv;
1272
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001273 CAM_DBG(CAM_ISP, "current substate %d",
Jing Zhoud352ed12017-03-20 23:59:56 -07001274 ctx_isp->substate_activated);
1275 rc = __cam_isp_ctx_apply_req_in_activated_state(ctx, apply,
1276 CAM_ISP_CTX_ACTIVATED_BUBBLE_APPLIED);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001277 CAM_DBG(CAM_ISP, "new substate %d", ctx_isp->substate_activated);
Jing Zhoud352ed12017-03-20 23:59:56 -07001278
1279 return rc;
1280}
1281
Jing Zhoub524a852017-05-16 15:47:30 +05301282static int __cam_isp_ctx_flush_req(struct cam_context *ctx,
1283 struct list_head *req_list, struct cam_req_mgr_flush_request *flush_req)
1284{
1285 int i, rc;
1286 uint32_t cancel_req_id_found = 0;
1287 struct cam_ctx_request *req;
1288 struct cam_ctx_request *req_temp;
1289 struct cam_isp_ctx_req *req_isp;
Alok Pandeyf308aec2018-01-22 18:10:59 +05301290 struct list_head flush_list;
Jing Zhoub524a852017-05-16 15:47:30 +05301291
Alok Pandeyf308aec2018-01-22 18:10:59 +05301292 INIT_LIST_HEAD(&flush_list);
Harsh Shah7835b3b2017-11-20 17:39:11 -08001293 spin_lock_bh(&ctx->lock);
Jing Zhoub524a852017-05-16 15:47:30 +05301294 if (list_empty(req_list)) {
Harsh Shah7835b3b2017-11-20 17:39:11 -08001295 spin_unlock_bh(&ctx->lock);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001296 CAM_DBG(CAM_ISP, "request list is empty");
Jing Zhoub524a852017-05-16 15:47:30 +05301297 return 0;
1298 }
1299
1300 list_for_each_entry_safe(req, req_temp, req_list, list) {
Alok Pandeyf308aec2018-01-22 18:10:59 +05301301 if (flush_req->type == CAM_REQ_MGR_FLUSH_TYPE_CANCEL_REQ) {
1302 if (req->request_id != flush_req->req_id) {
1303 continue;
1304 } else {
1305 list_del_init(&req->list);
1306 list_add_tail(&req->list, &flush_list);
1307 cancel_req_id_found = 1;
1308 break;
1309 }
1310 }
Jing Zhoub524a852017-05-16 15:47:30 +05301311 list_del_init(&req->list);
Alok Pandeyf308aec2018-01-22 18:10:59 +05301312 list_add_tail(&req->list, &flush_list);
1313 }
1314 spin_unlock_bh(&ctx->lock);
1315
1316 list_for_each_entry_safe(req, req_temp, &flush_list, list) {
Jing Zhoub524a852017-05-16 15:47:30 +05301317 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
1318 for (i = 0; i < req_isp->num_fence_map_out; i++) {
1319 if (req_isp->fence_map_out[i].sync_id != -1) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001320 CAM_DBG(CAM_ISP, "Flush req 0x%llx, fence %d",
1321 req->request_id,
Jing Zhoub524a852017-05-16 15:47:30 +05301322 req_isp->fence_map_out[i].sync_id);
1323 rc = cam_sync_signal(
1324 req_isp->fence_map_out[i].sync_id,
1325 CAM_SYNC_STATE_SIGNALED_ERROR);
1326 if (rc)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001327 CAM_ERR_RATE_LIMIT(CAM_ISP,
1328 "signal fence failed\n");
Jing Zhoub524a852017-05-16 15:47:30 +05301329 req_isp->fence_map_out[i].sync_id = -1;
1330 }
1331 }
Alok Pandey3f935962018-02-16 15:21:01 +05301332 spin_lock_bh(&ctx->lock);
Jing Zhoub524a852017-05-16 15:47:30 +05301333 list_add_tail(&req->list, &ctx->free_req_list);
Alok Pandey3f935962018-02-16 15:21:01 +05301334 spin_unlock_bh(&ctx->lock);
Jing Zhoub524a852017-05-16 15:47:30 +05301335 }
Jing Zhoub524a852017-05-16 15:47:30 +05301336
1337 if (flush_req->type == CAM_REQ_MGR_FLUSH_TYPE_CANCEL_REQ &&
1338 !cancel_req_id_found)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001339 CAM_DBG(CAM_ISP,
1340 "Flush request id:%lld is not found in the list",
1341 flush_req->req_id);
Jing Zhoub524a852017-05-16 15:47:30 +05301342
1343 return 0;
1344}
1345
1346static int __cam_isp_ctx_flush_req_in_top_state(
1347 struct cam_context *ctx,
1348 struct cam_req_mgr_flush_request *flush_req)
1349{
1350 int rc = 0;
1351
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001352 CAM_DBG(CAM_ISP, "try to flush pending list");
Jing Zhoub524a852017-05-16 15:47:30 +05301353 rc = __cam_isp_ctx_flush_req(ctx, &ctx->pending_req_list, flush_req);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001354 CAM_DBG(CAM_ISP, "Flush request in top state %d",
1355 ctx->state);
Jing Zhoub524a852017-05-16 15:47:30 +05301356 return rc;
1357}
1358
Jing Zhou4d4f03e2018-01-16 18:10:31 -08001359static int __cam_isp_ctx_flush_req_in_activated(
1360 struct cam_context *ctx,
1361 struct cam_req_mgr_flush_request *flush_req)
1362{
1363 int rc = 0;
1364 struct cam_isp_context *ctx_isp;
1365
1366 ctx_isp = (struct cam_isp_context *) ctx->ctx_priv;
1367 spin_lock_bh(&ctx->lock);
1368 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_FLUSH;
1369 ctx_isp->frame_skip_count = 2;
1370 spin_unlock_bh(&ctx->lock);
1371
1372 CAM_DBG(CAM_ISP, "Flush request in state %d", ctx->state);
1373 rc = __cam_isp_ctx_flush_req(ctx, &ctx->pending_req_list, flush_req);
1374 return rc;
1375}
1376
Jing Zhoub524a852017-05-16 15:47:30 +05301377static int __cam_isp_ctx_flush_req_in_ready(
1378 struct cam_context *ctx,
1379 struct cam_req_mgr_flush_request *flush_req)
1380{
1381 int rc = 0;
1382
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001383 CAM_DBG(CAM_ISP, "try to flush pending list");
Jing Zhoub524a852017-05-16 15:47:30 +05301384 rc = __cam_isp_ctx_flush_req(ctx, &ctx->pending_req_list, flush_req);
1385
1386 /* if nothing is in pending req list, change state to acquire*/
Harsh Shah7835b3b2017-11-20 17:39:11 -08001387 spin_lock_bh(&ctx->lock);
Jing Zhoub524a852017-05-16 15:47:30 +05301388 if (list_empty(&ctx->pending_req_list))
1389 ctx->state = CAM_CTX_ACQUIRED;
Harsh Shah7835b3b2017-11-20 17:39:11 -08001390 spin_unlock_bh(&ctx->lock);
Jing Zhoub524a852017-05-16 15:47:30 +05301391
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06001392 trace_cam_context_state("ISP", ctx);
1393
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001394 CAM_DBG(CAM_ISP, "Flush request in ready state. next state %d",
1395 ctx->state);
Jing Zhoub524a852017-05-16 15:47:30 +05301396 return rc;
1397}
1398
Jing Zhoud352ed12017-03-20 23:59:56 -07001399static struct cam_ctx_ops
1400 cam_isp_ctx_activated_state_machine[CAM_ISP_CTX_ACTIVATED_MAX] = {
1401 /* SOF */
1402 {
1403 .ioctl_ops = {},
1404 .crm_ops = {
1405 .apply_req = __cam_isp_ctx_apply_req_in_sof,
1406 },
1407 .irq_ops = NULL,
1408 },
1409 /* APPLIED */
1410 {
1411 .ioctl_ops = {},
1412 .crm_ops = {},
1413 .irq_ops = NULL,
1414 },
1415 /* EPOCH */
1416 {
1417 .ioctl_ops = {},
1418 .crm_ops = {
1419 .apply_req = __cam_isp_ctx_apply_req_in_epoch,
1420 },
1421 .irq_ops = NULL,
1422 },
1423 /* BUBBLE */
1424 {
1425 .ioctl_ops = {},
1426 .crm_ops = {
1427 .apply_req = __cam_isp_ctx_apply_req_in_bubble,
1428 },
1429 .irq_ops = NULL,
1430 },
1431 /* Bubble Applied */
1432 {
1433 .ioctl_ops = {},
1434 .crm_ops = {},
1435 .irq_ops = NULL,
1436 },
Jing Zhou4d4f03e2018-01-16 18:10:31 -08001437 /* HW ERROR */
1438 {
1439 .ioctl_ops = {},
1440 .crm_ops = {},
1441 .irq_ops = NULL,
1442 },
Jing Zhoud352ed12017-03-20 23:59:56 -07001443 /* HALT */
1444 {
1445 .ioctl_ops = {},
1446 .crm_ops = {},
1447 .irq_ops = NULL,
1448 },
Jing Zhou4d4f03e2018-01-16 18:10:31 -08001449 /* FLUSH */
1450 {
1451 .ioctl_ops = {},
1452 .crm_ops = {},
1453 .irq_ops = NULL,
1454 },
Jing Zhoud352ed12017-03-20 23:59:56 -07001455};
1456
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301457static int __cam_isp_ctx_rdi_only_sof_in_top_state(
1458 struct cam_isp_context *ctx_isp, void *evt_data)
1459{
1460 int rc = 0;
1461 struct cam_context *ctx = ctx_isp->base;
Junzhe Zou2df84502017-05-26 13:20:23 -07001462 struct cam_req_mgr_trigger_notify notify;
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301463 struct cam_isp_hw_sof_event_data *sof_event_data = evt_data;
1464 uint64_t request_id = 0;
1465
1466 if (!evt_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001467 CAM_ERR(CAM_ISP, "in valid sof event data");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301468 return -EINVAL;
1469 }
1470
1471 ctx_isp->frame_id++;
1472 ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001473 CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301474 ctx_isp->frame_id, ctx_isp->sof_timestamp_val);
1475
1476 /*
1477 * notify reqmgr with sof signal. Note, due to scheduling delay
1478 * we can run into situation that two active requests has already
1479 * be in the active queue while we try to do the notification.
1480 * In this case, we need to skip the current notification. This
1481 * helps the state machine to catch up the delay.
1482 */
Junzhe Zou2df84502017-05-26 13:20:23 -07001483 if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger &&
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301484 ctx_isp->active_req_cnt <= 2) {
1485 notify.link_hdl = ctx->link_hdl;
1486 notify.dev_hdl = ctx->dev_hdl;
1487 notify.frame_id = ctx_isp->frame_id;
Junzhe Zou2df84502017-05-26 13:20:23 -07001488 notify.trigger = CAM_TRIGGER_POINT_SOF;
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301489
Junzhe Zou2df84502017-05-26 13:20:23 -07001490 ctx->ctx_crm_intf->notify_trigger(&notify);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001491 CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301492 ctx_isp->frame_id);
1493
1494 /*
1495 * It is idle frame with out any applied request id, send
1496 * request id as zero
1497 */
1498 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
1499 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
1500 } else {
Harsh Shahcb0072c2017-09-26 19:22:10 -07001501 CAM_ERR_RATE_LIMIT(CAM_ISP, "Can not notify SOF to CRM");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301502 }
1503
1504 if (list_empty(&ctx->active_req_list))
1505 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
1506 else
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001507 CAM_DBG(CAM_ISP, "Still need to wait for the buf done");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301508
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001509 CAM_DBG(CAM_ISP, "next substate %d",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301510 ctx_isp->substate_activated);
1511 return rc;
1512}
1513
1514static int __cam_isp_ctx_rdi_only_sof_in_applied_state(
1515 struct cam_isp_context *ctx_isp, void *evt_data)
1516{
1517 struct cam_isp_hw_sof_event_data *sof_event_data = evt_data;
1518
1519 if (!evt_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001520 CAM_ERR(CAM_ISP, "in valid sof event data");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301521 return -EINVAL;
1522 }
1523
1524 ctx_isp->frame_id++;
1525 ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001526 CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301527 ctx_isp->frame_id, ctx_isp->sof_timestamp_val);
1528
1529 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE_APPLIED;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001530 CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301531
1532 return 0;
1533}
1534
1535static int __cam_isp_ctx_rdi_only_sof_in_bubble_applied(
1536 struct cam_isp_context *ctx_isp, void *evt_data)
1537{
1538 struct cam_ctx_request *req;
1539 struct cam_isp_ctx_req *req_isp;
1540 struct cam_context *ctx = ctx_isp->base;
1541 struct cam_isp_hw_sof_event_data *sof_event_data = evt_data;
1542 uint64_t request_id = 0;
1543
Ravikishore Pampana6648f172017-12-08 20:29:11 +05301544 /*
1545 * Sof in bubble applied state means, reg update not received.
1546 * before increment frame id and override time stamp value, send
1547 * the previous sof time stamp that got captured in the
1548 * sof in applied state.
1549 */
1550 CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx",
1551 ctx_isp->frame_id, ctx_isp->sof_timestamp_val);
1552 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
1553 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
1554
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301555 ctx_isp->frame_id++;
1556 ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001557 CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301558 ctx_isp->frame_id, ctx_isp->sof_timestamp_val);
1559
1560 if (list_empty(&ctx->pending_req_list)) {
1561 /*
1562 * If no pending req in epoch, this is an error case.
1563 * The recovery is to go back to sof state
1564 */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001565 CAM_ERR(CAM_ISP, "No pending request");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301566 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
1567
1568 /* Send SOF event as empty frame*/
1569 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
1570 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
1571
1572 goto end;
1573 }
1574
1575 req = list_first_entry(&ctx->pending_req_list, struct cam_ctx_request,
1576 list);
1577 req_isp = (struct cam_isp_ctx_req *)req->req_priv;
1578
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001579 CAM_DBG(CAM_ISP, "Report Bubble flag %d", req_isp->bubble_report);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301580 if (req_isp->bubble_report && ctx->ctx_crm_intf &&
1581 ctx->ctx_crm_intf->notify_err) {
1582 struct cam_req_mgr_error_notify notify;
1583
1584 notify.link_hdl = ctx->link_hdl;
1585 notify.dev_hdl = ctx->dev_hdl;
1586 notify.req_id = req->request_id;
1587 notify.error = CRM_KMD_ERR_BUBBLE;
1588 ctx->ctx_crm_intf->notify_err(&notify);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001589 CAM_DBG(CAM_ISP, "Notify CRM about Bubble frame %lld",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301590 ctx_isp->frame_id);
1591 } else {
1592 /*
1593 * Since can not bubble report, always move the request to
1594 * active list.
1595 */
1596 list_del_init(&req->list);
1597 list_add_tail(&req->list, &ctx->active_req_list);
1598 ctx_isp->active_req_cnt++;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001599 CAM_DBG(CAM_ISP, "move request %lld to active list(cnt = %d)",
1600 req->request_id, ctx_isp->active_req_cnt);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301601 req_isp->bubble_report = 0;
1602 }
1603
Ravikishore Pampana6648f172017-12-08 20:29:11 +05301604 if (!req_isp->bubble_report) {
1605 if (req->request_id > ctx_isp->reported_req_id) {
1606 request_id = req->request_id;
1607 ctx_isp->reported_req_id = request_id;
1608 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
1609 CAM_REQ_MGR_SOF_EVENT_ERROR);
1610 } else
1611 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
1612 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
1613 } else
1614 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
1615 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301616
1617 /* change the state to bubble, as reg update has not come */
1618 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001619 CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301620end:
1621 return 0;
1622}
1623
1624static int __cam_isp_ctx_rdi_only_sof_in_bubble_state(
1625 struct cam_isp_context *ctx_isp, void *evt_data)
1626{
1627 uint32_t i;
1628 struct cam_ctx_request *req;
1629 struct cam_context *ctx = ctx_isp->base;
Junzhe Zou2df84502017-05-26 13:20:23 -07001630 struct cam_req_mgr_trigger_notify notify;
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301631 struct cam_isp_hw_sof_event_data *sof_event_data = evt_data;
1632 struct cam_isp_ctx_req *req_isp;
1633 uint64_t request_id = 0;
1634
1635 if (!evt_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001636 CAM_ERR(CAM_ISP, "in valid sof event data");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301637 return -EINVAL;
1638 }
1639
1640 ctx_isp->frame_id++;
1641 ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001642 CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301643 ctx_isp->frame_id, ctx_isp->sof_timestamp_val);
1644 /*
1645 * Signal all active requests with error and move the all the active
1646 * requests to free list
1647 */
1648 while (!list_empty(&ctx->active_req_list)) {
1649 req = list_first_entry(&ctx->active_req_list,
1650 struct cam_ctx_request, list);
1651 list_del_init(&req->list);
1652 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001653 CAM_DBG(CAM_ISP, "signal fence in active list. fence num %d",
1654 req_isp->num_fence_map_out);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301655 for (i = 0; i < req_isp->num_fence_map_out; i++)
1656 if (req_isp->fence_map_out[i].sync_id != -1) {
1657 cam_sync_signal(
1658 req_isp->fence_map_out[i].sync_id,
1659 CAM_SYNC_STATE_SIGNALED_ERROR);
1660 }
1661 list_add_tail(&req->list, &ctx->free_req_list);
Harsh Shah1b8eb232017-10-09 19:20:52 -07001662 ctx_isp->active_req_cnt--;
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301663 }
1664
1665 /* notify reqmgr with sof signal */
Junzhe Zou2df84502017-05-26 13:20:23 -07001666 if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger) {
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301667 notify.link_hdl = ctx->link_hdl;
1668 notify.dev_hdl = ctx->dev_hdl;
1669 notify.frame_id = ctx_isp->frame_id;
Junzhe Zou2df84502017-05-26 13:20:23 -07001670 notify.trigger = CAM_TRIGGER_POINT_SOF;
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301671
Junzhe Zou2df84502017-05-26 13:20:23 -07001672 ctx->ctx_crm_intf->notify_trigger(&notify);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001673 CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301674 ctx_isp->frame_id);
1675
1676 } else {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001677 CAM_ERR(CAM_ISP, "Can not notify SOF to CRM");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301678 }
1679
1680 /*
1681 * It is idle frame with out any applied request id, send
1682 * request id as zero
1683 */
1684 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
1685 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
1686
1687 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
1688
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001689 CAM_DBG(CAM_ISP, "next substate %d",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301690 ctx_isp->substate_activated);
1691
1692 return 0;
1693}
1694
1695static int __cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state(
1696 struct cam_isp_context *ctx_isp, void *evt_data)
1697{
1698 struct cam_ctx_request *req;
1699 struct cam_context *ctx = ctx_isp->base;
1700 struct cam_isp_ctx_req *req_isp;
Junzhe Zou2df84502017-05-26 13:20:23 -07001701 struct cam_req_mgr_trigger_notify notify;
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301702 uint64_t request_id = 0;
1703
1704 /* notify reqmgr with sof signal*/
Junzhe Zou2df84502017-05-26 13:20:23 -07001705 if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger) {
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301706 if (list_empty(&ctx->pending_req_list)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001707 CAM_ERR(CAM_ISP, "Reg upd ack with no pending request");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301708 goto error;
1709 }
1710 req = list_first_entry(&ctx->pending_req_list,
1711 struct cam_ctx_request, list);
1712 list_del_init(&req->list);
1713
1714 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
1715 request_id = req->request_id;
1716 if (req_isp->num_fence_map_out != 0) {
1717 list_add_tail(&req->list, &ctx->active_req_list);
1718 ctx_isp->active_req_cnt++;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001719 CAM_DBG(CAM_ISP,
1720 "move request %lld to active list(cnt = %d)",
1721 req->request_id, ctx_isp->active_req_cnt);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301722 } else {
1723 /* no io config, so the request is completed. */
1724 list_add_tail(&req->list, &ctx->free_req_list);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001725 CAM_DBG(CAM_ISP,
1726 "move active req %lld to free list(cnt=%d)",
1727 req->request_id, ctx_isp->active_req_cnt);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301728 }
1729
1730 notify.link_hdl = ctx->link_hdl;
1731 notify.dev_hdl = ctx->dev_hdl;
1732 notify.frame_id = ctx_isp->frame_id;
Junzhe Zou2df84502017-05-26 13:20:23 -07001733 notify.trigger = CAM_TRIGGER_POINT_SOF;
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301734
Junzhe Zou2df84502017-05-26 13:20:23 -07001735 ctx->ctx_crm_intf->notify_trigger(&notify);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001736 CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301737 ctx_isp->frame_id);
1738 } else {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001739 CAM_ERR(CAM_ISP, "Can not notify SOF to CRM");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301740 }
1741 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
1742 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
1743
1744 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_EPOCH;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001745 CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301746
1747 return 0;
1748error:
1749 /* Send SOF event as idle frame*/
1750 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
1751 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
1752
1753 /*
1754 * There is no request in the pending list, move the sub state machine
1755 * to SOF sub state
1756 */
1757 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
1758
1759 return 0;
1760}
1761
1762static struct cam_isp_ctx_irq_ops
1763 cam_isp_ctx_rdi_only_activated_state_machine_irq
1764 [CAM_ISP_CTX_ACTIVATED_MAX] = {
1765 /* SOF */
1766 {
1767 .irq_ops = {
1768 NULL,
1769 __cam_isp_ctx_rdi_only_sof_in_top_state,
1770 __cam_isp_ctx_reg_upd_in_sof,
1771 NULL,
1772 NULL,
1773 NULL,
1774 },
1775 },
1776 /* APPLIED */
1777 {
1778 .irq_ops = {
1779 __cam_isp_ctx_handle_error,
1780 __cam_isp_ctx_rdi_only_sof_in_applied_state,
1781 NULL,
1782 NULL,
1783 NULL,
1784 __cam_isp_ctx_buf_done_in_applied,
1785 },
1786 },
1787 /* EPOCH */
1788 {
1789 .irq_ops = {
1790 __cam_isp_ctx_handle_error,
1791 __cam_isp_ctx_rdi_only_sof_in_top_state,
1792 NULL,
1793 NULL,
1794 NULL,
1795 __cam_isp_ctx_buf_done_in_epoch,
1796 },
1797 },
1798 /* BUBBLE*/
1799 {
1800 .irq_ops = {
1801 __cam_isp_ctx_handle_error,
1802 __cam_isp_ctx_rdi_only_sof_in_bubble_state,
1803 NULL,
1804 NULL,
1805 NULL,
1806 __cam_isp_ctx_buf_done_in_bubble,
1807 },
1808 },
1809 /* BUBBLE APPLIED ie PRE_BUBBLE */
1810 {
1811 .irq_ops = {
1812 __cam_isp_ctx_handle_error,
1813 __cam_isp_ctx_rdi_only_sof_in_bubble_applied,
1814 __cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state,
1815 NULL,
1816 NULL,
1817 __cam_isp_ctx_buf_done_in_bubble_applied,
1818 },
1819 },
Jing Zhou4d4f03e2018-01-16 18:10:31 -08001820 /* HW ERROR */
1821 {
1822 },
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301823 /* HALT */
1824 {
1825 },
Jing Zhou4d4f03e2018-01-16 18:10:31 -08001826 /* FLUSH */
1827 {
1828 .irq_ops = {
1829 NULL,
1830 __cam_isp_ctx_sof_in_flush,
1831 NULL,
1832 NULL,
1833 NULL,
1834 __cam_isp_ctx_buf_done_in_applied,
1835 },
1836 },
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301837};
1838
1839static int __cam_isp_ctx_rdi_only_apply_req_top_state(
1840 struct cam_context *ctx, struct cam_req_mgr_apply_request *apply)
1841{
1842 int rc = 0;
1843 struct cam_isp_context *ctx_isp =
1844 (struct cam_isp_context *) ctx->ctx_priv;
1845
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001846 CAM_DBG(CAM_ISP, "current substate %d",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301847 ctx_isp->substate_activated);
1848 rc = __cam_isp_ctx_apply_req_in_activated_state(ctx, apply,
1849 CAM_ISP_CTX_ACTIVATED_APPLIED);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001850 CAM_DBG(CAM_ISP, "new substate %d", ctx_isp->substate_activated);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301851
1852 return rc;
1853}
1854
1855static struct cam_ctx_ops
1856 cam_isp_ctx_rdi_only_activated_state_machine
1857 [CAM_ISP_CTX_ACTIVATED_MAX] = {
1858 /* SOF */
1859 {
1860 .ioctl_ops = {},
1861 .crm_ops = {
1862 .apply_req = __cam_isp_ctx_rdi_only_apply_req_top_state,
1863 },
1864 .irq_ops = NULL,
1865 },
1866 /* APPLIED */
1867 {
1868 .ioctl_ops = {},
1869 .crm_ops = {},
1870 .irq_ops = NULL,
1871 },
1872 /* EPOCH */
1873 {
1874 .ioctl_ops = {},
1875 .crm_ops = {
1876 .apply_req = __cam_isp_ctx_rdi_only_apply_req_top_state,
1877 },
1878 .irq_ops = NULL,
1879 },
1880 /* PRE BUBBLE */
1881 {
1882 .ioctl_ops = {},
1883 .crm_ops = {},
1884 .irq_ops = NULL,
1885 },
1886 /* BUBBLE */
1887 {
1888 .ioctl_ops = {},
1889 .crm_ops = {},
1890 .irq_ops = NULL,
1891 },
Jing Zhou4d4f03e2018-01-16 18:10:31 -08001892 /* HW ERROR */
1893 {
1894 .ioctl_ops = {},
1895 .crm_ops = {},
1896 .irq_ops = NULL,
1897 },
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301898 /* HALT */
1899 {
1900 .ioctl_ops = {},
1901 .crm_ops = {},
1902 .irq_ops = NULL,
1903 },
Jing Zhou4d4f03e2018-01-16 18:10:31 -08001904 /* FLUSHED */
1905 {
1906 .ioctl_ops = {},
1907 .crm_ops = {},
1908 .irq_ops = NULL,
1909 },
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301910};
1911
Jing Zhoud352ed12017-03-20 23:59:56 -07001912/* top level state machine */
1913static int __cam_isp_ctx_release_dev_in_top_state(struct cam_context *ctx,
1914 struct cam_release_dev_cmd *cmd)
1915{
1916 int rc = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -07001917 struct cam_hw_release_args rel_arg;
Jing Zhoud352ed12017-03-20 23:59:56 -07001918 struct cam_isp_context *ctx_isp =
1919 (struct cam_isp_context *) ctx->ctx_priv;
Jing Zhoub524a852017-05-16 15:47:30 +05301920 struct cam_req_mgr_flush_request flush_req;
Jing Zhoud352ed12017-03-20 23:59:56 -07001921
1922 if (ctx_isp->hw_ctx) {
1923 rel_arg.ctxt_to_hw_map = ctx_isp->hw_ctx;
1924 ctx->hw_mgr_intf->hw_release(ctx->hw_mgr_intf->hw_mgr_priv,
1925 &rel_arg);
1926 ctx_isp->hw_ctx = NULL;
1927 }
1928
Soundrapandian Jeyaprakash8d16e272017-10-12 11:05:37 -07001929 ctx->session_hdl = -1;
1930 ctx->dev_hdl = -1;
1931 ctx->link_hdl = -1;
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001932 ctx->ctx_crm_intf = NULL;
Jing Zhoud352ed12017-03-20 23:59:56 -07001933 ctx_isp->frame_id = 0;
Jing Zhoudedc4762017-06-19 17:45:36 +05301934 ctx_isp->active_req_cnt = 0;
1935 ctx_isp->reported_req_id = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -07001936
1937 /*
1938 * Ideally, we should never have any active request here.
1939 * But we still add some sanity check code here to help the debug
1940 */
1941 if (!list_empty(&ctx->active_req_list))
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001942 CAM_ERR(CAM_ISP, "Active list is not empty");
Jing Zhoud352ed12017-03-20 23:59:56 -07001943
Jing Zhoub524a852017-05-16 15:47:30 +05301944 /* Flush all the pending request list */
1945 flush_req.type = CAM_REQ_MGR_FLUSH_TYPE_ALL;
1946 flush_req.link_hdl = ctx->link_hdl;
1947 flush_req.dev_hdl = ctx->dev_hdl;
1948
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001949 CAM_DBG(CAM_ISP, "try to flush pending list");
Jing Zhoub524a852017-05-16 15:47:30 +05301950 rc = __cam_isp_ctx_flush_req(ctx, &ctx->pending_req_list, &flush_req);
1951
Jing Zhoud352ed12017-03-20 23:59:56 -07001952 ctx->state = CAM_CTX_AVAILABLE;
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06001953
1954 trace_cam_context_state("ISP", ctx);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001955 CAM_DBG(CAM_ISP, "next state %d", ctx->state);
Jing Zhoud352ed12017-03-20 23:59:56 -07001956 return rc;
1957}
1958
1959static int __cam_isp_ctx_config_dev_in_top_state(
1960 struct cam_context *ctx, struct cam_config_dev_cmd *cmd)
1961{
1962 int rc = 0;
1963 struct cam_ctx_request *req = NULL;
1964 struct cam_isp_ctx_req *req_isp;
1965 uint64_t packet_addr;
1966 struct cam_packet *packet;
1967 size_t len = 0;
1968 struct cam_hw_prepare_update_args cfg;
1969 struct cam_req_mgr_add_request add_req;
1970 struct cam_isp_context *ctx_isp =
1971 (struct cam_isp_context *) ctx->ctx_priv;
1972
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001973 CAM_DBG(CAM_ISP, "get free request object......");
Jing Zhoud352ed12017-03-20 23:59:56 -07001974
1975 /* get free request */
Jing Zhou93b3ec12017-06-15 17:43:39 -07001976 spin_lock_bh(&ctx->lock);
Jing Zhoud352ed12017-03-20 23:59:56 -07001977 if (!list_empty(&ctx->free_req_list)) {
1978 req = list_first_entry(&ctx->free_req_list,
1979 struct cam_ctx_request, list);
1980 list_del_init(&req->list);
1981 }
Jing Zhou93b3ec12017-06-15 17:43:39 -07001982 spin_unlock_bh(&ctx->lock);
Jing Zhoud352ed12017-03-20 23:59:56 -07001983
1984 if (!req) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001985 CAM_ERR(CAM_ISP, "No more request obj free");
Jing Zhoud352ed12017-03-20 23:59:56 -07001986 rc = -ENOMEM;
1987 goto end;
1988 }
1989
1990 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
1991
1992 /* for config dev, only memory handle is supported */
1993 /* map packet from the memhandle */
1994 rc = cam_mem_get_cpu_buf((int32_t) cmd->packet_handle,
1995 (uint64_t *) &packet_addr, &len);
1996 if (rc != 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001997 CAM_ERR(CAM_ISP, "Can not get packet address");
Jing Zhoud352ed12017-03-20 23:59:56 -07001998 rc = -EINVAL;
1999 goto free_req;
2000 }
2001
2002 packet = (struct cam_packet *) (packet_addr + cmd->offset);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002003 CAM_DBG(CAM_ISP, "pack_handle %llx", cmd->packet_handle);
2004 CAM_DBG(CAM_ISP, "packet address is 0x%llx", packet_addr);
2005 CAM_DBG(CAM_ISP, "packet with length %zu, offset 0x%llx",
Jing Zhoud352ed12017-03-20 23:59:56 -07002006 len, cmd->offset);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002007 CAM_DBG(CAM_ISP, "Packet request id %lld",
Jing Zhoud352ed12017-03-20 23:59:56 -07002008 packet->header.request_id);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002009 CAM_DBG(CAM_ISP, "Packet size 0x%x", packet->header.size);
2010 CAM_DBG(CAM_ISP, "packet op %d", packet->header.op_code);
Jing Zhoud352ed12017-03-20 23:59:56 -07002011
2012 /* preprocess the configuration */
2013 memset(&cfg, 0, sizeof(cfg));
2014 cfg.packet = packet;
2015 cfg.ctxt_to_hw_map = ctx_isp->hw_ctx;
2016 cfg.max_hw_update_entries = CAM_ISP_CTX_CFG_MAX;
2017 cfg.hw_update_entries = req_isp->cfg;
2018 cfg.max_out_map_entries = CAM_ISP_CTX_RES_MAX;
2019 cfg.max_in_map_entries = CAM_ISP_CTX_RES_MAX;
2020 cfg.out_map_entries = req_isp->fence_map_out;
2021 cfg.in_map_entries = req_isp->fence_map_in;
Vishalsingh Hajerie5450be2018-01-18 20:31:19 -08002022 cfg.priv = &req_isp->hw_update_data;
Jing Zhoud352ed12017-03-20 23:59:56 -07002023
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002024 CAM_DBG(CAM_ISP, "try to prepare config packet......");
Jing Zhoud352ed12017-03-20 23:59:56 -07002025
2026 rc = ctx->hw_mgr_intf->hw_prepare_update(
2027 ctx->hw_mgr_intf->hw_mgr_priv, &cfg);
2028 if (rc != 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002029 CAM_ERR(CAM_ISP, "Prepare config packet failed in HW layer");
Jing Zhoud352ed12017-03-20 23:59:56 -07002030 rc = -EFAULT;
2031 goto free_req;
2032 }
2033 req_isp->num_cfg = cfg.num_hw_update_entries;
2034 req_isp->num_fence_map_out = cfg.num_out_map_entries;
2035 req_isp->num_fence_map_in = cfg.num_in_map_entries;
2036 req_isp->num_acked = 0;
2037
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002038 CAM_DBG(CAM_ISP, "num_entry: %d, num fence out: %d, num fence in: %d",
Ravikishore Pampana24f712e2017-11-13 23:09:30 +05302039 req_isp->num_cfg, req_isp->num_fence_map_out,
Jing Zhoud352ed12017-03-20 23:59:56 -07002040 req_isp->num_fence_map_in);
2041
2042 req->request_id = packet->header.request_id;
2043 req->status = 1;
2044
Ravikishore Pampana24f712e2017-11-13 23:09:30 +05302045 CAM_DBG(CAM_ISP, "Packet request id 0x%llx packet opcode:%d",
Vishalsingh Hajerie5450be2018-01-18 20:31:19 -08002046 packet->header.request_id,
2047 req_isp->hw_update_data.packet_opcode_type);
Ravikishore Pampana24f712e2017-11-13 23:09:30 +05302048
Vishalsingh Hajerie5450be2018-01-18 20:31:19 -08002049 if (req_isp->hw_update_data.packet_opcode_type ==
2050 CAM_ISP_PACKET_INIT_DEV) {
Ravikishore Pampana24f712e2017-11-13 23:09:30 +05302051 if (ctx->state < CAM_CTX_ACTIVATED) {
2052 rc = __cam_isp_ctx_enqueue_init_request(ctx, req);
2053 if (rc)
2054 CAM_ERR(CAM_ISP, "Enqueue INIT pkt failed");
2055 } else {
2056 rc = -EINVAL;
2057 CAM_ERR(CAM_ISP, "Recevied INIT pkt in wrong state");
2058 }
2059 } else {
2060 if (ctx->state >= CAM_CTX_READY && ctx->ctx_crm_intf->add_req) {
2061 add_req.link_hdl = ctx->link_hdl;
2062 add_req.dev_hdl = ctx->dev_hdl;
2063 add_req.req_id = req->request_id;
2064 add_req.skip_before_applying = 0;
2065 rc = ctx->ctx_crm_intf->add_req(&add_req);
2066 if (rc) {
2067 CAM_ERR(CAM_ISP, "Add req failed: req id=%llu",
2068 req->request_id);
2069 } else {
2070 __cam_isp_ctx_enqueue_request_in_order(
2071 ctx, req);
2072 }
2073 } else {
2074 rc = -EINVAL;
2075 CAM_ERR(CAM_ISP, "Recevied Update in wrong state");
Jing Zhoud352ed12017-03-20 23:59:56 -07002076 }
2077 }
Ravikishore Pampana24f712e2017-11-13 23:09:30 +05302078 if (rc)
2079 goto free_req;
Jing Zhoud352ed12017-03-20 23:59:56 -07002080
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002081 CAM_DBG(CAM_ISP, "Preprocessing Config %lld successful",
Jing Zhoud352ed12017-03-20 23:59:56 -07002082 req->request_id);
2083
2084 return rc;
2085
2086free_req:
Jing Zhou93b3ec12017-06-15 17:43:39 -07002087 spin_lock_bh(&ctx->lock);
Jing Zhoud352ed12017-03-20 23:59:56 -07002088 list_add_tail(&req->list, &ctx->free_req_list);
Jing Zhou93b3ec12017-06-15 17:43:39 -07002089 spin_unlock_bh(&ctx->lock);
Jing Zhoud352ed12017-03-20 23:59:56 -07002090end:
2091 return rc;
2092}
2093
2094static int __cam_isp_ctx_acquire_dev_in_available(struct cam_context *ctx,
2095 struct cam_acquire_dev_cmd *cmd)
2096{
2097 int rc = 0;
2098 struct cam_hw_acquire_args param;
2099 struct cam_isp_resource *isp_res = NULL;
2100 struct cam_create_dev_hdl req_hdl_param;
2101 struct cam_hw_release_args release;
2102 struct cam_isp_context *ctx_isp =
2103 (struct cam_isp_context *) ctx->ctx_priv;
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302104 struct cam_isp_hw_cmd_args hw_cmd_args;
Jing Zhoud352ed12017-03-20 23:59:56 -07002105
2106 if (!ctx->hw_mgr_intf) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002107 CAM_ERR(CAM_ISP, "HW interface is not ready");
Jing Zhoud352ed12017-03-20 23:59:56 -07002108 rc = -EFAULT;
2109 goto end;
2110 }
2111
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002112 CAM_DBG(CAM_ISP,
2113 "session_hdl 0x%x, num_resources %d, hdl type %d, res %lld",
2114 cmd->session_handle, cmd->num_resources,
Jing Zhoud352ed12017-03-20 23:59:56 -07002115 cmd->handle_type, cmd->resource_hdl);
2116
2117 if (cmd->num_resources > CAM_ISP_CTX_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002118 CAM_ERR(CAM_ISP, "Too much resources in the acquire");
Jing Zhoud352ed12017-03-20 23:59:56 -07002119 rc = -ENOMEM;
2120 goto end;
2121 }
2122
2123 /* for now we only support user pointer */
2124 if (cmd->handle_type != 1) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002125 CAM_ERR(CAM_ISP, "Only user pointer is supported");
Jing Zhoud352ed12017-03-20 23:59:56 -07002126 rc = -EINVAL;
2127 goto end;
2128 }
2129
2130 isp_res = kzalloc(
2131 sizeof(*isp_res)*cmd->num_resources, GFP_KERNEL);
2132 if (!isp_res) {
2133 rc = -ENOMEM;
2134 goto end;
2135 }
2136
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002137 CAM_DBG(CAM_ISP, "start copy %d resources from user",
2138 cmd->num_resources);
Jing Zhoud352ed12017-03-20 23:59:56 -07002139
2140 if (copy_from_user(isp_res, (void __user *)cmd->resource_hdl,
2141 sizeof(*isp_res)*cmd->num_resources)) {
2142 rc = -EFAULT;
2143 goto free_res;
2144 }
2145
2146 param.context_data = ctx;
2147 param.event_cb = ctx->irq_cb_intf;
2148 param.num_acq = cmd->num_resources;
2149 param.acquire_info = (uint64_t) isp_res;
2150
2151 /* call HW manager to reserve the resource */
2152 rc = ctx->hw_mgr_intf->hw_acquire(ctx->hw_mgr_intf->hw_mgr_priv,
2153 &param);
2154 if (rc != 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002155 CAM_ERR(CAM_ISP, "Acquire device failed");
Jing Zhoud352ed12017-03-20 23:59:56 -07002156 goto free_res;
2157 }
2158
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302159 /* Query the context has rdi only resource */
2160 hw_cmd_args.ctxt_to_hw_map = param.ctxt_to_hw_map;
2161 hw_cmd_args.cmd_type = CAM_ISP_HW_MGR_CMD_IS_RDI_ONLY_CONTEXT;
2162 rc = ctx->hw_mgr_intf->hw_cmd(ctx->hw_mgr_intf->hw_mgr_priv,
2163 &hw_cmd_args);
2164 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002165 CAM_ERR(CAM_ISP, "HW command failed");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302166 goto free_hw;
2167 }
2168
2169 if (hw_cmd_args.u.is_rdi_only_context) {
2170 /*
2171 * this context has rdi only resource assign rdi only
2172 * state machine
2173 */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002174 CAM_DBG(CAM_ISP, "RDI only session Context");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302175
2176 ctx_isp->substate_machine_irq =
2177 cam_isp_ctx_rdi_only_activated_state_machine_irq;
2178 ctx_isp->substate_machine =
2179 cam_isp_ctx_rdi_only_activated_state_machine;
2180 } else {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002181 CAM_DBG(CAM_ISP, "Session has PIX or PIX and RDI resources");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302182 ctx_isp->substate_machine_irq =
2183 cam_isp_ctx_activated_state_machine_irq;
2184 ctx_isp->substate_machine =
2185 cam_isp_ctx_activated_state_machine;
2186 }
2187
Jing Zhoud352ed12017-03-20 23:59:56 -07002188 ctx_isp->hw_ctx = param.ctxt_to_hw_map;
2189
2190 req_hdl_param.session_hdl = cmd->session_handle;
2191 /* bridge is not ready for these flags. so false for now */
2192 req_hdl_param.v4l2_sub_dev_flag = 0;
2193 req_hdl_param.media_entity_flag = 0;
2194 req_hdl_param.ops = ctx->crm_ctx_intf;
2195 req_hdl_param.priv = ctx;
2196
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002197 CAM_DBG(CAM_ISP, "get device handle form bridge");
Jing Zhoud352ed12017-03-20 23:59:56 -07002198 ctx->dev_hdl = cam_create_device_hdl(&req_hdl_param);
2199 if (ctx->dev_hdl <= 0) {
2200 rc = -EFAULT;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002201 CAM_ERR(CAM_ISP, "Can not create device handle");
Jing Zhoud352ed12017-03-20 23:59:56 -07002202 goto free_hw;
2203 }
2204 cmd->dev_handle = ctx->dev_hdl;
2205
2206 /* store session information */
2207 ctx->session_hdl = cmd->session_handle;
2208
2209 ctx->state = CAM_CTX_ACQUIRED;
2210
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06002211 trace_cam_context_state("ISP", ctx);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002212 CAM_DBG(CAM_ISP, "Acquire success.");
Jing Zhoud352ed12017-03-20 23:59:56 -07002213 kfree(isp_res);
2214 return rc;
2215
2216free_hw:
2217 release.ctxt_to_hw_map = ctx_isp->hw_ctx;
2218 ctx->hw_mgr_intf->hw_release(ctx->hw_mgr_intf->hw_mgr_priv, &release);
2219 ctx_isp->hw_ctx = NULL;
2220free_res:
2221 kfree(isp_res);
2222end:
2223 return rc;
2224}
2225
2226static int __cam_isp_ctx_config_dev_in_acquired(struct cam_context *ctx,
2227 struct cam_config_dev_cmd *cmd)
2228{
2229 int rc = 0;
2230
2231 rc = __cam_isp_ctx_config_dev_in_top_state(ctx, cmd);
2232
Karthik Anantha Ram34dc2652017-10-20 15:49:54 -07002233 if (!rc && (ctx->link_hdl >= 0)) {
Jing Zhoud352ed12017-03-20 23:59:56 -07002234 ctx->state = CAM_CTX_READY;
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06002235 trace_cam_context_state("ISP", ctx);
2236 }
Jing Zhoud352ed12017-03-20 23:59:56 -07002237
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002238 CAM_DBG(CAM_ISP, "next state %d", ctx->state);
Jing Zhoud352ed12017-03-20 23:59:56 -07002239 return rc;
2240}
2241
2242static int __cam_isp_ctx_link_in_acquired(struct cam_context *ctx,
2243 struct cam_req_mgr_core_dev_link_setup *link)
2244{
2245 int rc = 0;
Junzhe Zou2df84502017-05-26 13:20:23 -07002246 struct cam_isp_context *ctx_isp =
2247 (struct cam_isp_context *) ctx->ctx_priv;
Jing Zhoud352ed12017-03-20 23:59:56 -07002248
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002249 CAM_DBG(CAM_ISP, "Enter.........");
Jing Zhoud352ed12017-03-20 23:59:56 -07002250
2251 ctx->link_hdl = link->link_hdl;
2252 ctx->ctx_crm_intf = link->crm_cb;
Junzhe Zou2df84502017-05-26 13:20:23 -07002253 ctx_isp->subscribe_event = link->subscribe_event;
Jing Zhoud352ed12017-03-20 23:59:56 -07002254
2255 /* change state only if we had the init config */
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06002256 if (!list_empty(&ctx->pending_req_list)) {
Jing Zhoud352ed12017-03-20 23:59:56 -07002257 ctx->state = CAM_CTX_READY;
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06002258 trace_cam_context_state("ISP", ctx);
2259 }
Jing Zhoud352ed12017-03-20 23:59:56 -07002260
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002261 CAM_DBG(CAM_ISP, "next state %d", ctx->state);
Jing Zhoud352ed12017-03-20 23:59:56 -07002262
2263 return rc;
2264}
2265
2266static int __cam_isp_ctx_unlink_in_acquired(struct cam_context *ctx,
2267 struct cam_req_mgr_core_dev_link_setup *unlink)
2268{
2269 int rc = 0;
2270
Karthik Anantha Ram34dc2652017-10-20 15:49:54 -07002271 ctx->link_hdl = -1;
Jing Zhoud352ed12017-03-20 23:59:56 -07002272 ctx->ctx_crm_intf = NULL;
2273
2274 return rc;
2275}
2276
2277static int __cam_isp_ctx_get_dev_info_in_acquired(struct cam_context *ctx,
2278 struct cam_req_mgr_device_info *dev_info)
2279{
2280 int rc = 0;
2281
2282 dev_info->dev_hdl = ctx->dev_hdl;
2283 strlcpy(dev_info->name, CAM_ISP_DEV_NAME, sizeof(dev_info->name));
2284 dev_info->dev_id = CAM_REQ_MGR_DEVICE_IFE;
2285 dev_info->p_delay = 1;
Junzhe Zou2df84502017-05-26 13:20:23 -07002286 dev_info->trigger = CAM_TRIGGER_POINT_SOF;
Jing Zhoud352ed12017-03-20 23:59:56 -07002287
2288 return rc;
2289}
2290
2291static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx,
2292 struct cam_start_stop_dev_cmd *cmd)
2293{
2294 int rc = 0;
Vishalsingh Hajerie5450be2018-01-18 20:31:19 -08002295 struct cam_hw_config_args arg;
Jing Zhoud352ed12017-03-20 23:59:56 -07002296 struct cam_ctx_request *req;
2297 struct cam_isp_ctx_req *req_isp;
2298 struct cam_isp_context *ctx_isp =
2299 (struct cam_isp_context *) ctx->ctx_priv;
2300
2301 if (cmd->session_handle != ctx->session_hdl ||
2302 cmd->dev_handle != ctx->dev_hdl) {
2303 rc = -EPERM;
2304 goto end;
2305 }
2306
2307 if (list_empty(&ctx->pending_req_list)) {
2308 /* should never happen */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002309 CAM_ERR(CAM_ISP, "Start device with empty configuration");
Jing Zhoud352ed12017-03-20 23:59:56 -07002310 rc = -EFAULT;
2311 goto end;
2312 } else {
2313 req = list_first_entry(&ctx->pending_req_list,
2314 struct cam_ctx_request, list);
2315 }
2316 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
2317
2318 if (!ctx_isp->hw_ctx) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002319 CAM_ERR(CAM_ISP, "Wrong hw context pointer.");
Jing Zhoud352ed12017-03-20 23:59:56 -07002320 rc = -EFAULT;
2321 goto end;
2322 }
Vishalsingh Hajerie5450be2018-01-18 20:31:19 -08002323
Jing Zhoud352ed12017-03-20 23:59:56 -07002324 arg.ctxt_to_hw_map = ctx_isp->hw_ctx;
Venkat Chintad983df82018-03-14 12:54:40 -07002325 arg.request_id = req->request_id;
Jing Zhoud352ed12017-03-20 23:59:56 -07002326 arg.hw_update_entries = req_isp->cfg;
2327 arg.num_hw_update_entries = req_isp->num_cfg;
Vishalsingh Hajerie5450be2018-01-18 20:31:19 -08002328 arg.priv = &req_isp->hw_update_data;
Jing Zhoud352ed12017-03-20 23:59:56 -07002329
2330 ctx_isp->frame_id = 0;
Jing Zhoudedc4762017-06-19 17:45:36 +05302331 ctx_isp->active_req_cnt = 0;
2332 ctx_isp->reported_req_id = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -07002333 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
2334
2335 /*
2336 * Only place to change state before calling the hw due to
2337 * hardware tasklet has higher priority that can cause the
2338 * irq handling comes early
2339 */
2340 ctx->state = CAM_CTX_ACTIVATED;
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06002341 trace_cam_context_state("ISP", ctx);
Jing Zhoud352ed12017-03-20 23:59:56 -07002342 rc = ctx->hw_mgr_intf->hw_start(ctx->hw_mgr_intf->hw_mgr_priv, &arg);
2343 if (rc) {
2344 /* HW failure. user need to clean up the resource */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002345 CAM_ERR(CAM_ISP, "Start HW failed");
Jing Zhoud352ed12017-03-20 23:59:56 -07002346 ctx->state = CAM_CTX_READY;
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06002347 trace_cam_context_state("ISP", ctx);
Jing Zhoud352ed12017-03-20 23:59:56 -07002348 goto end;
2349 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002350 CAM_DBG(CAM_ISP, "start device success");
Jing Zhoud352ed12017-03-20 23:59:56 -07002351end:
2352 return rc;
2353}
2354
2355static int __cam_isp_ctx_unlink_in_ready(struct cam_context *ctx,
2356 struct cam_req_mgr_core_dev_link_setup *unlink)
2357{
2358 int rc = 0;
2359
Karthik Anantha Ram34dc2652017-10-20 15:49:54 -07002360 ctx->link_hdl = -1;
Jing Zhoud352ed12017-03-20 23:59:56 -07002361 ctx->ctx_crm_intf = NULL;
2362 ctx->state = CAM_CTX_ACQUIRED;
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06002363 trace_cam_context_state("ISP", ctx);
Jing Zhoud352ed12017-03-20 23:59:56 -07002364
2365 return rc;
2366}
2367
2368static int __cam_isp_ctx_stop_dev_in_activated_unlock(
Ravikishore Pampanaf7c7fd02018-02-02 18:11:38 +05302369 struct cam_context *ctx, struct cam_start_stop_dev_cmd *stop_cmd)
Jing Zhoud352ed12017-03-20 23:59:56 -07002370{
2371 int rc = 0;
2372 uint32_t i;
2373 struct cam_hw_stop_args stop;
2374 struct cam_ctx_request *req;
2375 struct cam_isp_ctx_req *req_isp;
2376 struct cam_isp_context *ctx_isp =
2377 (struct cam_isp_context *) ctx->ctx_priv;
2378
2379 /* Mask off all the incoming hardware events */
Jing Zhou93b3ec12017-06-15 17:43:39 -07002380 spin_lock_bh(&ctx->lock);
Jing Zhoud352ed12017-03-20 23:59:56 -07002381 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_HALT;
Jing Zhou93b3ec12017-06-15 17:43:39 -07002382 spin_unlock_bh(&ctx->lock);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002383 CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated);
Jing Zhoud352ed12017-03-20 23:59:56 -07002384
2385 /* stop hw first */
2386 if (ctx_isp->hw_ctx) {
2387 stop.ctxt_to_hw_map = ctx_isp->hw_ctx;
Ravikishore Pampanaf7c7fd02018-02-02 18:11:38 +05302388 stop.args = stop_cmd;
Jing Zhoud352ed12017-03-20 23:59:56 -07002389 ctx->hw_mgr_intf->hw_stop(ctx->hw_mgr_intf->hw_mgr_priv,
2390 &stop);
2391 }
2392
2393 while (!list_empty(&ctx->pending_req_list)) {
2394 req = list_first_entry(&ctx->pending_req_list,
2395 struct cam_ctx_request, list);
2396 list_del_init(&req->list);
2397 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002398 CAM_DBG(CAM_ISP, "signal fence in pending list. fence num %d",
2399 req_isp->num_fence_map_out);
Jing Zhoud352ed12017-03-20 23:59:56 -07002400 for (i = 0; i < req_isp->num_fence_map_out; i++)
2401 if (req_isp->fence_map_out[i].sync_id != -1) {
2402 cam_sync_signal(
2403 req_isp->fence_map_out[i].sync_id,
2404 CAM_SYNC_STATE_SIGNALED_ERROR);
2405 }
2406 list_add_tail(&req->list, &ctx->free_req_list);
2407 }
2408
2409 while (!list_empty(&ctx->active_req_list)) {
2410 req = list_first_entry(&ctx->active_req_list,
2411 struct cam_ctx_request, list);
2412 list_del_init(&req->list);
2413 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002414 CAM_DBG(CAM_ISP, "signal fence in active list. fence num %d",
2415 req_isp->num_fence_map_out);
Jing Zhoud352ed12017-03-20 23:59:56 -07002416 for (i = 0; i < req_isp->num_fence_map_out; i++)
2417 if (req_isp->fence_map_out[i].sync_id != -1) {
2418 cam_sync_signal(
2419 req_isp->fence_map_out[i].sync_id,
2420 CAM_SYNC_STATE_SIGNALED_ERROR);
2421 }
2422 list_add_tail(&req->list, &ctx->free_req_list);
2423 }
2424 ctx_isp->frame_id = 0;
Jing Zhoudedc4762017-06-19 17:45:36 +05302425 ctx_isp->active_req_cnt = 0;
2426 ctx_isp->reported_req_id = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -07002427
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002428 CAM_DBG(CAM_ISP, "next state %d", ctx->state);
Jing Zhoud352ed12017-03-20 23:59:56 -07002429 return rc;
2430}
2431
2432static int __cam_isp_ctx_stop_dev_in_activated(struct cam_context *ctx,
2433 struct cam_start_stop_dev_cmd *cmd)
2434{
2435 int rc = 0;
2436
Ravikishore Pampanaf7c7fd02018-02-02 18:11:38 +05302437 __cam_isp_ctx_stop_dev_in_activated_unlock(ctx, cmd);
Jing Zhoud352ed12017-03-20 23:59:56 -07002438 ctx->state = CAM_CTX_ACQUIRED;
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06002439 trace_cam_context_state("ISP", ctx);
Jing Zhoud352ed12017-03-20 23:59:56 -07002440 return rc;
2441}
2442
2443static int __cam_isp_ctx_release_dev_in_activated(struct cam_context *ctx,
2444 struct cam_release_dev_cmd *cmd)
2445{
2446 int rc = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -07002447
Ravikishore Pampanaf7c7fd02018-02-02 18:11:38 +05302448 rc = __cam_isp_ctx_stop_dev_in_activated_unlock(ctx, NULL);
Harsh Shah2d96c5e2017-09-29 11:58:45 -07002449 if (rc)
2450 CAM_ERR(CAM_ISP, "Stop device failed rc=%d", rc);
Jing Zhoud352ed12017-03-20 23:59:56 -07002451
Harsh Shah2d96c5e2017-09-29 11:58:45 -07002452 rc = __cam_isp_ctx_release_dev_in_top_state(ctx, cmd);
2453 if (rc)
2454 CAM_ERR(CAM_ISP, "Release device failed rc=%d", rc);
Jing Zhoud352ed12017-03-20 23:59:56 -07002455
2456 return rc;
2457}
2458
Jing Zhou30504bd2017-11-21 11:36:07 -08002459static int __cam_isp_ctx_link_pause(struct cam_context *ctx)
2460{
2461 int rc = 0;
2462 struct cam_isp_hw_cmd_args hw_cmd_args;
2463 struct cam_isp_context *ctx_isp =
2464 (struct cam_isp_context *) ctx->ctx_priv;
2465
2466 hw_cmd_args.ctxt_to_hw_map = ctx_isp->hw_ctx;
2467 hw_cmd_args.cmd_type = CAM_ISP_HW_MGR_CMD_PAUSE_HW;
2468 rc = ctx->hw_mgr_intf->hw_cmd(ctx->hw_mgr_intf->hw_mgr_priv,
2469 &hw_cmd_args);
2470
2471 return rc;
2472}
2473
2474static int __cam_isp_ctx_link_resume(struct cam_context *ctx)
2475{
2476 int rc = 0;
2477 struct cam_isp_hw_cmd_args hw_cmd_args;
2478 struct cam_isp_context *ctx_isp =
2479 (struct cam_isp_context *) ctx->ctx_priv;
2480
2481 hw_cmd_args.ctxt_to_hw_map = ctx_isp->hw_ctx;
2482 hw_cmd_args.cmd_type = CAM_ISP_HW_MGR_CMD_RESUME_HW;
2483 rc = ctx->hw_mgr_intf->hw_cmd(ctx->hw_mgr_intf->hw_mgr_priv,
2484 &hw_cmd_args);
2485
2486 return rc;
2487}
2488
2489static int __cam_isp_ctx_process_evt(struct cam_context *ctx,
2490 struct cam_req_mgr_link_evt_data *link_evt_data)
2491{
2492 int rc = 0;
2493
2494 switch (link_evt_data->evt_type) {
2495 case CAM_REQ_MGR_LINK_EVT_ERR:
2496 /* No need to handle this message now */
2497 break;
2498 case CAM_REQ_MGR_LINK_EVT_PAUSE:
2499 __cam_isp_ctx_link_pause(ctx);
2500 break;
2501 case CAM_REQ_MGR_LINK_EVT_RESUME:
2502 __cam_isp_ctx_link_resume(ctx);
2503 break;
2504 default:
2505 CAM_WARN(CAM_ISP, "Unknown event from CRM");
2506 break;
2507 }
2508 return rc;
2509}
2510
Harsh Shah6e4bc932017-11-07 06:15:12 -08002511static int __cam_isp_ctx_unlink_in_activated(struct cam_context *ctx,
2512 struct cam_req_mgr_core_dev_link_setup *unlink)
2513{
2514 int rc = 0;
2515
2516 CAM_WARN(CAM_ISP,
2517 "Received unlink in activated state. It's unexpected");
Ravikishore Pampanaf7c7fd02018-02-02 18:11:38 +05302518
2519 rc = __cam_isp_ctx_stop_dev_in_activated_unlock(ctx, NULL);
Harsh Shah6e4bc932017-11-07 06:15:12 -08002520 if (rc)
2521 CAM_WARN(CAM_ISP, "Stop device failed rc=%d", rc);
2522
2523 rc = __cam_isp_ctx_unlink_in_ready(ctx, unlink);
2524 if (rc)
2525 CAM_ERR(CAM_ISP, "Unlink failed rc=%d", rc);
2526
2527 return rc;
2528}
2529
Jing Zhoud352ed12017-03-20 23:59:56 -07002530static int __cam_isp_ctx_apply_req(struct cam_context *ctx,
2531 struct cam_req_mgr_apply_request *apply)
2532{
2533 int rc = 0;
Vishalsingh Hajeri7a431b72018-03-01 14:07:24 -08002534 struct cam_ctx_ops *ctx_ops = NULL;
Jing Zhoud352ed12017-03-20 23:59:56 -07002535 struct cam_isp_context *ctx_isp =
2536 (struct cam_isp_context *) ctx->ctx_priv;
2537
Junzhe Zou5fa08b12017-08-15 10:08:12 -07002538 trace_cam_apply_req("ISP", apply->request_id);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002539 CAM_DBG(CAM_ISP, "Enter: apply req in Substate %d request _id:%lld",
2540 ctx_isp->substate_activated, apply->request_id);
Vishalsingh Hajeri7a431b72018-03-01 14:07:24 -08002541 ctx_ops = &ctx_isp->substate_machine[ctx_isp->substate_activated];
2542 if (ctx_ops->crm_ops.apply_req) {
2543 rc = ctx_ops->crm_ops.apply_req(ctx, apply);
Jing Zhoud352ed12017-03-20 23:59:56 -07002544 } else {
Harsh Shahcb0072c2017-09-26 19:22:10 -07002545 CAM_ERR_RATE_LIMIT(CAM_ISP,
2546 "No handle function in activated substate %d",
2547 ctx_isp->substate_activated);
Jing Zhoud352ed12017-03-20 23:59:56 -07002548 rc = -EFAULT;
2549 }
2550
2551 if (rc)
Harsh Shahcb0072c2017-09-26 19:22:10 -07002552 CAM_ERR_RATE_LIMIT(CAM_ISP,
2553 "Apply failed in active substate %d",
2554 ctx_isp->substate_activated);
Jing Zhoud352ed12017-03-20 23:59:56 -07002555 return rc;
2556}
2557
2558
2559
2560static int __cam_isp_ctx_handle_irq_in_activated(void *context,
2561 uint32_t evt_id, void *evt_data)
2562{
2563 int rc = 0;
Vishalsingh Hajeri7a431b72018-03-01 14:07:24 -08002564 struct cam_isp_ctx_irq_ops *irq_ops = NULL;
Jing Zhoud352ed12017-03-20 23:59:56 -07002565 struct cam_context *ctx = (struct cam_context *)context;
2566 struct cam_isp_context *ctx_isp =
2567 (struct cam_isp_context *)ctx->ctx_priv;
2568
Jing Zhou93b3ec12017-06-15 17:43:39 -07002569 spin_lock_bh(&ctx->lock);
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06002570
2571 trace_cam_isp_activated_irq(ctx, ctx_isp->substate_activated, evt_id,
2572 __cam_isp_ctx_get_event_ts(evt_id, evt_data));
2573
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002574 CAM_DBG(CAM_ISP, "Enter: State %d, Substate %d, evt id %d",
2575 ctx->state, ctx_isp->substate_activated, evt_id);
Vishalsingh Hajeri7a431b72018-03-01 14:07:24 -08002576 irq_ops = &ctx_isp->substate_machine_irq[ctx_isp->substate_activated];
2577 if (irq_ops->irq_ops[evt_id]) {
2578 rc = irq_ops->irq_ops[evt_id](ctx_isp, evt_data);
Jing Zhoud352ed12017-03-20 23:59:56 -07002579 } else {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002580 CAM_DBG(CAM_ISP, "No handle function for substate %d",
Jing Zhoud352ed12017-03-20 23:59:56 -07002581 ctx_isp->substate_activated);
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -07002582 __cam_isp_ctx_dump_state_monitor_array(ctx_isp);
Jing Zhoud352ed12017-03-20 23:59:56 -07002583 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002584 CAM_DBG(CAM_ISP, "Exit: State %d Substate %d",
2585 ctx->state, ctx_isp->substate_activated);
Jing Zhou93b3ec12017-06-15 17:43:39 -07002586 spin_unlock_bh(&ctx->lock);
Jing Zhoud352ed12017-03-20 23:59:56 -07002587 return rc;
2588}
2589
2590/* top state machine */
2591static struct cam_ctx_ops
2592 cam_isp_ctx_top_state_machine[CAM_CTX_STATE_MAX] = {
2593 /* Uninit */
2594 {
2595 .ioctl_ops = {},
2596 .crm_ops = {},
2597 .irq_ops = NULL,
2598 },
2599 /* Available */
2600 {
2601 .ioctl_ops = {
2602 .acquire_dev = __cam_isp_ctx_acquire_dev_in_available,
2603 },
2604 .crm_ops = {},
2605 .irq_ops = NULL,
2606 },
2607 /* Acquired */
2608 {
2609 .ioctl_ops = {
2610 .release_dev = __cam_isp_ctx_release_dev_in_top_state,
2611 .config_dev = __cam_isp_ctx_config_dev_in_acquired,
2612 },
2613 .crm_ops = {
2614 .link = __cam_isp_ctx_link_in_acquired,
2615 .unlink = __cam_isp_ctx_unlink_in_acquired,
2616 .get_dev_info = __cam_isp_ctx_get_dev_info_in_acquired,
Jing Zhoub524a852017-05-16 15:47:30 +05302617 .flush_req = __cam_isp_ctx_flush_req_in_top_state,
Jing Zhoud352ed12017-03-20 23:59:56 -07002618 },
2619 .irq_ops = NULL,
2620 },
2621 /* Ready */
2622 {
2623 .ioctl_ops = {
2624 .start_dev = __cam_isp_ctx_start_dev_in_ready,
2625 .release_dev = __cam_isp_ctx_release_dev_in_top_state,
2626 .config_dev = __cam_isp_ctx_config_dev_in_top_state,
2627 },
2628 .crm_ops = {
2629 .unlink = __cam_isp_ctx_unlink_in_ready,
Jing Zhoub524a852017-05-16 15:47:30 +05302630 .flush_req = __cam_isp_ctx_flush_req_in_ready,
Jing Zhoud352ed12017-03-20 23:59:56 -07002631 },
2632 .irq_ops = NULL,
2633 },
2634 /* Activated */
2635 {
2636 .ioctl_ops = {
2637 .stop_dev = __cam_isp_ctx_stop_dev_in_activated,
2638 .release_dev = __cam_isp_ctx_release_dev_in_activated,
2639 .config_dev = __cam_isp_ctx_config_dev_in_top_state,
2640 },
2641 .crm_ops = {
Harsh Shah6e4bc932017-11-07 06:15:12 -08002642 .unlink = __cam_isp_ctx_unlink_in_activated,
Jing Zhoud352ed12017-03-20 23:59:56 -07002643 .apply_req = __cam_isp_ctx_apply_req,
Jing Zhou4d4f03e2018-01-16 18:10:31 -08002644 .flush_req = __cam_isp_ctx_flush_req_in_activated,
Jing Zhou30504bd2017-11-21 11:36:07 -08002645 .process_evt = __cam_isp_ctx_process_evt,
Jing Zhoud352ed12017-03-20 23:59:56 -07002646 },
2647 .irq_ops = __cam_isp_ctx_handle_irq_in_activated,
2648 },
2649};
2650
2651
2652int cam_isp_context_init(struct cam_isp_context *ctx,
2653 struct cam_context *ctx_base,
2654 struct cam_req_mgr_kmd_ops *crm_node_intf,
Pavan Kumar Chilamkurthi96fd3c92018-01-25 14:16:57 -08002655 struct cam_hw_mgr_intf *hw_intf,
2656 uint32_t ctx_id)
Jing Zhoud352ed12017-03-20 23:59:56 -07002657
2658{
2659 int rc = -1;
2660 int i;
2661
2662 if (!ctx || !ctx_base) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002663 CAM_ERR(CAM_ISP, "Invalid Context");
Jing Zhoud352ed12017-03-20 23:59:56 -07002664 goto err;
2665 }
2666
2667 /* ISP context setup */
2668 memset(ctx, 0, sizeof(*ctx));
2669
2670 ctx->base = ctx_base;
2671 ctx->frame_id = 0;
Jing Zhoudedc4762017-06-19 17:45:36 +05302672 ctx->active_req_cnt = 0;
2673 ctx->reported_req_id = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -07002674 ctx->hw_ctx = NULL;
2675 ctx->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
2676 ctx->substate_machine = cam_isp_ctx_activated_state_machine;
2677 ctx->substate_machine_irq = cam_isp_ctx_activated_state_machine_irq;
2678
2679 for (i = 0; i < CAM_CTX_REQ_MAX; i++) {
2680 ctx->req_base[i].req_priv = &ctx->req_isp[i];
2681 ctx->req_isp[i].base = &ctx->req_base[i];
2682 }
2683
2684 /* camera context setup */
Pavan Kumar Chilamkurthi96fd3c92018-01-25 14:16:57 -08002685 rc = cam_context_init(ctx_base, isp_dev_name, CAM_ISP, ctx_id,
2686 crm_node_intf, hw_intf, ctx->req_base, CAM_CTX_REQ_MAX);
Jing Zhoud352ed12017-03-20 23:59:56 -07002687 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002688 CAM_ERR(CAM_ISP, "Camera Context Base init failed");
Jing Zhoud352ed12017-03-20 23:59:56 -07002689 goto err;
2690 }
2691
2692 /* link camera context with isp context */
2693 ctx_base->state_machine = cam_isp_ctx_top_state_machine;
2694 ctx_base->ctx_priv = ctx;
2695
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -07002696 /* initializing current state for error logging */
2697 for (i = 0; i < CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES; i++) {
2698 ctx->cam_isp_ctx_state_monitor[i].curr_state =
2699 CAM_ISP_CTX_ACTIVATED_MAX;
2700 }
2701 atomic64_set(&ctx->state_monitor_head, -1);
Jing Zhoud352ed12017-03-20 23:59:56 -07002702err:
2703 return rc;
2704}
2705
2706int cam_isp_context_deinit(struct cam_isp_context *ctx)
2707{
2708 int rc = 0;
2709
2710 if (ctx->base)
2711 cam_context_deinit(ctx->base);
2712
2713 if (ctx->substate_activated != CAM_ISP_CTX_ACTIVATED_SOF)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002714 CAM_ERR(CAM_ISP, "ISP context substate is invalid");
Jing Zhoud352ed12017-03-20 23:59:56 -07002715
2716 memset(ctx, 0, sizeof(*ctx));
2717 return rc;
2718}