msm: camera: calculate sof_count in ISPIF instead of VFE
Instead of counting the frame id inside VFE camif,
obtain the sof count in ispif and then pass the count into VFE
also add the capability to enable the sof count in VFE
Change-Id: I90c0178d933cb4c80627eb9a5f22b4bb13b10b27
Signed-off-by: Peter Liu <pingchie@codeaurora.org>
diff --git a/drivers/media/video/msm/csi/include/csi2.0/msm_ispif_hwreg.h b/drivers/media/video/msm/csi/include/csi2.0/msm_ispif_hwreg.h
index ecc4fea..c678ea2 100644
--- a/drivers/media/video/msm/csi/include/csi2.0/msm_ispif_hwreg.h
+++ b/drivers/media/video/msm/csi/include/csi2.0/msm_ispif_hwreg.h
@@ -69,9 +69,11 @@
#define RAW_INTF_1_OVERFLOW_IRQ 25
#define RESET_DONE_IRQ 27
-#define ISPIF_IRQ_STATUS_MASK 0xA493000
-#define ISPIF_IRQ_1_STATUS_MASK 0xA493000
-#define ISPIF_IRQ_STATUS_RDI_SOF_MASK 0x492000
+#define ISPIF_IRQ_STATUS_MASK 0xA493249
+#define ISPIF_IRQ_1_STATUS_MASK 0xA493249
+#define ISPIF_IRQ_STATUS_RDI_SOF_MASK 0x492000
+#define ISPIF_IRQ_STATUS_PIX_SOF_MASK 0x249
+#define ISPIF_IRQ_STATUS_SOF_MASK 0x492249
#define ISPIF_IRQ_GLOBAL_CLEAR_CMD 0x1
#endif
diff --git a/drivers/media/video/msm/csi/include/csi3.0/msm_ispif_hwreg.h b/drivers/media/video/msm/csi/include/csi3.0/msm_ispif_hwreg.h
index 820adf4..4b17538 100644
--- a/drivers/media/video/msm/csi/include/csi3.0/msm_ispif_hwreg.h
+++ b/drivers/media/video/msm/csi/include/csi3.0/msm_ispif_hwreg.h
@@ -83,9 +83,12 @@
#define RAW_INTF_1_OVERFLOW_IRQ 25
#define RESET_DONE_IRQ 27
-#define ISPIF_IRQ_STATUS_MASK 0xA493000
-#define ISPIF_IRQ_1_STATUS_MASK 0xA493000
-#define ISPIF_IRQ_STATUS_RDI_SOF_MASK 0x492000
+#define ISPIF_IRQ_STATUS_MASK 0xA493249
+#define ISPIF_IRQ_1_STATUS_MASK 0xA493249
+#define ISPIF_IRQ_STATUS_RDI_SOF_MASK 0x492000
+#define ISPIF_IRQ_STATUS_PIX_SOF_MASK 0x249
+#define ISPIF_IRQ_STATUS_SOF_MASK 0x492249
#define ISPIF_IRQ_GLOBAL_CLEAR_CMD 0x1
+
#endif
diff --git a/drivers/media/video/msm/csi/msm_ispif.c b/drivers/media/video/msm/csi/msm_ispif.c
index b23efb5..092ee90 100644
--- a/drivers/media/video/msm/csi/msm_ispif.c
+++ b/drivers/media/video/msm/csi/msm_ispif.c
@@ -24,6 +24,7 @@
#define V4L2_IDENT_ISPIF 50001
#define CSID_VERSION_V2 0x02000011
#define CSID_VERSION_V3 0x30000000
+
#define MAX_CID 15
static atomic_t ispif_irq_cnt;
@@ -52,6 +53,7 @@
else
data1 |= (0x1 << PIX_0_VFE_RST_STB) |
(0x1 << PIX_0_CSID_RST_STB);
+ ispif->pix_sof_count = 0;
break;
case RDI0:
@@ -127,7 +129,7 @@
(0x1 << PIX_1_CSID_RST_STB) |
(0x1 << RDI_2_VFE_RST_STB) |
(0x1 << RDI_2_CSID_RST_STB);
- return 0;
+ ispif->pix_sof_count = 0;
msm_camera_io_w(data, ispif->base + ISPIF_RST_CMD_ADDR);
rc = wait_for_completion_interruptible(&ispif->reset_complete);
if (ispif->csid_version >= CSID_VERSION_V3) {
@@ -568,7 +570,8 @@
DECLARE_TASKLET(ispif_tasklet, ispif_do_tasklet, 0);
-static void ispif_process_irq(struct ispif_irq_status *out)
+static void ispif_process_irq(struct ispif_device *ispif,
+ struct ispif_irq_status *out)
{
unsigned long flags;
struct ispif_isr_queue_cmd *qcmd;
@@ -583,6 +586,13 @@
qcmd->ispifInterruptStatus0 = out->ispifIrqStatus0;
qcmd->ispifInterruptStatus1 = out->ispifIrqStatus1;
+ if (qcmd->ispifInterruptStatus0 & ISPIF_IRQ_STATUS_PIX_SOF_MASK) {
+ CDBG("%s: ispif PIX sof irq\n", __func__);
+ ispif->pix_sof_count++;
+ v4l2_subdev_notify(&ispif->subdev, NOTIFY_VFE_SOF_COUNT,
+ (void *)&ispif->pix_sof_count);
+ }
+
spin_lock_irqsave(&ispif_tasklet_lock, flags);
list_add_tail(&qcmd->list, &ispif_tasklet_q);
@@ -605,7 +615,7 @@
msm_camera_io_w(out->ispifIrqStatus1,
ispif->base + ISPIF_IRQ_CLEAR_1_ADDR);
- CDBG("ispif->irq: Irq_status0 = 0x%x\n",
+ CDBG("%s: irq ispif->irq: Irq_status0 = 0x%x\n", __func__,
out->ispifIrqStatus0);
if (out->ispifIrqStatus0 & ISPIF_IRQ_STATUS_MASK) {
if (out->ispifIrqStatus0 & (0x1 << RESET_DONE_IRQ))
@@ -614,10 +624,10 @@
pr_err("%s: pix intf 0 overflow.\n", __func__);
if (out->ispifIrqStatus0 & (0x1 << RAW_INTF_0_OVERFLOW_IRQ))
pr_err("%s: rdi intf 0 overflow.\n", __func__);
- if ((out->ispifIrqStatus0 & ISPIF_IRQ_STATUS_RDI_SOF_MASK) ||
+ if ((out->ispifIrqStatus0 & ISPIF_IRQ_STATUS_SOF_MASK) ||
(out->ispifIrqStatus1 &
- ISPIF_IRQ_STATUS_RDI_SOF_MASK)) {
- ispif_process_irq(out);
+ ISPIF_IRQ_STATUS_SOF_MASK)) {
+ ispif_process_irq(ispif, out);
}
}
msm_camera_io_w(ISPIF_IRQ_GLOBAL_CLEAR_CMD, ispif->base +
@@ -648,7 +658,6 @@
INIT_LIST_HEAD(&ispif_tasklet_q);
rc = request_irq(ispif->irq->start, msm_io_ispif_irq,
IRQF_TRIGGER_RISING, "ispif", ispif);
-
init_completion(&ispif->reset_complete);
ispif->csid_version = *csid_version;
diff --git a/drivers/media/video/msm/csi/msm_ispif.h b/drivers/media/video/msm/csi/msm_ispif.h
index df93a44..f4ad661 100644
--- a/drivers/media/video/msm/csi/msm_ispif.h
+++ b/drivers/media/video/msm/csi/msm_ispif.h
@@ -34,6 +34,7 @@
struct completion reset_complete;
uint32_t csid_version;
struct clk *ispif_clk[5];
+ uint32_t pix_sof_count;
};
struct ispif_isr_queue_cmd {
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/video/msm/msm.h
index 687ed74..bdd1e98 100644
--- a/drivers/media/video/msm/msm.h
+++ b/drivers/media/video/msm/msm.h
@@ -148,6 +148,7 @@
NOTIFY_VFE_MSG_COMP_STATS, /* arg = struct msm_stats_buf */
NOTIFY_VFE_BUF_EVT, /* arg = struct msm_vfe_resp */
NOTIFY_VFE_CAMIF_ERROR,
+ NOTIFY_VFE_SOF_COUNT, /*arg = int*/
NOTIFY_PCLK_CHANGE, /* arg = pclk */
NOTIFY_CSIPHY_CFG, /* arg = msm_camera_csiphy_params */
NOTIFY_CSID_CFG, /* arg = msm_camera_csid_params */
diff --git a/drivers/media/video/msm/msm_isp.c b/drivers/media/video/msm/msm_isp.c
index 935ce75..789f6cf 100644
--- a/drivers/media/video/msm/msm_isp.c
+++ b/drivers/media/video/msm/msm_isp.c
@@ -81,6 +81,20 @@
return 0;
}
+static int msm_isp_notify_VFE_SOF_COUNT_EVT(struct v4l2_subdev *sd, void *arg)
+{
+ struct msm_vfe_cfg_cmd cfgcmd;
+ struct msm_camvfe_params vfe_params;
+ int rc;
+
+ cfgcmd.cmd_type = CMD_VFE_SOF_COUNT_UPDATE;
+ cfgcmd.value = NULL;
+ vfe_params.vfe_cfg = &cfgcmd;
+ vfe_params.data = arg;
+ rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
+ return 0;
+}
+
int msm_isp_vfe_msg_to_img_mode(struct msm_cam_media_controller *pmctl,
int vfe_msg)
{
@@ -297,6 +311,9 @@
if (notification == NOTIFY_VFE_BUF_FREE_EVT)
return msm_isp_notify_VFE_BUF_FREE_EVT(sd, arg);
+ if (notification == NOTIFY_VFE_SOF_COUNT)
+ return msm_isp_notify_VFE_SOF_COUNT_EVT(sd, arg);
+
isp_event = kzalloc(sizeof(struct msm_isp_event_ctrl), GFP_ATOMIC);
if (!isp_event) {
pr_err("%s Insufficient memory. return", __func__);
diff --git a/drivers/media/video/msm/server/msm_cam_server.c b/drivers/media/video/msm/server/msm_cam_server.c
index 36b9576..8fb25ca 100644
--- a/drivers/media/video/msm/server/msm_cam_server.c
+++ b/drivers/media/video/msm/server/msm_cam_server.c
@@ -1463,6 +1463,7 @@
switch (notification) {
case NOTIFY_ISP_MSG_EVT:
case NOTIFY_VFE_MSG_OUT:
+ case NOTIFY_VFE_SOF_COUNT:
case NOTIFY_VFE_MSG_STATS:
case NOTIFY_VFE_MSG_COMP_STATS:
case NOTIFY_VFE_BUF_EVT:
diff --git a/drivers/media/video/msm/vfe/msm_vfe32.c b/drivers/media/video/msm/vfe/msm_vfe32.c
index 2f50d7f..258f560 100644
--- a/drivers/media/video/msm/vfe/msm_vfe32.c
+++ b/drivers/media/video/msm/vfe/msm_vfe32.c
@@ -599,6 +599,7 @@
/* this is unsigned 32 bit integer. */
vfe32_ctrl->share_ctrl->vfeFrameId = 0;
+
/* Stats control variables. */
memset(&(vfe32_ctrl->afbfStatsControl), 0,
sizeof(struct vfe_stats_control));
@@ -3543,11 +3544,14 @@
VFE_MODE_OF_OPERATION_VIDEO) &&
(vfe32_ctrl->share_ctrl->vfeFrameId %
vfe32_ctrl->hfr_mode != 0)) {
- vfe32_ctrl->share_ctrl->vfeFrameId++;
+ if (vfe32_ctrl->vfe_sof_count_enable)
+ vfe32_ctrl->share_ctrl->vfeFrameId++;
CDBG("Skip the SOF notification when HFR enabled\n");
return;
}
- vfe32_ctrl->share_ctrl->vfeFrameId++;
+ if (vfe32_ctrl->vfe_sof_count_enable)
+ vfe32_ctrl->share_ctrl->vfeFrameId++;
+
vfe32_send_isp_msg(&vfe32_ctrl->subdev,
vfe32_ctrl->share_ctrl->vfeFrameId, MSG_ID_SOF_ACK);
CDBG("camif_sof_irq, frameId = %d\n",
@@ -4373,7 +4377,6 @@
struct vfe32_ctrl_type *vfe32_ctrl, uint32_t irqstatus)
{
uint32_t status_bits = VFE_COM_STATUS & irqstatus;
-
if ((vfe32_ctrl->hfr_mode != HFR_MODE_OFF) &&
(vfe32_ctrl->share_ctrl->vfeFrameId %
vfe32_ctrl->hfr_mode != 0)) {
@@ -4845,7 +4848,9 @@
cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE &&
cmd->cmd_type != CMD_STATS_BG_BUF_RELEASE &&
cmd->cmd_type != CMD_STATS_BF_BUF_RELEASE &&
- cmd->cmd_type != CMD_STATS_BHIST_BUF_RELEASE) {
+ cmd->cmd_type != CMD_STATS_BHIST_BUF_RELEASE &&
+ cmd->cmd_type != CMD_VFE_SOF_COUNT_UPDATE &&
+ cmd->cmd_type != CMD_VFE_COUNT_SOF_ENABLE) {
if (copy_from_user(&vfecmd,
(void __user *)(cmd->value),
sizeof(vfecmd))) {
@@ -4925,6 +4930,19 @@
case CMD_GENERAL:
rc = vfe32_proc_general(pmctl, &vfecmd, vfe32_ctrl);
break;
+ case CMD_VFE_COUNT_SOF_ENABLE: {
+ int enable = *((int *)cmd->value);
+ if (enable)
+ vfe32_ctrl->vfe_sof_count_enable = TRUE;
+ else
+ vfe32_ctrl->vfe_sof_count_enable = false;
+ }
+ break;
+ case CMD_VFE_SOF_COUNT_UPDATE:
+ if (!vfe32_ctrl->vfe_sof_count_enable)
+ vfe32_ctrl->share_ctrl->vfeFrameId =
+ *((uint32_t *)vfe_params->data);
+ break;
case CMD_CONFIG_PING_ADDR: {
int path = *((int *)cmd->value);
struct vfe32_output_ch *outch =
@@ -5081,6 +5099,7 @@
vfe32_ctrl->update_rolloff = false;
vfe32_ctrl->update_la = false;
vfe32_ctrl->update_gamma = false;
+ vfe32_ctrl->vfe_sof_count_enable = false;
vfe32_ctrl->hfr_mode = HFR_MODE_OFF;
memset(&vfe32_ctrl->stats_ctrl, 0, sizeof(struct msm_stats_bufq_ctrl));
diff --git a/drivers/media/video/msm/vfe/msm_vfe32.h b/drivers/media/video/msm/vfe/msm_vfe32.h
index 170bfb7..209c289 100644
--- a/drivers/media/video/msm/vfe/msm_vfe32.h
+++ b/drivers/media/video/msm/vfe/msm_vfe32.h
@@ -988,6 +988,7 @@
uint32_t extlen;
void *extdata;
+ int8_t vfe_sof_count_enable;
int8_t start_ack_pending;
int8_t update_ack_pending;
bool is_reset_blocking;
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index 2a07002..db88540 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -486,7 +486,8 @@
#define CMD_STATS_BG_BUF_RELEASE 56
#define CMD_STATS_BF_BUF_RELEASE 57
#define CMD_STATS_BHIST_BUF_RELEASE 58
-
+#define CMD_VFE_SOF_COUNT_UPDATE 59
+#define CMD_VFE_COUNT_SOF_ENABLE 60
#define CMD_AXI_CFG_PRIM BIT(8)
#define CMD_AXI_CFG_PRIM_ALL_CHNLS BIT(9)