camera: vfe32: Create synchronous version of VFE reset cmd.
Logically from RESET to RESET_ACK, no interrupt should be
generated from hardware. Synchronous RESET call makes
code flow simpler.
Create a new ISP command VFE_CMD_RESET_2 which blocks
until RESET_ACK irq fires.
Change-Id: I1c1974c01d7037f457ab767a83f5cece3fe23705
Signed-off-by: Shuzhen Wang <shuzhenw@codeaurora.org>
diff --git a/drivers/media/video/msm/vfe/msm_vfe32.c b/drivers/media/video/msm/vfe/msm_vfe32.c
index c5ff79d..284db08 100644
--- a/drivers/media/video/msm/vfe/msm_vfe32.c
+++ b/drivers/media/video/msm/vfe/msm_vfe32.c
@@ -379,12 +379,27 @@
"GET_RGB_G_TABLE",
"GET_LA_TABLE",
"DEMOSAICV3_UPDATE",
+ "DUMMY_11",
+ "DUMMY_12", /*130*/
+ "DUMMY_13",
+ "DUMMY_14",
+ "DUMMY_15",
+ "DUMMY_16",
+ "DUMMY_17", /*135*/
+ "DUMMY_18",
+ "DUMMY_19",
+ "DUMMY_20",
+ "STATS_REQBUF",
+ "STATS_ENQUEUEBUF", /*140*/
+ "STATS_FLUSH_BUFQ",
+ "STATS_UNREGBUF",
"STATS_BG_START",
"STATS_BG_STOP",
- "STATS_BF_START",
+ "STATS_BF_START", /*145*/
"STATS_BF_STOP",
"STATS_BHIST_START",
"STATS_BHIST_STOP",
+ "RESET_2",
};
uint8_t vfe32_use_bayer_stats(struct vfe32_ctrl_type *vfe32_ctrl)
@@ -548,7 +563,7 @@
vfe32_ctrl->share_ctrl->stop_ack_pending = FALSE;
spin_unlock_irqrestore(&vfe32_ctrl->share_ctrl->stop_flag_lock, flags);
- vfe32_ctrl->reset_ack_pending = FALSE;
+ init_completion(&vfe32_ctrl->reset_complete);
spin_lock_irqsave(&vfe32_ctrl->update_ack_lock, flags);
vfe32_ctrl->update_ack_pending = FALSE;
@@ -649,7 +664,7 @@
vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
}
-static void vfe32_reset(struct vfe32_ctrl_type *vfe32_ctrl)
+static int vfe32_reset(struct vfe32_ctrl_type *vfe32_ctrl)
{
vfe32_reset_internal_variables(vfe32_ctrl);
/* disable all interrupts. vfeImaskLocal is also reset to 0
@@ -684,6 +699,12 @@
to the command register using the barrier */
msm_camera_io_w_mb(VFE_RESET_UPON_RESET_CMD,
vfe32_ctrl->share_ctrl->vfebase + VFE_GLOBAL_RESET);
+
+ if (vfe32_ctrl->is_reset_blocking)
+ return wait_for_completion_interruptible(
+ &vfe32_ctrl->reset_complete);
+ else
+ return 0;
}
static int vfe32_operation_config(uint32_t *cmd,
@@ -1740,6 +1761,7 @@
case VFE_CMD_RESET:
pr_info("vfe32_proc_general: cmdID = %s\n",
vfe32_general_cmd[cmd->id]);
+ vfe32_ctrl->is_reset_blocking = false;
vfe32_reset(vfe32_ctrl);
break;
case VFE_CMD_START:
@@ -3236,6 +3258,12 @@
CDBG("%s Stopping liveshot ", __func__);
vfe32_stop_liveshot(pmctl, vfe32_ctrl);
break;
+ case VFE_CMD_RESET_2:
+ CDBG("vfe32_proc_general: cmdID = %s\n",
+ vfe32_general_cmd[cmd->id]);
+ vfe32_ctrl->is_reset_blocking = true;
+ vfe32_reset(vfe32_ctrl);
+ break;
default:
if (cmd->length != vfe32_cmd[cmd->id].length)
return -EINVAL;
@@ -3629,8 +3657,12 @@
/* reload all write masters. (frame & line)*/
msm_camera_io_w(0x7FFF,
vfe32_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
- vfe32_send_isp_msg(&vfe32_ctrl->subdev,
- vfe32_ctrl->share_ctrl->vfeFrameId, MSG_ID_RESET_ACK);
+ if (vfe32_ctrl->is_reset_blocking)
+ complete(&vfe32_ctrl->reset_complete);
+ else
+ vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+ vfe32_ctrl->share_ctrl->vfeFrameId,
+ MSG_ID_RESET_ACK);
}
}
diff --git a/drivers/media/video/msm/vfe/msm_vfe32.h b/drivers/media/video/msm/vfe/msm_vfe32.h
index 0b685e1..1795aa2 100644
--- a/drivers/media/video/msm/vfe/msm_vfe32.h
+++ b/drivers/media/video/msm/vfe/msm_vfe32.h
@@ -986,8 +986,9 @@
void *extdata;
int8_t start_ack_pending;
- int8_t reset_ack_pending;
int8_t update_ack_pending;
+ bool is_reset_blocking;
+ struct completion reset_complete;
enum vfe_output_state recording_state;
int8_t update_linear;
int8_t update_rolloff;
diff --git a/include/media/msm_isp.h b/include/media/msm_isp.h
index 0ee7417..ab9e70c 100644
--- a/include/media/msm_isp.h
+++ b/include/media/msm_isp.h
@@ -217,6 +217,7 @@
#define VFE_CMD_STATS_BF_STOP 146
#define VFE_CMD_STATS_BHIST_START 147
#define VFE_CMD_STATS_BHIST_STOP 148
+#define VFE_CMD_RESET_2 149
struct msm_isp_cmd {
int32_t id;