Skip to content

Commit e71c354

Browse files
Vikram SharmaGerrit - the friendly Code Review server
authored andcommitted
msm: camera: cam_isp: Recovery after IRQ delayed
Dynamic FPS to Detect IRQ delay. If the irq is delayed, the frame drop is reported. This commit helps to recover from the frame drop. We a added a new blob command to report fps from UMD to KMD. This patch Use this fps to calculate If there is a IRQ delay or not. If yes then It sets a flag 'irq_delay_detected'. Change-Id: I3cbcd9275d705f8c2458c7860780fbab615fabc4 Signed-off-by: Vikram Sharma <[email protected]>
1 parent 5def64c commit e71c354

File tree

6 files changed

+186
-18
lines changed

6 files changed

+186
-18
lines changed

drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c

Lines changed: 132 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,14 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state(
452452
trace_cam_buf_done("ISP", ctx, req);
453453

454454
req_isp = (struct cam_isp_ctx_req *) req->req_priv;
455+
if (ctx_isp->frame_id == 1)
456+
ctx_isp->irq_timestamps = done->irq_mono_boot_time;
457+
else if (ctx_isp->fps && ((done->irq_mono_boot_time -
458+
ctx_isp->irq_timestamps) > ((1000*1000)/ctx_isp->fps)))
459+
ctx_isp->irq_delay_detect = true;
460+
461+
ctx_isp->irq_timestamps = done->irq_mono_boot_time;
462+
455463
for (i = 0; i < done->num_handles; i++) {
456464
for (j = 0; j < req_isp->num_fence_map_out; j++) {
457465
if (done->resource_handle[i] ==
@@ -565,6 +573,26 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state(
565573
ctx_isp->substate_activated);
566574
}
567575

576+
if (ctx_isp->active_req_cnt && ctx_isp->irq_delay_detect) {
577+
CAM_ERR(CAM_ISP, "isp req[%lld] IRQ buf done got delayed",
578+
req->request_id);
579+
req = list_first_entry(&ctx->active_req_list,
580+
struct cam_ctx_request, list);
581+
req_isp = (struct cam_isp_ctx_req *) req->req_priv;
582+
583+
for (j = 0; j < req_isp->num_fence_map_out; j++) {
584+
rc = cam_sync_signal(req_isp->fence_map_out[j].sync_id,
585+
CAM_SYNC_STATE_SIGNALED_ERROR);
586+
if (rc)
587+
CAM_DBG(CAM_ISP, "Sync failed with rc = %d",
588+
rc);
589+
req_isp->fence_map_out[j].sync_id = -1;
590+
}
591+
list_del_init(&req->list);
592+
list_add_tail(&req->list, &ctx->free_req_list);
593+
ctx_isp->active_req_cnt--;
594+
}
595+
ctx_isp->irq_delay_detect = false;
568596
end:
569597
return rc;
570598
}
@@ -643,12 +671,47 @@ static void __cam_isp_ctx_send_sof_timestamp(
643671
static int __cam_isp_ctx_reg_upd_in_epoch_state(
644672
struct cam_isp_context *ctx_isp, void *evt_data)
645673
{
646-
if (ctx_isp->frame_id == 1)
674+
struct cam_isp_hw_reg_update_event_data *rup_event_data = evt_data;
675+
676+
struct cam_context *ctx = ctx_isp->base;
677+
struct cam_ctx_request *req = NULL;
678+
struct cam_isp_ctx_req *req_isp = NULL;
679+
680+
if (ctx_isp->frame_id == 1) {
647681
CAM_DBG(CAM_ISP, "Reg update for early PCR");
648-
else
682+
if (!list_empty(&ctx->active_req_list)) {
683+
req = list_first_entry(&ctx->active_req_list,
684+
struct cam_ctx_request, list);
685+
req_isp = (struct cam_isp_ctx_req *) req->req_priv;
686+
} else if (!list_empty(&ctx->wait_req_list)) {
687+
req = list_first_entry(&ctx->active_req_list,
688+
struct cam_ctx_request, list);
689+
req_isp = (struct cam_isp_ctx_req *) req->req_priv;
690+
}
691+
} else {
692+
if (!list_empty(&ctx->wait_req_list)) {
693+
req = list_first_entry(&ctx->active_req_list,
694+
struct cam_ctx_request, list);
695+
req_isp = (struct cam_isp_ctx_req *) req->req_priv;
696+
}
649697
CAM_WARN(CAM_ISP,
650698
"Unexpected reg update in activated substate:%d for frame_id:%lld",
651699
ctx_isp->substate_activated, ctx_isp->frame_id);
700+
}
701+
702+
if (req_isp && req_isp->hw_update_data.fps) {
703+
ctx_isp->fps = req_isp->hw_update_data.fps;
704+
CAM_DBG(CAM_ISP, "req_isp %pK, Upadting ctx_isp->fps %d",
705+
req_isp, ctx_isp->fps);
706+
}
707+
708+
if (ctx_isp->frame_id == 1)
709+
ctx_isp->irq_timestamps = rup_event_data->irq_mono_boot_time;
710+
else if (ctx_isp->fps && ((rup_event_data->irq_mono_boot_time -
711+
ctx_isp->irq_timestamps) > ((1000*1000)/ctx_isp->fps)))
712+
ctx_isp->irq_delay_detect = true;
713+
714+
ctx_isp->irq_timestamps = rup_event_data->irq_mono_boot_time;
652715
return 0;
653716
}
654717

@@ -658,7 +721,8 @@ static int __cam_isp_ctx_reg_upd_in_activated_state(
658721
int rc = 0;
659722
struct cam_ctx_request *req;
660723
struct cam_context *ctx = ctx_isp->base;
661-
struct cam_isp_ctx_req *req_isp;
724+
struct cam_isp_ctx_req *req_isp = NULL;
725+
struct cam_isp_hw_reg_update_event_data *rup_event_data = evt_data;
662726

663727
if (list_empty(&ctx->wait_req_list)) {
664728
CAM_ERR(CAM_ISP, "Reg upd ack with no waiting request");
@@ -683,13 +747,22 @@ static int __cam_isp_ctx_reg_upd_in_activated_state(
683747
req->request_id, ctx_isp->active_req_cnt, ctx->ctx_id);
684748
}
685749

750+
if (req_isp && req_isp->hw_update_data.fps)
751+
ctx_isp->fps = req_isp->hw_update_data.fps;
752+
686753
/*
687754
* This function only called directly from applied and bubble applied
688755
* state so change substate here.
689756
*/
690757
ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_EPOCH;
691758
CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated);
759+
if (ctx_isp->frame_id == 1)
760+
ctx_isp->irq_timestamps = rup_event_data->irq_mono_boot_time;
761+
else if (ctx_isp->fps && ((rup_event_data->irq_mono_boot_time -
762+
ctx_isp->irq_timestamps) > ((1000*1000)/ctx_isp->fps)))
763+
ctx_isp->irq_delay_detect = true;
692764

765+
ctx_isp->irq_timestamps = rup_event_data->irq_mono_boot_time;
693766
end:
694767
return rc;
695768
}
@@ -817,6 +890,14 @@ static int __cam_isp_ctx_sof_in_activated_state(
817890
ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
818891
ctx_isp->boot_timestamp = sof_event_data->boot_time;
819892

893+
if (ctx_isp->frame_id == 1)
894+
ctx_isp->irq_timestamps = sof_event_data->irq_mono_boot_time;
895+
else if (ctx_isp->fps && ((sof_event_data->irq_mono_boot_time -
896+
ctx_isp->irq_timestamps) > ((1000*1000)/ctx_isp->fps)))
897+
ctx_isp->irq_delay_detect = true;
898+
899+
ctx_isp->irq_timestamps = sof_event_data->irq_mono_boot_time;
900+
820901
CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx, ctx %u",
821902
ctx_isp->frame_id, ctx_isp->sof_timestamp_val, ctx->ctx_id);
822903

@@ -828,8 +909,9 @@ static int __cam_isp_ctx_reg_upd_in_sof(struct cam_isp_context *ctx_isp,
828909
{
829910
int rc = 0;
830911
struct cam_ctx_request *req = NULL;
831-
struct cam_isp_ctx_req *req_isp;
912+
struct cam_isp_ctx_req *req_isp = NULL;
832913
struct cam_context *ctx = ctx_isp->base;
914+
struct cam_isp_hw_reg_update_event_data *rup_event_data = evt_data;
833915

834916
if (ctx->state != CAM_CTX_ACTIVATED && ctx_isp->frame_id > 1) {
835917
CAM_DBG(CAM_ISP, "invalid RUP");
@@ -852,6 +934,16 @@ static int __cam_isp_ctx_reg_upd_in_sof(struct cam_isp_context *ctx_isp,
852934
"receive rup in unexpected state");
853935
}
854936

937+
if (req_isp && req_isp->hw_update_data.fps)
938+
ctx_isp->fps = req_isp->hw_update_data.fps;
939+
940+
if (ctx_isp->frame_id == 1)
941+
ctx_isp->irq_timestamps = rup_event_data->irq_mono_boot_time;
942+
else if (ctx_isp->fps && ((rup_event_data->irq_mono_boot_time -
943+
ctx_isp->irq_timestamps) > ((1000*1000)/ctx_isp->fps)))
944+
ctx_isp->irq_delay_detect = true;
945+
946+
ctx_isp->irq_timestamps = rup_event_data->irq_mono_boot_time;
855947
end:
856948
return rc;
857949
}
@@ -860,9 +952,10 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
860952
void *evt_data)
861953
{
862954
struct cam_ctx_request *req;
863-
struct cam_isp_ctx_req *req_isp;
955+
struct cam_isp_ctx_req *req_isp = NULL;
864956
struct cam_context *ctx = ctx_isp->base;
865957
uint64_t request_id = 0;
958+
struct cam_isp_hw_epoch_event_data *epoch_hw_event_data = evt_data;
866959

867960
if (list_empty(&ctx->wait_req_list)) {
868961
/*
@@ -928,6 +1021,15 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
9281021
ctx_isp->substate_activated);
9291022
end:
9301023

1024+
if (ctx_isp->frame_id == 1)
1025+
ctx_isp->irq_timestamps =
1026+
epoch_hw_event_data->irq_mono_boot_time;
1027+
else if (ctx_isp->fps && ((epoch_hw_event_data->irq_mono_boot_time -
1028+
ctx_isp->irq_timestamps) > ((1000*1000)/ctx_isp->fps)))
1029+
ctx_isp->irq_delay_detect = true;
1030+
1031+
ctx_isp->irq_timestamps = epoch_hw_event_data->irq_mono_boot_time;
1032+
9311033
return 0;
9321034
}
9331035

@@ -960,6 +1062,14 @@ static int __cam_isp_ctx_sof_in_epoch(struct cam_isp_context *ctx_isp,
9601062
ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
9611063
ctx_isp->boot_timestamp = sof_event_data->boot_time;
9621064

1065+
if (ctx_isp->frame_id == 1)
1066+
ctx_isp->irq_timestamps = sof_event_data->irq_mono_boot_time;
1067+
else if (ctx_isp->fps && ((sof_event_data->irq_mono_boot_time -
1068+
ctx_isp->irq_timestamps) > ((1000*1000)/ctx_isp->fps)))
1069+
ctx_isp->irq_delay_detect = true;
1070+
1071+
ctx_isp->irq_timestamps = sof_event_data->irq_mono_boot_time;
1072+
9631073
if (list_empty(&ctx->active_req_list))
9641074
ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
9651075
else
@@ -1442,7 +1552,7 @@ static int __cam_isp_ctx_fs2_reg_upd_in_sof(struct cam_isp_context *ctx_isp,
14421552
{
14431553
int rc = 0;
14441554
struct cam_ctx_request *req = NULL;
1445-
struct cam_isp_ctx_req *req_isp;
1555+
struct cam_isp_ctx_req *req_isp = NULL;
14461556
struct cam_context *ctx = ctx_isp->base;
14471557

14481558
if (ctx->state != CAM_CTX_ACTIVATED && ctx_isp->frame_id > 1) {
@@ -1466,6 +1576,9 @@ static int __cam_isp_ctx_fs2_reg_upd_in_sof(struct cam_isp_context *ctx_isp,
14661576
"receive rup in unexpected state");
14671577
}
14681578

1579+
if (req_isp && req_isp->hw_update_data.fps)
1580+
ctx_isp->fps = req_isp->hw_update_data.fps;
1581+
14691582
end:
14701583
return rc;
14711584
}
@@ -1476,7 +1589,7 @@ static int __cam_isp_ctx_fs2_reg_upd_in_applied_state(
14761589
int rc = 0;
14771590
struct cam_ctx_request *req = NULL;
14781591
struct cam_context *ctx = ctx_isp->base;
1479-
struct cam_isp_ctx_req *req_isp;
1592+
struct cam_isp_ctx_req *req_isp = NULL;
14801593
struct cam_req_mgr_trigger_notify notify;
14811594
uint64_t request_id = 0;
14821595

@@ -1499,6 +1612,9 @@ static int __cam_isp_ctx_fs2_reg_upd_in_applied_state(
14991612
list_add_tail(&req->list, &ctx->free_req_list);
15001613
}
15011614

1615+
if (req_isp && req_isp->hw_update_data.fps)
1616+
ctx_isp->fps = req_isp->hw_update_data.fps;
1617+
15021618
/*
15031619
* This function only called directly from applied and bubble applied
15041620
* state so change substate here.
@@ -2393,7 +2509,7 @@ static int __cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state(
23932509
{
23942510
struct cam_ctx_request *req;
23952511
struct cam_context *ctx = ctx_isp->base;
2396-
struct cam_isp_ctx_req *req_isp;
2512+
struct cam_isp_ctx_req *req_isp = NULL;
23972513
struct cam_req_mgr_trigger_notify notify;
23982514
uint64_t request_id = 0;
23992515

@@ -2448,6 +2564,9 @@ static int __cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state(
24482564
jiffies_to_msecs(jiffies);
24492565
}
24502566

2567+
if (req_isp && req_isp->hw_update_data.fps)
2568+
ctx_isp->fps = req_isp->hw_update_data.fps;
2569+
24512570
__cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
24522571
CAM_REQ_MGR_SOF_EVENT_SUCCESS);
24532572
CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated);
@@ -2723,7 +2842,7 @@ static int __cam_isp_ctx_config_dev_in_top_state(
27232842
{
27242843
int rc = 0, i;
27252844
struct cam_ctx_request *req = NULL;
2726-
struct cam_isp_ctx_req *req_isp;
2845+
struct cam_isp_ctx_req *req_isp = NULL;
27272846
uintptr_t packet_addr;
27282847
struct cam_packet *packet;
27292848
size_t len = 0;
@@ -2812,6 +2931,7 @@ static int __cam_isp_ctx_config_dev_in_top_state(
28122931
rc = -EFAULT;
28132932
goto free_cpu_buf;
28142933
}
2934+
28152935
req_isp->num_cfg = cfg.num_hw_update_entries;
28162936
req_isp->num_fence_map_out = cfg.num_out_map_entries;
28172937
req_isp->num_fence_map_in = cfg.num_in_map_entries;
@@ -2868,6 +2988,7 @@ static int __cam_isp_ctx_config_dev_in_top_state(
28682988
CAM_ERR(CAM_ISP, "Recevied Update in wrong state");
28692989
}
28702990
}
2991+
28712992
if (rc)
28722993
goto put_ref;
28732994

@@ -3649,8 +3770,6 @@ static int __cam_isp_ctx_apply_req(struct cam_context *ctx,
36493770
return rc;
36503771
}
36513772

3652-
3653-
36543773
static int __cam_isp_ctx_handle_irq_in_activated(void *context,
36553774
uint32_t evt_id, void *evt_data)
36563775
{
@@ -3856,6 +3975,8 @@ int cam_isp_context_init(struct cam_isp_context *ctx,
38563975
for (i = 0; i < CAM_CTX_REQ_MAX; i++) {
38573976
ctx->req_base[i].req_priv = &ctx->req_isp[i];
38583977
ctx->req_isp[i].base = &ctx->req_base[i];
3978+
/*Set default fps value to 30 FPS*/
3979+
ctx->req_isp[i].hw_update_data.fps = CAM_ISP_CTX_DEFAULT_FPS;
38593980
}
38603981

38613982
/* camera context setup */

drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@
3434
*/
3535
#define CAM_ISP_CTX_CFG_MAX 22
3636

37+
/*
38+
* Defalut fps value set to 30
39+
*/
40+
#define CAM_ISP_CTX_DEFAULT_FPS 30
41+
3742
/*
3843
* Maximum entries in state monitoring array for error logging
3944
*/
@@ -180,6 +185,9 @@ struct cam_isp_context_req_id_info {
180185
* @hw_acquired: Indicate whether HW resources are acquired
181186
* @init_received: Indicate whether init config packet is received
182187
* @split_acquire: Indicate whether a separate acquire is expected
188+
* @irq_delay_detect: Indicate whether a irq delay has detected or not
189+
* @irq_timestamps: Timestamp from last handled IRQ
190+
* @fps: Current FPS for the activated state.
183191
*
184192
*/
185193
struct cam_isp_context {
@@ -209,6 +217,9 @@ struct cam_isp_context {
209217
bool hw_acquired;
210218
bool init_received;
211219
bool split_acquire;
220+
bool irq_delay_detect;
221+
uint64_t irq_timestamps;
222+
uint32_t fps;
212223
};
213224

214225
/**

0 commit comments

Comments
 (0)