From 4783238a598ef4829691c376d3ab7d1ed0896dad Mon Sep 17 00:00:00 2001 From: Shilpa Mamidi Date: Wed, 11 May 2016 15:04:16 +0530 Subject: [PATCH 1/3] msm: isp: Add 48K UB for MSM8917 target Add support to increase UB size to 48K and also change burst length for MSM8917 as per HW specifications. Change-Id: I086aa920fb93524aa2bf8a740514a3012cd5f8a0 Signed-off-by: Shilpa Mamidi Signed-off-by: Shubhraprakash Das --- drivers/media/platform/msm/camera_v2/isp/msm_isp.h | 1 + drivers/media/platform/msm/camera_v2/isp/msm_isp40.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h index 95465fb24feb..d7129868e3fd 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h @@ -40,6 +40,7 @@ #define VFE40_8952_VERSION 0x10060000 #define VFE40_8976_VERSION 0x10050000 #define VFE40_8937_VERSION 0x10080000 +#define VFE40_8917_VERSION 0x10080001 #define VFE40_8953_VERSION 0x10090000 #define VFE32_8909_VERSION 0x30600 diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c index d4f0453d72ff..a76ccc06c9e1 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c @@ -326,6 +326,7 @@ static void msm_vfe40_init_hardware_reg(struct vfe_device *vfe_dev) break; case VFE40_8937_VERSION: case VFE40_8953_VERSION: + case VFE40_8917_VERSION: default: ISP_DBG("%s: No special QOS\n", __func__); } @@ -1475,6 +1476,7 @@ static void msm_vfe40_axi_cfg_wm_reg( wm_bit_shift = VFE40_WM_BIT_SHIFT; } else if (vfe_dev->vfe_hw_version == VFE40_8976_VERSION || vfe_dev->vfe_hw_version == VFE40_8937_VERSION || + vfe_dev->vfe_hw_version == VFE40_8917_VERSION || vfe_dev->vfe_hw_version == VFE40_8953_VERSION) { burst_len = VFE40_BURST_LEN_8952_VERSION; wm_bit_shift = VFE40_WM_BIT_SHIFT_8976_VERSION; @@ -1986,6 +1988,7 @@ static void msm_vfe40_stats_cfg_ub(struct vfe_device *vfe_dev) if (vfe_dev->vfe_hw_version == VFE40_8916_VERSION || vfe_dev->vfe_hw_version == VFE40_8939_VERSION || vfe_dev->vfe_hw_version == VFE40_8937_VERSION || + vfe_dev->vfe_hw_version == VFE40_8917_VERSION || vfe_dev->vfe_hw_version == VFE40_8953_VERSION) { stats_burst_len = VFE40_STATS_BURST_LEN_8916_VERSION; ub_offset = VFE40_UB_SIZE_8916; From 653e570ddf69e447f9ca65013bb744129aee92a6 Mon Sep 17 00:00:00 2001 From: Jing Zhou Date: Mon, 11 Apr 2016 10:20:47 -0700 Subject: [PATCH 2/3] msm: camera: isp: Fix the framedrop setting issue This change fixes a framedrop issue due to unsynced epoch signal. In dual vfe case, the epoch signal from each VFE might arrived in any order. Since reset the framedrop pattern for both VFE is done in the epocch signal, we need to align this action with the last vfe epoch signal. The current implementation is to do the reset always on the vfe1 signal, this has led to incorrect framedrop pattern reset which cause the framedrop pattern out of sync between two VFEs. This change aligns this action with the latest epoch signal so split will not happen. CRs-fixed: 991080 Change-Id: I20a911fd8cec9e36e6867fa19428513f36054a8a Signed-off-by: Jing Zhou Signed-off-by: Shubhraprakash Das --- .../platform/msm/camera_v2/isp/msm_isp.h | 1 + .../msm/camera_v2/isp/msm_isp_axi_util.c | 91 ++++++++++++++++++- .../platform/msm/camera_v2/isp/msm_isp_util.c | 9 +- 3 files changed, 98 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h index d7129868e3fd..763b6a575326 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h @@ -653,6 +653,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 { diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c index fbac6d81ded0..0d456112f6f3 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c @@ -539,6 +539,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. @@ -554,10 +637,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) { @@ -2584,6 +2672,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) { diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c index 460746089c53..5b12c1239bf4 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c @@ -1917,11 +1917,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); From 36edcc0d58a8c96659901dbf539e45f018a43906 Mon Sep 17 00:00:00 2001 From: Jing Zhou Date: Fri, 1 Apr 2016 15:49:56 -0700 Subject: [PATCH 3/3] msm: camera: isp: Fix RDI stream streamoff issue When stop the RDI stream, the wait flag should not be set to true if we are halting the system. In the new logic, the halt will cause the system timeout due to ispif might be stopped. The change will stop the RDI without waiting if the VFE will be halted. CRs-fixed: 991080 Change-Id: Ia0a7512006c1eeb15deb10b87aaff5668a7b5ef2 Signed-off-by: Jing Zhou Signed-off-by: Shubhraprakash Das --- .../msm/camera_v2/isp/msm_isp_axi_util.c | 74 ++++++++----------- 1 file changed, 30 insertions(+), 44 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c index 0d456112f6f3..3dd55e02826d 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c @@ -2025,24 +2025,6 @@ static void msm_isp_get_camif_update_state_and_halt( pix_stream_cnt++; } - if ((pix_stream_cnt) && - (axi_data->src_info[VFE_PIX_0].input_mux != EXTERNAL_READ)) { - if (cur_pix_stream_cnt == 0 && pix_stream_cnt && - stream_cfg_cmd->cmd == START_STREAM) - *camif_update = ENABLE_CAMIF; - else if (cur_pix_stream_cnt && - (cur_pix_stream_cnt - pix_stream_cnt) == 0 && - stream_cfg_cmd->cmd == STOP_STREAM) - *camif_update = DISABLE_CAMIF; - else if (cur_pix_stream_cnt && - (cur_pix_stream_cnt - pix_stream_cnt) == 0 && - stream_cfg_cmd->cmd == STOP_IMMEDIATELY) - *camif_update = DISABLE_CAMIF_IMMEDIATELY; - else - *camif_update = NO_UPDATE; - } else - *camif_update = NO_UPDATE; - if (vfe_dev->axi_data.num_active_stream == stream_cfg_cmd->num_streams && (stream_cfg_cmd->cmd == STOP_STREAM || stream_cfg_cmd->cmd == STOP_IMMEDIATELY)) @@ -2050,6 +2032,24 @@ static void msm_isp_get_camif_update_state_and_halt( else *halt = 0; + if ((pix_stream_cnt) && + (axi_data->src_info[VFE_PIX_0].input_mux != EXTERNAL_READ)) { + if (cur_pix_stream_cnt == 0 && pix_stream_cnt && + stream_cfg_cmd->cmd == START_STREAM) + *camif_update = ENABLE_CAMIF; + else if (cur_pix_stream_cnt && + (cur_pix_stream_cnt - pix_stream_cnt) == 0 && + (stream_cfg_cmd->cmd == STOP_STREAM || + stream_cfg_cmd->cmd == STOP_IMMEDIATELY)) { + if (*halt) + *camif_update = DISABLE_CAMIF_IMMEDIATELY; + else + *camif_update = DISABLE_CAMIF; + } + else + *camif_update = NO_UPDATE; + } else + *camif_update = NO_UPDATE; } static void msm_isp_update_camif_output_count( @@ -2734,34 +2734,20 @@ static int msm_isp_stop_axi_stream(struct vfe_device *vfe_dev, wait_for_complete_for_this_stream = 0; stream_info->state = STOP_PENDING; - ISP_DBG("Stop axi Stream 0x%x\n", stream_info->stream_id); - if (stream_info->stream_src == CAMIF_RAW || - stream_info->stream_src == IDEAL_RAW) { - /* We dont get reg update IRQ for raw snapshot - * so frame skip cant be ocnfigured - */ - if ((camif_update != DISABLE_CAMIF_IMMEDIATELY) && - (!ext_read)) - wait_for_complete_for_this_stream = 1; - } else if (stream_info->stream_type == BURST_STREAM && - stream_info->runtime_num_burst_capture == 0) { - /* Configure AXI writemasters to stop immediately - * since for burst case, write masters already skip - * all frames. - */ - if (stream_info->stream_src == RDI_INTF_0 || - stream_info->stream_src == RDI_INTF_1 || - stream_info->stream_src == RDI_INTF_2) - wait_for_complete_for_this_stream = 1; - } else { - if ((camif_update != DISABLE_CAMIF_IMMEDIATELY) && - !halt && (!ext_read)) - wait_for_complete_for_this_stream = 1; - } - ISP_DBG("%s: vfe_dev %d camif_update %d halt %d wait %d\n", - __func__, vfe_dev->pdev->id, camif_update, halt, + if (!halt && !ext_read && + !(stream_info->stream_type == BURST_STREAM && + stream_info->runtime_num_burst_capture == 0)) + wait_for_complete_for_this_stream = 1; + + ISP_DBG("%s: stream 0x%x, vfe %d camif %d halt %d wait %d\n", + __func__, + stream_info->stream_id, + vfe_dev->pdev->id, + camif_update, + halt, wait_for_complete_for_this_stream); + intf = SRC_TO_INTF(stream_info->stream_src); if (!wait_for_complete_for_this_stream || stream_info->state == INACTIVE ||