Loading drivers/media/platform/msm/camera_v2/isp/msm_isp.h +1 −0 Original line number Diff line number Diff line Loading @@ -616,6 +616,7 @@ struct dual_vfe_resource { struct msm_vfe_stats_shared_data *stats_data[MAX_VFE]; struct msm_vfe_axi_shared_data *axi_data[MAX_VFE]; uint32_t wm_reload_mask[MAX_VFE]; uint32_t epoch_sync_mask; }; struct master_slave_resource_info { Loading drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +90 −1 Original line number Diff line number Diff line Loading @@ -543,6 +543,89 @@ static void msm_isp_cfg_framedrop_reg(struct vfe_device *vfe_dev, } } /** * msm_isp_check_epoch_status() - check the epock signal for framedrop * * @vfe_dev: The h/w on which the epoch signel is reveived * @frame_src: The source of the epoch signal for this frame * * For dual vfe case and pixel stream, if both vfe's epoch signal is * received, this function will return success. * It will also return the vfe1 for further process * For none dual VFE stream or none pixl source, this * funciton will just return success. * * Returns 1 - epoch received is complete. * 0 - epoch reveived is not complete. */ static int msm_isp_check_epoch_status(struct vfe_device **vfe_dev, enum msm_vfe_input_src frame_src) { struct vfe_device *vfe_dev_cur = *vfe_dev; struct vfe_device *vfe_dev_other = NULL; uint32_t vfe_id_other = 0; uint32_t vfe_id_cur = 0; uint32_t epoch_mask = 0; unsigned long flags; int completed = 0; spin_lock_irqsave( &vfe_dev_cur->common_data->common_dev_data_lock, flags); if (vfe_dev_cur->is_split && frame_src == VFE_PIX_0) { if (vfe_dev_cur->pdev->id == ISP_VFE0) { vfe_id_cur = ISP_VFE0; vfe_id_other = ISP_VFE1; } else { vfe_id_cur = ISP_VFE1; vfe_id_other = ISP_VFE0; } vfe_dev_other = vfe_dev_cur->common_data->dual_vfe_res-> vfe_dev[vfe_id_other]; if (vfe_dev_cur->common_data->dual_vfe_res-> epoch_sync_mask & (1 << vfe_id_cur)) { /* serious scheduling delay */ pr_err("Missing epoch: vfe %d, epoch mask 0x%x\n", vfe_dev_cur->pdev->id, vfe_dev_cur->common_data->dual_vfe_res-> epoch_sync_mask); goto fatal; } vfe_dev_cur->common_data->dual_vfe_res-> epoch_sync_mask |= (1 << vfe_id_cur); epoch_mask = (1 << vfe_id_cur) | (1 << vfe_id_other); if ((vfe_dev_cur->common_data->dual_vfe_res-> epoch_sync_mask & epoch_mask) == epoch_mask) { if (vfe_id_other == ISP_VFE0) *vfe_dev = vfe_dev_cur; else *vfe_dev = vfe_dev_other; vfe_dev_cur->common_data->dual_vfe_res-> epoch_sync_mask &= ~epoch_mask; completed = 1; } } else completed = 1; spin_unlock_irqrestore( &vfe_dev_cur->common_data->common_dev_data_lock, flags); return completed; fatal: spin_unlock_irqrestore( &vfe_dev_cur->common_data->common_dev_data_lock, flags); /* new error event code will be added later */ msm_isp_halt_send_error(vfe_dev_cur, ISP_EVENT_PING_PONG_MISMATCH); return 0; } /** * msm_isp_update_framedrop_reg() - Update frame period pattern on h/w * @vfe_dev: The h/w on which the perion pattern is updated. Loading @@ -558,10 +641,15 @@ void msm_isp_update_framedrop_reg(struct vfe_device *vfe_dev, enum msm_vfe_input_src frame_src) { int i; struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; struct msm_vfe_axi_shared_data *axi_data = NULL; struct msm_vfe_axi_stream *stream_info; unsigned long flags; if (msm_isp_check_epoch_status(&vfe_dev, frame_src) != 1) return; axi_data = &vfe_dev->axi_data; for (i = 0; i < VFE_AXI_SRC_MAX; i++) { if (SRC_TO_INTF(axi_data->stream_info[i].stream_src) != frame_src) { Loading Loading @@ -2581,6 +2669,7 @@ static int msm_isp_start_axi_stream(struct vfe_device *vfe_dev, vfe_dev->hw_info->vfe_ops.core_ops. update_camif_state(vfe_dev, camif_update); vfe_dev->axi_data.camif_state = CAMIF_ENABLE; vfe_dev->common_data->dual_vfe_res->epoch_sync_mask = 0; } if (wait_for_complete) { Loading drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c +7 −2 Original line number Diff line number Diff line Loading @@ -2153,11 +2153,16 @@ int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) ISP_DBG("%s open_cnt %u\n", __func__, vfe_dev->vfe_open_cnt); if (vfe_dev->common_data == NULL) { pr_err("%s: Error in probe. No common_data\n", __func__); if (vfe_dev->common_data == NULL || vfe_dev->common_data->dual_vfe_res == NULL) { pr_err("%s: Error in probe. No common_data or dual vfe res\n", __func__); return -EINVAL; } if (vfe_dev->pdev->id == ISP_VFE0) vfe_dev->common_data->dual_vfe_res->epoch_sync_mask = 0; mutex_lock(&vfe_dev->realtime_mutex); mutex_lock(&vfe_dev->core_mutex); Loading Loading
drivers/media/platform/msm/camera_v2/isp/msm_isp.h +1 −0 Original line number Diff line number Diff line Loading @@ -616,6 +616,7 @@ struct dual_vfe_resource { struct msm_vfe_stats_shared_data *stats_data[MAX_VFE]; struct msm_vfe_axi_shared_data *axi_data[MAX_VFE]; uint32_t wm_reload_mask[MAX_VFE]; uint32_t epoch_sync_mask; }; struct master_slave_resource_info { Loading
drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +90 −1 Original line number Diff line number Diff line Loading @@ -543,6 +543,89 @@ static void msm_isp_cfg_framedrop_reg(struct vfe_device *vfe_dev, } } /** * msm_isp_check_epoch_status() - check the epock signal for framedrop * * @vfe_dev: The h/w on which the epoch signel is reveived * @frame_src: The source of the epoch signal for this frame * * For dual vfe case and pixel stream, if both vfe's epoch signal is * received, this function will return success. * It will also return the vfe1 for further process * For none dual VFE stream or none pixl source, this * funciton will just return success. * * Returns 1 - epoch received is complete. * 0 - epoch reveived is not complete. */ static int msm_isp_check_epoch_status(struct vfe_device **vfe_dev, enum msm_vfe_input_src frame_src) { struct vfe_device *vfe_dev_cur = *vfe_dev; struct vfe_device *vfe_dev_other = NULL; uint32_t vfe_id_other = 0; uint32_t vfe_id_cur = 0; uint32_t epoch_mask = 0; unsigned long flags; int completed = 0; spin_lock_irqsave( &vfe_dev_cur->common_data->common_dev_data_lock, flags); if (vfe_dev_cur->is_split && frame_src == VFE_PIX_0) { if (vfe_dev_cur->pdev->id == ISP_VFE0) { vfe_id_cur = ISP_VFE0; vfe_id_other = ISP_VFE1; } else { vfe_id_cur = ISP_VFE1; vfe_id_other = ISP_VFE0; } vfe_dev_other = vfe_dev_cur->common_data->dual_vfe_res-> vfe_dev[vfe_id_other]; if (vfe_dev_cur->common_data->dual_vfe_res-> epoch_sync_mask & (1 << vfe_id_cur)) { /* serious scheduling delay */ pr_err("Missing epoch: vfe %d, epoch mask 0x%x\n", vfe_dev_cur->pdev->id, vfe_dev_cur->common_data->dual_vfe_res-> epoch_sync_mask); goto fatal; } vfe_dev_cur->common_data->dual_vfe_res-> epoch_sync_mask |= (1 << vfe_id_cur); epoch_mask = (1 << vfe_id_cur) | (1 << vfe_id_other); if ((vfe_dev_cur->common_data->dual_vfe_res-> epoch_sync_mask & epoch_mask) == epoch_mask) { if (vfe_id_other == ISP_VFE0) *vfe_dev = vfe_dev_cur; else *vfe_dev = vfe_dev_other; vfe_dev_cur->common_data->dual_vfe_res-> epoch_sync_mask &= ~epoch_mask; completed = 1; } } else completed = 1; spin_unlock_irqrestore( &vfe_dev_cur->common_data->common_dev_data_lock, flags); return completed; fatal: spin_unlock_irqrestore( &vfe_dev_cur->common_data->common_dev_data_lock, flags); /* new error event code will be added later */ msm_isp_halt_send_error(vfe_dev_cur, ISP_EVENT_PING_PONG_MISMATCH); return 0; } /** * msm_isp_update_framedrop_reg() - Update frame period pattern on h/w * @vfe_dev: The h/w on which the perion pattern is updated. Loading @@ -558,10 +641,15 @@ void msm_isp_update_framedrop_reg(struct vfe_device *vfe_dev, enum msm_vfe_input_src frame_src) { int i; struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; struct msm_vfe_axi_shared_data *axi_data = NULL; struct msm_vfe_axi_stream *stream_info; unsigned long flags; if (msm_isp_check_epoch_status(&vfe_dev, frame_src) != 1) return; axi_data = &vfe_dev->axi_data; for (i = 0; i < VFE_AXI_SRC_MAX; i++) { if (SRC_TO_INTF(axi_data->stream_info[i].stream_src) != frame_src) { Loading Loading @@ -2581,6 +2669,7 @@ static int msm_isp_start_axi_stream(struct vfe_device *vfe_dev, vfe_dev->hw_info->vfe_ops.core_ops. update_camif_state(vfe_dev, camif_update); vfe_dev->axi_data.camif_state = CAMIF_ENABLE; vfe_dev->common_data->dual_vfe_res->epoch_sync_mask = 0; } if (wait_for_complete) { Loading
drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c +7 −2 Original line number Diff line number Diff line Loading @@ -2153,11 +2153,16 @@ int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) ISP_DBG("%s open_cnt %u\n", __func__, vfe_dev->vfe_open_cnt); if (vfe_dev->common_data == NULL) { pr_err("%s: Error in probe. No common_data\n", __func__); if (vfe_dev->common_data == NULL || vfe_dev->common_data->dual_vfe_res == NULL) { pr_err("%s: Error in probe. No common_data or dual vfe res\n", __func__); return -EINVAL; } if (vfe_dev->pdev->id == ISP_VFE0) vfe_dev->common_data->dual_vfe_res->epoch_sync_mask = 0; mutex_lock(&vfe_dev->realtime_mutex); mutex_lock(&vfe_dev->core_mutex); Loading