msm: camera: sof freeze enhancement
Enable CSID IRQ dynamically and add sof recover logic, in case kernel get sof freeze hints from userspace,will enable IRQs to monitor the status of moduels,if sof recovers after 2.5 secs then kernel get MSM_SD_UNNOTIFY_FREEZE to disable all the IRQs. CRs-Fixed: 973732 Change-Id: I7aa6dcd60e0858258c40c3d6517e2974e6e2b722 Signed-off-by: Ramesh V <ramev@codeaurora.org>
This commit is contained in:
parent
99658ec7e3
commit
79e5686c6b
15 changed files with 115 additions and 21 deletions
|
@ -16,7 +16,7 @@
|
|||
#include "msm_isp_axi_util.h"
|
||||
|
||||
#define HANDLE_TO_IDX(handle) (handle & 0xFF)
|
||||
#define ISP_SOF_DEBUG_COUNT 0
|
||||
#define ISP_SOF_DEBUG_COUNT 5
|
||||
|
||||
static int msm_isp_update_dual_HW_ms_info_at_start(
|
||||
struct vfe_device *vfe_dev,
|
||||
|
|
|
@ -1088,6 +1088,8 @@ static long msm_isp_ioctl_unlocked(struct v4l2_subdev *sd,
|
|||
vfe_dev->isp_raw1_debug = 0;
|
||||
vfe_dev->isp_raw2_debug = 0;
|
||||
break;
|
||||
case MSM_SD_UNNOTIFY_FREEZE:
|
||||
break;
|
||||
case MSM_SD_SHUTDOWN:
|
||||
while (vfe_dev->vfe_open_cnt != 0)
|
||||
msm_isp_close_node(sd, NULL);
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
|
||||
#define ISPIF_TIMEOUT_SLEEP_US 1000
|
||||
#define ISPIF_TIMEOUT_ALL_US 1000000
|
||||
#define ISPIF_SOF_DEBUG_COUNT 0
|
||||
#define ISPIF_SOF_DEBUG_COUNT 5
|
||||
|
||||
#undef CDBG
|
||||
#ifdef CONFIG_MSMB_CAMERA_DEBUG
|
||||
|
|
|
@ -503,12 +503,16 @@ static inline int __msm_sd_close_subdevs(struct msm_sd_subdev *msm_sd,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int __msm_sd_notify_freeze_subdevs(struct msm_sd_subdev *msm_sd)
|
||||
static inline int __msm_sd_notify_freeze_subdevs(struct msm_sd_subdev *msm_sd,
|
||||
int enable)
|
||||
{
|
||||
struct v4l2_subdev *sd;
|
||||
sd = &msm_sd->sd;
|
||||
|
||||
v4l2_subdev_call(sd, core, ioctl, MSM_SD_NOTIFY_FREEZE, NULL);
|
||||
if (enable)
|
||||
v4l2_subdev_call(sd, core, ioctl, MSM_SD_NOTIFY_FREEZE, NULL);
|
||||
else
|
||||
v4l2_subdev_call(sd, core, ioctl, MSM_SD_UNNOTIFY_FREEZE, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -716,10 +720,18 @@ static long msm_private_ioctl(struct file *file, void *fh,
|
|||
break;
|
||||
|
||||
case MSM_CAM_V4L2_IOCTL_NOTIFY_DEBUG: {
|
||||
pr_err("Notifying subdevs about potential sof freeze\n");
|
||||
if (event_data->status) {
|
||||
pr_err("%s:Notifying subdevs about potential sof freeze\n",
|
||||
__func__);
|
||||
} else {
|
||||
pr_err("%s:Notifying subdevs about sof recover\n",
|
||||
__func__);
|
||||
}
|
||||
|
||||
if (!list_empty(&msm_v4l2_dev->subdevs)) {
|
||||
list_for_each_entry(msm_sd, &ordered_sd_list, list)
|
||||
__msm_sd_notify_freeze_subdevs(msm_sd);
|
||||
__msm_sd_notify_freeze_subdevs(msm_sd,
|
||||
event_data->status);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -442,6 +442,8 @@ static long msm_buf_mngr_subdev_ioctl(struct v4l2_subdev *sd,
|
|||
case VIDIOC_MSM_BUF_MNGR_FLUSH:
|
||||
rc = msm_generic_buf_mngr_flush(buf_mngr_dev, argp);
|
||||
break;
|
||||
case MSM_SD_UNNOTIFY_FREEZE:
|
||||
break;
|
||||
case MSM_SD_SHUTDOWN:
|
||||
msm_buf_mngr_sd_shutdown(buf_mngr_dev, argp);
|
||||
break;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -37,6 +37,9 @@ struct msm_sd_close_ioctl {
|
|||
|
||||
#define MSM_SD_NOTIFY_FREEZE \
|
||||
_IOWR('V', BASE_VIDIOC_PRIVATE + 30, struct msm_sd_close_ioctl)
|
||||
|
||||
#define MSM_SD_UNNOTIFY_FREEZE \
|
||||
_IOWR('V', BASE_VIDIOC_PRIVATE + 31, struct msm_sd_close_ioctl)
|
||||
/*
|
||||
* This is used to install Sequence in msm_sd_register.
|
||||
* During msm_close, proper close sequence will be triggered.
|
||||
|
|
|
@ -3332,6 +3332,8 @@ STREAM_BUFF_END:
|
|||
}
|
||||
case MSM_SD_NOTIFY_FREEZE:
|
||||
break;
|
||||
case MSM_SD_UNNOTIFY_FREEZE:
|
||||
break;
|
||||
case MSM_SD_SHUTDOWN:
|
||||
CPP_DBG("MSM_SD_SHUTDOWN\n");
|
||||
mutex_unlock(&cpp_dev->mutex);
|
||||
|
@ -4075,6 +4077,8 @@ static long msm_cpp_subdev_fops_compat_ioctl(struct file *file,
|
|||
break;
|
||||
case MSM_SD_NOTIFY_FREEZE:
|
||||
break;
|
||||
case MSM_SD_UNNOTIFY_FREEZE:
|
||||
break;
|
||||
case MSM_SD_SHUTDOWN:
|
||||
cmd = MSM_SD_SHUTDOWN;
|
||||
break;
|
||||
|
@ -4107,6 +4111,8 @@ static long msm_cpp_subdev_fops_compat_ioctl(struct file *file,
|
|||
break;
|
||||
case MSM_SD_NOTIFY_FREEZE:
|
||||
break;
|
||||
case MSM_SD_UNNOTIFY_FREEZE:
|
||||
break;
|
||||
default:
|
||||
pr_err_ratelimited("%s: unsupported compat type :%d\n",
|
||||
__func__, cmd);
|
||||
|
|
|
@ -1487,6 +1487,8 @@ static long msm_actuator_subdev_ioctl(struct v4l2_subdev *sd,
|
|||
return msm_actuator_config(a_ctrl, argp);
|
||||
case MSM_SD_NOTIFY_FREEZE:
|
||||
return 0;
|
||||
case MSM_SD_UNNOTIFY_FREEZE:
|
||||
return 0;
|
||||
case MSM_SD_SHUTDOWN:
|
||||
if (!a_ctrl->i2c_client.i2c_func_tbl) {
|
||||
pr_err("a_ctrl->i2c_client.i2c_func_tbl NULL\n");
|
||||
|
|
|
@ -1698,6 +1698,8 @@ static long msm_cci_subdev_ioctl(struct v4l2_subdev *sd,
|
|||
break;
|
||||
case MSM_SD_NOTIFY_FREEZE:
|
||||
break;
|
||||
case MSM_SD_UNNOTIFY_FREEZE:
|
||||
break;
|
||||
case MSM_SD_SHUTDOWN: {
|
||||
struct msm_camera_cci_ctrl ctrl_cmd;
|
||||
ctrl_cmd.cmd = MSM_CCI_RELEASE;
|
||||
|
|
|
@ -196,6 +196,27 @@ static void msm_csid_set_debug_reg(struct csid_device *csid_dev,
|
|||
struct msm_camera_csid_params *csid_params) {}
|
||||
#endif
|
||||
|
||||
static void msm_csid_set_sof_freeze_debug_reg(struct csid_device *csid_dev)
|
||||
{
|
||||
uint32_t val = 0;
|
||||
|
||||
if (csid_dev->csid_3p_enabled == 1) {
|
||||
val = ((1 << csid_dev->current_csid_params.lane_cnt) - 1) <<
|
||||
csid_dev->ctrl_reg->
|
||||
csid_reg.csid_err_lane_overflow_offset_3p;
|
||||
} else {
|
||||
val = ((1 << csid_dev->current_csid_params.lane_cnt) - 1) <<
|
||||
csid_dev->ctrl_reg->
|
||||
csid_reg.csid_err_lane_overflow_offset_2p;
|
||||
}
|
||||
val |= csid_dev->ctrl_reg->csid_reg.csid_irq_mask_val;
|
||||
val |= SHORT_PKT_OFFSET;
|
||||
msm_camera_io_w(val, csid_dev->base +
|
||||
csid_dev->ctrl_reg->csid_reg.csid_irq_mask_addr);
|
||||
msm_camera_io_w(val, csid_dev->base +
|
||||
csid_dev->ctrl_reg->csid_reg.csid_irq_clear_cmd_addr);
|
||||
}
|
||||
|
||||
static int msm_csid_reset(struct csid_device *csid_dev)
|
||||
{
|
||||
int32_t rc = 0;
|
||||
|
@ -417,7 +438,7 @@ static irqreturn_t msm_csid_irq(int irq_num, void *data)
|
|||
}
|
||||
irq = msm_camera_io_r(csid_dev->base +
|
||||
csid_dev->ctrl_reg->csid_reg.csid_irq_status_addr);
|
||||
CDBG("%s CSID%d_IRQ_STATUS_ADDR = 0x%x\n",
|
||||
pr_err_ratelimited("%s CSID%d_IRQ_STATUS_ADDR = 0x%x\n",
|
||||
__func__, csid_dev->pdev->id, irq);
|
||||
if (irq & (0x1 <<
|
||||
csid_dev->ctrl_reg->csid_reg.csid_rst_done_irq_bitshift))
|
||||
|
@ -733,6 +754,7 @@ static int32_t msm_csid_cmd(struct csid_device *csid_dev, void __user *arg)
|
|||
}
|
||||
csid_params.lut_params.vc_cfg[i] = vc_cfg;
|
||||
}
|
||||
csid_dev->current_csid_params = csid_params;
|
||||
csid_dev->csid_sof_debug = SOF_DEBUG_DISABLE;
|
||||
rc = msm_csid_config(csid_dev, &csid_params);
|
||||
MEM_CLEAN:
|
||||
|
@ -768,6 +790,7 @@ static long msm_csid_subdev_ioctl(struct v4l2_subdev *sd,
|
|||
{
|
||||
int rc = -ENOIOCTLCMD;
|
||||
struct csid_device *csid_dev = v4l2_get_subdevdata(sd);
|
||||
|
||||
mutex_lock(&csid_dev->mutex);
|
||||
CDBG("%s:%d id %d\n", __func__, __LINE__, csid_dev->pdev->id);
|
||||
switch (cmd) {
|
||||
|
@ -780,7 +803,15 @@ static long msm_csid_subdev_ioctl(struct v4l2_subdev *sd,
|
|||
case MSM_SD_NOTIFY_FREEZE:
|
||||
if (csid_dev->csid_state != CSID_POWER_UP)
|
||||
break;
|
||||
csid_dev->csid_sof_debug = SOF_DEBUG_ENABLE;
|
||||
if (csid_dev->csid_sof_debug == SOF_DEBUG_DISABLE) {
|
||||
csid_dev->csid_sof_debug = SOF_DEBUG_ENABLE;
|
||||
msm_csid_set_sof_freeze_debug_reg(csid_dev);
|
||||
}
|
||||
break;
|
||||
case MSM_SD_UNNOTIFY_FREEZE:
|
||||
if (csid_dev->csid_state != CSID_POWER_UP)
|
||||
break;
|
||||
csid_dev->csid_sof_debug = SOF_DEBUG_DISABLE;
|
||||
break;
|
||||
case VIDIOC_MSM_CSID_RELEASE:
|
||||
case MSM_SD_SHUTDOWN:
|
||||
|
@ -890,6 +921,7 @@ static int32_t msm_csid_cmd32(struct csid_device *csid_dev, void __user *arg)
|
|||
csid_params.lut_params.vc_cfg[i] = vc_cfg;
|
||||
}
|
||||
rc = msm_csid_config(csid_dev, &csid_params);
|
||||
csid_dev->current_csid_params = csid_params;
|
||||
|
||||
MEM_CLEAN32:
|
||||
for (i--; i >= 0; i--) {
|
||||
|
@ -927,7 +959,15 @@ static long msm_csid_subdev_ioctl32(struct v4l2_subdev *sd,
|
|||
case MSM_SD_NOTIFY_FREEZE:
|
||||
if (csid_dev->csid_state != CSID_POWER_UP)
|
||||
break;
|
||||
csid_dev->csid_sof_debug = SOF_DEBUG_ENABLE;
|
||||
if (csid_dev->csid_sof_debug == SOF_DEBUG_DISABLE) {
|
||||
csid_dev->csid_sof_debug = SOF_DEBUG_ENABLE;
|
||||
msm_csid_set_sof_freeze_debug_reg(csid_dev);
|
||||
}
|
||||
break;
|
||||
case MSM_SD_UNNOTIFY_FREEZE:
|
||||
if (csid_dev->csid_state != CSID_POWER_UP)
|
||||
break;
|
||||
csid_dev->csid_sof_debug = SOF_DEBUG_DISABLE;
|
||||
break;
|
||||
case VIDIOC_MSM_CSID_RELEASE:
|
||||
case MSM_SD_SHUTDOWN:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -112,6 +112,7 @@ struct csid_device {
|
|||
int32_t regulator_count;
|
||||
uint8_t is_testmode;
|
||||
struct msm_camera_csid_testmode_parms testmode_params;
|
||||
struct msm_camera_csid_params current_csid_params;
|
||||
uint32_t csid_sof_debug;
|
||||
uint32_t csid_lane_cnt;
|
||||
};
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#define CSI_3PHASE_HW 1
|
||||
#define MAX_LANES 4
|
||||
#define CLOCK_OFFSET 0x700
|
||||
#define CSIPHY_SOF_DEBUG_COUNT 3
|
||||
|
||||
#undef CDBG
|
||||
#define CDBG(fmt, args...) pr_debug(fmt, ##args)
|
||||
|
@ -636,6 +637,13 @@ static irqreturn_t msm_csiphy_irq(int irq_num, void *data)
|
|||
int i;
|
||||
struct csiphy_device *csiphy_dev = data;
|
||||
|
||||
if (csiphy_dev->csiphy_sof_debug == SOF_DEBUG_ENABLE) {
|
||||
if (csiphy_dev->csiphy_sof_debug_count < CSIPHY_SOF_DEBUG_COUNT)
|
||||
csiphy_dev->csiphy_sof_debug_count++;
|
||||
else
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
for (i = 0; i < csiphy_dev->num_irq_registers; i++) {
|
||||
irq = msm_camera_io_r(
|
||||
csiphy_dev->base +
|
||||
|
@ -645,7 +653,8 @@ static irqreturn_t msm_csiphy_irq(int irq_num, void *data)
|
|||
csiphy_dev->base +
|
||||
csiphy_dev->ctrl_reg->csiphy_reg.
|
||||
mipi_csiphy_interrupt_clear0_addr + 0x4*i);
|
||||
CDBG("%s MIPI_CSIPHY%d_INTERRUPT_STATUS%d = 0x%x\n",
|
||||
pr_err_ratelimited(
|
||||
"%s CSIPHY%d_IRQ_STATUS_ADDR%d = 0x%x\n",
|
||||
__func__, csiphy_dev->pdev->id, i, irq);
|
||||
msm_camera_io_w(0x0,
|
||||
csiphy_dev->base +
|
||||
|
@ -809,7 +818,7 @@ static int msm_csiphy_init(struct csiphy_device *csiphy_dev)
|
|||
rc = -ENOMEM;
|
||||
return rc;
|
||||
}
|
||||
|
||||
csiphy_dev->csiphy_sof_debug_count = 0;
|
||||
CDBG("%s:%d called\n", __func__, __LINE__);
|
||||
if (csiphy_dev->csiphy_state == CSIPHY_POWER_UP) {
|
||||
pr_err("%s: csiphy invalid state %d\n", __func__,
|
||||
|
@ -1110,7 +1119,10 @@ static int msm_csiphy_release(struct csiphy_device *csiphy_dev, void *arg)
|
|||
csiphy_dev->ctrl_reg->csiphy_reg.
|
||||
mipi_csiphy_glbl_pwr_cfg_addr);
|
||||
}
|
||||
|
||||
if (csiphy_dev->csiphy_sof_debug == SOF_DEBUG_ENABLE) {
|
||||
csiphy_dev->csiphy_sof_debug = SOF_DEBUG_DISABLE;
|
||||
disable_irq(csiphy_dev->irq->start);
|
||||
}
|
||||
if (csiphy_dev->hw_dts_version <= CSIPHY_VERSION_V22) {
|
||||
msm_cam_clk_enable(&csiphy_dev->pdev->dev,
|
||||
csiphy_dev->csiphy_clk_info, csiphy_dev->csiphy_clk,
|
||||
|
@ -1167,8 +1179,6 @@ static int32_t msm_csiphy_cmd(struct csiphy_device *csiphy_dev, void *arg)
|
|||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
if (csiphy_dev->csiphy_sof_debug == SOF_DEBUG_ENABLE)
|
||||
disable_irq(csiphy_dev->irq->start);
|
||||
rc = msm_csiphy_release(csiphy_dev, &csi_lane_params);
|
||||
break;
|
||||
default:
|
||||
|
@ -1214,8 +1224,17 @@ static long msm_csiphy_subdev_ioctl(struct v4l2_subdev *sd,
|
|||
if (!csiphy_dev || !csiphy_dev->ctrl_reg ||
|
||||
!csiphy_dev->ref_count)
|
||||
break;
|
||||
csiphy_dev->csiphy_sof_debug = SOF_DEBUG_ENABLE;
|
||||
enable_irq(csiphy_dev->irq->start);
|
||||
if (csiphy_dev->csiphy_sof_debug == SOF_DEBUG_DISABLE) {
|
||||
csiphy_dev->csiphy_sof_debug = SOF_DEBUG_ENABLE;
|
||||
enable_irq(csiphy_dev->irq->start);
|
||||
}
|
||||
break;
|
||||
case MSM_SD_UNNOTIFY_FREEZE:
|
||||
if (!csiphy_dev || !csiphy_dev->ctrl_reg ||
|
||||
!csiphy_dev->ref_count)
|
||||
break;
|
||||
csiphy_dev->csiphy_sof_debug = SOF_DEBUG_DISABLE;
|
||||
disable_irq(csiphy_dev->irq->start);
|
||||
break;
|
||||
default:
|
||||
pr_err_ratelimited("%s: command not found\n", __func__);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -163,6 +163,7 @@ struct csiphy_device {
|
|||
uint8_t csiphy_3phase;
|
||||
uint8_t num_irq_registers;
|
||||
uint32_t csiphy_sof_debug;
|
||||
uint32_t csiphy_sof_debug_count;
|
||||
};
|
||||
|
||||
#define VIDIOC_MSM_CSIPHY_RELEASE \
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2009-2015, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2009-2016, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -655,6 +655,8 @@ static long msm_flash_subdev_ioctl(struct v4l2_subdev *sd,
|
|||
return msm_flash_config(fctrl, argp);
|
||||
case MSM_SD_NOTIFY_FREEZE:
|
||||
return 0;
|
||||
case MSM_SD_UNNOTIFY_FREEZE:
|
||||
return 0;
|
||||
case MSM_SD_SHUTDOWN:
|
||||
if (!fctrl->func_tbl) {
|
||||
pr_err("fctrl->func_tbl NULL\n");
|
||||
|
|
|
@ -316,6 +316,8 @@ static long msm_sensor_subdev_ioctl(struct v4l2_subdev *sd,
|
|||
return 0;
|
||||
case MSM_SD_NOTIFY_FREEZE:
|
||||
return 0;
|
||||
case MSM_SD_UNNOTIFY_FREEZE:
|
||||
return 0;
|
||||
default:
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue