Merge "msm: camera: isp: Fix RDI stream streamoff issue"
This commit is contained in:
commit
afc9724015
4 changed files with 132 additions and 47 deletions
|
@ -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
|
||||
|
||||
|
@ -652,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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
@ -1937,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))
|
||||
|
@ -1962,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(
|
||||
|
@ -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) {
|
||||
|
@ -2645,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 ||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue