blob: a506ff4676c4f7ca2565311f07719fe18b5bab2f [file] [log] [blame]
Shravya Samala43583ea2020-04-29 14:25:37 +05301/* Copyright (c) 2017-2020, 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"
Suraj Dongre26811922018-06-27 19:30:01 -070026#include "cam_packet_util.h"
27#include "cam_context_utils.h"
Trishansh Bhardwaj0508a772018-10-01 12:32:49 +053028#include "cam_common_util.h"
Jing Zhoud352ed12017-03-20 23:59:56 -070029
Rishabh Jaindbcea3a2019-03-15 12:46:51 +053030static const char isp_dev_name[] = "cam-isp";
Suraj Dongre26811922018-06-27 19:30:01 -070031
32static int cam_isp_context_dump_active_request(void *data, unsigned long iova,
33 uint32_t buf_info);
34
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -070035static void __cam_isp_ctx_update_state_monitor_array(
36 struct cam_isp_context *ctx_isp,
37 enum cam_isp_state_change_trigger trigger_type,
38 uint32_t req_id)
39{
Alok Pandey6a9a5c32018-07-27 13:39:03 +053040 uint64_t iterator = 0;
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -070041
Alok Pandey6a9a5c32018-07-27 13:39:03 +053042 div64_u64_rem(atomic64_add_return(1, &ctx_isp->state_monitor_head),
43 CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES, &iterator);
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -070044 ctx_isp->cam_isp_ctx_state_monitor[iterator].curr_state =
45 ctx_isp->substate_activated;
46 ctx_isp->cam_isp_ctx_state_monitor[iterator].trigger =
47 trigger_type;
48 ctx_isp->cam_isp_ctx_state_monitor[iterator].req_id =
49 req_id;
50 ctx_isp->cam_isp_ctx_state_monitor[iterator].evt_time_stamp =
51 jiffies_to_msecs(jiffies);
52}
53
54static const char *__cam_isp_ctx_substate_val_to_type(
55 uint32_t type)
56{
57 switch (type) {
58 case CAM_ISP_CTX_ACTIVATED_SOF:
59 return "SOF";
60 case CAM_ISP_CTX_ACTIVATED_APPLIED:
61 return "APPLIED";
62 case CAM_ISP_CTX_ACTIVATED_EPOCH:
63 return "EPOCH";
64 case CAM_ISP_CTX_ACTIVATED_BUBBLE:
65 return "BUBBLE";
66 case CAM_ISP_CTX_ACTIVATED_BUBBLE_APPLIED:
67 return "BUBBLE_APPLIED";
68 case CAM_ISP_CTX_ACTIVATED_HALT:
69 return "HALT";
70 default:
71 return "CAM_ISP_CTX_INVALID_STATE";
72 }
73}
74
75static const char *__cam_isp_hw_evt_val_to_type(
76 uint32_t evt_id)
77{
78 switch (evt_id) {
79 case CAM_ISP_STATE_CHANGE_TRIGGER_ERROR:
80 return "ERROR";
81 case CAM_ISP_STATE_CHANGE_TRIGGER_SOF:
82 return "SOF";
83 case CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE:
84 return "REG_UPDATE";
85 case CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH:
86 return "EPOCH";
87 case CAM_ISP_STATE_CHANGE_TRIGGER_EOF:
88 return "EOF";
89 case CAM_ISP_STATE_CHANGE_TRIGGER_DONE:
90 return "DONE";
91 default:
92 return "CAM_ISP_EVENT_INVALID";
93 }
94}
95
96static void __cam_isp_ctx_dump_state_monitor_array(
97 struct cam_isp_context *ctx_isp)
98{
99 int i = 0;
100 uint64_t state_head = 0;
101 uint64_t index;
Alok Pandey6a9a5c32018-07-27 13:39:03 +0530102 struct cam_isp_context_state_monitor *cam_isp_ctx_state_monitor;
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700103
104 state_head = atomic64_read(&ctx_isp->state_monitor_head);
105 CAM_ERR_RATE_LIMIT(CAM_ISP,
106 "Dumping state information for preceding requests");
107
108 for (i = CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES - 1; i >= 0;
109 i--) {
Alok Pandey6a9a5c32018-07-27 13:39:03 +0530110 div64_u64_rem(((state_head - i) +
111 CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES),
112 CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES, &index);
113 cam_isp_ctx_state_monitor =
114 &ctx_isp->cam_isp_ctx_state_monitor[index];
115
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700116 CAM_ERR_RATE_LIMIT(CAM_ISP,
Alok Pandey6a9a5c32018-07-27 13:39:03 +0530117 "time[0x%llx] req_id[%u] state[%s] evt_type[%s]",
118 cam_isp_ctx_state_monitor->evt_time_stamp,
119 cam_isp_ctx_state_monitor->req_id,
120 __cam_isp_ctx_substate_val_to_type(
121 cam_isp_ctx_state_monitor->curr_state),
122 __cam_isp_hw_evt_val_to_type(
123 cam_isp_ctx_state_monitor->trigger));
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700124 }
125}
126
Jing Zhou77962c52017-09-18 19:13:34 -0700127static int __cam_isp_ctx_enqueue_request_in_order(
128 struct cam_context *ctx, struct cam_ctx_request *req)
129{
130 struct cam_ctx_request *req_current;
131 struct cam_ctx_request *req_prev;
132 struct list_head temp_list;
133
134 INIT_LIST_HEAD(&temp_list);
135 spin_lock_bh(&ctx->lock);
136 if (list_empty(&ctx->pending_req_list)) {
137 list_add_tail(&req->list, &ctx->pending_req_list);
138 } else {
139 list_for_each_entry_safe_reverse(
140 req_current, req_prev, &ctx->pending_req_list, list) {
141 if (req->request_id < req_current->request_id) {
142 list_del_init(&req_current->list);
143 list_add(&req_current->list, &temp_list);
144 continue;
145 } else if (req->request_id == req_current->request_id) {
146 CAM_WARN(CAM_ISP,
147 "Received duplicated request %lld",
148 req->request_id);
149 }
150 break;
151 }
152 list_add_tail(&req->list, &ctx->pending_req_list);
153
154 if (!list_empty(&temp_list)) {
155 list_for_each_entry_safe(
156 req_current, req_prev, &temp_list, list) {
157 list_del_init(&req_current->list);
158 list_add_tail(&req_current->list,
159 &ctx->pending_req_list);
160 }
161 }
162 }
163 spin_unlock_bh(&ctx->lock);
164 return 0;
165}
166
Ravikishore Pampana24f712e2017-11-13 23:09:30 +0530167static int __cam_isp_ctx_enqueue_init_request(
168 struct cam_context *ctx, struct cam_ctx_request *req)
169{
170 int rc = 0;
171 struct cam_ctx_request *req_old;
172 struct cam_isp_ctx_req *req_isp_old;
173 struct cam_isp_ctx_req *req_isp_new;
174
175 spin_lock_bh(&ctx->lock);
176 if (list_empty(&ctx->pending_req_list)) {
177 list_add_tail(&req->list, &ctx->pending_req_list);
178 CAM_DBG(CAM_ISP, "INIT packet added req id= %d",
179 req->request_id);
180 goto end;
181 }
182
183 req_old = list_first_entry(&ctx->pending_req_list,
184 struct cam_ctx_request, list);
185 req_isp_old = (struct cam_isp_ctx_req *) req_old->req_priv;
186 req_isp_new = (struct cam_isp_ctx_req *) req->req_priv;
Vishalsingh Hajerie5450be2018-01-18 20:31:19 -0800187 if (req_isp_old->hw_update_data.packet_opcode_type ==
188 CAM_ISP_PACKET_INIT_DEV) {
Ravikishore Pampana24f712e2017-11-13 23:09:30 +0530189 if ((req_isp_old->num_cfg + req_isp_new->num_cfg) >=
190 CAM_ISP_CTX_CFG_MAX) {
191 CAM_WARN(CAM_ISP, "Can not merge INIT pkt");
192 rc = -ENOMEM;
193 }
194
195 if (req_isp_old->num_fence_map_out != 0 ||
196 req_isp_old->num_fence_map_in != 0) {
197 CAM_WARN(CAM_ISP, "Invalid INIT pkt sequence");
198 rc = -EINVAL;
199 }
200
201 if (!rc) {
202 memcpy(req_isp_old->fence_map_out,
203 req_isp_new->fence_map_out,
204 sizeof(req_isp_new->fence_map_out[0])*
205 req_isp_new->num_fence_map_out);
206 req_isp_old->num_fence_map_out =
207 req_isp_new->num_fence_map_out;
208
209 memcpy(req_isp_old->fence_map_in,
210 req_isp_new->fence_map_in,
211 sizeof(req_isp_new->fence_map_in[0])*
212 req_isp_new->num_fence_map_in);
213 req_isp_old->num_fence_map_in =
214 req_isp_new->num_fence_map_in;
215
216 memcpy(&req_isp_old->cfg[req_isp_old->num_cfg],
217 req_isp_new->cfg,
218 sizeof(req_isp_new->cfg[0])*
219 req_isp_new->num_cfg);
220 req_isp_old->num_cfg += req_isp_new->num_cfg;
221
222 list_add_tail(&req->list, &ctx->free_req_list);
223 }
224 } else {
225 CAM_WARN(CAM_ISP,
226 "Received Update pkt before INIT pkt. req_id= %lld",
227 req->request_id);
228 rc = -EINVAL;
229 }
230end:
231 spin_unlock_bh(&ctx->lock);
232 return rc;
233}
234
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700235static const char *__cam_isp_resource_handle_id_to_type(
236 uint32_t resource_handle)
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700237{
238 switch (resource_handle) {
239 case CAM_ISP_IFE_OUT_RES_FULL:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700240 return "FULL";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700241 case CAM_ISP_IFE_OUT_RES_DS4:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700242 return "DS4";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700243 case CAM_ISP_IFE_OUT_RES_DS16:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700244 return "DS16";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700245 case CAM_ISP_IFE_OUT_RES_RAW_DUMP:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700246 return "RAW_DUMP";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700247 case CAM_ISP_IFE_OUT_RES_FD:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700248 return "FD";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700249 case CAM_ISP_IFE_OUT_RES_PDAF:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700250 return "PDAF";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700251 case CAM_ISP_IFE_OUT_RES_RDI_0:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700252 return "RDI_0";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700253 case CAM_ISP_IFE_OUT_RES_RDI_1:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700254 return "RDI_1";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700255 case CAM_ISP_IFE_OUT_RES_RDI_2:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700256 return "RDI_2";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700257 case CAM_ISP_IFE_OUT_RES_RDI_3:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700258 return "RDI_3";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700259 case CAM_ISP_IFE_OUT_RES_STATS_HDR_BE:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700260 return "STATS_HDR_BE";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700261 case CAM_ISP_IFE_OUT_RES_STATS_HDR_BHIST:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700262 return "STATS_HDR_BHIST";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700263 case CAM_ISP_IFE_OUT_RES_STATS_TL_BG:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700264 return "STATS_TL_BG";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700265 case CAM_ISP_IFE_OUT_RES_STATS_BF:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700266 return "STATS_BF";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700267 case CAM_ISP_IFE_OUT_RES_STATS_AWB_BG:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700268 return "STATS_AWB_BG";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700269 case CAM_ISP_IFE_OUT_RES_STATS_BHIST:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700270 return "STATS_BHIST";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700271 case CAM_ISP_IFE_OUT_RES_STATS_RS:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700272 return "STATS_RS";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700273 case CAM_ISP_IFE_OUT_RES_STATS_CS:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700274 return "STATS_CS";
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700275 default:
276 return "CAM_ISP_Invalid_Resource_Type";
277 }
278}
279
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -0600280static uint64_t __cam_isp_ctx_get_event_ts(uint32_t evt_id, void *evt_data)
281{
282 uint64_t ts = 0;
283
284 if (!evt_data)
285 return 0;
286
287 switch (evt_id) {
288 case CAM_ISP_HW_EVENT_ERROR:
289 ts = ((struct cam_isp_hw_error_event_data *)evt_data)->
290 timestamp;
291 break;
292 case CAM_ISP_HW_EVENT_SOF:
293 ts = ((struct cam_isp_hw_sof_event_data *)evt_data)->
294 timestamp;
295 break;
296 case CAM_ISP_HW_EVENT_REG_UPDATE:
297 ts = ((struct cam_isp_hw_reg_update_event_data *)evt_data)->
298 timestamp;
299 break;
300 case CAM_ISP_HW_EVENT_EPOCH:
301 ts = ((struct cam_isp_hw_epoch_event_data *)evt_data)->
302 timestamp;
303 break;
304 case CAM_ISP_HW_EVENT_EOF:
305 ts = ((struct cam_isp_hw_eof_event_data *)evt_data)->
306 timestamp;
307 break;
308 case CAM_ISP_HW_EVENT_DONE:
309 break;
310 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700311 CAM_DBG(CAM_ISP, "Invalid Event Type %d", evt_id);
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -0600312 }
313
314 return ts;
315}
316
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700317static void __cam_isp_ctx_handle_buf_done_fail_log(
318 struct cam_isp_ctx_req *req_isp)
319{
320 int i;
321
Harsh Shah1b8eb232017-10-09 19:20:52 -0700322 if (req_isp->num_fence_map_out >= CAM_ISP_CTX_RES_MAX) {
323 CAM_ERR_RATE_LIMIT(CAM_ISP,
324 "Num Resources exceed mMAX %d >= %d ",
325 req_isp->num_fence_map_out, CAM_ISP_CTX_RES_MAX);
326 return;
327 }
328
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -0700329 CAM_ERR_RATE_LIMIT(CAM_ISP,
330 "Resource Handles that fail to generate buf_done in prev frame");
331 for (i = 0; i < req_isp->num_fence_map_out; i++) {
332 if (req_isp->fence_map_out[i].sync_id != -1)
333 CAM_ERR_RATE_LIMIT(CAM_ISP,
334 "Resource_Handle: [%s] Sync_ID: [0x%x]",
335 __cam_isp_resource_handle_id_to_type(
336 req_isp->fence_map_out[i].resource_handle),
337 req_isp->fence_map_out[i].sync_id);
338 }
339}
340
Jing Zhoud352ed12017-03-20 23:59:56 -0700341static int __cam_isp_ctx_handle_buf_done_in_activated_state(
342 struct cam_isp_context *ctx_isp,
343 struct cam_isp_hw_done_event_data *done,
344 uint32_t bubble_state)
345{
346 int rc = 0;
347 int i, j;
348 struct cam_ctx_request *req;
349 struct cam_isp_ctx_req *req_isp;
350 struct cam_context *ctx = ctx_isp->base;
351
352 if (list_empty(&ctx->active_req_list)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700353 CAM_DBG(CAM_ISP, "Buf done with no active request!");
Jing Zhoud352ed12017-03-20 23:59:56 -0700354 goto end;
355 }
356
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700357 CAM_DBG(CAM_ISP, "Enter with bubble_state %d", bubble_state);
Jing Zhoud352ed12017-03-20 23:59:56 -0700358
359 req = list_first_entry(&ctx->active_req_list,
360 struct cam_ctx_request, list);
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -0600361
362 trace_cam_buf_done("ISP", ctx, req);
363
Jing Zhoud352ed12017-03-20 23:59:56 -0700364 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
365 for (i = 0; i < done->num_handles; i++) {
366 for (j = 0; j < req_isp->num_fence_map_out; j++) {
367 if (done->resource_handle[i] ==
368 req_isp->fence_map_out[j].resource_handle)
369 break;
370 }
371
372 if (j == req_isp->num_fence_map_out) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700373 CAM_ERR(CAM_ISP,
374 "Can not find matching lane handle 0x%x!",
Jing Zhoud352ed12017-03-20 23:59:56 -0700375 done->resource_handle[i]);
376 rc = -EINVAL;
377 continue;
378 }
379
Harsh Shah1b8eb232017-10-09 19:20:52 -0700380 if (req_isp->fence_map_out[j].sync_id == -1) {
381 __cam_isp_ctx_handle_buf_done_fail_log(req_isp);
382 continue;
383 }
Jing Zhoubb536a82017-05-18 15:20:38 -0700384
Junzhe Zou09820a72018-09-06 18:11:41 -0700385 if (!req_isp->bubble_detected) {
vhajeri05545252017-11-10 18:43:08 -0800386 CAM_DBG(CAM_ISP,
387 "Sync with success: req %lld res 0x%x fd 0x%x",
388 req->request_id,
389 req_isp->fence_map_out[j].resource_handle,
390 req_isp->fence_map_out[j].sync_id);
391
392 rc = cam_sync_signal(req_isp->fence_map_out[j].sync_id,
393 CAM_SYNC_STATE_SIGNALED_SUCCESS);
394 if (rc)
395 CAM_DBG(CAM_ISP, "Sync failed with rc = %d",
Jeyaprakash Soundrapandian32e5ae52017-11-17 23:44:44 -0800396 rc);
397 } else if (!req_isp->bubble_report) {
398 CAM_DBG(CAM_ISP,
399 "Sync with failure: req %lld res 0x%x fd 0x%x",
400 req->request_id,
401 req_isp->fence_map_out[j].resource_handle,
402 req_isp->fence_map_out[j].sync_id);
403
404 rc = cam_sync_signal(req_isp->fence_map_out[j].sync_id,
405 CAM_SYNC_STATE_SIGNALED_ERROR);
406 if (rc)
407 CAM_ERR(CAM_ISP, "Sync failed with rc = %d",
vhajeri05545252017-11-10 18:43:08 -0800408 rc);
Jing Zhoud352ed12017-03-20 23:59:56 -0700409 } else {
410 /*
411 * Ignore the buffer done if bubble detect is on
Junzhe Zou09820a72018-09-06 18:11:41 -0700412 * Increment the ack number here, and queue the
413 * request back to pending list whenever all the
414 * buffers are done.
Jing Zhoud352ed12017-03-20 23:59:56 -0700415 */
Junzhe Zou09820a72018-09-06 18:11:41 -0700416 req_isp->num_acked++;
Harsh Shah1b8eb232017-10-09 19:20:52 -0700417 CAM_DBG(CAM_ISP,
418 "buf done with bubble state %d recovery %d",
419 bubble_state, req_isp->bubble_report);
Jing Zhoud352ed12017-03-20 23:59:56 -0700420 continue;
421 }
422
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700423 CAM_DBG(CAM_ISP, "req %lld, reset sync id 0x%x",
Harsh Shah1b8eb232017-10-09 19:20:52 -0700424 req->request_id,
425 req_isp->fence_map_out[j].sync_id);
426 if (!rc) {
427 req_isp->num_acked++;
428 req_isp->fence_map_out[j].sync_id = -1;
429 }
Jing Zhoud352ed12017-03-20 23:59:56 -0700430 }
431
Harsh Shah1b8eb232017-10-09 19:20:52 -0700432 if (req_isp->num_acked > req_isp->num_fence_map_out) {
433 /* Should not happen */
434 CAM_ERR(CAM_ISP,
435 "WARNING: req_id %lld num_acked %d > map_out %d",
436 req->request_id, req_isp->num_acked,
437 req_isp->num_fence_map_out);
438 WARN_ON(req_isp->num_acked > req_isp->num_fence_map_out);
439 }
Junzhe Zou09820a72018-09-06 18:11:41 -0700440
441 if (req_isp->num_acked != req_isp->num_fence_map_out)
442 return rc;
443
444 ctx_isp->active_req_cnt--;
445
446 if (req_isp->bubble_detected && req_isp->bubble_report) {
447 req_isp->num_acked = 0;
448 req_isp->bubble_detected = false;
449 list_del_init(&req->list);
450 list_add(&req->list, &ctx->pending_req_list);
Ayush Kumarf13969a92019-07-18 13:02:43 +0530451 atomic_set(&ctx_isp->process_bubble, 0);
Junzhe Zou09820a72018-09-06 18:11:41 -0700452
453 CAM_DBG(CAM_REQ,
454 "Move active request %lld to pending list(cnt = %d) [bubble recovery]",
455 req->request_id, ctx_isp->active_req_cnt);
456 } else {
Jing Zhoud352ed12017-03-20 23:59:56 -0700457 list_del_init(&req->list);
458 list_add_tail(&req->list, &ctx->free_req_list);
Junzhe Zou09820a72018-09-06 18:11:41 -0700459
Karthik Anantha Ram5438d572018-06-15 10:48:19 -0700460 CAM_DBG(CAM_REQ,
461 "Move active request %lld to free list(cnt = %d) [all fences done]",
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700462 req->request_id, ctx_isp->active_req_cnt);
Jing Zhoud352ed12017-03-20 23:59:56 -0700463 }
464
465end:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700466 __cam_isp_ctx_update_state_monitor_array(ctx_isp,
467 CAM_ISP_STATE_CHANGE_TRIGGER_DONE,
468 ctx_isp->base->req_list->request_id);
Jing Zhoud352ed12017-03-20 23:59:56 -0700469 return rc;
470}
471
Karthik Anantha Ramc93754c2018-03-28 14:21:14 -0700472static void __cam_isp_ctx_send_sof_boot_timestamp(
473 struct cam_isp_context *ctx_isp, uint64_t request_id,
474 uint32_t sof_event_status)
475{
476 struct cam_req_mgr_message req_msg;
477
478 req_msg.session_hdl = ctx_isp->base->session_hdl;
479 req_msg.u.frame_msg.frame_id = ctx_isp->frame_id;
480 req_msg.u.frame_msg.request_id = request_id;
481 req_msg.u.frame_msg.timestamp = ctx_isp->boot_timestamp;
482 req_msg.u.frame_msg.link_hdl = ctx_isp->base->link_hdl;
483 req_msg.u.frame_msg.sof_status = sof_event_status;
484
485 CAM_DBG(CAM_ISP,
486 "request id:%lld frame number:%lld boot time stamp:0x%llx",
487 request_id, ctx_isp->frame_id,
488 ctx_isp->boot_timestamp);
489
490 if (cam_req_mgr_notify_message(&req_msg,
491 V4L_EVENT_CAM_REQ_MGR_SOF_BOOT_TS,
492 V4L_EVENT_CAM_REQ_MGR_EVENT))
493 CAM_ERR(CAM_ISP,
494 "Error in notifying the boot time for req id:%lld",
495 request_id);
496}
497
498
Jing Zhoudedc4762017-06-19 17:45:36 +0530499static void __cam_isp_ctx_send_sof_timestamp(
500 struct cam_isp_context *ctx_isp, uint64_t request_id,
501 uint32_t sof_event_status)
502{
503 struct cam_req_mgr_message req_msg;
504
505 req_msg.session_hdl = ctx_isp->base->session_hdl;
506 req_msg.u.frame_msg.frame_id = ctx_isp->frame_id;
507 req_msg.u.frame_msg.request_id = request_id;
508 req_msg.u.frame_msg.timestamp = ctx_isp->sof_timestamp_val;
509 req_msg.u.frame_msg.link_hdl = ctx_isp->base->link_hdl;
510 req_msg.u.frame_msg.sof_status = sof_event_status;
511
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700512 CAM_DBG(CAM_ISP,
513 "request id:%lld frame number:%lld SOF time stamp:0x%llx",
514 request_id, ctx_isp->frame_id,
Jing Zhoudedc4762017-06-19 17:45:36 +0530515 ctx_isp->sof_timestamp_val);
Karthik Anantha Ramc93754c2018-03-28 14:21:14 -0700516 CAM_DBG(CAM_ISP, "sof status:%d", sof_event_status);
Jing Zhoudedc4762017-06-19 17:45:36 +0530517
Harsh Shah67fa2312017-10-30 04:03:07 -0700518 if (cam_req_mgr_notify_message(&req_msg,
Jing Zhoudedc4762017-06-19 17:45:36 +0530519 V4L_EVENT_CAM_REQ_MGR_SOF, V4L_EVENT_CAM_REQ_MGR_EVENT))
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700520 CAM_ERR(CAM_ISP,
521 "Error in notifying the sof time for req id:%lld",
522 request_id);
Karthik Anantha Ramc93754c2018-03-28 14:21:14 -0700523
524 __cam_isp_ctx_send_sof_boot_timestamp(ctx_isp,
525 request_id, sof_event_status);
526
Jing Zhoudedc4762017-06-19 17:45:36 +0530527}
528
Karthik Anantha Ram15326072018-05-18 14:47:00 -0700529static int __cam_isp_ctx_reg_upd_in_epoch_state(
530 struct cam_isp_context *ctx_isp, void *evt_data)
531{
532 if (ctx_isp->frame_id == 1)
533 CAM_DBG(CAM_ISP, "Reg update for early PCR");
534 else
535 CAM_WARN(CAM_ISP,
536 "Unexpected reg update in activated substate:%d for frame_id:%lld",
537 ctx_isp->substate_activated, ctx_isp->frame_id);
538 return 0;
539}
540
Jing Zhoud352ed12017-03-20 23:59:56 -0700541static int __cam_isp_ctx_reg_upd_in_activated_state(
542 struct cam_isp_context *ctx_isp, void *evt_data)
543{
544 int rc = 0;
545 struct cam_ctx_request *req;
546 struct cam_context *ctx = ctx_isp->base;
547 struct cam_isp_ctx_req *req_isp;
548
Junzhe Zoufdcd4722018-06-11 18:05:33 -0700549 if (list_empty(&ctx->wait_req_list)) {
550 CAM_ERR(CAM_ISP, "Reg upd ack with no waiting request");
Jing Zhoud352ed12017-03-20 23:59:56 -0700551 goto end;
552 }
Junzhe Zoufdcd4722018-06-11 18:05:33 -0700553 req = list_first_entry(&ctx->wait_req_list,
Jing Zhoud352ed12017-03-20 23:59:56 -0700554 struct cam_ctx_request, list);
555 list_del_init(&req->list);
556
557 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
558 if (req_isp->num_fence_map_out != 0) {
Jing Zhoud352ed12017-03-20 23:59:56 -0700559 list_add_tail(&req->list, &ctx->active_req_list);
Jing Zhoudedc4762017-06-19 17:45:36 +0530560 ctx_isp->active_req_cnt++;
Karthik Anantha Ram5438d572018-06-15 10:48:19 -0700561 CAM_DBG(CAM_REQ, "move request %lld to active list(cnt = %d)",
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700562 req->request_id, ctx_isp->active_req_cnt);
Jing Zhoud352ed12017-03-20 23:59:56 -0700563 } else {
564 /* no io config, so the request is completed. */
565 list_add_tail(&req->list, &ctx->free_req_list);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700566 CAM_DBG(CAM_ISP,
567 "move active request %lld to free list(cnt = %d)",
568 req->request_id, ctx_isp->active_req_cnt);
Jing Zhoud352ed12017-03-20 23:59:56 -0700569 }
570
571 /*
572 * This function only called directly from applied and bubble applied
573 * state so change substate here.
574 */
575 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_EPOCH;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700576 CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated);
Jing Zhoud352ed12017-03-20 23:59:56 -0700577
578end:
579 return rc;
580}
581
582static int __cam_isp_ctx_notify_sof_in_actived_state(
583 struct cam_isp_context *ctx_isp, void *evt_data)
584{
Junzhe Zou2df84502017-05-26 13:20:23 -0700585 int rc = 0;
586 struct cam_req_mgr_trigger_notify notify;
Jing Zhoud352ed12017-03-20 23:59:56 -0700587 struct cam_context *ctx = ctx_isp->base;
Jing Zhoudedc4762017-06-19 17:45:36 +0530588 struct cam_ctx_request *req;
589 uint64_t request_id = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -0700590
Jing Zhoudedc4762017-06-19 17:45:36 +0530591 /*
592 * notify reqmgr with sof signal. Note, due to scheduling delay
593 * we can run into situation that two active requests has already
594 * be in the active queue while we try to do the notification.
595 * In this case, we need to skip the current notification. This
596 * helps the state machine to catch up the delay.
597 */
Junzhe Zou2df84502017-05-26 13:20:23 -0700598 if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger &&
Jing Zhoudedc4762017-06-19 17:45:36 +0530599 ctx_isp->active_req_cnt <= 2) {
Junzhe Zou2df84502017-05-26 13:20:23 -0700600 if (ctx_isp->subscribe_event & CAM_TRIGGER_POINT_SOF) {
601 notify.link_hdl = ctx->link_hdl;
602 notify.dev_hdl = ctx->dev_hdl;
603 notify.frame_id = ctx_isp->frame_id;
604 notify.trigger = CAM_TRIGGER_POINT_SOF;
Jing Zhoud352ed12017-03-20 23:59:56 -0700605
Junzhe Zou2df84502017-05-26 13:20:23 -0700606 ctx->ctx_crm_intf->notify_trigger(&notify);
607 CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld",
608 ctx_isp->frame_id);
609 }
Jing Zhoudedc4762017-06-19 17:45:36 +0530610
611 list_for_each_entry(req, &ctx->active_req_list, list) {
612 if (req->request_id > ctx_isp->reported_req_id) {
613 request_id = req->request_id;
614 ctx_isp->reported_req_id = request_id;
615 break;
616 }
617 }
618
Ravikishore Pampana6648f172017-12-08 20:29:11 +0530619 if (ctx_isp->substate_activated == CAM_ISP_CTX_ACTIVATED_BUBBLE)
620 request_id = 0;
621
Jing Zhoudedc4762017-06-19 17:45:36 +0530622 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
623 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
Jing Zhoud352ed12017-03-20 23:59:56 -0700624 } else {
Harsh Shahcb0072c2017-09-26 19:22:10 -0700625 CAM_ERR_RATE_LIMIT(CAM_ISP, "Can not notify SOF to CRM");
Junzhe Zou2df84502017-05-26 13:20:23 -0700626 rc = -EFAULT;
Jing Zhoud352ed12017-03-20 23:59:56 -0700627 }
628
Jing Zhoudedc4762017-06-19 17:45:36 +0530629 return 0;
Jing Zhoud352ed12017-03-20 23:59:56 -0700630}
631
Junzhe Zou2df84502017-05-26 13:20:23 -0700632static int __cam_isp_ctx_notify_eof_in_actived_state(
633 struct cam_isp_context *ctx_isp, void *evt_data)
634{
635 int rc = 0;
636 struct cam_req_mgr_trigger_notify notify;
637 struct cam_context *ctx = ctx_isp->base;
638
639 if (!(ctx_isp->subscribe_event & CAM_TRIGGER_POINT_EOF))
640 return rc;
641
642 /* notify reqmgr with eof signal */
643 if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger) {
644 notify.link_hdl = ctx->link_hdl;
645 notify.dev_hdl = ctx->dev_hdl;
646 notify.frame_id = ctx_isp->frame_id;
647 notify.trigger = CAM_TRIGGER_POINT_EOF;
648
649 ctx->ctx_crm_intf->notify_trigger(&notify);
650 CAM_DBG(CAM_ISP, "Notify CRM EOF frame %lld\n",
651 ctx_isp->frame_id);
652 } else {
653 CAM_ERR(CAM_ISP, "Can not notify EOF to CRM");
654 rc = -EFAULT;
655 }
656
657 return rc;
658}
Jing Zhoud352ed12017-03-20 23:59:56 -0700659
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +0530660static int __cam_isp_ctx_reg_upd_in_hw_error(
661 struct cam_isp_context *ctx_isp, void *evt_data)
662{
663 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
664 return 0;
665}
666
Jing Zhoudedc4762017-06-19 17:45:36 +0530667static int __cam_isp_ctx_sof_in_activated_state(
668 struct cam_isp_context *ctx_isp, void *evt_data)
Jing Zhoud352ed12017-03-20 23:59:56 -0700669{
670 int rc = 0;
Jing Zhoudedc4762017-06-19 17:45:36 +0530671 struct cam_isp_hw_sof_event_data *sof_event_data = evt_data;
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700672 struct cam_ctx_request *req;
673 struct cam_context *ctx = ctx_isp->base;
674
675 req = list_last_entry(&ctx->pending_req_list,
676 struct cam_ctx_request, list);
Jing Zhoud352ed12017-03-20 23:59:56 -0700677
Jing Zhoudedc4762017-06-19 17:45:36 +0530678 if (!evt_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700679 CAM_ERR(CAM_ISP, "in valid sof event data");
Jing Zhoudedc4762017-06-19 17:45:36 +0530680 return -EINVAL;
681 }
682
Jing Zhoud352ed12017-03-20 23:59:56 -0700683 ctx_isp->frame_id++;
Jing Zhoudedc4762017-06-19 17:45:36 +0530684 ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
Karthik Anantha Ramc93754c2018-03-28 14:21:14 -0700685 ctx_isp->boot_timestamp = sof_event_data->boot_time;
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700686 __cam_isp_ctx_update_state_monitor_array(ctx_isp,
687 CAM_ISP_STATE_CHANGE_TRIGGER_SOF, req->request_id);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700688 CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx",
Jing Zhoudedc4762017-06-19 17:45:36 +0530689 ctx_isp->frame_id, ctx_isp->sof_timestamp_val);
Jing Zhoud352ed12017-03-20 23:59:56 -0700690
691 return rc;
692}
693
694static int __cam_isp_ctx_reg_upd_in_sof(struct cam_isp_context *ctx_isp,
695 void *evt_data)
696{
697 int rc = 0;
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700698 struct cam_ctx_request *req = NULL;
Jing Zhoud352ed12017-03-20 23:59:56 -0700699 struct cam_isp_ctx_req *req_isp;
700 struct cam_context *ctx = ctx_isp->base;
701
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700702 if (ctx->state != CAM_CTX_ACTIVATED && ctx_isp->frame_id > 1) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700703 CAM_DBG(CAM_ISP, "invalid RUP");
Jing Zhoud352ed12017-03-20 23:59:56 -0700704 goto end;
705 }
706
707 /*
708 * This is for the first update. The initial setting will
709 * cause the reg_upd in the first frame.
710 */
Junzhe Zoue7d56fc2018-08-10 14:50:17 -0700711 if (!list_empty(&ctx->wait_req_list)) {
712 req = list_first_entry(&ctx->wait_req_list,
Jing Zhoud352ed12017-03-20 23:59:56 -0700713 struct cam_ctx_request, list);
714 list_del_init(&req->list);
715 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
Junzhe Zoue7d56fc2018-08-10 14:50:17 -0700716 if (req_isp->num_fence_map_out == req_isp->num_acked)
Jing Zhoud352ed12017-03-20 23:59:56 -0700717 list_add_tail(&req->list, &ctx->free_req_list);
Junzhe Zoue7d56fc2018-08-10 14:50:17 -0700718 else
719 CAM_ERR(CAM_ISP,
720 "receive rup in unexpected state");
Jing Zhoud352ed12017-03-20 23:59:56 -0700721 }
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700722 if (req != NULL) {
723 __cam_isp_ctx_update_state_monitor_array(ctx_isp,
724 CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE,
725 req->request_id);
726 }
Jing Zhoud352ed12017-03-20 23:59:56 -0700727end:
728 return rc;
729}
730
731static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
732 void *evt_data)
733{
Jing Zhoud352ed12017-03-20 23:59:56 -0700734 struct cam_ctx_request *req;
735 struct cam_isp_ctx_req *req_isp;
736 struct cam_context *ctx = ctx_isp->base;
Jing Zhoudedc4762017-06-19 17:45:36 +0530737 uint64_t request_id = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -0700738
Karthik Anantha Ram4cb91db2018-08-10 11:16:19 -0700739 if (list_empty(&ctx->wait_req_list)) {
Jing Zhoud352ed12017-03-20 23:59:56 -0700740 /*
Karthik Anantha Ram4cb91db2018-08-10 11:16:19 -0700741 * If no wait req in epoch, this is an error case.
Jing Zhoud352ed12017-03-20 23:59:56 -0700742 * The recovery is to go back to sof state
743 */
Junzhe Zoue7d56fc2018-08-10 14:50:17 -0700744 CAM_ERR(CAM_ISP, "No wait request");
Jing Zhoud352ed12017-03-20 23:59:56 -0700745 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
Jing Zhoudedc4762017-06-19 17:45:36 +0530746
747 /* Send SOF event as empty frame*/
748 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
749 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
750
Jing Zhoud352ed12017-03-20 23:59:56 -0700751 goto end;
752 }
753
Karthik Anantha Ram4cb91db2018-08-10 11:16:19 -0700754 req = list_first_entry(&ctx->wait_req_list, struct cam_ctx_request,
Jing Zhoud352ed12017-03-20 23:59:56 -0700755 list);
756 req_isp = (struct cam_isp_ctx_req *)req->req_priv;
Junzhe Zou09820a72018-09-06 18:11:41 -0700757 req_isp->bubble_detected = true;
Jing Zhoud352ed12017-03-20 23:59:56 -0700758
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700759 CAM_DBG(CAM_ISP, "Report Bubble flag %d", req_isp->bubble_report);
Jing Zhoud352ed12017-03-20 23:59:56 -0700760 if (req_isp->bubble_report && ctx->ctx_crm_intf &&
761 ctx->ctx_crm_intf->notify_err) {
762 struct cam_req_mgr_error_notify notify;
763
764 notify.link_hdl = ctx->link_hdl;
765 notify.dev_hdl = ctx->dev_hdl;
766 notify.req_id = req->request_id;
767 notify.error = CRM_KMD_ERR_BUBBLE;
768 ctx->ctx_crm_intf->notify_err(&notify);
Ayush Kumarf13969a92019-07-18 13:02:43 +0530769 atomic_set(&ctx_isp->process_bubble, 1);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700770 CAM_DBG(CAM_ISP, "Notify CRM about Bubble frame %lld",
Jing Zhoud352ed12017-03-20 23:59:56 -0700771 ctx_isp->frame_id);
Jing Zhou45b55cc2017-05-16 17:27:18 -0700772 } else {
Jing Zhou45b55cc2017-05-16 17:27:18 -0700773 req_isp->bubble_report = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -0700774 }
775
Junzhe Zou09820a72018-09-06 18:11:41 -0700776 /*
777 * Always move the request to active list. Let buf done
778 * function handles the rest.
779 */
780 CAM_DBG(CAM_REQ, "move request %lld to active list(cnt = %d)",
781 req->request_id, ctx_isp->active_req_cnt);
782 ctx_isp->active_req_cnt++;
783 list_del_init(&req->list);
784 list_add_tail(&req->list, &ctx->active_req_list);
785
Ravikishore Pampana6648f172017-12-08 20:29:11 +0530786 if (req->request_id > ctx_isp->reported_req_id) {
787 request_id = req->request_id;
788 ctx_isp->reported_req_id = request_id;
789 }
Jing Zhoudedc4762017-06-19 17:45:36 +0530790 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
791 CAM_REQ_MGR_SOF_EVENT_ERROR);
792
Jing Zhoud352ed12017-03-20 23:59:56 -0700793 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700794 CAM_DBG(CAM_ISP, "next substate %d",
Jing Zhoud352ed12017-03-20 23:59:56 -0700795 ctx_isp->substate_activated);
796end:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700797 if (request_id == 0) {
798 req = list_last_entry(&ctx->active_req_list,
799 struct cam_ctx_request, list);
800 __cam_isp_ctx_update_state_monitor_array(ctx_isp,
801 CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, req->request_id);
802 } else {
803 __cam_isp_ctx_update_state_monitor_array(ctx_isp,
804 CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, request_id);
805 }
Jing Zhoudedc4762017-06-19 17:45:36 +0530806 return 0;
Jing Zhoud352ed12017-03-20 23:59:56 -0700807}
808
809
810static int __cam_isp_ctx_buf_done_in_applied(struct cam_isp_context *ctx_isp,
811 void *evt_data)
812{
813 int rc = 0;
814 struct cam_isp_hw_done_event_data *done =
815 (struct cam_isp_hw_done_event_data *) evt_data;
816
817 rc = __cam_isp_ctx_handle_buf_done_in_activated_state(ctx_isp, done, 0);
818 return rc;
819}
820
821
822static int __cam_isp_ctx_sof_in_epoch(struct cam_isp_context *ctx_isp,
823 void *evt_data)
824{
825 int rc = 0;
Jing Zhoudedc4762017-06-19 17:45:36 +0530826 struct cam_context *ctx = ctx_isp->base;
827 struct cam_isp_hw_sof_event_data *sof_event_data = evt_data;
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700828 struct cam_ctx_request *req;
Jing Zhou93b3ec12017-06-15 17:43:39 -0700829
Jing Zhoudedc4762017-06-19 17:45:36 +0530830 if (!evt_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700831 CAM_ERR(CAM_ISP, "in valid sof event data");
Jing Zhoudedc4762017-06-19 17:45:36 +0530832 return -EINVAL;
833 }
Jing Zhoud352ed12017-03-20 23:59:56 -0700834
835 ctx_isp->frame_id++;
Jing Zhoudedc4762017-06-19 17:45:36 +0530836 ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
Karthik Anantha Ramc93754c2018-03-28 14:21:14 -0700837 ctx_isp->boot_timestamp = sof_event_data->boot_time;
Jing Zhoudedc4762017-06-19 17:45:36 +0530838
Jing Zhou93b3ec12017-06-15 17:43:39 -0700839 if (list_empty(&ctx->active_req_list))
840 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
841 else
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700842 CAM_DBG(CAM_ISP, "Still need to wait for the buf done");
Jing Zhoudedc4762017-06-19 17:45:36 +0530843
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700844 req = list_last_entry(&ctx->active_req_list,
845 struct cam_ctx_request, list);
Junzhe Zoue7d56fc2018-08-10 14:50:17 -0700846 if (req)
847 __cam_isp_ctx_update_state_monitor_array(ctx_isp,
848 CAM_ISP_STATE_CHANGE_TRIGGER_SOF,
849 ctx->req_list->request_id);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700850 CAM_DBG(CAM_ISP, "next substate %d",
Jing Zhoud352ed12017-03-20 23:59:56 -0700851 ctx_isp->substate_activated);
852
853 return rc;
854}
855
856static int __cam_isp_ctx_buf_done_in_epoch(struct cam_isp_context *ctx_isp,
857 void *evt_data)
858{
859 int rc = 0;
860 struct cam_isp_hw_done_event_data *done =
861 (struct cam_isp_hw_done_event_data *) evt_data;
862
863 rc = __cam_isp_ctx_handle_buf_done_in_activated_state(ctx_isp, done, 0);
864 return rc;
865}
866
Jing Zhoud352ed12017-03-20 23:59:56 -0700867static int __cam_isp_ctx_buf_done_in_bubble(
868 struct cam_isp_context *ctx_isp, void *evt_data)
869{
870 int rc = 0;
871 struct cam_isp_hw_done_event_data *done =
872 (struct cam_isp_hw_done_event_data *) evt_data;
873
874 rc = __cam_isp_ctx_handle_buf_done_in_activated_state(ctx_isp, done, 1);
875 return rc;
876}
877
Jing Zhoud352ed12017-03-20 23:59:56 -0700878static int __cam_isp_ctx_epoch_in_bubble_applied(
879 struct cam_isp_context *ctx_isp, void *evt_data)
880{
881 struct cam_ctx_request *req;
882 struct cam_isp_ctx_req *req_isp;
883 struct cam_context *ctx = ctx_isp->base;
Jing Zhoudedc4762017-06-19 17:45:36 +0530884 uint64_t request_id = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -0700885
886 /*
887 * This means we missed the reg upd ack. So we need to
888 * transition to BUBBLE state again.
889 */
890
Junzhe Zoue7d56fc2018-08-10 14:50:17 -0700891 if (list_empty(&ctx->wait_req_list)) {
Jing Zhoud352ed12017-03-20 23:59:56 -0700892 /*
893 * If no pending req in epoch, this is an error case.
894 * Just go back to the bubble state.
895 */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700896 CAM_ERR(CAM_ISP, "No pending request.");
Jing Zhoudedc4762017-06-19 17:45:36 +0530897 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
898 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
899
Jing Zhoud352ed12017-03-20 23:59:56 -0700900 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE;
901 goto end;
902 }
903
Junzhe Zoue7d56fc2018-08-10 14:50:17 -0700904 req = list_first_entry(&ctx->wait_req_list, struct cam_ctx_request,
Jing Zhoud352ed12017-03-20 23:59:56 -0700905 list);
906 req_isp = (struct cam_isp_ctx_req *)req->req_priv;
Junzhe Zou09820a72018-09-06 18:11:41 -0700907 req_isp->bubble_detected = true;
Jing Zhoud352ed12017-03-20 23:59:56 -0700908
909 if (req_isp->bubble_report && ctx->ctx_crm_intf &&
910 ctx->ctx_crm_intf->notify_err) {
911 struct cam_req_mgr_error_notify notify;
912
913 notify.link_hdl = ctx->link_hdl;
914 notify.dev_hdl = ctx->dev_hdl;
915 notify.req_id = req->request_id;
916 notify.error = CRM_KMD_ERR_BUBBLE;
917 ctx->ctx_crm_intf->notify_err(&notify);
Karthik Anantha Ram5438d572018-06-15 10:48:19 -0700918 CAM_DBG(CAM_REQ,
919 "Notify CRM about Bubble req_id %llu frame %lld",
920 req->request_id, ctx_isp->frame_id);
Jing Zhou45b55cc2017-05-16 17:27:18 -0700921 } else {
Jing Zhou45b55cc2017-05-16 17:27:18 -0700922 req_isp->bubble_report = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -0700923 }
924
Junzhe Zou09820a72018-09-06 18:11:41 -0700925 /*
926 * Always move the request to active list. Let buf done
927 * function handles the rest.
928 */
929 CAM_DBG(CAM_ISP, "move request %lld to active list(cnt = %d)",
930 req->request_id, ctx_isp->active_req_cnt);
931 ctx_isp->active_req_cnt++;
932 list_del_init(&req->list);
933 list_add_tail(&req->list, &ctx->active_req_list);
934
Ravikishore Pampana6648f172017-12-08 20:29:11 +0530935 if (!req_isp->bubble_report) {
936 if (req->request_id > ctx_isp->reported_req_id) {
937 request_id = req->request_id;
938 ctx_isp->reported_req_id = request_id;
939 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
940 CAM_REQ_MGR_SOF_EVENT_ERROR);
941 } else
942 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
943 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
944 } else
945 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
946 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
Jing Zhoudedc4762017-06-19 17:45:36 +0530947
Jing Zhoud352ed12017-03-20 23:59:56 -0700948 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700949 CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated);
Jing Zhoud352ed12017-03-20 23:59:56 -0700950end:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700951 req = list_last_entry(&ctx->active_req_list, struct cam_ctx_request,
952 list);
Junzhe Zoue7d56fc2018-08-10 14:50:17 -0700953 if (req)
954 __cam_isp_ctx_update_state_monitor_array(ctx_isp,
955 CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, req->request_id);
Jing Zhoud352ed12017-03-20 23:59:56 -0700956 return 0;
957}
958
959static int __cam_isp_ctx_buf_done_in_bubble_applied(
960 struct cam_isp_context *ctx_isp, void *evt_data)
961{
962 int rc = 0;
963 struct cam_isp_hw_done_event_data *done =
964 (struct cam_isp_hw_done_event_data *) evt_data;
965
966 rc = __cam_isp_ctx_handle_buf_done_in_activated_state(ctx_isp, done, 1);
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -0700967 __cam_isp_ctx_update_state_monitor_array(ctx_isp,
968 CAM_ISP_STATE_CHANGE_TRIGGER_DONE,
969 ctx_isp->base->req_list->request_id);
Jing Zhoud352ed12017-03-20 23:59:56 -0700970 return rc;
971}
972
973static int __cam_isp_ctx_handle_error(struct cam_isp_context *ctx_isp,
974 void *evt_data)
975{
976 int rc = 0;
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +0530977 uint32_t i = 0;
978 bool found = 0;
979 struct cam_ctx_request *req = NULL;
980 struct cam_ctx_request *req_temp;
981 struct cam_isp_ctx_req *req_isp = NULL;
Jing Zhoud352ed12017-03-20 23:59:56 -0700982 struct cam_req_mgr_error_notify notify;
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +0530983 uint64_t error_request_id;
Vishalsingh Hajeri7a431b72018-03-01 14:07:24 -0800984 struct cam_hw_fence_map_entry *fence_map_out = NULL;
Jing Zhoud352ed12017-03-20 23:59:56 -0700985
986 struct cam_context *ctx = ctx_isp->base;
987 struct cam_isp_hw_error_event_data *error_event_data =
988 (struct cam_isp_hw_error_event_data *)evt_data;
989
990 uint32_t error_type = error_event_data->error_type;
991
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700992 CAM_DBG(CAM_ISP, "Enter error_type = %d", error_type);
Jing Zhoud352ed12017-03-20 23:59:56 -0700993 if ((error_type == CAM_ISP_HW_ERROR_OVERFLOW) ||
994 (error_type == CAM_ISP_HW_ERROR_BUSIF_OVERFLOW))
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +0530995 notify.error = CRM_KMD_ERR_OVERFLOW;
Jing Zhoud352ed12017-03-20 23:59:56 -0700996
997 /*
998 * Need to check the active req
999 * move all of them to the pending request list
1000 * Note this funciton need revisit!
1001 */
1002
1003 if (list_empty(&ctx->active_req_list)) {
Harsh Shahcb0072c2017-09-26 19:22:10 -07001004 CAM_ERR_RATE_LIMIT(CAM_ISP,
1005 "handling error with no active request");
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +05301006 } else {
1007 list_for_each_entry_safe(req, req_temp,
1008 &ctx->active_req_list, list) {
1009 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
1010 if (!req_isp->bubble_report) {
1011 for (i = 0; i < req_isp->num_fence_map_out;
1012 i++) {
Vishalsingh Hajeri7a431b72018-03-01 14:07:24 -08001013 fence_map_out =
1014 &req_isp->fence_map_out[i];
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +05301015 CAM_ERR(CAM_ISP, "req %llu, Sync fd %x",
Vishalsingh Hajeri7a431b72018-03-01 14:07:24 -08001016 req->request_id,
1017 req_isp->fence_map_out[i].sync_id);
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +05301018 if (req_isp->fence_map_out[i].sync_id
1019 != -1) {
1020 rc = cam_sync_signal(
Vishalsingh Hajeri7a431b72018-03-01 14:07:24 -08001021 fence_map_out->sync_id,
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +05301022 CAM_SYNC_STATE_SIGNALED_ERROR);
Vishalsingh Hajeri7a431b72018-03-01 14:07:24 -08001023 fence_map_out->sync_id =
1024 -1;
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +05301025 }
1026 }
1027 list_del_init(&req->list);
1028 list_add_tail(&req->list, &ctx->free_req_list);
1029 ctx_isp->active_req_cnt--;
1030 } else {
1031 found = 1;
1032 break;
1033 }
1034 }
Jing Zhoud352ed12017-03-20 23:59:56 -07001035 }
1036
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +05301037 if (found) {
1038 list_for_each_entry_safe_reverse(req, req_temp,
1039 &ctx->active_req_list, list) {
1040 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
1041 list_del_init(&req->list);
1042 list_add(&req->list, &ctx->pending_req_list);
1043 ctx_isp->active_req_cnt--;
1044 }
1045 }
1046
1047 do {
1048 if (list_empty(&ctx->pending_req_list)) {
1049 error_request_id = ctx_isp->last_applied_req_id + 1;
1050 req_isp = NULL;
1051 break;
1052 }
1053 req = list_first_entry(&ctx->pending_req_list,
1054 struct cam_ctx_request, list);
1055 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
1056 error_request_id = ctx_isp->last_applied_req_id;
1057
1058 if (req_isp->bubble_report)
1059 break;
1060
1061 for (i = 0; i < req_isp->num_fence_map_out; i++) {
1062 if (req_isp->fence_map_out[i].sync_id != -1)
1063 rc = cam_sync_signal(
1064 req_isp->fence_map_out[i].sync_id,
1065 CAM_SYNC_STATE_SIGNALED_ERROR);
1066 req_isp->fence_map_out[i].sync_id = -1;
1067 }
1068 list_del_init(&req->list);
1069 list_add_tail(&req->list, &ctx->free_req_list);
1070
1071 } while (req->request_id < ctx_isp->last_applied_req_id);
1072
Jing Zhoud352ed12017-03-20 23:59:56 -07001073
1074 if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_err) {
1075 notify.link_hdl = ctx->link_hdl;
1076 notify.dev_hdl = ctx->dev_hdl;
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +05301077 notify.req_id = error_request_id;
1078
1079 if (req_isp && req_isp->bubble_report)
1080 notify.error = CRM_KMD_ERR_BUBBLE;
1081
1082 CAM_WARN(CAM_ISP, "Notify CRM: req %lld, frame %lld\n",
1083 error_request_id, ctx_isp->frame_id);
Jing Zhoud352ed12017-03-20 23:59:56 -07001084
1085 ctx->ctx_crm_intf->notify_err(&notify);
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +05301086 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_HW_ERROR;
Jing Zhoud352ed12017-03-20 23:59:56 -07001087 } else {
Harsh Shahcb0072c2017-09-26 19:22:10 -07001088 CAM_ERR_RATE_LIMIT(CAM_ISP, "Can not notify ERRROR to CRM");
Jing Zhoud352ed12017-03-20 23:59:56 -07001089 rc = -EFAULT;
1090 }
1091
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -07001092
1093 list_del_init(&req->list);
1094 list_add(&req->list, &ctx->pending_req_list);
1095 /* might need to check if active list is empty */
1096 if (req != NULL) {
1097 __cam_isp_ctx_update_state_monitor_array(ctx_isp,
1098 CAM_ISP_STATE_CHANGE_TRIGGER_ERROR, req->request_id);
1099 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001100 CAM_DBG(CAM_ISP, "Exit");
Jing Zhoud352ed12017-03-20 23:59:56 -07001101 return rc;
1102}
1103
1104static struct cam_isp_ctx_irq_ops
1105 cam_isp_ctx_activated_state_machine_irq[CAM_ISP_CTX_ACTIVATED_MAX] = {
1106 /* SOF */
1107 {
1108 .irq_ops = {
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +05301109 __cam_isp_ctx_handle_error,
Jing Zhoudedc4762017-06-19 17:45:36 +05301110 __cam_isp_ctx_sof_in_activated_state,
Jing Zhoud352ed12017-03-20 23:59:56 -07001111 __cam_isp_ctx_reg_upd_in_sof,
1112 __cam_isp_ctx_notify_sof_in_actived_state,
Junzhe Zou2df84502017-05-26 13:20:23 -07001113 __cam_isp_ctx_notify_eof_in_actived_state,
Jing Zhoud352ed12017-03-20 23:59:56 -07001114 NULL,
1115 },
1116 },
1117 /* APPLIED */
1118 {
1119 .irq_ops = {
1120 __cam_isp_ctx_handle_error,
Jing Zhoudedc4762017-06-19 17:45:36 +05301121 __cam_isp_ctx_sof_in_activated_state,
Jing Zhoud352ed12017-03-20 23:59:56 -07001122 __cam_isp_ctx_reg_upd_in_activated_state,
1123 __cam_isp_ctx_epoch_in_applied,
Junzhe Zou2df84502017-05-26 13:20:23 -07001124 __cam_isp_ctx_notify_eof_in_actived_state,
Jing Zhoud352ed12017-03-20 23:59:56 -07001125 __cam_isp_ctx_buf_done_in_applied,
1126 },
1127 },
1128 /* EPOCH */
1129 {
1130 .irq_ops = {
1131 __cam_isp_ctx_handle_error,
1132 __cam_isp_ctx_sof_in_epoch,
Karthik Anantha Ram15326072018-05-18 14:47:00 -07001133 __cam_isp_ctx_reg_upd_in_epoch_state,
Jing Zhoud352ed12017-03-20 23:59:56 -07001134 __cam_isp_ctx_notify_sof_in_actived_state,
Junzhe Zou2df84502017-05-26 13:20:23 -07001135 __cam_isp_ctx_notify_eof_in_actived_state,
Jing Zhoud352ed12017-03-20 23:59:56 -07001136 __cam_isp_ctx_buf_done_in_epoch,
1137 },
1138 },
1139 /* BUBBLE */
1140 {
1141 .irq_ops = {
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +05301142 __cam_isp_ctx_handle_error,
Jing Zhoudedc4762017-06-19 17:45:36 +05301143 __cam_isp_ctx_sof_in_activated_state,
Jing Zhoud352ed12017-03-20 23:59:56 -07001144 NULL,
1145 __cam_isp_ctx_notify_sof_in_actived_state,
Junzhe Zou2df84502017-05-26 13:20:23 -07001146 __cam_isp_ctx_notify_eof_in_actived_state,
Jing Zhoud352ed12017-03-20 23:59:56 -07001147 __cam_isp_ctx_buf_done_in_bubble,
1148 },
1149 },
1150 /* Bubble Applied */
1151 {
1152 .irq_ops = {
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +05301153 __cam_isp_ctx_handle_error,
Jing Zhoudedc4762017-06-19 17:45:36 +05301154 __cam_isp_ctx_sof_in_activated_state,
Jing Zhoud352ed12017-03-20 23:59:56 -07001155 __cam_isp_ctx_reg_upd_in_activated_state,
1156 __cam_isp_ctx_epoch_in_bubble_applied,
1157 NULL,
1158 __cam_isp_ctx_buf_done_in_bubble_applied,
1159 },
1160 },
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +05301161 /* HW ERROR */
1162 {
1163 .irq_ops = {
1164 NULL,
1165 __cam_isp_ctx_sof_in_activated_state,
1166 __cam_isp_ctx_reg_upd_in_hw_error,
1167 NULL,
1168 NULL,
1169 NULL,
1170 },
1171 },
Jing Zhoud352ed12017-03-20 23:59:56 -07001172 /* HALT */
1173 {
1174 },
1175};
1176
1177static int __cam_isp_ctx_apply_req_in_activated_state(
1178 struct cam_context *ctx, struct cam_req_mgr_apply_request *apply,
1179 uint32_t next_state)
1180{
1181 int rc = 0;
1182 struct cam_ctx_request *req;
Karthik Anantha Ramb9474402018-08-27 16:14:56 -07001183 struct cam_ctx_request *active_req = NULL;
Jing Zhoud352ed12017-03-20 23:59:56 -07001184 struct cam_isp_ctx_req *req_isp;
Harsh Shah1b8eb232017-10-09 19:20:52 -07001185 struct cam_isp_ctx_req *active_req_isp;
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -07001186 struct cam_isp_context *ctx_isp = NULL;
Jing Zhoud352ed12017-03-20 23:59:56 -07001187 struct cam_hw_config_args cfg;
1188
1189 if (list_empty(&ctx->pending_req_list)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001190 CAM_ERR(CAM_ISP, "No available request for Apply id %lld",
1191 apply->request_id);
Jing Zhoud352ed12017-03-20 23:59:56 -07001192 rc = -EFAULT;
1193 goto end;
1194 }
Jing Zhou9eabf472017-05-16 11:59:41 -07001195
1196 /*
1197 * When the pipeline has issue, the requests can be queued up in the
1198 * pipeline. In this case, we should reject the additional request.
1199 * The maximum number of request allowed to be outstanding is 2.
1200 *
1201 */
Jing Zhoudedc4762017-06-19 17:45:36 +05301202 ctx_isp = (struct cam_isp_context *) ctx->ctx_priv;
Ayush Kumarf13969a92019-07-18 13:02:43 +05301203 if (atomic_read(&ctx_isp->process_bubble)) {
1204 CAM_ERR_RATE_LIMIT(CAM_ISP,
1205 "Processing bubble cannot apply Request Id %llu",
1206 apply->request_id);
1207 rc = -EAGAIN;
1208 goto end;
1209 }
1210
Karthik Anantha Ramb9474402018-08-27 16:14:56 -07001211 spin_lock_bh(&ctx->lock);
Jing Zhoud352ed12017-03-20 23:59:56 -07001212 req = list_first_entry(&ctx->pending_req_list, struct cam_ctx_request,
1213 list);
Karthik Anantha Ramb9474402018-08-27 16:14:56 -07001214 spin_unlock_bh(&ctx->lock);
Jing Zhoud352ed12017-03-20 23:59:56 -07001215
1216 /*
1217 * Check whehter the request id is matching the tip, if not, this means
1218 * we are in the middle of the error handling. Need to reject this apply
1219 */
1220 if (req->request_id != apply->request_id) {
Harsh Shahf7136392017-08-29 12:42:52 -07001221 CAM_ERR_RATE_LIMIT(CAM_ISP,
1222 "Invalid Request Id asking %llu existing %llu",
1223 apply->request_id, req->request_id);
Jing Zhoud352ed12017-03-20 23:59:56 -07001224 rc = -EFAULT;
1225 goto end;
1226 }
1227
Karthik Anantha Ram5438d572018-06-15 10:48:19 -07001228 CAM_DBG(CAM_REQ, "Apply request %lld in substate %d", req->request_id,
1229 ctx_isp->substate_activated);
Jing Zhoud352ed12017-03-20 23:59:56 -07001230 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
Jing Zhoud352ed12017-03-20 23:59:56 -07001231
Chandan Gera5c1e31b2018-12-09 07:44:05 +05301232 if (ctx_isp->active_req_cnt >= 4) {
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -07001233 CAM_ERR_RATE_LIMIT(CAM_ISP,
Harsh Shah1b8eb232017-10-09 19:20:52 -07001234 "Reject apply request (id %lld) due to congestion(cnt = %d)",
1235 req->request_id,
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -07001236 ctx_isp->active_req_cnt);
Karthik Anantha Ramb9474402018-08-27 16:14:56 -07001237
1238 spin_lock_bh(&ctx->lock);
1239 if (!list_empty(&ctx->active_req_list))
Harsh Shah1b8eb232017-10-09 19:20:52 -07001240 active_req = list_first_entry(&ctx->active_req_list,
1241 struct cam_ctx_request, list);
Karthik Anantha Ramb9474402018-08-27 16:14:56 -07001242 else
Harsh Shah1b8eb232017-10-09 19:20:52 -07001243 CAM_ERR_RATE_LIMIT(CAM_ISP,
1244 "WARNING: should not happen (cnt = %d) but active_list empty",
1245 ctx_isp->active_req_cnt);
Karthik Anantha Ramb9474402018-08-27 16:14:56 -07001246 spin_unlock_bh(&ctx->lock);
1247
1248 if (active_req) {
1249 active_req_isp =
1250 (struct cam_isp_ctx_req *) active_req->req_priv;
1251 __cam_isp_ctx_handle_buf_done_fail_log(active_req_isp);
Harsh Shah1b8eb232017-10-09 19:20:52 -07001252 }
Karthik Anantha Ramb9474402018-08-27 16:14:56 -07001253
1254 rc = -EFAULT;
1255 goto end;
Karthik Anantha Ramba3bd972017-09-25 15:35:26 -07001256 }
Jing Zhoud352ed12017-03-20 23:59:56 -07001257 req_isp->bubble_report = apply->report_if_bubble;
1258
1259 cfg.ctxt_to_hw_map = ctx_isp->hw_ctx;
Venkat Chintad983df82018-03-14 12:54:40 -07001260 cfg.request_id = req->request_id;
Jing Zhoud352ed12017-03-20 23:59:56 -07001261 cfg.hw_update_entries = req_isp->cfg;
1262 cfg.num_hw_update_entries = req_isp->num_cfg;
Vishalsingh Hajerie5450be2018-01-18 20:31:19 -08001263 cfg.priv = &req_isp->hw_update_data;
Junzhe Zou4d505a52018-04-10 14:43:33 -07001264 cfg.init_packet = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -07001265
1266 rc = ctx->hw_mgr_intf->hw_config(ctx->hw_mgr_intf->hw_mgr_priv, &cfg);
1267 if (rc) {
Harsh Shahcb0072c2017-09-26 19:22:10 -07001268 CAM_ERR_RATE_LIMIT(CAM_ISP, "Can not apply the configuration");
Jing Zhoud352ed12017-03-20 23:59:56 -07001269 } else {
Jing Zhou93b3ec12017-06-15 17:43:39 -07001270 spin_lock_bh(&ctx->lock);
Jing Zhoud352ed12017-03-20 23:59:56 -07001271 ctx_isp->substate_activated = next_state;
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +05301272 ctx_isp->last_applied_req_id = apply->request_id;
Junzhe Zoufdcd4722018-06-11 18:05:33 -07001273 list_del_init(&req->list);
1274 list_add_tail(&req->list, &ctx->wait_req_list);
Alok Pandeyfdfa5ba2017-09-22 14:21:25 +05301275 CAM_DBG(CAM_ISP, "new substate state %d, applied req %lld",
1276 next_state, ctx_isp->last_applied_req_id);
Jing Zhou93b3ec12017-06-15 17:43:39 -07001277 spin_unlock_bh(&ctx->lock);
Jing Zhoud352ed12017-03-20 23:59:56 -07001278 }
1279end:
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -07001280 if (ctx_isp != NULL) {
1281 __cam_isp_ctx_update_state_monitor_array(ctx_isp,
1282 CAM_ISP_STATE_CHANGE_TRIGGER_SOF,
1283 ctx->req_list->request_id);
1284 }
Jing Zhoud352ed12017-03-20 23:59:56 -07001285 return rc;
1286}
1287
1288static int __cam_isp_ctx_apply_req_in_sof(
1289 struct cam_context *ctx, struct cam_req_mgr_apply_request *apply)
1290{
1291 int rc = 0;
1292 struct cam_isp_context *ctx_isp =
1293 (struct cam_isp_context *) ctx->ctx_priv;
1294
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001295 CAM_DBG(CAM_ISP, "current substate %d",
Jing Zhoud352ed12017-03-20 23:59:56 -07001296 ctx_isp->substate_activated);
1297 rc = __cam_isp_ctx_apply_req_in_activated_state(ctx, apply,
1298 CAM_ISP_CTX_ACTIVATED_APPLIED);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001299 CAM_DBG(CAM_ISP, "new substate %d", ctx_isp->substate_activated);
Jing Zhoud352ed12017-03-20 23:59:56 -07001300
1301 return rc;
1302}
1303
1304static int __cam_isp_ctx_apply_req_in_epoch(
1305 struct cam_context *ctx, struct cam_req_mgr_apply_request *apply)
1306{
1307 int rc = 0;
1308 struct cam_isp_context *ctx_isp =
1309 (struct cam_isp_context *) ctx->ctx_priv;
1310
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001311 CAM_DBG(CAM_ISP, "current substate %d",
Jing Zhoud352ed12017-03-20 23:59:56 -07001312 ctx_isp->substate_activated);
1313 rc = __cam_isp_ctx_apply_req_in_activated_state(ctx, apply,
1314 CAM_ISP_CTX_ACTIVATED_APPLIED);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001315 CAM_DBG(CAM_ISP, "new substate %d", ctx_isp->substate_activated);
Jing Zhoud352ed12017-03-20 23:59:56 -07001316
1317 return rc;
1318}
1319
1320static int __cam_isp_ctx_apply_req_in_bubble(
1321 struct cam_context *ctx, struct cam_req_mgr_apply_request *apply)
1322{
1323 int rc = 0;
1324 struct cam_isp_context *ctx_isp =
1325 (struct cam_isp_context *) ctx->ctx_priv;
1326
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001327 CAM_DBG(CAM_ISP, "current substate %d",
Jing Zhoud352ed12017-03-20 23:59:56 -07001328 ctx_isp->substate_activated);
1329 rc = __cam_isp_ctx_apply_req_in_activated_state(ctx, apply,
1330 CAM_ISP_CTX_ACTIVATED_BUBBLE_APPLIED);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001331 CAM_DBG(CAM_ISP, "new substate %d", ctx_isp->substate_activated);
Jing Zhoud352ed12017-03-20 23:59:56 -07001332
1333 return rc;
1334}
1335
Jing Zhoub524a852017-05-16 15:47:30 +05301336static int __cam_isp_ctx_flush_req(struct cam_context *ctx,
1337 struct list_head *req_list, struct cam_req_mgr_flush_request *flush_req)
1338{
1339 int i, rc;
1340 uint32_t cancel_req_id_found = 0;
1341 struct cam_ctx_request *req;
1342 struct cam_ctx_request *req_temp;
1343 struct cam_isp_ctx_req *req_isp;
Alok Pandeyf308aec2018-01-22 18:10:59 +05301344 struct list_head flush_list;
Jing Zhoub524a852017-05-16 15:47:30 +05301345
Alok Pandeyf308aec2018-01-22 18:10:59 +05301346 INIT_LIST_HEAD(&flush_list);
Jing Zhoub524a852017-05-16 15:47:30 +05301347 if (list_empty(req_list)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001348 CAM_DBG(CAM_ISP, "request list is empty");
Junzhe Zoufdcd4722018-06-11 18:05:33 -07001349 if (flush_req->type == CAM_REQ_MGR_FLUSH_TYPE_CANCEL_REQ) {
1350 CAM_ERR(CAM_ISP, "no request to cancel");
1351 return -EINVAL;
1352 } else
1353 return 0;
Jing Zhoub524a852017-05-16 15:47:30 +05301354 }
1355
Karthik Anantha Ram5438d572018-06-15 10:48:19 -07001356 CAM_DBG(CAM_REQ, "Flush [%u] in progress for req_id %llu",
1357 flush_req->type, flush_req->req_id);
Jing Zhoub524a852017-05-16 15:47:30 +05301358 list_for_each_entry_safe(req, req_temp, req_list, list) {
Alok Pandeyf308aec2018-01-22 18:10:59 +05301359 if (flush_req->type == CAM_REQ_MGR_FLUSH_TYPE_CANCEL_REQ) {
1360 if (req->request_id != flush_req->req_id) {
1361 continue;
1362 } else {
1363 list_del_init(&req->list);
1364 list_add_tail(&req->list, &flush_list);
1365 cancel_req_id_found = 1;
1366 break;
1367 }
1368 }
Jing Zhoub524a852017-05-16 15:47:30 +05301369 list_del_init(&req->list);
Alok Pandeyf308aec2018-01-22 18:10:59 +05301370 list_add_tail(&req->list, &flush_list);
1371 }
Alok Pandeyf308aec2018-01-22 18:10:59 +05301372
1373 list_for_each_entry_safe(req, req_temp, &flush_list, list) {
Jing Zhoub524a852017-05-16 15:47:30 +05301374 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
1375 for (i = 0; i < req_isp->num_fence_map_out; i++) {
1376 if (req_isp->fence_map_out[i].sync_id != -1) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001377 CAM_DBG(CAM_ISP, "Flush req 0x%llx, fence %d",
1378 req->request_id,
Jing Zhoub524a852017-05-16 15:47:30 +05301379 req_isp->fence_map_out[i].sync_id);
1380 rc = cam_sync_signal(
1381 req_isp->fence_map_out[i].sync_id,
1382 CAM_SYNC_STATE_SIGNALED_ERROR);
1383 if (rc)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001384 CAM_ERR_RATE_LIMIT(CAM_ISP,
1385 "signal fence failed\n");
Jing Zhoub524a852017-05-16 15:47:30 +05301386 req_isp->fence_map_out[i].sync_id = -1;
1387 }
1388 }
1389 list_add_tail(&req->list, &ctx->free_req_list);
Jing Zhoub524a852017-05-16 15:47:30 +05301390 }
Jing Zhoub524a852017-05-16 15:47:30 +05301391
1392 if (flush_req->type == CAM_REQ_MGR_FLUSH_TYPE_CANCEL_REQ &&
Vishalsingh Hajeri53ba6ff2018-05-09 18:07:15 -07001393 !cancel_req_id_found) {
1394 CAM_INFO(CAM_ISP,
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001395 "Flush request id:%lld is not found in the list",
1396 flush_req->req_id);
Vishalsingh Hajeri53ba6ff2018-05-09 18:07:15 -07001397 return -EINVAL;
1398 }
Jing Zhoub524a852017-05-16 15:47:30 +05301399
1400 return 0;
1401}
1402
1403static int __cam_isp_ctx_flush_req_in_top_state(
1404 struct cam_context *ctx,
1405 struct cam_req_mgr_flush_request *flush_req)
1406{
Alok Pandey12ce5ba2018-07-03 14:34:22 +05301407 struct cam_isp_context *ctx_isp =
1408 (struct cam_isp_context *) ctx->ctx_priv;
1409 struct cam_isp_stop_args stop_isp;
1410 struct cam_hw_stop_args stop_args;
1411 struct cam_isp_start_args start_isp;
Mangalaram ARCHANAc91892a2019-07-12 14:47:01 +05301412 struct cam_hw_reset_args reset_args;
Jing Zhoub524a852017-05-16 15:47:30 +05301413 int rc = 0;
1414
Mangalaram ARCHANAc91892a2019-07-12 14:47:01 +05301415 CAM_DBG(CAM_ISP, "ctx id:%d try to flush pending list",
1416 ctx->ctx_id);
Venkat Chintac8e610f2018-05-08 17:40:44 -07001417 spin_lock_bh(&ctx->lock);
Jing Zhoub524a852017-05-16 15:47:30 +05301418 rc = __cam_isp_ctx_flush_req(ctx, &ctx->pending_req_list, flush_req);
Venkat Chintac8e610f2018-05-08 17:40:44 -07001419 spin_unlock_bh(&ctx->lock);
Alok Pandey12ce5ba2018-07-03 14:34:22 +05301420
Ayush Kumarf13969a92019-07-18 13:02:43 +05301421 atomic_set(&ctx_isp->process_bubble, 0);
Shravya Samala43583ea2020-04-29 14:25:37 +05301422 atomic_set(&ctx_isp->bubble_sof_count, 0);
Alok Pandey12ce5ba2018-07-03 14:34:22 +05301423 if (flush_req->type == CAM_REQ_MGR_FLUSH_TYPE_ALL) {
1424 /* if active and wait list are empty, return */
1425 spin_lock_bh(&ctx->lock);
1426 if ((list_empty(&ctx->wait_req_list)) &&
1427 (list_empty(&ctx->active_req_list))) {
1428 spin_unlock_bh(&ctx->lock);
Mangalaram ARCHANAc91892a2019-07-12 14:47:01 +05301429 CAM_DBG(CAM_ISP,
1430 "ctx id:%d active and wait list are empty",
1431 ctx->ctx_id);
Alok Pandey12ce5ba2018-07-03 14:34:22 +05301432 goto end;
1433 }
1434 spin_unlock_bh(&ctx->lock);
1435
1436 /* Stop hw first before active list flush */
1437 stop_args.ctxt_to_hw_map = ctx_isp->hw_ctx;
1438 stop_isp.hw_stop_cmd = CAM_ISP_HW_STOP_AT_FRAME_BOUNDARY;
1439 stop_isp.stop_only = true;
1440 stop_args.args = (void *)&stop_isp;
1441 ctx->hw_mgr_intf->hw_stop(ctx->hw_mgr_intf->hw_mgr_priv,
1442 &stop_args);
Mangalaram ARCHANAc91892a2019-07-12 14:47:01 +05301443 CAM_DBG(CAM_ISP, "try to reset hw");
1444 /* Reset hw */
1445 reset_args.ctxt_to_hw_map = ctx_isp->hw_ctx;
1446 rc = ctx->hw_mgr_intf->hw_reset(ctx->hw_mgr_intf->hw_mgr_priv,
1447 &reset_args);
1448 if (rc)
1449 goto end;
Alok Pandey12ce5ba2018-07-03 14:34:22 +05301450
1451 spin_lock_bh(&ctx->lock);
Mangalaram ARCHANAc91892a2019-07-12 14:47:01 +05301452 CAM_DBG(CAM_ISP, "ctx id:%d try to flush wait list",
1453 ctx->ctx_id);
Alok Pandey12ce5ba2018-07-03 14:34:22 +05301454 rc = __cam_isp_ctx_flush_req(ctx, &ctx->wait_req_list,
1455 flush_req);
Mangalaram ARCHANAc91892a2019-07-12 14:47:01 +05301456 CAM_DBG(CAM_ISP, "ctx id:%d try to flush active list",
1457 ctx->ctx_id);
Alok Pandey12ce5ba2018-07-03 14:34:22 +05301458 rc = __cam_isp_ctx_flush_req(ctx, &ctx->active_req_list,
1459 flush_req);
Junzhe Zou09820a72018-09-06 18:11:41 -07001460 ctx_isp->active_req_cnt = 0;
Alok Pandey12ce5ba2018-07-03 14:34:22 +05301461 spin_unlock_bh(&ctx->lock);
1462
1463 /* Start hw */
1464 start_isp.hw_config.ctxt_to_hw_map = ctx_isp->hw_ctx;
1465 start_isp.start_only = true;
1466 start_isp.hw_config.priv = NULL;
1467
1468 rc = ctx->hw_mgr_intf->hw_start(ctx->hw_mgr_intf->hw_mgr_priv,
1469 &start_isp);
1470 }
1471
1472end:
Mangalaram ARCHANAc91892a2019-07-12 14:47:01 +05301473 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
1474 CAM_DBG(CAM_ISP, "ctx id:%d Flush request in top state %d",
1475 ctx->ctx_id, ctx->state);
Jing Zhoub524a852017-05-16 15:47:30 +05301476 return rc;
1477}
1478
1479static int __cam_isp_ctx_flush_req_in_ready(
1480 struct cam_context *ctx,
1481 struct cam_req_mgr_flush_request *flush_req)
1482{
1483 int rc = 0;
1484
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001485 CAM_DBG(CAM_ISP, "try to flush pending list");
Venkat Chintac8e610f2018-05-08 17:40:44 -07001486 spin_lock_bh(&ctx->lock);
Jing Zhoub524a852017-05-16 15:47:30 +05301487 rc = __cam_isp_ctx_flush_req(ctx, &ctx->pending_req_list, flush_req);
1488
Alok Pandey12ce5ba2018-07-03 14:34:22 +05301489 /* if nothing is in pending req list, change state to acquire */
Jing Zhoub524a852017-05-16 15:47:30 +05301490 if (list_empty(&ctx->pending_req_list))
1491 ctx->state = CAM_CTX_ACQUIRED;
Harsh Shah7835b3b2017-11-20 17:39:11 -08001492 spin_unlock_bh(&ctx->lock);
Jing Zhoub524a852017-05-16 15:47:30 +05301493
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06001494 trace_cam_context_state("ISP", ctx);
1495
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001496 CAM_DBG(CAM_ISP, "Flush request in ready state. next state %d",
1497 ctx->state);
Jing Zhoub524a852017-05-16 15:47:30 +05301498 return rc;
1499}
1500
Jing Zhoud352ed12017-03-20 23:59:56 -07001501static struct cam_ctx_ops
1502 cam_isp_ctx_activated_state_machine[CAM_ISP_CTX_ACTIVATED_MAX] = {
1503 /* SOF */
1504 {
1505 .ioctl_ops = {},
1506 .crm_ops = {
1507 .apply_req = __cam_isp_ctx_apply_req_in_sof,
1508 },
1509 .irq_ops = NULL,
1510 },
1511 /* APPLIED */
1512 {
1513 .ioctl_ops = {},
1514 .crm_ops = {},
1515 .irq_ops = NULL,
1516 },
1517 /* EPOCH */
1518 {
1519 .ioctl_ops = {},
1520 .crm_ops = {
1521 .apply_req = __cam_isp_ctx_apply_req_in_epoch,
1522 },
1523 .irq_ops = NULL,
1524 },
1525 /* BUBBLE */
1526 {
1527 .ioctl_ops = {},
1528 .crm_ops = {
1529 .apply_req = __cam_isp_ctx_apply_req_in_bubble,
1530 },
1531 .irq_ops = NULL,
1532 },
1533 /* Bubble Applied */
1534 {
1535 .ioctl_ops = {},
1536 .crm_ops = {},
1537 .irq_ops = NULL,
1538 },
Jing Zhou4d4f03e2018-01-16 18:10:31 -08001539 /* HW ERROR */
1540 {
1541 .ioctl_ops = {},
1542 .crm_ops = {},
1543 .irq_ops = NULL,
1544 },
Jing Zhoud352ed12017-03-20 23:59:56 -07001545 /* HALT */
1546 {
1547 .ioctl_ops = {},
1548 .crm_ops = {},
1549 .irq_ops = NULL,
1550 },
1551};
1552
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301553static int __cam_isp_ctx_rdi_only_sof_in_top_state(
1554 struct cam_isp_context *ctx_isp, void *evt_data)
1555{
1556 int rc = 0;
1557 struct cam_context *ctx = ctx_isp->base;
Junzhe Zou2df84502017-05-26 13:20:23 -07001558 struct cam_req_mgr_trigger_notify notify;
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301559 struct cam_isp_hw_sof_event_data *sof_event_data = evt_data;
1560 uint64_t request_id = 0;
1561
1562 if (!evt_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001563 CAM_ERR(CAM_ISP, "in valid sof event data");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301564 return -EINVAL;
1565 }
1566
1567 ctx_isp->frame_id++;
1568 ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
Karthik Anantha Ramc93754c2018-03-28 14:21:14 -07001569 ctx_isp->boot_timestamp = sof_event_data->boot_time;
1570
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001571 CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301572 ctx_isp->frame_id, ctx_isp->sof_timestamp_val);
1573
1574 /*
1575 * notify reqmgr with sof signal. Note, due to scheduling delay
1576 * we can run into situation that two active requests has already
1577 * be in the active queue while we try to do the notification.
1578 * In this case, we need to skip the current notification. This
1579 * helps the state machine to catch up the delay.
1580 */
Junzhe Zou2df84502017-05-26 13:20:23 -07001581 if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger &&
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301582 ctx_isp->active_req_cnt <= 2) {
1583 notify.link_hdl = ctx->link_hdl;
1584 notify.dev_hdl = ctx->dev_hdl;
1585 notify.frame_id = ctx_isp->frame_id;
Junzhe Zou2df84502017-05-26 13:20:23 -07001586 notify.trigger = CAM_TRIGGER_POINT_SOF;
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301587
Junzhe Zou2df84502017-05-26 13:20:23 -07001588 ctx->ctx_crm_intf->notify_trigger(&notify);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001589 CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301590 ctx_isp->frame_id);
1591
1592 /*
1593 * It is idle frame with out any applied request id, send
1594 * request id as zero
1595 */
1596 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
1597 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
1598 } else {
Harsh Shahcb0072c2017-09-26 19:22:10 -07001599 CAM_ERR_RATE_LIMIT(CAM_ISP, "Can not notify SOF to CRM");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301600 }
1601
1602 if (list_empty(&ctx->active_req_list))
1603 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
1604 else
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001605 CAM_DBG(CAM_ISP, "Still need to wait for the buf done");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301606
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001607 CAM_DBG(CAM_ISP, "next substate %d",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301608 ctx_isp->substate_activated);
1609 return rc;
1610}
1611
1612static int __cam_isp_ctx_rdi_only_sof_in_applied_state(
1613 struct cam_isp_context *ctx_isp, void *evt_data)
1614{
1615 struct cam_isp_hw_sof_event_data *sof_event_data = evt_data;
1616
1617 if (!evt_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001618 CAM_ERR(CAM_ISP, "in valid sof event data");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301619 return -EINVAL;
1620 }
1621
1622 ctx_isp->frame_id++;
1623 ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
Karthik Anantha Ramc93754c2018-03-28 14:21:14 -07001624 ctx_isp->boot_timestamp = sof_event_data->boot_time;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001625 CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301626 ctx_isp->frame_id, ctx_isp->sof_timestamp_val);
1627
1628 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE_APPLIED;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001629 CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301630
1631 return 0;
1632}
1633
1634static int __cam_isp_ctx_rdi_only_sof_in_bubble_applied(
1635 struct cam_isp_context *ctx_isp, void *evt_data)
1636{
1637 struct cam_ctx_request *req;
1638 struct cam_isp_ctx_req *req_isp;
1639 struct cam_context *ctx = ctx_isp->base;
1640 struct cam_isp_hw_sof_event_data *sof_event_data = evt_data;
1641 uint64_t request_id = 0;
1642
Ravikishore Pampana6648f172017-12-08 20:29:11 +05301643 /*
1644 * Sof in bubble applied state means, reg update not received.
1645 * before increment frame id and override time stamp value, send
1646 * the previous sof time stamp that got captured in the
1647 * sof in applied state.
1648 */
1649 CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx",
1650 ctx_isp->frame_id, ctx_isp->sof_timestamp_val);
1651 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
1652 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
1653
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301654 ctx_isp->frame_id++;
1655 ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
Karthik Anantha Ramc93754c2018-03-28 14:21:14 -07001656 ctx_isp->boot_timestamp = sof_event_data->boot_time;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001657 CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301658 ctx_isp->frame_id, ctx_isp->sof_timestamp_val);
1659
Junzhe Zou09820a72018-09-06 18:11:41 -07001660 if (list_empty(&ctx->wait_req_list)) {
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301661 /*
1662 * If no pending req in epoch, this is an error case.
1663 * The recovery is to go back to sof state
1664 */
Junzhe Zou09820a72018-09-06 18:11:41 -07001665 CAM_ERR(CAM_ISP, "No wait request");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301666 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
1667
1668 /* Send SOF event as empty frame*/
1669 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
1670 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
1671
1672 goto end;
1673 }
1674
Junzhe Zou09820a72018-09-06 18:11:41 -07001675 req = list_first_entry(&ctx->wait_req_list, struct cam_ctx_request,
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301676 list);
1677 req_isp = (struct cam_isp_ctx_req *)req->req_priv;
Junzhe Zou09820a72018-09-06 18:11:41 -07001678 req_isp->bubble_detected = true;
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301679
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001680 CAM_DBG(CAM_ISP, "Report Bubble flag %d", req_isp->bubble_report);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301681 if (req_isp->bubble_report && ctx->ctx_crm_intf &&
1682 ctx->ctx_crm_intf->notify_err) {
1683 struct cam_req_mgr_error_notify notify;
1684
1685 notify.link_hdl = ctx->link_hdl;
1686 notify.dev_hdl = ctx->dev_hdl;
1687 notify.req_id = req->request_id;
1688 notify.error = CRM_KMD_ERR_BUBBLE;
1689 ctx->ctx_crm_intf->notify_err(&notify);
Shravya Samala43583ea2020-04-29 14:25:37 +05301690 atomic_set(&ctx_isp->process_bubble, 1);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001691 CAM_DBG(CAM_ISP, "Notify CRM about Bubble frame %lld",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301692 ctx_isp->frame_id);
1693 } else {
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301694 req_isp->bubble_report = 0;
1695 }
1696
Junzhe Zou09820a72018-09-06 18:11:41 -07001697 /*
1698 * Always move the request to active list. Let buf done
1699 * function handles the rest.
1700 */
1701 ctx_isp->active_req_cnt++;
1702 list_del_init(&req->list);
1703 list_add_tail(&req->list, &ctx->active_req_list);
1704 CAM_DBG(CAM_ISP, "move request %lld to active list(cnt = %d)",
1705 req->request_id, ctx_isp->active_req_cnt);
1706
Ravikishore Pampana6648f172017-12-08 20:29:11 +05301707 if (!req_isp->bubble_report) {
1708 if (req->request_id > ctx_isp->reported_req_id) {
1709 request_id = req->request_id;
1710 ctx_isp->reported_req_id = request_id;
1711 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
1712 CAM_REQ_MGR_SOF_EVENT_ERROR);
1713 } else
1714 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
1715 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
1716 } else
1717 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
1718 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301719
1720 /* change the state to bubble, as reg update has not come */
1721 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001722 CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301723end:
1724 return 0;
1725}
1726
1727static int __cam_isp_ctx_rdi_only_sof_in_bubble_state(
1728 struct cam_isp_context *ctx_isp, void *evt_data)
1729{
1730 uint32_t i;
1731 struct cam_ctx_request *req;
1732 struct cam_context *ctx = ctx_isp->base;
Junzhe Zou2df84502017-05-26 13:20:23 -07001733 struct cam_req_mgr_trigger_notify notify;
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301734 struct cam_isp_hw_sof_event_data *sof_event_data = evt_data;
1735 struct cam_isp_ctx_req *req_isp;
1736 uint64_t request_id = 0;
1737
1738 if (!evt_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001739 CAM_ERR(CAM_ISP, "in valid sof event data");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301740 return -EINVAL;
1741 }
1742
1743 ctx_isp->frame_id++;
1744 ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
Karthik Anantha Ramc93754c2018-03-28 14:21:14 -07001745 ctx_isp->boot_timestamp = sof_event_data->boot_time;
Shravya Samala43583ea2020-04-29 14:25:37 +05301746 atomic_inc(&ctx_isp->bubble_sof_count);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001747 CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301748 ctx_isp->frame_id, ctx_isp->sof_timestamp_val);
Shravya Samala43583ea2020-04-29 14:25:37 +05301749
1750 if (atomic_read(&ctx_isp->process_bubble) &&
1751 (!list_empty(&ctx->active_req_list)) &&
1752 (atomic_read(&ctx_isp->bubble_sof_count) <
1753 CAM_ISP_CTX_BUBBLE_SOF_COUNT_MAX)) {
1754 CAM_INFO(CAM_ISP,
1755 "Processing bubble, bubble_sof_count :%u",
1756 atomic_read(&ctx_isp->bubble_sof_count));
1757 goto end;
1758 }
1759
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301760 /*
1761 * Signal all active requests with error and move the all the active
1762 * requests to free list
1763 */
1764 while (!list_empty(&ctx->active_req_list)) {
1765 req = list_first_entry(&ctx->active_req_list,
1766 struct cam_ctx_request, list);
1767 list_del_init(&req->list);
1768 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001769 CAM_DBG(CAM_ISP, "signal fence in active list. fence num %d",
1770 req_isp->num_fence_map_out);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301771 for (i = 0; i < req_isp->num_fence_map_out; i++)
1772 if (req_isp->fence_map_out[i].sync_id != -1) {
1773 cam_sync_signal(
1774 req_isp->fence_map_out[i].sync_id,
1775 CAM_SYNC_STATE_SIGNALED_ERROR);
1776 }
1777 list_add_tail(&req->list, &ctx->free_req_list);
Harsh Shah1b8eb232017-10-09 19:20:52 -07001778 ctx_isp->active_req_cnt--;
Shravya Samala43583ea2020-04-29 14:25:37 +05301779 atomic_set(&ctx_isp->bubble_sof_count, 0);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301780 }
1781
Shravya Samala43583ea2020-04-29 14:25:37 +05301782 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
1783end:
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301784 /* notify reqmgr with sof signal */
Junzhe Zou2df84502017-05-26 13:20:23 -07001785 if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger) {
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301786 notify.link_hdl = ctx->link_hdl;
1787 notify.dev_hdl = ctx->dev_hdl;
1788 notify.frame_id = ctx_isp->frame_id;
Junzhe Zou2df84502017-05-26 13:20:23 -07001789 notify.trigger = CAM_TRIGGER_POINT_SOF;
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301790
Junzhe Zou2df84502017-05-26 13:20:23 -07001791 ctx->ctx_crm_intf->notify_trigger(&notify);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001792 CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301793 ctx_isp->frame_id);
1794
1795 } else {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001796 CAM_ERR(CAM_ISP, "Can not notify SOF to CRM");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301797 }
1798
1799 /*
1800 * It is idle frame with out any applied request id, send
1801 * request id as zero
1802 */
1803 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
1804 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
1805
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001806 CAM_DBG(CAM_ISP, "next substate %d",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301807 ctx_isp->substate_activated);
1808
1809 return 0;
1810}
1811
1812static int __cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state(
1813 struct cam_isp_context *ctx_isp, void *evt_data)
1814{
1815 struct cam_ctx_request *req;
1816 struct cam_context *ctx = ctx_isp->base;
1817 struct cam_isp_ctx_req *req_isp;
Junzhe Zou2df84502017-05-26 13:20:23 -07001818 struct cam_req_mgr_trigger_notify notify;
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301819 uint64_t request_id = 0;
1820
Lynus Vazcbda4b02018-03-26 15:48:01 +05301821 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_EPOCH;
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301822 /* notify reqmgr with sof signal*/
Junzhe Zou2df84502017-05-26 13:20:23 -07001823 if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger) {
Junzhe Zoue7d56fc2018-08-10 14:50:17 -07001824 if (list_empty(&ctx->wait_req_list)) {
1825 CAM_ERR(CAM_ISP, "Reg upd ack with no waiting request");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301826 goto error;
1827 }
Junzhe Zoue7d56fc2018-08-10 14:50:17 -07001828 req = list_first_entry(&ctx->wait_req_list,
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301829 struct cam_ctx_request, list);
1830 list_del_init(&req->list);
1831
1832 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
Lynus Vazcbda4b02018-03-26 15:48:01 +05301833 request_id =
1834 (req_isp->hw_update_data.packet_opcode_type ==
1835 CAM_ISP_PACKET_INIT_DEV) ?
1836 0 : req->request_id;
1837
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301838 if (req_isp->num_fence_map_out != 0) {
1839 list_add_tail(&req->list, &ctx->active_req_list);
1840 ctx_isp->active_req_cnt++;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001841 CAM_DBG(CAM_ISP,
1842 "move request %lld to active list(cnt = %d)",
1843 req->request_id, ctx_isp->active_req_cnt);
Lynus Vazcbda4b02018-03-26 15:48:01 +05301844 /* if packet has buffers, set correct request id */
1845 request_id = req->request_id;
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301846 } else {
1847 /* no io config, so the request is completed. */
1848 list_add_tail(&req->list, &ctx->free_req_list);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001849 CAM_DBG(CAM_ISP,
1850 "move active req %lld to free list(cnt=%d)",
1851 req->request_id, ctx_isp->active_req_cnt);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301852 }
1853
1854 notify.link_hdl = ctx->link_hdl;
1855 notify.dev_hdl = ctx->dev_hdl;
1856 notify.frame_id = ctx_isp->frame_id;
Junzhe Zou2df84502017-05-26 13:20:23 -07001857 notify.trigger = CAM_TRIGGER_POINT_SOF;
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301858
Junzhe Zou2df84502017-05-26 13:20:23 -07001859 ctx->ctx_crm_intf->notify_trigger(&notify);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001860 CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301861 ctx_isp->frame_id);
1862 } else {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001863 CAM_ERR(CAM_ISP, "Can not notify SOF to CRM");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301864 }
Lynus Vazcbda4b02018-03-26 15:48:01 +05301865 if (request_id)
1866 ctx_isp->reported_req_id = request_id;
1867
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301868 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
1869 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001870 CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301871
1872 return 0;
1873error:
1874 /* Send SOF event as idle frame*/
1875 __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
1876 CAM_REQ_MGR_SOF_EVENT_SUCCESS);
1877
1878 /*
1879 * There is no request in the pending list, move the sub state machine
1880 * to SOF sub state
1881 */
1882 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
1883
1884 return 0;
1885}
1886
1887static struct cam_isp_ctx_irq_ops
1888 cam_isp_ctx_rdi_only_activated_state_machine_irq
1889 [CAM_ISP_CTX_ACTIVATED_MAX] = {
1890 /* SOF */
1891 {
1892 .irq_ops = {
1893 NULL,
1894 __cam_isp_ctx_rdi_only_sof_in_top_state,
1895 __cam_isp_ctx_reg_upd_in_sof,
1896 NULL,
1897 NULL,
1898 NULL,
1899 },
1900 },
1901 /* APPLIED */
1902 {
1903 .irq_ops = {
1904 __cam_isp_ctx_handle_error,
1905 __cam_isp_ctx_rdi_only_sof_in_applied_state,
1906 NULL,
1907 NULL,
1908 NULL,
1909 __cam_isp_ctx_buf_done_in_applied,
1910 },
1911 },
1912 /* EPOCH */
1913 {
1914 .irq_ops = {
1915 __cam_isp_ctx_handle_error,
1916 __cam_isp_ctx_rdi_only_sof_in_top_state,
1917 NULL,
1918 NULL,
1919 NULL,
1920 __cam_isp_ctx_buf_done_in_epoch,
1921 },
1922 },
1923 /* BUBBLE*/
1924 {
1925 .irq_ops = {
1926 __cam_isp_ctx_handle_error,
1927 __cam_isp_ctx_rdi_only_sof_in_bubble_state,
1928 NULL,
1929 NULL,
1930 NULL,
1931 __cam_isp_ctx_buf_done_in_bubble,
1932 },
1933 },
1934 /* BUBBLE APPLIED ie PRE_BUBBLE */
1935 {
1936 .irq_ops = {
1937 __cam_isp_ctx_handle_error,
1938 __cam_isp_ctx_rdi_only_sof_in_bubble_applied,
1939 __cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state,
1940 NULL,
1941 NULL,
1942 __cam_isp_ctx_buf_done_in_bubble_applied,
1943 },
1944 },
Jing Zhou4d4f03e2018-01-16 18:10:31 -08001945 /* HW ERROR */
1946 {
1947 },
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301948 /* HALT */
1949 {
1950 },
1951};
1952
1953static int __cam_isp_ctx_rdi_only_apply_req_top_state(
1954 struct cam_context *ctx, struct cam_req_mgr_apply_request *apply)
1955{
1956 int rc = 0;
1957 struct cam_isp_context *ctx_isp =
1958 (struct cam_isp_context *) ctx->ctx_priv;
1959
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001960 CAM_DBG(CAM_ISP, "current substate %d",
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301961 ctx_isp->substate_activated);
1962 rc = __cam_isp_ctx_apply_req_in_activated_state(ctx, apply,
1963 CAM_ISP_CTX_ACTIVATED_APPLIED);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001964 CAM_DBG(CAM_ISP, "new substate %d", ctx_isp->substate_activated);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301965
1966 return rc;
1967}
1968
1969static struct cam_ctx_ops
1970 cam_isp_ctx_rdi_only_activated_state_machine
1971 [CAM_ISP_CTX_ACTIVATED_MAX] = {
1972 /* SOF */
1973 {
1974 .ioctl_ops = {},
1975 .crm_ops = {
1976 .apply_req = __cam_isp_ctx_rdi_only_apply_req_top_state,
1977 },
1978 .irq_ops = NULL,
1979 },
1980 /* APPLIED */
1981 {
1982 .ioctl_ops = {},
1983 .crm_ops = {},
1984 .irq_ops = NULL,
1985 },
1986 /* EPOCH */
1987 {
1988 .ioctl_ops = {},
1989 .crm_ops = {
1990 .apply_req = __cam_isp_ctx_rdi_only_apply_req_top_state,
1991 },
1992 .irq_ops = NULL,
1993 },
1994 /* PRE BUBBLE */
1995 {
1996 .ioctl_ops = {},
1997 .crm_ops = {},
1998 .irq_ops = NULL,
1999 },
2000 /* BUBBLE */
2001 {
2002 .ioctl_ops = {},
2003 .crm_ops = {},
2004 .irq_ops = NULL,
2005 },
Jing Zhou4d4f03e2018-01-16 18:10:31 -08002006 /* HW ERROR */
2007 {
2008 .ioctl_ops = {},
2009 .crm_ops = {},
2010 .irq_ops = NULL,
2011 },
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302012 /* HALT */
2013 {
2014 .ioctl_ops = {},
2015 .crm_ops = {},
2016 .irq_ops = NULL,
2017 },
2018};
2019
Jing Zhoud352ed12017-03-20 23:59:56 -07002020/* top level state machine */
2021static int __cam_isp_ctx_release_dev_in_top_state(struct cam_context *ctx,
2022 struct cam_release_dev_cmd *cmd)
2023{
2024 int rc = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -07002025 struct cam_hw_release_args rel_arg;
Jing Zhoud352ed12017-03-20 23:59:56 -07002026 struct cam_isp_context *ctx_isp =
2027 (struct cam_isp_context *) ctx->ctx_priv;
Jing Zhoub524a852017-05-16 15:47:30 +05302028 struct cam_req_mgr_flush_request flush_req;
Jing Zhoud352ed12017-03-20 23:59:56 -07002029
2030 if (ctx_isp->hw_ctx) {
2031 rel_arg.ctxt_to_hw_map = ctx_isp->hw_ctx;
2032 ctx->hw_mgr_intf->hw_release(ctx->hw_mgr_intf->hw_mgr_priv,
2033 &rel_arg);
2034 ctx_isp->hw_ctx = NULL;
2035 }
2036
Soundrapandian Jeyaprakash8d16e272017-10-12 11:05:37 -07002037 ctx->session_hdl = -1;
2038 ctx->dev_hdl = -1;
2039 ctx->link_hdl = -1;
Jing Zhoue71fd4a2017-05-15 19:44:34 -07002040 ctx->ctx_crm_intf = NULL;
Jing Zhoud352ed12017-03-20 23:59:56 -07002041 ctx_isp->frame_id = 0;
Jing Zhoudedc4762017-06-19 17:45:36 +05302042 ctx_isp->active_req_cnt = 0;
2043 ctx_isp->reported_req_id = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -07002044
2045 /*
2046 * Ideally, we should never have any active request here.
2047 * But we still add some sanity check code here to help the debug
2048 */
2049 if (!list_empty(&ctx->active_req_list))
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002050 CAM_ERR(CAM_ISP, "Active list is not empty");
Jing Zhoud352ed12017-03-20 23:59:56 -07002051
Jing Zhoub524a852017-05-16 15:47:30 +05302052 /* Flush all the pending request list */
2053 flush_req.type = CAM_REQ_MGR_FLUSH_TYPE_ALL;
2054 flush_req.link_hdl = ctx->link_hdl;
2055 flush_req.dev_hdl = ctx->dev_hdl;
2056
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002057 CAM_DBG(CAM_ISP, "try to flush pending list");
Venkat Chintac8e610f2018-05-08 17:40:44 -07002058 spin_lock_bh(&ctx->lock);
Jing Zhoub524a852017-05-16 15:47:30 +05302059 rc = __cam_isp_ctx_flush_req(ctx, &ctx->pending_req_list, &flush_req);
Venkat Chintac8e610f2018-05-08 17:40:44 -07002060 spin_unlock_bh(&ctx->lock);
Jing Zhoud352ed12017-03-20 23:59:56 -07002061 ctx->state = CAM_CTX_AVAILABLE;
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06002062
2063 trace_cam_context_state("ISP", ctx);
Karthik Anantha Ram5438d572018-06-15 10:48:19 -07002064 CAM_DBG(CAM_ISP, "Release device success[%u] next state %d",
2065 ctx->ctx_id, ctx->state);
Jing Zhoud352ed12017-03-20 23:59:56 -07002066 return rc;
2067}
2068
2069static int __cam_isp_ctx_config_dev_in_top_state(
2070 struct cam_context *ctx, struct cam_config_dev_cmd *cmd)
2071{
Junzhe Zou93be4212018-07-30 14:52:56 -07002072 int rc = 0, i;
Jing Zhoud352ed12017-03-20 23:59:56 -07002073 struct cam_ctx_request *req = NULL;
2074 struct cam_isp_ctx_req *req_isp;
Trishansh Bhardwaj0508a772018-10-01 12:32:49 +05302075 uintptr_t packet_addr;
Jing Zhoud352ed12017-03-20 23:59:56 -07002076 struct cam_packet *packet;
2077 size_t len = 0;
Mukund Madhusudan Atre95cec7a2019-01-15 17:10:08 -08002078 size_t remain_len = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -07002079 struct cam_hw_prepare_update_args cfg;
2080 struct cam_req_mgr_add_request add_req;
2081 struct cam_isp_context *ctx_isp =
2082 (struct cam_isp_context *) ctx->ctx_priv;
2083
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002084 CAM_DBG(CAM_ISP, "get free request object......");
Jing Zhoud352ed12017-03-20 23:59:56 -07002085
2086 /* get free request */
Jing Zhou93b3ec12017-06-15 17:43:39 -07002087 spin_lock_bh(&ctx->lock);
Jing Zhoud352ed12017-03-20 23:59:56 -07002088 if (!list_empty(&ctx->free_req_list)) {
2089 req = list_first_entry(&ctx->free_req_list,
2090 struct cam_ctx_request, list);
2091 list_del_init(&req->list);
2092 }
Jing Zhou93b3ec12017-06-15 17:43:39 -07002093 spin_unlock_bh(&ctx->lock);
Jing Zhoud352ed12017-03-20 23:59:56 -07002094
2095 if (!req) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002096 CAM_ERR(CAM_ISP, "No more request obj free");
Jing Zhoud352ed12017-03-20 23:59:56 -07002097 rc = -ENOMEM;
2098 goto end;
2099 }
2100
2101 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
2102
2103 /* for config dev, only memory handle is supported */
2104 /* map packet from the memhandle */
2105 rc = cam_mem_get_cpu_buf((int32_t) cmd->packet_handle,
Trishansh Bhardwaj0508a772018-10-01 12:32:49 +05302106 &packet_addr, &len);
Jing Zhoud352ed12017-03-20 23:59:56 -07002107 if (rc != 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002108 CAM_ERR(CAM_ISP, "Can not get packet address");
Jing Zhoud352ed12017-03-20 23:59:56 -07002109 rc = -EINVAL;
2110 goto free_req;
2111 }
2112
Mukund Madhusudan Atre95cec7a2019-01-15 17:10:08 -08002113 remain_len = len;
2114 if ((len < sizeof(struct cam_packet)) ||
2115 ((size_t)cmd->offset >= len - sizeof(struct cam_packet))) {
2116 CAM_ERR(CAM_ISP, "invalid buff length: %zu or offset", len);
2117 return -EINVAL;
2118 }
2119
2120 remain_len -= (size_t)cmd->offset;
Trishansh Bhardwaj0508a772018-10-01 12:32:49 +05302121 packet = (struct cam_packet *)(packet_addr + (uint32_t)cmd->offset);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002122 CAM_DBG(CAM_ISP, "pack_handle %llx", cmd->packet_handle);
Trishansh Bhardwaj0508a772018-10-01 12:32:49 +05302123 CAM_DBG(CAM_ISP, "packet address is 0x%zx", packet_addr);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002124 CAM_DBG(CAM_ISP, "packet with length %zu, offset 0x%llx",
Jing Zhoud352ed12017-03-20 23:59:56 -07002125 len, cmd->offset);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002126 CAM_DBG(CAM_ISP, "Packet request id %lld",
Jing Zhoud352ed12017-03-20 23:59:56 -07002127 packet->header.request_id);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002128 CAM_DBG(CAM_ISP, "Packet size 0x%x", packet->header.size);
2129 CAM_DBG(CAM_ISP, "packet op %d", packet->header.op_code);
Jing Zhoud352ed12017-03-20 23:59:56 -07002130
2131 /* preprocess the configuration */
2132 memset(&cfg, 0, sizeof(cfg));
2133 cfg.packet = packet;
Mukund Madhusudan Atre95cec7a2019-01-15 17:10:08 -08002134 cfg.remain_len = remain_len;
Jing Zhoud352ed12017-03-20 23:59:56 -07002135 cfg.ctxt_to_hw_map = ctx_isp->hw_ctx;
2136 cfg.max_hw_update_entries = CAM_ISP_CTX_CFG_MAX;
2137 cfg.hw_update_entries = req_isp->cfg;
2138 cfg.max_out_map_entries = CAM_ISP_CTX_RES_MAX;
2139 cfg.max_in_map_entries = CAM_ISP_CTX_RES_MAX;
2140 cfg.out_map_entries = req_isp->fence_map_out;
2141 cfg.in_map_entries = req_isp->fence_map_in;
Vishalsingh Hajerie5450be2018-01-18 20:31:19 -08002142 cfg.priv = &req_isp->hw_update_data;
Suraj Dongre26811922018-06-27 19:30:01 -07002143 cfg.pf_data = &(req->pf_data);
Jing Zhoud352ed12017-03-20 23:59:56 -07002144
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002145 CAM_DBG(CAM_ISP, "try to prepare config packet......");
Jing Zhoud352ed12017-03-20 23:59:56 -07002146
2147 rc = ctx->hw_mgr_intf->hw_prepare_update(
2148 ctx->hw_mgr_intf->hw_mgr_priv, &cfg);
2149 if (rc != 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002150 CAM_ERR(CAM_ISP, "Prepare config packet failed in HW layer");
Jing Zhoud352ed12017-03-20 23:59:56 -07002151 rc = -EFAULT;
2152 goto free_req;
2153 }
2154 req_isp->num_cfg = cfg.num_hw_update_entries;
2155 req_isp->num_fence_map_out = cfg.num_out_map_entries;
2156 req_isp->num_fence_map_in = cfg.num_in_map_entries;
2157 req_isp->num_acked = 0;
Junzhe Zou09820a72018-09-06 18:11:41 -07002158 req_isp->bubble_detected = false;
Jing Zhoud352ed12017-03-20 23:59:56 -07002159
Junzhe Zou93be4212018-07-30 14:52:56 -07002160 for (i = 0; i < req_isp->num_fence_map_out; i++) {
2161 rc = cam_sync_get_obj_ref(req_isp->fence_map_out[i].sync_id);
2162 if (rc) {
2163 CAM_ERR(CAM_ISP, "Can't get ref for fence %d",
2164 req_isp->fence_map_out[i].sync_id);
2165 goto put_ref;
2166 }
2167 }
2168
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002169 CAM_DBG(CAM_ISP, "num_entry: %d, num fence out: %d, num fence in: %d",
Ravikishore Pampana24f712e2017-11-13 23:09:30 +05302170 req_isp->num_cfg, req_isp->num_fence_map_out,
Jing Zhoud352ed12017-03-20 23:59:56 -07002171 req_isp->num_fence_map_in);
2172
2173 req->request_id = packet->header.request_id;
2174 req->status = 1;
2175
Lynus Vazcbda4b02018-03-26 15:48:01 +05302176 CAM_DBG(CAM_ISP, "Packet request id %lld packet opcode:%d",
Vishalsingh Hajerie5450be2018-01-18 20:31:19 -08002177 packet->header.request_id,
2178 req_isp->hw_update_data.packet_opcode_type);
Ravikishore Pampana24f712e2017-11-13 23:09:30 +05302179
Vishalsingh Hajerie5450be2018-01-18 20:31:19 -08002180 if (req_isp->hw_update_data.packet_opcode_type ==
2181 CAM_ISP_PACKET_INIT_DEV) {
Ravikishore Pampana24f712e2017-11-13 23:09:30 +05302182 if (ctx->state < CAM_CTX_ACTIVATED) {
2183 rc = __cam_isp_ctx_enqueue_init_request(ctx, req);
2184 if (rc)
2185 CAM_ERR(CAM_ISP, "Enqueue INIT pkt failed");
2186 } else {
2187 rc = -EINVAL;
2188 CAM_ERR(CAM_ISP, "Recevied INIT pkt in wrong state");
2189 }
2190 } else {
2191 if (ctx->state >= CAM_CTX_READY && ctx->ctx_crm_intf->add_req) {
2192 add_req.link_hdl = ctx->link_hdl;
2193 add_req.dev_hdl = ctx->dev_hdl;
2194 add_req.req_id = req->request_id;
2195 add_req.skip_before_applying = 0;
2196 rc = ctx->ctx_crm_intf->add_req(&add_req);
2197 if (rc) {
2198 CAM_ERR(CAM_ISP, "Add req failed: req id=%llu",
2199 req->request_id);
2200 } else {
2201 __cam_isp_ctx_enqueue_request_in_order(
2202 ctx, req);
2203 }
2204 } else {
2205 rc = -EINVAL;
2206 CAM_ERR(CAM_ISP, "Recevied Update in wrong state");
Jing Zhoud352ed12017-03-20 23:59:56 -07002207 }
2208 }
Ravikishore Pampana24f712e2017-11-13 23:09:30 +05302209 if (rc)
Junzhe Zou93be4212018-07-30 14:52:56 -07002210 goto put_ref;
Jing Zhoud352ed12017-03-20 23:59:56 -07002211
Karthik Anantha Ram5438d572018-06-15 10:48:19 -07002212 CAM_DBG(CAM_REQ,
2213 "Preprocessing Config req_id %lld successful on ctx %u",
2214 req->request_id, ctx->ctx_id);
Jing Zhoud352ed12017-03-20 23:59:56 -07002215
2216 return rc;
2217
Junzhe Zou93be4212018-07-30 14:52:56 -07002218put_ref:
2219 for (--i; i >= 0; i--) {
2220 rc = cam_sync_put_obj_ref(req_isp->fence_map_out[i].sync_id);
2221 if (rc)
2222 CAM_ERR(CAM_CTXT, "Failed to put ref of fence %d",
2223 req_isp->fence_map_out[i].sync_id);
2224 }
Jing Zhoud352ed12017-03-20 23:59:56 -07002225free_req:
Jing Zhou93b3ec12017-06-15 17:43:39 -07002226 spin_lock_bh(&ctx->lock);
Jing Zhoud352ed12017-03-20 23:59:56 -07002227 list_add_tail(&req->list, &ctx->free_req_list);
Jing Zhou93b3ec12017-06-15 17:43:39 -07002228 spin_unlock_bh(&ctx->lock);
Jing Zhoud352ed12017-03-20 23:59:56 -07002229end:
2230 return rc;
2231}
2232
2233static int __cam_isp_ctx_acquire_dev_in_available(struct cam_context *ctx,
2234 struct cam_acquire_dev_cmd *cmd)
2235{
2236 int rc = 0;
2237 struct cam_hw_acquire_args param;
2238 struct cam_isp_resource *isp_res = NULL;
2239 struct cam_create_dev_hdl req_hdl_param;
2240 struct cam_hw_release_args release;
2241 struct cam_isp_context *ctx_isp =
2242 (struct cam_isp_context *) ctx->ctx_priv;
Sridhar Gujje20c475a2018-11-14 15:58:09 +05302243 struct cam_hw_cmd_args hw_cmd_args;
2244 struct cam_isp_hw_cmd_args isp_hw_cmd_args;
Jing Zhoud352ed12017-03-20 23:59:56 -07002245
2246 if (!ctx->hw_mgr_intf) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002247 CAM_ERR(CAM_ISP, "HW interface is not ready");
Jing Zhoud352ed12017-03-20 23:59:56 -07002248 rc = -EFAULT;
2249 goto end;
2250 }
2251
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002252 CAM_DBG(CAM_ISP,
2253 "session_hdl 0x%x, num_resources %d, hdl type %d, res %lld",
2254 cmd->session_handle, cmd->num_resources,
Jing Zhoud352ed12017-03-20 23:59:56 -07002255 cmd->handle_type, cmd->resource_hdl);
2256
2257 if (cmd->num_resources > CAM_ISP_CTX_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002258 CAM_ERR(CAM_ISP, "Too much resources in the acquire");
Jing Zhoud352ed12017-03-20 23:59:56 -07002259 rc = -ENOMEM;
2260 goto end;
2261 }
2262
2263 /* for now we only support user pointer */
2264 if (cmd->handle_type != 1) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002265 CAM_ERR(CAM_ISP, "Only user pointer is supported");
Jing Zhoud352ed12017-03-20 23:59:56 -07002266 rc = -EINVAL;
2267 goto end;
2268 }
2269
2270 isp_res = kzalloc(
2271 sizeof(*isp_res)*cmd->num_resources, GFP_KERNEL);
2272 if (!isp_res) {
2273 rc = -ENOMEM;
2274 goto end;
2275 }
2276
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002277 CAM_DBG(CAM_ISP, "start copy %d resources from user",
2278 cmd->num_resources);
Jing Zhoud352ed12017-03-20 23:59:56 -07002279
Trishansh Bhardwaj0508a772018-10-01 12:32:49 +05302280 if (copy_from_user(isp_res, u64_to_user_ptr(cmd->resource_hdl),
Jing Zhoud352ed12017-03-20 23:59:56 -07002281 sizeof(*isp_res)*cmd->num_resources)) {
2282 rc = -EFAULT;
2283 goto free_res;
2284 }
2285
2286 param.context_data = ctx;
2287 param.event_cb = ctx->irq_cb_intf;
2288 param.num_acq = cmd->num_resources;
Trishansh Bhardwaj0508a772018-10-01 12:32:49 +05302289 param.acquire_info = (uintptr_t) isp_res;
Jing Zhoud352ed12017-03-20 23:59:56 -07002290
2291 /* call HW manager to reserve the resource */
2292 rc = ctx->hw_mgr_intf->hw_acquire(ctx->hw_mgr_intf->hw_mgr_priv,
2293 &param);
2294 if (rc != 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002295 CAM_ERR(CAM_ISP, "Acquire device failed");
Jing Zhoud352ed12017-03-20 23:59:56 -07002296 goto free_res;
2297 }
2298
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302299 /* Query the context has rdi only resource */
2300 hw_cmd_args.ctxt_to_hw_map = param.ctxt_to_hw_map;
Suraj Dongre26811922018-06-27 19:30:01 -07002301 hw_cmd_args.cmd_type = CAM_HW_MGR_CMD_INTERNAL;
2302 isp_hw_cmd_args.cmd_type = CAM_ISP_HW_MGR_CMD_IS_RDI_ONLY_CONTEXT;
2303 hw_cmd_args.u.internal_args = (void *)&isp_hw_cmd_args;
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302304 rc = ctx->hw_mgr_intf->hw_cmd(ctx->hw_mgr_intf->hw_mgr_priv,
2305 &hw_cmd_args);
2306 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002307 CAM_ERR(CAM_ISP, "HW command failed");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302308 goto free_hw;
2309 }
2310
Suraj Dongre26811922018-06-27 19:30:01 -07002311 if (isp_hw_cmd_args.u.is_rdi_only_context) {
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302312 /*
2313 * this context has rdi only resource assign rdi only
2314 * state machine
2315 */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002316 CAM_DBG(CAM_ISP, "RDI only session Context");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302317
2318 ctx_isp->substate_machine_irq =
2319 cam_isp_ctx_rdi_only_activated_state_machine_irq;
2320 ctx_isp->substate_machine =
2321 cam_isp_ctx_rdi_only_activated_state_machine;
2322 } else {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002323 CAM_DBG(CAM_ISP, "Session has PIX or PIX and RDI resources");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302324 ctx_isp->substate_machine_irq =
2325 cam_isp_ctx_activated_state_machine_irq;
2326 ctx_isp->substate_machine =
2327 cam_isp_ctx_activated_state_machine;
2328 }
2329
Suraj Dongre26811922018-06-27 19:30:01 -07002330 ctx_isp->rdi_only_context = isp_hw_cmd_args.u.is_rdi_only_context;
Jing Zhoud352ed12017-03-20 23:59:56 -07002331 ctx_isp->hw_ctx = param.ctxt_to_hw_map;
Suraj Dongre26811922018-06-27 19:30:01 -07002332 ctx->ctxt_to_hw_map = param.ctxt_to_hw_map;
Jing Zhoud352ed12017-03-20 23:59:56 -07002333
2334 req_hdl_param.session_hdl = cmd->session_handle;
2335 /* bridge is not ready for these flags. so false for now */
2336 req_hdl_param.v4l2_sub_dev_flag = 0;
2337 req_hdl_param.media_entity_flag = 0;
2338 req_hdl_param.ops = ctx->crm_ctx_intf;
2339 req_hdl_param.priv = ctx;
2340
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002341 CAM_DBG(CAM_ISP, "get device handle form bridge");
Jing Zhoud352ed12017-03-20 23:59:56 -07002342 ctx->dev_hdl = cam_create_device_hdl(&req_hdl_param);
2343 if (ctx->dev_hdl <= 0) {
2344 rc = -EFAULT;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002345 CAM_ERR(CAM_ISP, "Can not create device handle");
Jing Zhoud352ed12017-03-20 23:59:56 -07002346 goto free_hw;
2347 }
2348 cmd->dev_handle = ctx->dev_hdl;
2349
2350 /* store session information */
2351 ctx->session_hdl = cmd->session_handle;
Sridhar Gujje20c475a2018-11-14 15:58:09 +05302352
Jing Zhoud352ed12017-03-20 23:59:56 -07002353 ctx->state = CAM_CTX_ACQUIRED;
2354
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06002355 trace_cam_context_state("ISP", ctx);
Karthik Anantha Ram5438d572018-06-15 10:48:19 -07002356 CAM_DBG(CAM_ISP,
Sridhar Gujje20c475a2018-11-14 15:58:09 +05302357 "Acquire success on session_hdl 0x%x num_rsrces %d RDI only %d ctx %u",
2358 cmd->session_handle, cmd->num_resources,
Junzhe Zou2520a0e2018-09-04 15:17:08 -07002359 (isp_hw_cmd_args.u.is_rdi_only_context ? 1 : 0), ctx->ctx_id);
Sridhar Gujje20c475a2018-11-14 15:58:09 +05302360 kfree(isp_res);
Jing Zhoud352ed12017-03-20 23:59:56 -07002361 return rc;
2362
2363free_hw:
2364 release.ctxt_to_hw_map = ctx_isp->hw_ctx;
2365 ctx->hw_mgr_intf->hw_release(ctx->hw_mgr_intf->hw_mgr_priv, &release);
2366 ctx_isp->hw_ctx = NULL;
2367free_res:
Sridhar Gujje20c475a2018-11-14 15:58:09 +05302368 kfree(isp_res);
Jing Zhoud352ed12017-03-20 23:59:56 -07002369end:
2370 return rc;
2371}
2372
2373static int __cam_isp_ctx_config_dev_in_acquired(struct cam_context *ctx,
2374 struct cam_config_dev_cmd *cmd)
2375{
2376 int rc = 0;
2377
2378 rc = __cam_isp_ctx_config_dev_in_top_state(ctx, cmd);
2379
Karthik Anantha Ram34dc2652017-10-20 15:49:54 -07002380 if (!rc && (ctx->link_hdl >= 0)) {
Jing Zhoud352ed12017-03-20 23:59:56 -07002381 ctx->state = CAM_CTX_READY;
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06002382 trace_cam_context_state("ISP", ctx);
2383 }
Jing Zhoud352ed12017-03-20 23:59:56 -07002384
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002385 CAM_DBG(CAM_ISP, "next state %d", ctx->state);
Jing Zhoud352ed12017-03-20 23:59:56 -07002386 return rc;
2387}
2388
2389static int __cam_isp_ctx_link_in_acquired(struct cam_context *ctx,
2390 struct cam_req_mgr_core_dev_link_setup *link)
2391{
2392 int rc = 0;
Junzhe Zou2df84502017-05-26 13:20:23 -07002393 struct cam_isp_context *ctx_isp =
2394 (struct cam_isp_context *) ctx->ctx_priv;
Jing Zhoud352ed12017-03-20 23:59:56 -07002395
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002396 CAM_DBG(CAM_ISP, "Enter.........");
Jing Zhoud352ed12017-03-20 23:59:56 -07002397
2398 ctx->link_hdl = link->link_hdl;
2399 ctx->ctx_crm_intf = link->crm_cb;
Junzhe Zou2df84502017-05-26 13:20:23 -07002400 ctx_isp->subscribe_event = link->subscribe_event;
Jing Zhoud352ed12017-03-20 23:59:56 -07002401
2402 /* change state only if we had the init config */
Sridhar Gujje20c475a2018-11-14 15:58:09 +05302403 if (!list_empty(&ctx->pending_req_list)) {
Jing Zhoud352ed12017-03-20 23:59:56 -07002404 ctx->state = CAM_CTX_READY;
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06002405 trace_cam_context_state("ISP", ctx);
2406 }
Jing Zhoud352ed12017-03-20 23:59:56 -07002407
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002408 CAM_DBG(CAM_ISP, "next state %d", ctx->state);
Jing Zhoud352ed12017-03-20 23:59:56 -07002409
2410 return rc;
2411}
2412
2413static int __cam_isp_ctx_unlink_in_acquired(struct cam_context *ctx,
2414 struct cam_req_mgr_core_dev_link_setup *unlink)
2415{
2416 int rc = 0;
2417
Karthik Anantha Ram34dc2652017-10-20 15:49:54 -07002418 ctx->link_hdl = -1;
Jing Zhoud352ed12017-03-20 23:59:56 -07002419 ctx->ctx_crm_intf = NULL;
2420
2421 return rc;
2422}
2423
2424static int __cam_isp_ctx_get_dev_info_in_acquired(struct cam_context *ctx,
2425 struct cam_req_mgr_device_info *dev_info)
2426{
2427 int rc = 0;
2428
2429 dev_info->dev_hdl = ctx->dev_hdl;
2430 strlcpy(dev_info->name, CAM_ISP_DEV_NAME, sizeof(dev_info->name));
2431 dev_info->dev_id = CAM_REQ_MGR_DEVICE_IFE;
2432 dev_info->p_delay = 1;
Junzhe Zou2df84502017-05-26 13:20:23 -07002433 dev_info->trigger = CAM_TRIGGER_POINT_SOF;
Jing Zhoud352ed12017-03-20 23:59:56 -07002434
2435 return rc;
2436}
2437
2438static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx,
2439 struct cam_start_stop_dev_cmd *cmd)
2440{
2441 int rc = 0;
Alok Pandey12ce5ba2018-07-03 14:34:22 +05302442 struct cam_isp_start_args start_isp;
Jing Zhoud352ed12017-03-20 23:59:56 -07002443 struct cam_ctx_request *req;
2444 struct cam_isp_ctx_req *req_isp;
2445 struct cam_isp_context *ctx_isp =
2446 (struct cam_isp_context *) ctx->ctx_priv;
2447
2448 if (cmd->session_handle != ctx->session_hdl ||
2449 cmd->dev_handle != ctx->dev_hdl) {
2450 rc = -EPERM;
2451 goto end;
2452 }
2453
2454 if (list_empty(&ctx->pending_req_list)) {
2455 /* should never happen */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002456 CAM_ERR(CAM_ISP, "Start device with empty configuration");
Jing Zhoud352ed12017-03-20 23:59:56 -07002457 rc = -EFAULT;
2458 goto end;
2459 } else {
2460 req = list_first_entry(&ctx->pending_req_list,
2461 struct cam_ctx_request, list);
2462 }
2463 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
2464
2465 if (!ctx_isp->hw_ctx) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002466 CAM_ERR(CAM_ISP, "Wrong hw context pointer.");
Jing Zhoud352ed12017-03-20 23:59:56 -07002467 rc = -EFAULT;
2468 goto end;
2469 }
Vishalsingh Hajerie5450be2018-01-18 20:31:19 -08002470
Alok Pandey12ce5ba2018-07-03 14:34:22 +05302471 start_isp.hw_config.ctxt_to_hw_map = ctx_isp->hw_ctx;
2472 start_isp.hw_config.request_id = req->request_id;
2473 start_isp.hw_config.hw_update_entries = req_isp->cfg;
2474 start_isp.hw_config.num_hw_update_entries = req_isp->num_cfg;
2475 start_isp.hw_config.priv = &req_isp->hw_update_data;
2476 start_isp.hw_config.init_packet = 1;
2477 start_isp.start_only = false;
Jing Zhoud352ed12017-03-20 23:59:56 -07002478
Ayush Kumarf13969a92019-07-18 13:02:43 +05302479 atomic_set(&ctx_isp->process_bubble, 0);
Shravya Samala43583ea2020-04-29 14:25:37 +05302480 atomic_set(&ctx_isp->bubble_sof_count, 0);
Jing Zhoud352ed12017-03-20 23:59:56 -07002481 ctx_isp->frame_id = 0;
Jing Zhoudedc4762017-06-19 17:45:36 +05302482 ctx_isp->active_req_cnt = 0;
2483 ctx_isp->reported_req_id = 0;
Lynus Vazcbda4b02018-03-26 15:48:01 +05302484 ctx_isp->substate_activated = ctx_isp->rdi_only_context ?
Harsh Shahb2e046942018-05-09 15:41:07 -07002485 CAM_ISP_CTX_ACTIVATED_APPLIED :
2486 (req_isp->num_fence_map_out) ? CAM_ISP_CTX_ACTIVATED_EPOCH :
2487 CAM_ISP_CTX_ACTIVATED_SOF;
Jing Zhoud352ed12017-03-20 23:59:56 -07002488
2489 /*
2490 * Only place to change state before calling the hw due to
2491 * hardware tasklet has higher priority that can cause the
2492 * irq handling comes early
2493 */
2494 ctx->state = CAM_CTX_ACTIVATED;
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06002495 trace_cam_context_state("ISP", ctx);
Alok Pandey12ce5ba2018-07-03 14:34:22 +05302496 rc = ctx->hw_mgr_intf->hw_start(ctx->hw_mgr_intf->hw_mgr_priv,
2497 &start_isp);
Jing Zhoud352ed12017-03-20 23:59:56 -07002498 if (rc) {
2499 /* HW failure. user need to clean up the resource */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002500 CAM_ERR(CAM_ISP, "Start HW failed");
Jing Zhoud352ed12017-03-20 23:59:56 -07002501 ctx->state = CAM_CTX_READY;
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06002502 trace_cam_context_state("ISP", ctx);
Jing Zhoud352ed12017-03-20 23:59:56 -07002503 goto end;
2504 }
Karthik Anantha Ram5438d572018-06-15 10:48:19 -07002505 CAM_DBG(CAM_ISP, "start device success ctx %u", ctx->ctx_id);
Harsh Shahb2e046942018-05-09 15:41:07 -07002506
Junzhe Zoue7d56fc2018-08-10 14:50:17 -07002507 list_del_init(&req->list);
2508
Harsh Shahb2e046942018-05-09 15:41:07 -07002509 if (req_isp->num_fence_map_out) {
Harsh Shahb2e046942018-05-09 15:41:07 -07002510 list_add_tail(&req->list, &ctx->active_req_list);
Junzhe Zoue7d56fc2018-08-10 14:50:17 -07002511 ctx_isp->active_req_cnt++;
2512 } else {
2513 list_add_tail(&req->list, &ctx->wait_req_list);
Harsh Shahb2e046942018-05-09 15:41:07 -07002514 }
Jing Zhoud352ed12017-03-20 23:59:56 -07002515end:
2516 return rc;
2517}
2518
2519static int __cam_isp_ctx_unlink_in_ready(struct cam_context *ctx,
2520 struct cam_req_mgr_core_dev_link_setup *unlink)
2521{
2522 int rc = 0;
2523
Karthik Anantha Ram34dc2652017-10-20 15:49:54 -07002524 ctx->link_hdl = -1;
Jing Zhoud352ed12017-03-20 23:59:56 -07002525 ctx->ctx_crm_intf = NULL;
2526 ctx->state = CAM_CTX_ACQUIRED;
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06002527 trace_cam_context_state("ISP", ctx);
Jing Zhoud352ed12017-03-20 23:59:56 -07002528
2529 return rc;
2530}
2531
2532static int __cam_isp_ctx_stop_dev_in_activated_unlock(
Ravikishore Pampanaf7c7fd02018-02-02 18:11:38 +05302533 struct cam_context *ctx, struct cam_start_stop_dev_cmd *stop_cmd)
Jing Zhoud352ed12017-03-20 23:59:56 -07002534{
2535 int rc = 0;
2536 uint32_t i;
2537 struct cam_hw_stop_args stop;
2538 struct cam_ctx_request *req;
2539 struct cam_isp_ctx_req *req_isp;
2540 struct cam_isp_context *ctx_isp =
2541 (struct cam_isp_context *) ctx->ctx_priv;
Alok Pandey12ce5ba2018-07-03 14:34:22 +05302542 struct cam_isp_stop_args stop_isp;
Jing Zhoud352ed12017-03-20 23:59:56 -07002543
2544 /* Mask off all the incoming hardware events */
Jing Zhou93b3ec12017-06-15 17:43:39 -07002545 spin_lock_bh(&ctx->lock);
Jing Zhoud352ed12017-03-20 23:59:56 -07002546 ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_HALT;
Jing Zhou93b3ec12017-06-15 17:43:39 -07002547 spin_unlock_bh(&ctx->lock);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002548 CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated);
Jing Zhoud352ed12017-03-20 23:59:56 -07002549
2550 /* stop hw first */
2551 if (ctx_isp->hw_ctx) {
2552 stop.ctxt_to_hw_map = ctx_isp->hw_ctx;
Alok Pandey12ce5ba2018-07-03 14:34:22 +05302553
2554 if (stop_cmd)
2555 stop_isp.hw_stop_cmd =
2556 CAM_ISP_HW_STOP_AT_FRAME_BOUNDARY;
2557 else
2558 stop_isp.hw_stop_cmd = CAM_ISP_HW_STOP_IMMEDIATELY;
2559
2560 stop_isp.stop_only = false;
2561 stop.args = (void *) &stop_isp;
Jing Zhoud352ed12017-03-20 23:59:56 -07002562 ctx->hw_mgr_intf->hw_stop(ctx->hw_mgr_intf->hw_mgr_priv,
2563 &stop);
2564 }
2565
2566 while (!list_empty(&ctx->pending_req_list)) {
2567 req = list_first_entry(&ctx->pending_req_list,
2568 struct cam_ctx_request, list);
2569 list_del_init(&req->list);
2570 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002571 CAM_DBG(CAM_ISP, "signal fence in pending list. fence num %d",
2572 req_isp->num_fence_map_out);
Jing Zhoud352ed12017-03-20 23:59:56 -07002573 for (i = 0; i < req_isp->num_fence_map_out; i++)
2574 if (req_isp->fence_map_out[i].sync_id != -1) {
2575 cam_sync_signal(
2576 req_isp->fence_map_out[i].sync_id,
2577 CAM_SYNC_STATE_SIGNALED_ERROR);
2578 }
2579 list_add_tail(&req->list, &ctx->free_req_list);
2580 }
2581
Alok Pandey12ce5ba2018-07-03 14:34:22 +05302582 while (!list_empty(&ctx->wait_req_list)) {
2583 req = list_first_entry(&ctx->wait_req_list,
2584 struct cam_ctx_request, list);
2585 list_del_init(&req->list);
2586 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
2587 CAM_DBG(CAM_ISP, "signal fence in wait list. fence num %d",
2588 req_isp->num_fence_map_out);
2589 for (i = 0; i < req_isp->num_fence_map_out; i++)
2590 if (req_isp->fence_map_out[i].sync_id != -1) {
2591 cam_sync_signal(
2592 req_isp->fence_map_out[i].sync_id,
2593 CAM_SYNC_STATE_SIGNALED_ERROR);
2594 }
2595 list_add_tail(&req->list, &ctx->free_req_list);
2596 }
2597
Jing Zhoud352ed12017-03-20 23:59:56 -07002598 while (!list_empty(&ctx->active_req_list)) {
2599 req = list_first_entry(&ctx->active_req_list,
2600 struct cam_ctx_request, list);
2601 list_del_init(&req->list);
2602 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002603 CAM_DBG(CAM_ISP, "signal fence in active list. fence num %d",
2604 req_isp->num_fence_map_out);
Jing Zhoud352ed12017-03-20 23:59:56 -07002605 for (i = 0; i < req_isp->num_fence_map_out; i++)
2606 if (req_isp->fence_map_out[i].sync_id != -1) {
2607 cam_sync_signal(
2608 req_isp->fence_map_out[i].sync_id,
2609 CAM_SYNC_STATE_SIGNALED_ERROR);
2610 }
2611 list_add_tail(&req->list, &ctx->free_req_list);
2612 }
2613 ctx_isp->frame_id = 0;
Jing Zhoudedc4762017-06-19 17:45:36 +05302614 ctx_isp->active_req_cnt = 0;
2615 ctx_isp->reported_req_id = 0;
Ayush Kumarf13969a92019-07-18 13:02:43 +05302616 atomic_set(&ctx_isp->process_bubble, 0);
Shravya Samala43583ea2020-04-29 14:25:37 +05302617 atomic_set(&ctx_isp->bubble_sof_count, 0);
Jing Zhoud352ed12017-03-20 23:59:56 -07002618
Karthik Anantha Ram5438d572018-06-15 10:48:19 -07002619 CAM_DBG(CAM_ISP, "Stop device success next state %d on ctx %u",
2620 ctx->state, ctx->ctx_id);
Jing Zhoud352ed12017-03-20 23:59:56 -07002621 return rc;
2622}
2623
2624static int __cam_isp_ctx_stop_dev_in_activated(struct cam_context *ctx,
2625 struct cam_start_stop_dev_cmd *cmd)
2626{
2627 int rc = 0;
2628
Ravikishore Pampanaf7c7fd02018-02-02 18:11:38 +05302629 __cam_isp_ctx_stop_dev_in_activated_unlock(ctx, cmd);
Jing Zhoud352ed12017-03-20 23:59:56 -07002630 ctx->state = CAM_CTX_ACQUIRED;
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06002631 trace_cam_context_state("ISP", ctx);
Jing Zhoud352ed12017-03-20 23:59:56 -07002632 return rc;
2633}
2634
2635static int __cam_isp_ctx_release_dev_in_activated(struct cam_context *ctx,
2636 struct cam_release_dev_cmd *cmd)
2637{
2638 int rc = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -07002639
Ravikishore Pampanaf7c7fd02018-02-02 18:11:38 +05302640 rc = __cam_isp_ctx_stop_dev_in_activated_unlock(ctx, NULL);
Harsh Shah2d96c5e2017-09-29 11:58:45 -07002641 if (rc)
2642 CAM_ERR(CAM_ISP, "Stop device failed rc=%d", rc);
Jing Zhoud352ed12017-03-20 23:59:56 -07002643
Harsh Shah2d96c5e2017-09-29 11:58:45 -07002644 rc = __cam_isp_ctx_release_dev_in_top_state(ctx, cmd);
2645 if (rc)
2646 CAM_ERR(CAM_ISP, "Release device failed rc=%d", rc);
Jing Zhoud352ed12017-03-20 23:59:56 -07002647
2648 return rc;
2649}
2650
Jing Zhou30504bd2017-11-21 11:36:07 -08002651static int __cam_isp_ctx_link_pause(struct cam_context *ctx)
2652{
2653 int rc = 0;
Suraj Dongre26811922018-06-27 19:30:01 -07002654 struct cam_hw_cmd_args hw_cmd_args;
2655 struct cam_isp_hw_cmd_args isp_hw_cmd_args;
Jing Zhou30504bd2017-11-21 11:36:07 -08002656 struct cam_isp_context *ctx_isp =
2657 (struct cam_isp_context *) ctx->ctx_priv;
2658
2659 hw_cmd_args.ctxt_to_hw_map = ctx_isp->hw_ctx;
Suraj Dongre26811922018-06-27 19:30:01 -07002660 hw_cmd_args.cmd_type = CAM_HW_MGR_CMD_INTERNAL;
2661 isp_hw_cmd_args.cmd_type = CAM_ISP_HW_MGR_CMD_PAUSE_HW;
2662 hw_cmd_args.u.internal_args = (void *)&isp_hw_cmd_args;
Jing Zhou30504bd2017-11-21 11:36:07 -08002663 rc = ctx->hw_mgr_intf->hw_cmd(ctx->hw_mgr_intf->hw_mgr_priv,
2664 &hw_cmd_args);
2665
2666 return rc;
2667}
2668
2669static int __cam_isp_ctx_link_resume(struct cam_context *ctx)
2670{
2671 int rc = 0;
Suraj Dongre26811922018-06-27 19:30:01 -07002672 struct cam_hw_cmd_args hw_cmd_args;
2673 struct cam_isp_hw_cmd_args isp_hw_cmd_args;
Jing Zhou30504bd2017-11-21 11:36:07 -08002674 struct cam_isp_context *ctx_isp =
2675 (struct cam_isp_context *) ctx->ctx_priv;
2676
2677 hw_cmd_args.ctxt_to_hw_map = ctx_isp->hw_ctx;
Suraj Dongre26811922018-06-27 19:30:01 -07002678 hw_cmd_args.cmd_type = CAM_HW_MGR_CMD_INTERNAL;
2679 isp_hw_cmd_args.cmd_type = CAM_ISP_HW_MGR_CMD_RESUME_HW;
2680 hw_cmd_args.u.internal_args = (void *)&isp_hw_cmd_args;
Jing Zhou30504bd2017-11-21 11:36:07 -08002681 rc = ctx->hw_mgr_intf->hw_cmd(ctx->hw_mgr_intf->hw_mgr_priv,
2682 &hw_cmd_args);
2683
2684 return rc;
2685}
2686
Karthik Anantha Ram3ef71c32018-06-21 16:38:15 -07002687static int __cam_isp_ctx_handle_sof_freeze_evt(
2688 struct cam_context *ctx)
2689{
2690 int rc = 0;
Suraj Dongre26811922018-06-27 19:30:01 -07002691 struct cam_hw_cmd_args hw_cmd_args;
2692 struct cam_isp_hw_cmd_args isp_hw_cmd_args;
Karthik Anantha Ram3ef71c32018-06-21 16:38:15 -07002693 struct cam_isp_context *ctx_isp =
2694 (struct cam_isp_context *) ctx->ctx_priv;
2695
2696 hw_cmd_args.ctxt_to_hw_map = ctx_isp->hw_ctx;
Suraj Dongre26811922018-06-27 19:30:01 -07002697 hw_cmd_args.cmd_type = CAM_HW_MGR_CMD_INTERNAL;
2698 isp_hw_cmd_args.cmd_type = CAM_ISP_HW_MGR_CMD_SOF_DEBUG;
2699 isp_hw_cmd_args.u.sof_irq_enable = 1;
2700 hw_cmd_args.u.internal_args = (void *)&isp_hw_cmd_args;
Karthik Anantha Ram3ef71c32018-06-21 16:38:15 -07002701
2702 rc = ctx->hw_mgr_intf->hw_cmd(ctx->hw_mgr_intf->hw_mgr_priv,
2703 &hw_cmd_args);
2704
2705 return rc;
2706}
2707
Jing Zhou30504bd2017-11-21 11:36:07 -08002708static int __cam_isp_ctx_process_evt(struct cam_context *ctx,
2709 struct cam_req_mgr_link_evt_data *link_evt_data)
2710{
2711 int rc = 0;
2712
2713 switch (link_evt_data->evt_type) {
2714 case CAM_REQ_MGR_LINK_EVT_ERR:
2715 /* No need to handle this message now */
2716 break;
2717 case CAM_REQ_MGR_LINK_EVT_PAUSE:
2718 __cam_isp_ctx_link_pause(ctx);
2719 break;
2720 case CAM_REQ_MGR_LINK_EVT_RESUME:
2721 __cam_isp_ctx_link_resume(ctx);
2722 break;
Karthik Anantha Ram3ef71c32018-06-21 16:38:15 -07002723 case CAM_REQ_MGR_LINK_EVT_SOF_FREEZE:
2724 __cam_isp_ctx_handle_sof_freeze_evt(ctx);
2725 break;
Jing Zhou30504bd2017-11-21 11:36:07 -08002726 default:
2727 CAM_WARN(CAM_ISP, "Unknown event from CRM");
2728 break;
2729 }
2730 return rc;
2731}
2732
Harsh Shah6e4bc932017-11-07 06:15:12 -08002733static int __cam_isp_ctx_unlink_in_activated(struct cam_context *ctx,
2734 struct cam_req_mgr_core_dev_link_setup *unlink)
2735{
2736 int rc = 0;
2737
2738 CAM_WARN(CAM_ISP,
2739 "Received unlink in activated state. It's unexpected");
Ravikishore Pampanaf7c7fd02018-02-02 18:11:38 +05302740
2741 rc = __cam_isp_ctx_stop_dev_in_activated_unlock(ctx, NULL);
Harsh Shah6e4bc932017-11-07 06:15:12 -08002742 if (rc)
2743 CAM_WARN(CAM_ISP, "Stop device failed rc=%d", rc);
2744
2745 rc = __cam_isp_ctx_unlink_in_ready(ctx, unlink);
2746 if (rc)
2747 CAM_ERR(CAM_ISP, "Unlink failed rc=%d", rc);
2748
2749 return rc;
2750}
2751
Jing Zhoud352ed12017-03-20 23:59:56 -07002752static int __cam_isp_ctx_apply_req(struct cam_context *ctx,
2753 struct cam_req_mgr_apply_request *apply)
2754{
2755 int rc = 0;
Vishalsingh Hajeri7a431b72018-03-01 14:07:24 -08002756 struct cam_ctx_ops *ctx_ops = NULL;
Jing Zhoud352ed12017-03-20 23:59:56 -07002757 struct cam_isp_context *ctx_isp =
2758 (struct cam_isp_context *) ctx->ctx_priv;
2759
Junzhe Zou5fa08b12017-08-15 10:08:12 -07002760 trace_cam_apply_req("ISP", apply->request_id);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002761 CAM_DBG(CAM_ISP, "Enter: apply req in Substate %d request _id:%lld",
2762 ctx_isp->substate_activated, apply->request_id);
Vishalsingh Hajeri7a431b72018-03-01 14:07:24 -08002763 ctx_ops = &ctx_isp->substate_machine[ctx_isp->substate_activated];
2764 if (ctx_ops->crm_ops.apply_req) {
2765 rc = ctx_ops->crm_ops.apply_req(ctx, apply);
Jing Zhoud352ed12017-03-20 23:59:56 -07002766 } else {
Harsh Shahcb0072c2017-09-26 19:22:10 -07002767 CAM_ERR_RATE_LIMIT(CAM_ISP,
2768 "No handle function in activated substate %d",
2769 ctx_isp->substate_activated);
Jing Zhoud352ed12017-03-20 23:59:56 -07002770 rc = -EFAULT;
2771 }
2772
2773 if (rc)
Harsh Shahcb0072c2017-09-26 19:22:10 -07002774 CAM_ERR_RATE_LIMIT(CAM_ISP,
2775 "Apply failed in active substate %d",
2776 ctx_isp->substate_activated);
Jing Zhoud352ed12017-03-20 23:59:56 -07002777 return rc;
2778}
2779
2780
2781
2782static int __cam_isp_ctx_handle_irq_in_activated(void *context,
2783 uint32_t evt_id, void *evt_data)
2784{
2785 int rc = 0;
Vishalsingh Hajeri7a431b72018-03-01 14:07:24 -08002786 struct cam_isp_ctx_irq_ops *irq_ops = NULL;
Jing Zhoud352ed12017-03-20 23:59:56 -07002787 struct cam_context *ctx = (struct cam_context *)context;
2788 struct cam_isp_context *ctx_isp =
2789 (struct cam_isp_context *)ctx->ctx_priv;
2790
Jing Zhou93b3ec12017-06-15 17:43:39 -07002791 spin_lock_bh(&ctx->lock);
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -06002792
2793 trace_cam_isp_activated_irq(ctx, ctx_isp->substate_activated, evt_id,
2794 __cam_isp_ctx_get_event_ts(evt_id, evt_data));
2795
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002796 CAM_DBG(CAM_ISP, "Enter: State %d, Substate %d, evt id %d",
2797 ctx->state, ctx_isp->substate_activated, evt_id);
Vishalsingh Hajeri7a431b72018-03-01 14:07:24 -08002798 irq_ops = &ctx_isp->substate_machine_irq[ctx_isp->substate_activated];
2799 if (irq_ops->irq_ops[evt_id]) {
2800 rc = irq_ops->irq_ops[evt_id](ctx_isp, evt_data);
Jing Zhoud352ed12017-03-20 23:59:56 -07002801 } else {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002802 CAM_DBG(CAM_ISP, "No handle function for substate %d",
Jing Zhoud352ed12017-03-20 23:59:56 -07002803 ctx_isp->substate_activated);
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -07002804 __cam_isp_ctx_dump_state_monitor_array(ctx_isp);
Jing Zhoud352ed12017-03-20 23:59:56 -07002805 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002806 CAM_DBG(CAM_ISP, "Exit: State %d Substate %d",
2807 ctx->state, ctx_isp->substate_activated);
Jing Zhou93b3ec12017-06-15 17:43:39 -07002808 spin_unlock_bh(&ctx->lock);
Jing Zhoud352ed12017-03-20 23:59:56 -07002809 return rc;
2810}
2811
2812/* top state machine */
2813static struct cam_ctx_ops
2814 cam_isp_ctx_top_state_machine[CAM_CTX_STATE_MAX] = {
2815 /* Uninit */
2816 {
2817 .ioctl_ops = {},
2818 .crm_ops = {},
2819 .irq_ops = NULL,
2820 },
2821 /* Available */
2822 {
2823 .ioctl_ops = {
2824 .acquire_dev = __cam_isp_ctx_acquire_dev_in_available,
2825 },
2826 .crm_ops = {},
2827 .irq_ops = NULL,
2828 },
2829 /* Acquired */
2830 {
2831 .ioctl_ops = {
2832 .release_dev = __cam_isp_ctx_release_dev_in_top_state,
2833 .config_dev = __cam_isp_ctx_config_dev_in_acquired,
2834 },
2835 .crm_ops = {
2836 .link = __cam_isp_ctx_link_in_acquired,
2837 .unlink = __cam_isp_ctx_unlink_in_acquired,
2838 .get_dev_info = __cam_isp_ctx_get_dev_info_in_acquired,
Jing Zhoub524a852017-05-16 15:47:30 +05302839 .flush_req = __cam_isp_ctx_flush_req_in_top_state,
Jing Zhoud352ed12017-03-20 23:59:56 -07002840 },
2841 .irq_ops = NULL,
Suraj Dongre26811922018-06-27 19:30:01 -07002842 .pagefault_ops = cam_isp_context_dump_active_request,
Jing Zhoud352ed12017-03-20 23:59:56 -07002843 },
2844 /* Ready */
2845 {
2846 .ioctl_ops = {
2847 .start_dev = __cam_isp_ctx_start_dev_in_ready,
2848 .release_dev = __cam_isp_ctx_release_dev_in_top_state,
2849 .config_dev = __cam_isp_ctx_config_dev_in_top_state,
2850 },
2851 .crm_ops = {
2852 .unlink = __cam_isp_ctx_unlink_in_ready,
Jing Zhoub524a852017-05-16 15:47:30 +05302853 .flush_req = __cam_isp_ctx_flush_req_in_ready,
Jing Zhoud352ed12017-03-20 23:59:56 -07002854 },
2855 .irq_ops = NULL,
Suraj Dongre26811922018-06-27 19:30:01 -07002856 .pagefault_ops = cam_isp_context_dump_active_request,
Jing Zhoud352ed12017-03-20 23:59:56 -07002857 },
2858 /* Activated */
2859 {
2860 .ioctl_ops = {
2861 .stop_dev = __cam_isp_ctx_stop_dev_in_activated,
2862 .release_dev = __cam_isp_ctx_release_dev_in_activated,
2863 .config_dev = __cam_isp_ctx_config_dev_in_top_state,
2864 },
2865 .crm_ops = {
Harsh Shah6e4bc932017-11-07 06:15:12 -08002866 .unlink = __cam_isp_ctx_unlink_in_activated,
Jing Zhoud352ed12017-03-20 23:59:56 -07002867 .apply_req = __cam_isp_ctx_apply_req,
Junzhe Zoufdcd4722018-06-11 18:05:33 -07002868 .flush_req = __cam_isp_ctx_flush_req_in_top_state,
Jing Zhou30504bd2017-11-21 11:36:07 -08002869 .process_evt = __cam_isp_ctx_process_evt,
Jing Zhoud352ed12017-03-20 23:59:56 -07002870 },
2871 .irq_ops = __cam_isp_ctx_handle_irq_in_activated,
Suraj Dongre26811922018-06-27 19:30:01 -07002872 .pagefault_ops = cam_isp_context_dump_active_request,
Jing Zhoud352ed12017-03-20 23:59:56 -07002873 },
2874};
2875
2876
Suraj Dongre26811922018-06-27 19:30:01 -07002877static int cam_isp_context_dump_active_request(void *data, unsigned long iova,
2878 uint32_t buf_info)
2879{
2880
2881 struct cam_context *ctx = (struct cam_context *)data;
2882 struct cam_ctx_request *req = NULL;
2883 struct cam_ctx_request *req_temp = NULL;
2884 struct cam_isp_ctx_req *req_isp = NULL;
2885 struct cam_isp_prepare_hw_update_data *hw_update_data = NULL;
2886 struct cam_hw_mgr_dump_pf_data *pf_dbg_entry = NULL;
2887 bool mem_found = false;
2888 int rc = 0;
2889
2890 struct cam_isp_context *isp_ctx =
2891 (struct cam_isp_context *)ctx->ctx_priv;
2892
2893 if (!isp_ctx) {
2894 CAM_ERR(CAM_ISP, "Invalid isp ctx");
2895 return -EINVAL;
2896 }
2897
2898 CAM_INFO(CAM_ISP, "iommu fault handler for isp ctx %d state %d",
2899 ctx->ctx_id, ctx->state);
2900
2901 list_for_each_entry_safe(req, req_temp,
2902 &ctx->active_req_list, list) {
2903 req_isp = (struct cam_isp_ctx_req *) req->req_priv;
2904 hw_update_data = &req_isp->hw_update_data;
2905 pf_dbg_entry = &(req->pf_data);
2906 CAM_INFO(CAM_ISP, "req_id : %lld ", req->request_id);
2907
2908 rc = cam_context_dump_pf_info_to_hw(ctx, pf_dbg_entry->packet,
2909 iova, buf_info, &mem_found);
2910 if (rc)
2911 CAM_ERR(CAM_ISP, "Failed to dump pf info");
2912
2913 if (mem_found)
2914 CAM_ERR(CAM_ISP, "Found page fault in req %lld %d",
2915 req->request_id, rc);
2916 }
2917
2918 return rc;
2919}
2920
Jing Zhoud352ed12017-03-20 23:59:56 -07002921int cam_isp_context_init(struct cam_isp_context *ctx,
2922 struct cam_context *ctx_base,
2923 struct cam_req_mgr_kmd_ops *crm_node_intf,
Pavan Kumar Chilamkurthi96fd3c92018-01-25 14:16:57 -08002924 struct cam_hw_mgr_intf *hw_intf,
2925 uint32_t ctx_id)
Jing Zhoud352ed12017-03-20 23:59:56 -07002926
2927{
2928 int rc = -1;
2929 int i;
2930
2931 if (!ctx || !ctx_base) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002932 CAM_ERR(CAM_ISP, "Invalid Context");
Jing Zhoud352ed12017-03-20 23:59:56 -07002933 goto err;
2934 }
2935
2936 /* ISP context setup */
2937 memset(ctx, 0, sizeof(*ctx));
2938
2939 ctx->base = ctx_base;
2940 ctx->frame_id = 0;
Jing Zhoudedc4762017-06-19 17:45:36 +05302941 ctx->active_req_cnt = 0;
2942 ctx->reported_req_id = 0;
Jing Zhoud352ed12017-03-20 23:59:56 -07002943 ctx->hw_ctx = NULL;
2944 ctx->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
2945 ctx->substate_machine = cam_isp_ctx_activated_state_machine;
2946 ctx->substate_machine_irq = cam_isp_ctx_activated_state_machine_irq;
2947
2948 for (i = 0; i < CAM_CTX_REQ_MAX; i++) {
2949 ctx->req_base[i].req_priv = &ctx->req_isp[i];
2950 ctx->req_isp[i].base = &ctx->req_base[i];
2951 }
2952
2953 /* camera context setup */
Pavan Kumar Chilamkurthi96fd3c92018-01-25 14:16:57 -08002954 rc = cam_context_init(ctx_base, isp_dev_name, CAM_ISP, ctx_id,
2955 crm_node_intf, hw_intf, ctx->req_base, CAM_CTX_REQ_MAX);
Jing Zhoud352ed12017-03-20 23:59:56 -07002956 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002957 CAM_ERR(CAM_ISP, "Camera Context Base init failed");
Jing Zhoud352ed12017-03-20 23:59:56 -07002958 goto err;
2959 }
2960
2961 /* link camera context with isp context */
2962 ctx_base->state_machine = cam_isp_ctx_top_state_machine;
2963 ctx_base->ctx_priv = ctx;
2964
Vishalsingh Hajeric0cab062017-09-28 18:25:16 -07002965 /* initializing current state for error logging */
2966 for (i = 0; i < CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES; i++) {
2967 ctx->cam_isp_ctx_state_monitor[i].curr_state =
2968 CAM_ISP_CTX_ACTIVATED_MAX;
2969 }
2970 atomic64_set(&ctx->state_monitor_head, -1);
Jing Zhoud352ed12017-03-20 23:59:56 -07002971err:
2972 return rc;
2973}
2974
2975int cam_isp_context_deinit(struct cam_isp_context *ctx)
2976{
2977 int rc = 0;
2978
2979 if (ctx->base)
2980 cam_context_deinit(ctx->base);
2981
2982 if (ctx->substate_activated != CAM_ISP_CTX_ACTIVATED_SOF)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002983 CAM_ERR(CAM_ISP, "ISP context substate is invalid");
Jing Zhoud352ed12017-03-20 23:59:56 -07002984
2985 memset(ctx, 0, sizeof(*ctx));
2986 return rc;
2987}