msm: camera: isp: Turn off irq and overflow signal

When vfe is halted, an overflow signal could be generated that
has side effects. Turn off this signal when halting vfe. Also,
disable interrupts when halting the vfe due prevent other side
effects.

CRs-Fixed: 953865
Change-Id: I706d796c500db4a201149196d7ed15965c0b1bb7
Signed-off-by: Shubhraprakash Das <sadas@codeaurora.org>
This commit is contained in:
Shubhraprakash Das 2016-02-05 15:52:41 -08:00 committed by David Keitel
parent fb64289cf4
commit a90d8e325e
7 changed files with 403 additions and 353 deletions

View file

@ -71,6 +71,16 @@ struct msm_vfe_stats_stream;
#define VFE_SD_HW_MAX VFE_SD_COMMON #define VFE_SD_HW_MAX VFE_SD_COMMON
/* Irq operations to perform on the irq mask register */
enum msm_isp_irq_operation {
/* enable the irq bits in given parameters */
MSM_ISP_IRQ_ENABLE = 1,
/* disable the irq bits in the given parameters */
MSM_ISP_IRQ_DISABLE = 2,
/* set the irq bits to the given parameters */
MSM_ISP_IRQ_SET = 3,
};
/* This struct is used to save/track SOF info for some INTF. /* This struct is used to save/track SOF info for some INTF.
* e.g. used in Master-Slave mode */ * e.g. used in Master-Slave mode */
struct msm_vfe_sof_info { struct msm_vfe_sof_info {
@ -144,7 +154,6 @@ struct msm_vfe_irq_ops {
void (*process_stats_irq)(struct vfe_device *vfe_dev, void (*process_stats_irq)(struct vfe_device *vfe_dev,
uint32_t irq_status0, uint32_t irq_status1, uint32_t irq_status0, uint32_t irq_status1,
struct msm_isp_timestamp *ts); struct msm_isp_timestamp *ts);
void (*enable_camif_err)(struct vfe_device *vfe_dev, int enable);
}; };
struct msm_vfe_axi_ops { struct msm_vfe_axi_ops {
@ -223,7 +232,6 @@ struct msm_vfe_core_ops {
void (*get_overflow_mask)(uint32_t *overflow_mask); void (*get_overflow_mask)(uint32_t *overflow_mask);
void (*get_irq_mask)(struct vfe_device *vfe_dev, void (*get_irq_mask)(struct vfe_device *vfe_dev,
uint32_t *irq0_mask, uint32_t *irq1_mask); uint32_t *irq0_mask, uint32_t *irq1_mask);
void (*restore_irq_mask)(struct vfe_device *vfe_dev);
void (*get_halt_restart_mask)(uint32_t *irq0_mask, void (*get_halt_restart_mask)(uint32_t *irq0_mask,
uint32_t *irq1_mask); uint32_t *irq1_mask);
void (*get_rdi_wm_mask)(struct vfe_device *vfe_dev, void (*get_rdi_wm_mask)(struct vfe_device *vfe_dev,
@ -516,8 +524,6 @@ enum msm_vfe_overflow_state {
struct msm_vfe_error_info { struct msm_vfe_error_info {
atomic_t overflow_state; atomic_t overflow_state;
uint32_t overflow_recover_irq_mask0;
uint32_t overflow_recover_irq_mask1;
uint32_t error_mask0; uint32_t error_mask0;
uint32_t error_mask1; uint32_t error_mask1;
uint32_t violation_status; uint32_t violation_status;
@ -696,7 +702,6 @@ struct vfe_device {
int vfe_clk_idx; int vfe_clk_idx;
uint32_t vfe_open_cnt; uint32_t vfe_open_cnt;
uint8_t vt_enable; uint8_t vt_enable;
uint8_t ignore_error;
uint32_t vfe_ub_policy; uint32_t vfe_ub_policy;
uint8_t reset_pending; uint8_t reset_pending;
uint8_t reg_update_requested; uint8_t reg_update_requested;
@ -717,6 +722,10 @@ struct vfe_device {
uint32_t isp_raw1_debug; uint32_t isp_raw1_debug;
uint32_t isp_raw2_debug; uint32_t isp_raw2_debug;
uint8_t is_camif_raw_crop_supported; uint8_t is_camif_raw_crop_supported;
/* irq info */
uint32_t irq0_mask;
uint32_t irq1_mask;
}; };
struct vfe_parent_device { struct vfe_parent_device {

View file

@ -96,6 +96,35 @@ static uint8_t stats_pingpong_offset_map[] = {
#define VFE40_CLK_IDX 2 #define VFE40_CLK_IDX 2
static struct msm_cam_clk_info msm_vfe40_clk_info[VFE_CLK_INFO_MAX]; static struct msm_cam_clk_info msm_vfe40_clk_info[VFE_CLK_INFO_MAX];
static void msm_vfe40_config_irq(struct vfe_device *vfe_dev,
uint32_t irq0_mask, uint32_t irq1_mask,
enum msm_isp_irq_operation oper)
{
uint32_t val;
switch (oper) {
case MSM_ISP_IRQ_ENABLE:
val = msm_camera_io_r(vfe_dev->vfe_base + 0x28);
val |= irq0_mask;
msm_camera_io_w_mb(val, vfe_dev->vfe_base + 0x28);
val = msm_camera_io_r(vfe_dev->vfe_base + 0x2C);
val |= irq1_mask;
msm_camera_io_w_mb(val, vfe_dev->vfe_base + 0x2C);
break;
case MSM_ISP_IRQ_DISABLE:
val = msm_camera_io_r(vfe_dev->vfe_base + 0x28);
val &= ~irq0_mask;
msm_camera_io_w_mb(val, vfe_dev->vfe_base + 0x28);
val = msm_camera_io_r(vfe_dev->vfe_base + 0x2C);
val &= ~irq1_mask;
msm_camera_io_w_mb(val, vfe_dev->vfe_base + 0x2C);
break;
case MSM_ISP_IRQ_SET:
msm_camera_io_w_mb(irq0_mask, vfe_dev->vfe_base + 0x28);
msm_camera_io_w_mb(irq1_mask, vfe_dev->vfe_base + 0x2C);
}
}
static int32_t msm_vfe40_init_qos_parms(struct vfe_device *vfe_dev, static int32_t msm_vfe40_init_qos_parms(struct vfe_device *vfe_dev,
struct msm_vfe_hw_init_parms *qos_parms, struct msm_vfe_hw_init_parms *qos_parms,
struct msm_vfe_hw_init_parms *ds_parms) struct msm_vfe_hw_init_parms *ds_parms)
@ -346,8 +375,10 @@ bus_scale_register_failed:
static void msm_vfe40_release_hardware(struct vfe_device *vfe_dev) static void msm_vfe40_release_hardware(struct vfe_device *vfe_dev)
{ {
/* disable all mask before tasklet kill */ /* disable all mask before tasklet kill */
msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x28); vfe_dev->irq0_mask = 0;
msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x2C); vfe_dev->irq1_mask = 0;
msm_vfe40_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
MSM_ISP_IRQ_SET);
disable_irq(vfe_dev->vfe_irq->start); disable_irq(vfe_dev->vfe_irq->start);
free_irq(vfe_dev->vfe_irq->start, vfe_dev); free_irq(vfe_dev->vfe_irq->start, vfe_dev);
@ -412,20 +443,27 @@ static void msm_vfe40_init_hardware_reg(struct vfe_device *vfe_dev)
msm_vfe40_init_vbif_parms(vfe_dev, &vbif_parms); msm_vfe40_init_vbif_parms(vfe_dev, &vbif_parms);
/* BUS_CFG */ /* BUS_CFG */
msm_camera_io_w(0x10000001, vfe_dev->vfe_base + 0x50); msm_camera_io_w(0x10000001, vfe_dev->vfe_base + 0x50);
msm_camera_io_w(0xE00000F1, vfe_dev->vfe_base + 0x28); vfe_dev->irq0_mask = 0xE00000F1;
msm_camera_io_w_mb(0xFEFFFFFF, vfe_dev->vfe_base + 0x2C); vfe_dev->irq1_mask = 0xFEFFFFFF;
msm_vfe40_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
MSM_ISP_IRQ_SET);
msm_camera_io_w(0xFFFFFFFF, vfe_dev->vfe_base + 0x30); msm_camera_io_w(0xFFFFFFFF, vfe_dev->vfe_base + 0x30);
msm_camera_io_w_mb(0xFEFFFFFF, vfe_dev->vfe_base + 0x34); msm_camera_io_w_mb(0xFEFFFFFF, vfe_dev->vfe_base + 0x34);
msm_camera_io_w(1, vfe_dev->vfe_base + 0x24); msm_camera_io_w(1, vfe_dev->vfe_base + 0x24);
msm_camera_io_w(0, vfe_dev->vfe_base + 0x30); msm_camera_io_w(0, vfe_dev->vfe_base + 0x30);
msm_camera_io_w_mb(0, vfe_dev->vfe_base + 0x34); msm_camera_io_w_mb(0, vfe_dev->vfe_base + 0x34);
msm_camera_io_w(1, vfe_dev->vfe_base + 0x24); msm_camera_io_w(1, vfe_dev->vfe_base + 0x24);
msm_vfe40_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
MSM_ISP_IRQ_SET);
} }
static void msm_vfe40_clear_status_reg(struct vfe_device *vfe_dev) static void msm_vfe40_clear_status_reg(struct vfe_device *vfe_dev)
{ {
msm_camera_io_w((1 << 31), vfe_dev->vfe_base + 0x28); vfe_dev->irq0_mask = (1 << 31);
msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x2C); vfe_dev->irq1_mask = 0;
msm_vfe40_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
MSM_ISP_IRQ_SET);
msm_camera_io_w(0xFFFFFFFF, vfe_dev->vfe_base + 0x30); msm_camera_io_w(0xFFFFFFFF, vfe_dev->vfe_base + 0x30);
msm_camera_io_w_mb(0xFFFFFFFF, vfe_dev->vfe_base + 0x34); msm_camera_io_w_mb(0xFFFFFFFF, vfe_dev->vfe_base + 0x34);
msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x24); msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x24);
@ -635,23 +673,9 @@ static void msm_vfe40_process_error_status(struct vfe_device *vfe_dev)
msm_isp_util_update_last_overflow_ab_ib(vfe_dev); msm_isp_util_update_last_overflow_ab_ib(vfe_dev);
} }
static void msm_vfe40_enable_camif_error(struct vfe_device *vfe_dev,
int enable)
{
uint32_t val;
val = msm_camera_io_r(vfe_dev->vfe_base + 0x2C);
if (enable)
msm_camera_io_w_mb(val | BIT(0), vfe_dev->vfe_base + 0x2C);
else
msm_camera_io_w_mb(val & ~(BIT(0)), vfe_dev->vfe_base + 0x2C);
}
static void msm_vfe40_read_irq_status(struct vfe_device *vfe_dev, static void msm_vfe40_read_irq_status(struct vfe_device *vfe_dev,
uint32_t *irq_status0, uint32_t *irq_status1) uint32_t *irq_status0, uint32_t *irq_status1)
{ {
uint32_t irq_mask0, irq_mask1;
*irq_status0 = msm_camera_io_r(vfe_dev->vfe_base + 0x38); *irq_status0 = msm_camera_io_r(vfe_dev->vfe_base + 0x38);
*irq_status1 = msm_camera_io_r(vfe_dev->vfe_base + 0x3C); *irq_status1 = msm_camera_io_r(vfe_dev->vfe_base + 0x3C);
/* /*
@ -667,15 +691,14 @@ static void msm_vfe40_read_irq_status(struct vfe_device *vfe_dev,
*irq_status0 &= ~(0x18000000); *irq_status0 &= ~(0x18000000);
} }
irq_mask0 = msm_camera_io_r(vfe_dev->vfe_base + 0x28); *irq_status0 &= vfe_dev->irq0_mask;
irq_mask1 = msm_camera_io_r(vfe_dev->vfe_base + 0x2C); *irq_status1 &= vfe_dev->irq1_mask;
*irq_status0 &= irq_mask0;
*irq_status1 &= irq_mask1;
if (*irq_status1 & (1 << 0)) { if (*irq_status1 & (1 << 0)) {
vfe_dev->error_info.camif_status = vfe_dev->error_info.camif_status =
msm_camera_io_r(vfe_dev->vfe_base + 0x31C); msm_camera_io_r(vfe_dev->vfe_base + 0x31C);
msm_vfe40_enable_camif_error(vfe_dev, 0); vfe_dev->irq1_mask &= ~(1 << 0);
msm_vfe40_config_irq(vfe_dev, 0, (1 << 0), MSM_ISP_IRQ_DISABLE);
} }
if (*irq_status1 & (1 << 7)) if (*irq_status1 & (1 << 7))
@ -891,52 +914,49 @@ static void msm_vfe40_axi_cfg_comp_mask(struct vfe_device *vfe_dev,
struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
uint32_t comp_mask, comp_mask_index = uint32_t comp_mask, comp_mask_index =
stream_info->comp_mask_index; stream_info->comp_mask_index;
uint32_t irq_mask;
comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x40); comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x40);
comp_mask &= ~(0x7F << (comp_mask_index * 8)); comp_mask &= ~(0x7F << (comp_mask_index * 8));
comp_mask |= (axi_data->composite_info[comp_mask_index]. comp_mask |= (axi_data->composite_info[comp_mask_index].
stream_composite_mask << (comp_mask_index * 8)); stream_composite_mask << (comp_mask_index * 8));
irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x28); vfe_dev->irq0_mask |= 1 << (comp_mask_index + 25);
irq_mask |= 1 << (comp_mask_index + 25);
msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x40); msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x40);
msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x28); msm_vfe40_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
MSM_ISP_IRQ_SET);
} }
static void msm_vfe40_axi_clear_comp_mask(struct vfe_device *vfe_dev, static void msm_vfe40_axi_clear_comp_mask(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info) struct msm_vfe_axi_stream *stream_info)
{ {
uint32_t comp_mask, comp_mask_index = stream_info->comp_mask_index; uint32_t comp_mask, comp_mask_index = stream_info->comp_mask_index;
uint32_t irq_mask; vfe_dev->irq0_mask &= ~BIT(27);
comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x40); comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x40);
comp_mask &= ~(0x7F << (comp_mask_index * 8)); comp_mask &= ~(0x7F << (comp_mask_index * 8));
irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x28); vfe_dev->irq0_mask &= ~(1 << (comp_mask_index + 25));
irq_mask &= ~(1 << (comp_mask_index + 25));
msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x40); msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x40);
msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x28); msm_vfe40_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
MSM_ISP_IRQ_SET);
} }
static void msm_vfe40_axi_cfg_wm_irq_mask(struct vfe_device *vfe_dev, static void msm_vfe40_axi_cfg_wm_irq_mask(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info) struct msm_vfe_axi_stream *stream_info)
{ {
uint32_t irq_mask; vfe_dev->irq0_mask |= 1 << (stream_info->wm[0] + 8);
irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x28); msm_vfe40_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
irq_mask |= 1 << (stream_info->wm[0] + 8); MSM_ISP_IRQ_SET);
msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x28);
} }
static void msm_vfe40_axi_clear_wm_irq_mask(struct vfe_device *vfe_dev, static void msm_vfe40_axi_clear_wm_irq_mask(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info) struct msm_vfe_axi_stream *stream_info)
{ {
uint32_t irq_mask; vfe_dev->irq0_mask &= ~(1 << (stream_info->wm[0] + 8));
irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x28); msm_vfe40_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
irq_mask &= ~(1 << (stream_info->wm[0] + 8)); MSM_ISP_IRQ_SET);
msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x28);
} }
static void msm_vfe40_cfg_framedrop(void __iomem *vfe_base, static void msm_vfe40_cfg_framedrop(void __iomem *vfe_base,
@ -1176,10 +1196,10 @@ static void msm_vfe40_cfg_fetch_engine(struct vfe_device *vfe_dev,
temp |= (1 << 1); temp |= (1 << 1);
msm_camera_io_w(temp, vfe_dev->vfe_base + 0x50); msm_camera_io_w(temp, vfe_dev->vfe_base + 0x50);
temp = msm_camera_io_r(vfe_dev->vfe_base + 0x28); vfe_dev->irq0_mask &= 0xFEFFFFFF;
temp &= 0xFEFFFFFF; vfe_dev->irq0_mask |= (1 << 24);
temp |= (1 << 24); msm_vfe40_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
msm_camera_io_w(temp, vfe_dev->vfe_base + 0x28); MSM_ISP_IRQ_SET);
msm_camera_io_w((fe_cfg->fetch_height - 1), msm_camera_io_w((fe_cfg->fetch_height - 1),
vfe_dev->vfe_base + 0x238); vfe_dev->vfe_base + 0x238);
@ -1473,9 +1493,10 @@ static void msm_vfe40_update_camif_state(struct vfe_device *vfe_dev,
msm_camera_io_w(0xFFFFFFFF, vfe_dev->vfe_base + 0x30); msm_camera_io_w(0xFFFFFFFF, vfe_dev->vfe_base + 0x30);
msm_camera_io_w_mb(0xFFFFFFFF, vfe_dev->vfe_base + 0x34); msm_camera_io_w_mb(0xFFFFFFFF, vfe_dev->vfe_base + 0x34);
msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x24); msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x24);
val = msm_camera_io_r(vfe_dev->vfe_base + 0x28); vfe_dev->irq0_mask |= 0xF7;
val |= 0xF7; msm_vfe40_config_irq(vfe_dev, vfe_dev->irq0_mask,
msm_camera_io_w_mb(val, vfe_dev->vfe_base + 0x28); vfe_dev->irq1_mask,
MSM_ISP_IRQ_SET);
msm_camera_io_w_mb(0x140000, vfe_dev->vfe_base + 0x318); msm_camera_io_w_mb(0x140000, vfe_dev->vfe_base + 0x318);
bus_en = bus_en =
@ -1494,17 +1515,25 @@ static void msm_vfe40_update_camif_state(struct vfe_device *vfe_dev,
msm_camera_io_w_mb(0x4, vfe_dev->vfe_base + 0x2F4); msm_camera_io_w_mb(0x4, vfe_dev->vfe_base + 0x2F4);
msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x2F4); msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x2F4);
vfe_dev->axi_data.src_info[VFE_PIX_0].active = 1; vfe_dev->axi_data.src_info[VFE_PIX_0].active = 1;
} else if (update_state == DISABLE_CAMIF) { } else if (update_state == DISABLE_CAMIF ||
msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x2F4); DISABLE_CAMIF_IMMEDIATELY == update_state) {
msm_vfe40_config_irq(vfe_dev, 0, 0,
MSM_ISP_IRQ_SET);
val = msm_camera_io_r(vfe_dev->vfe_base + 0x464);
/* disable danger signal */
msm_camera_io_w_mb(val & ~(1 << 8), vfe_dev->vfe_base + 0x464);
msm_camera_io_w_mb((update_state == DISABLE_CAMIF ? 0x0 : 0x6),
vfe_dev->vfe_base + 0x2F4);
vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0; vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0;
/* testgen OFF*/ /* testgen OFF*/
if (vfe_dev->axi_data.src_info[VFE_PIX_0].input_mux == TESTGEN) if (vfe_dev->axi_data.src_info[VFE_PIX_0].input_mux == TESTGEN)
msm_camera_io_w(1 << 1, vfe_dev->vfe_base + 0x93C); msm_camera_io_w(1 << 1, vfe_dev->vfe_base + 0x93C);
} else if (update_state == DISABLE_CAMIF_IMMEDIATELY) { msm_camera_io_w(0, vfe_dev->vfe_base + 0x30);
msm_camera_io_w_mb(0x6, vfe_dev->vfe_base + 0x2F4); msm_camera_io_w((1 << 0), vfe_dev->vfe_base + 0x34);
vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0; msm_camera_io_w_mb(1, vfe_dev->vfe_base + 0x24);
if (vfe_dev->axi_data.src_info[VFE_PIX_0].input_mux == TESTGEN) msm_vfe40_config_irq(vfe_dev, vfe_dev->irq0_mask,
msm_camera_io_w(1 << 1, vfe_dev->vfe_base + 0x93C); vfe_dev->irq1_mask,
MSM_ISP_IRQ_SET);
} }
} }
@ -1808,8 +1837,8 @@ static int msm_vfe40_axi_halt(struct vfe_device *vfe_dev,
enum msm_vfe_input_src i; enum msm_vfe_input_src i;
/* Keep only halt and restart mask */ /* Keep only halt and restart mask */
msm_camera_io_w(BIT(31), vfe_dev->vfe_base + 0x28); msm_vfe40_config_irq(vfe_dev, (1 << 31), (1 << 8),
msm_camera_io_w(BIT(8), vfe_dev->vfe_base + 0x2C); MSM_ISP_IRQ_SET);
/*Clear IRQ Status */ /*Clear IRQ Status */
msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x30); msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x30);
msm_camera_io_w(0xFEFFFEFF, vfe_dev->vfe_base + 0x34); msm_camera_io_w(0xFEFFFEFF, vfe_dev->vfe_base + 0x34);
@ -1859,7 +1888,8 @@ static int msm_vfe40_axi_halt(struct vfe_device *vfe_dev,
static int msm_vfe40_axi_restart(struct vfe_device *vfe_dev, static int msm_vfe40_axi_restart(struct vfe_device *vfe_dev,
uint32_t blocking, uint32_t enable_camif) uint32_t blocking, uint32_t enable_camif)
{ {
vfe_dev->hw_info->vfe_ops.core_ops.restore_irq_mask(vfe_dev); msm_vfe40_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
MSM_ISP_IRQ_SET);
/* Clear IRQ Status */ /* Clear IRQ Status */
msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x30); msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x30);
msm_camera_io_w(0xFEFFFEFF, vfe_dev->vfe_base + 0x34); msm_camera_io_w(0xFEFFFEFF, vfe_dev->vfe_base + 0x34);
@ -1988,20 +2018,20 @@ static void msm_vfe40_stats_cfg_wm_irq_mask(
struct vfe_device *vfe_dev, struct vfe_device *vfe_dev,
struct msm_vfe_stats_stream *stream_info) struct msm_vfe_stats_stream *stream_info)
{ {
uint32_t irq_mask; vfe_dev->irq0_mask |=
irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x28); 1 << (STATS_IDX(stream_info->stream_handle) + 16);
irq_mask |= 1 << (STATS_IDX(stream_info->stream_handle) + 16); msm_vfe40_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x28); MSM_ISP_IRQ_SET);
} }
static void msm_vfe40_stats_clear_wm_irq_mask( static void msm_vfe40_stats_clear_wm_irq_mask(
struct vfe_device *vfe_dev, struct vfe_device *vfe_dev,
struct msm_vfe_stats_stream *stream_info) struct msm_vfe_stats_stream *stream_info)
{ {
uint32_t irq_mask; vfe_dev->irq0_mask &=
irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x28); ~(1 << (STATS_IDX(stream_info->stream_handle) + 16));
irq_mask &= ~(1 << (STATS_IDX(stream_info->stream_handle) + 16)); msm_vfe40_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x28); MSM_ISP_IRQ_SET);
} }
static void msm_vfe40_stats_cfg_wm_reg( static void msm_vfe40_stats_cfg_wm_reg(
@ -2270,20 +2300,10 @@ static void msm_vfe40_get_rdi_wm_mask(struct vfe_device *vfe_dev,
static void msm_vfe40_get_irq_mask(struct vfe_device *vfe_dev, static void msm_vfe40_get_irq_mask(struct vfe_device *vfe_dev,
uint32_t *irq0_mask, uint32_t *irq1_mask) uint32_t *irq0_mask, uint32_t *irq1_mask)
{ {
*irq0_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x28); *irq0_mask = vfe_dev->irq0_mask;
*irq1_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x2C); *irq1_mask = vfe_dev->irq1_mask;
} }
static void msm_vfe40_restore_irq_mask(struct vfe_device *vfe_dev)
{
msm_camera_io_w(vfe_dev->error_info.overflow_recover_irq_mask0,
vfe_dev->vfe_base + 0x28);
msm_camera_io_w(vfe_dev->error_info.overflow_recover_irq_mask1,
vfe_dev->vfe_base + 0x2C);
}
static void msm_vfe40_get_halt_restart_mask(uint32_t *irq0_mask, static void msm_vfe40_get_halt_restart_mask(uint32_t *irq0_mask,
uint32_t *irq1_mask) uint32_t *irq1_mask)
{ {
@ -2329,7 +2349,6 @@ struct msm_vfe_hardware_info vfe40_hw_info = {
.process_axi_irq = msm_isp_process_axi_irq, .process_axi_irq = msm_isp_process_axi_irq,
.process_stats_irq = msm_isp_process_stats_irq, .process_stats_irq = msm_isp_process_stats_irq,
.process_epoch_irq = msm_vfe40_process_epoch_irq, .process_epoch_irq = msm_vfe40_process_epoch_irq,
.enable_camif_err = msm_vfe40_enable_camif_error,
}, },
.axi_ops = { .axi_ops = {
.reload_wm = msm_vfe40_axi_reload_wm, .reload_wm = msm_vfe40_axi_reload_wm,
@ -2374,7 +2393,6 @@ struct msm_vfe_hardware_info vfe40_hw_info = {
.get_overflow_mask = msm_vfe40_get_overflow_mask, .get_overflow_mask = msm_vfe40_get_overflow_mask,
.get_rdi_wm_mask = msm_vfe40_get_rdi_wm_mask, .get_rdi_wm_mask = msm_vfe40_get_rdi_wm_mask,
.get_irq_mask = msm_vfe40_get_irq_mask, .get_irq_mask = msm_vfe40_get_irq_mask,
.restore_irq_mask = msm_vfe40_restore_irq_mask,
.get_halt_restart_mask = .get_halt_restart_mask =
msm_vfe40_get_halt_restart_mask, msm_vfe40_get_halt_restart_mask,
.process_error_status = msm_vfe40_process_error_status, .process_error_status = msm_vfe40_process_error_status,

View file

@ -65,6 +65,36 @@ static uint8_t stats_pingpong_offset_map[] = {
#define VFE44_CLK_IDX 2 #define VFE44_CLK_IDX 2
static struct msm_cam_clk_info msm_vfe44_clk_info[VFE_CLK_INFO_MAX]; static struct msm_cam_clk_info msm_vfe44_clk_info[VFE_CLK_INFO_MAX];
static void msm_vfe44_config_irq(struct vfe_device *vfe_dev,
uint32_t irq0_mask, uint32_t irq1_mask,
enum msm_isp_irq_operation oper)
{
uint32_t val;
switch (oper) {
case MSM_ISP_IRQ_ENABLE:
val = msm_camera_io_r(vfe_dev->vfe_base + 0x28);
val |= irq0_mask;
msm_camera_io_w_mb(val, vfe_dev->vfe_base + 0x28);
val = msm_camera_io_r(vfe_dev->vfe_base + 0x2C);
val |= irq1_mask;
msm_camera_io_w_mb(val, vfe_dev->vfe_base + 0x2C);
break;
case MSM_ISP_IRQ_DISABLE:
val = msm_camera_io_r(vfe_dev->vfe_base + 0x28);
val &= ~irq0_mask;
msm_camera_io_w_mb(val, vfe_dev->vfe_base + 0x28);
val = msm_camera_io_r(vfe_dev->vfe_base + 0x2C);
val &= ~irq1_mask;
msm_camera_io_w_mb(val, vfe_dev->vfe_base + 0x2C);
break;
case MSM_ISP_IRQ_SET:
msm_camera_io_w_mb(irq0_mask, vfe_dev->vfe_base + 0x28);
msm_camera_io_w_mb(irq1_mask, vfe_dev->vfe_base + 0x2C);
break;
}
}
static int32_t msm_vfe44_init_dt_parms(struct vfe_device *vfe_dev, static int32_t msm_vfe44_init_dt_parms(struct vfe_device *vfe_dev,
struct msm_vfe_hw_init_parms *dt_parms) struct msm_vfe_hw_init_parms *dt_parms)
{ {
@ -213,8 +243,10 @@ bus_scale_register_failed:
static void msm_vfe44_release_hardware(struct vfe_device *vfe_dev) static void msm_vfe44_release_hardware(struct vfe_device *vfe_dev)
{ {
msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x28); vfe_dev->irq0_mask = 0;
msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x2C); vfe_dev->irq1_mask = 0;
msm_vfe44_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
MSM_ISP_IRQ_SET);
disable_irq(vfe_dev->vfe_irq->start); disable_irq(vfe_dev->vfe_irq->start);
free_irq(vfe_dev->vfe_irq->start, vfe_dev); free_irq(vfe_dev->vfe_irq->start, vfe_dev);
tasklet_kill(&vfe_dev->vfe_tasklet); tasklet_kill(&vfe_dev->vfe_tasklet);
@ -253,8 +285,10 @@ static void msm_vfe44_init_hardware_reg(struct vfe_device *vfe_dev)
/* BUS_CFG */ /* BUS_CFG */
msm_camera_io_w(0x10000001, vfe_dev->vfe_base + 0x50); msm_camera_io_w(0x10000001, vfe_dev->vfe_base + 0x50);
msm_camera_io_w(0xE00000F1, vfe_dev->vfe_base + 0x28); vfe_dev->irq0_mask = 0xE00000F1;
msm_camera_io_w_mb(0xFFFFFFFF, vfe_dev->vfe_base + 0x2C); vfe_dev->irq1_mask = 0xFFFFFFFF;
msm_vfe44_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
MSM_ISP_IRQ_SET);
msm_camera_io_w(0xFFFFFFFF, vfe_dev->vfe_base + 0x30); msm_camera_io_w(0xFFFFFFFF, vfe_dev->vfe_base + 0x30);
msm_camera_io_w_mb(0xFFFFFFFF, vfe_dev->vfe_base + 0x34); msm_camera_io_w_mb(0xFFFFFFFF, vfe_dev->vfe_base + 0x34);
msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x24); msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x24);
@ -263,8 +297,10 @@ static void msm_vfe44_init_hardware_reg(struct vfe_device *vfe_dev)
static void msm_vfe44_clear_status_reg(struct vfe_device *vfe_dev) static void msm_vfe44_clear_status_reg(struct vfe_device *vfe_dev)
{ {
msm_camera_io_w(0x80000000, vfe_dev->vfe_base + 0x28); vfe_dev->irq0_mask = 0x80000000;
msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x2C); vfe_dev->irq1_mask = 0;
msm_vfe44_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
MSM_ISP_IRQ_SET);
msm_camera_io_w(0xFFFFFFFF, vfe_dev->vfe_base + 0x30); msm_camera_io_w(0xFFFFFFFF, vfe_dev->vfe_base + 0x30);
msm_camera_io_w_mb(0xFFFFFFFF, vfe_dev->vfe_base + 0x34); msm_camera_io_w_mb(0xFFFFFFFF, vfe_dev->vfe_base + 0x34);
msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x24); msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x24);
@ -468,33 +504,17 @@ static void msm_vfe44_process_error_status(struct vfe_device *vfe_dev)
} }
} }
static void msm_vfe44_enable_camif_error(struct vfe_device *vfe_dev,
int enable)
{
uint32_t val;
val = msm_camera_io_r(vfe_dev->vfe_base + 0x2C);
if (enable)
msm_camera_io_w_mb(val | BIT(0), vfe_dev->vfe_base + 0x2C);
else
msm_camera_io_w_mb(val & ~(BIT(0)), vfe_dev->vfe_base + 0x2C);
}
static void msm_vfe44_read_irq_status(struct vfe_device *vfe_dev, static void msm_vfe44_read_irq_status(struct vfe_device *vfe_dev,
uint32_t *irq_status0, uint32_t *irq_status1) uint32_t *irq_status0, uint32_t *irq_status1)
{ {
uint32_t irq_mask0 = 0, irq_mask1 = 0;
irq_mask0 = msm_camera_io_r(vfe_dev->vfe_base + 0x28);
irq_mask1 = msm_camera_io_r(vfe_dev->vfe_base + 0x2C);
*irq_status0 = msm_camera_io_r(vfe_dev->vfe_base + 0x38); *irq_status0 = msm_camera_io_r(vfe_dev->vfe_base + 0x38);
*irq_status1 = msm_camera_io_r(vfe_dev->vfe_base + 0x3C); *irq_status1 = msm_camera_io_r(vfe_dev->vfe_base + 0x3C);
msm_camera_io_w(*irq_status0, vfe_dev->vfe_base + 0x30); msm_camera_io_w(*irq_status0, vfe_dev->vfe_base + 0x30);
msm_camera_io_w(*irq_status1, vfe_dev->vfe_base + 0x34); msm_camera_io_w(*irq_status1, vfe_dev->vfe_base + 0x34);
msm_camera_io_w_mb(1, vfe_dev->vfe_base + 0x24); msm_camera_io_w_mb(1, vfe_dev->vfe_base + 0x24);
*irq_status0 &= irq_mask0; *irq_status0 &= vfe_dev->irq0_mask;
*irq_status1 &= irq_mask1; *irq_status1 &= vfe_dev->irq1_mask;
if (*irq_status0 & 0x10000000) { if (*irq_status0 & 0x10000000) {
pr_err_ratelimited("%s: Protection triggered\n", __func__); pr_err_ratelimited("%s: Protection triggered\n", __func__);
*irq_status0 &= ~(0x10000000); *irq_status0 &= ~(0x10000000);
@ -503,7 +523,8 @@ static void msm_vfe44_read_irq_status(struct vfe_device *vfe_dev,
if (*irq_status1 & (1 << 0)) { if (*irq_status1 & (1 << 0)) {
vfe_dev->error_info.camif_status = vfe_dev->error_info.camif_status =
msm_camera_io_r(vfe_dev->vfe_base + 0x31C); msm_camera_io_r(vfe_dev->vfe_base + 0x31C);
msm_vfe44_enable_camif_error(vfe_dev, 0); vfe_dev->irq1_mask &= ~(1 << 0);
msm_vfe44_config_irq(vfe_dev, 0, (1 << 0), MSM_ISP_IRQ_DISABLE);
} }
if (*irq_status1 & (1 << 7)) if (*irq_status1 & (1 << 7))
@ -726,7 +747,6 @@ static void msm_vfe44_axi_cfg_comp_mask(struct vfe_device *vfe_dev,
struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
uint32_t comp_mask, comp_mask_index = uint32_t comp_mask, comp_mask_index =
stream_info->comp_mask_index; stream_info->comp_mask_index;
uint32_t irq_mask;
comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x40); comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x40);
comp_mask &= ~(0x7F << (comp_mask_index * 8)); comp_mask &= ~(0x7F << (comp_mask_index * 8));
@ -734,42 +754,39 @@ static void msm_vfe44_axi_cfg_comp_mask(struct vfe_device *vfe_dev,
stream_composite_mask << (comp_mask_index * 8)); stream_composite_mask << (comp_mask_index * 8));
msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x40); msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x40);
irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x28); vfe_dev->irq0_mask |= 1 << (comp_mask_index + 25);
irq_mask |= 1 << (comp_mask_index + 25); msm_vfe44_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x28); MSM_ISP_IRQ_SET);
} }
static void msm_vfe44_axi_clear_comp_mask(struct vfe_device *vfe_dev, static void msm_vfe44_axi_clear_comp_mask(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info) struct msm_vfe_axi_stream *stream_info)
{ {
uint32_t comp_mask, comp_mask_index = stream_info->comp_mask_index; uint32_t comp_mask, comp_mask_index = stream_info->comp_mask_index;
uint32_t irq_mask;
comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x40); comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x40);
comp_mask &= ~(0x7F << (comp_mask_index * 8)); comp_mask &= ~(0x7F << (comp_mask_index * 8));
msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x40); msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x40);
irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x28); vfe_dev->irq0_mask &= ~(1 << (comp_mask_index + 25));
irq_mask &= ~(1 << (comp_mask_index + 25)); msm_vfe44_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x28); MSM_ISP_IRQ_SET);
} }
static void msm_vfe44_axi_cfg_wm_irq_mask(struct vfe_device *vfe_dev, static void msm_vfe44_axi_cfg_wm_irq_mask(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info) struct msm_vfe_axi_stream *stream_info)
{ {
uint32_t irq_mask; vfe_dev->irq0_mask |= 1 << (stream_info->wm[0] + 8);
irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x28); msm_vfe44_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
irq_mask |= 1 << (stream_info->wm[0] + 8); MSM_ISP_IRQ_SET);
msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x28);
} }
static void msm_vfe44_axi_clear_wm_irq_mask(struct vfe_device *vfe_dev, static void msm_vfe44_axi_clear_wm_irq_mask(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info) struct msm_vfe_axi_stream *stream_info)
{ {
uint32_t irq_mask; vfe_dev->irq0_mask &= ~(1 << (stream_info->wm[0] + 8));
irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x28); msm_vfe44_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
irq_mask &= ~(1 << (stream_info->wm[0] + 8)); MSM_ISP_IRQ_SET);
msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x28);
} }
static void msm_vfe44_cfg_framedrop(void __iomem *vfe_base, static void msm_vfe44_cfg_framedrop(void __iomem *vfe_base,
@ -1005,10 +1022,10 @@ static void msm_vfe44_cfg_fetch_engine(struct vfe_device *vfe_dev,
temp |= (1 << 1); temp |= (1 << 1);
msm_camera_io_w(temp, vfe_dev->vfe_base + 0x50); msm_camera_io_w(temp, vfe_dev->vfe_base + 0x50);
temp = msm_camera_io_r(vfe_dev->vfe_base + 0x28); vfe_dev->irq0_mask &= 0xFEFFFFFF;
temp &= 0xFEFFFFFF; vfe_dev->irq0_mask |= (1 << 24);
temp |= (1 << 24); msm_vfe44_config_irq(vfe_dev, vfe_dev->irq0_mask,
msm_camera_io_w(temp, vfe_dev->vfe_base + 0x28); vfe_dev->irq1_mask, MSM_ISP_IRQ_SET);
msm_camera_io_w((fe_cfg->fetch_height - 1) & 0xFFF, msm_camera_io_w((fe_cfg->fetch_height - 1) & 0xFFF,
vfe_dev->vfe_base + 0x238); vfe_dev->vfe_base + 0x238);
@ -1136,9 +1153,9 @@ static void msm_vfe44_update_camif_state(struct vfe_device *vfe_dev,
msm_camera_io_w_mb(0xFFFFFFFF, vfe_dev->vfe_base + 0x34); msm_camera_io_w_mb(0xFFFFFFFF, vfe_dev->vfe_base + 0x34);
msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x24); msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x24);
val = msm_camera_io_r(vfe_dev->vfe_base + 0x28); vfe_dev->irq0_mask |= 0xF7;
val |= 0xF7; msm_vfe44_config_irq(vfe_dev, vfe_dev->irq0_mask,
msm_camera_io_w_mb(val, vfe_dev->vfe_base + 0x28); vfe_dev->irq1_mask, MSM_ISP_IRQ_SET);
msm_camera_io_w_mb(0x140000, vfe_dev->vfe_base + 0x318); msm_camera_io_w_mb(0x140000, vfe_dev->vfe_base + 0x318);
bus_en = bus_en =
@ -1155,12 +1172,21 @@ static void msm_vfe44_update_camif_state(struct vfe_device *vfe_dev,
msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x2F4); msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x2F4);
vfe_dev->axi_data.src_info[VFE_PIX_0].active = 1; vfe_dev->axi_data.src_info[VFE_PIX_0].active = 1;
} else if (update_state == DISABLE_CAMIF) { } else if (update_state == DISABLE_CAMIF ||
msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x2F4); DISABLE_CAMIF_IMMEDIATELY == update_state) {
vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0; msm_vfe44_config_irq(vfe_dev, 0,
} else if (update_state == DISABLE_CAMIF_IMMEDIATELY) { 0, MSM_ISP_IRQ_SET);
msm_camera_io_w_mb(0x6, vfe_dev->vfe_base + 0x2F4); val = msm_camera_io_r(vfe_dev->vfe_base + 0xC18);
/* disable danger signal */
msm_camera_io_w_mb(val & ~(1 << 8), vfe_dev->vfe_base + 0xC18);
msm_camera_io_w_mb((update_state == DISABLE_CAMIF ? 0x0 : 0x6),
vfe_dev->vfe_base + 0x2F4);
vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0; vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0;
msm_camera_io_w(0, vfe_dev->vfe_base + 0x30);
msm_camera_io_w((1 << 0), vfe_dev->vfe_base + 0x34);
msm_camera_io_w_mb(1, vfe_dev->vfe_base + 0x24);
msm_vfe44_config_irq(vfe_dev, vfe_dev->irq0_mask,
vfe_dev->irq1_mask, MSM_ISP_IRQ_SET);
} }
} }
@ -1408,8 +1434,8 @@ static int msm_vfe44_axi_halt(struct vfe_device *vfe_dev,
enum msm_vfe_input_src i; enum msm_vfe_input_src i;
/* Keep only halt and restart mask */ /* Keep only halt and restart mask */
msm_camera_io_w(BIT(31), vfe_dev->vfe_base + 0x28); msm_vfe44_config_irq(vfe_dev, (1 << 31), (1 << 8),
msm_camera_io_w(BIT(8), vfe_dev->vfe_base + 0x2C); MSM_ISP_IRQ_SET);
/*Clear IRQ Status0, only leave reset irq mask*/ /*Clear IRQ Status0, only leave reset irq mask*/
msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x30); msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x30);
@ -1469,7 +1495,8 @@ static int msm_vfe44_axi_halt(struct vfe_device *vfe_dev,
static int msm_vfe44_axi_restart(struct vfe_device *vfe_dev, static int msm_vfe44_axi_restart(struct vfe_device *vfe_dev,
uint32_t blocking, uint32_t enable_camif) uint32_t blocking, uint32_t enable_camif)
{ {
vfe_dev->hw_info->vfe_ops.core_ops.restore_irq_mask(vfe_dev); msm_vfe44_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
MSM_ISP_IRQ_SET);
msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x30); msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x30);
msm_camera_io_w(0xFEFFFEFF, vfe_dev->vfe_base + 0x34); msm_camera_io_w(0xFEFFFEFF, vfe_dev->vfe_base + 0x34);
msm_camera_io_w(0x1, vfe_dev->vfe_base + 0x24); msm_camera_io_w(0x1, vfe_dev->vfe_base + 0x24);
@ -1624,20 +1651,20 @@ static void msm_vfe44_stats_cfg_wm_irq_mask(
struct vfe_device *vfe_dev, struct vfe_device *vfe_dev,
struct msm_vfe_stats_stream *stream_info) struct msm_vfe_stats_stream *stream_info)
{ {
uint32_t irq_mask; vfe_dev->irq0_mask |=
irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x28); 1 << (STATS_IDX(stream_info->stream_handle) + 15);
irq_mask |= 1 << (STATS_IDX(stream_info->stream_handle) + 15); msm_vfe44_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x28); MSM_ISP_IRQ_SET);
} }
static void msm_vfe44_stats_clear_wm_irq_mask( static void msm_vfe44_stats_clear_wm_irq_mask(
struct vfe_device *vfe_dev, struct vfe_device *vfe_dev,
struct msm_vfe_stats_stream *stream_info) struct msm_vfe_stats_stream *stream_info)
{ {
uint32_t irq_mask; vfe_dev->irq0_mask &=
irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x28); ~(1 << (STATS_IDX(stream_info->stream_handle) + 15));
irq_mask &= ~(1 << (STATS_IDX(stream_info->stream_handle) + 15)); msm_vfe44_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x28); MSM_ISP_IRQ_SET);
} }
static void msm_vfe44_stats_cfg_wm_reg( static void msm_vfe44_stats_cfg_wm_reg(
@ -1917,20 +1944,10 @@ static void msm_vfe44_get_rdi_wm_mask(struct vfe_device *vfe_dev,
static void msm_vfe44_get_irq_mask(struct vfe_device *vfe_dev, static void msm_vfe44_get_irq_mask(struct vfe_device *vfe_dev,
uint32_t *irq0_mask, uint32_t *irq1_mask) uint32_t *irq0_mask, uint32_t *irq1_mask)
{ {
*irq0_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x28); *irq0_mask = vfe_dev->irq0_mask;
*irq1_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x2C); *irq1_mask = vfe_dev->irq1_mask;
} }
static void msm_vfe44_restore_irq_mask(struct vfe_device *vfe_dev)
{
msm_camera_io_w(vfe_dev->error_info.overflow_recover_irq_mask0,
vfe_dev->vfe_base + 0x28);
msm_camera_io_w(vfe_dev->error_info.overflow_recover_irq_mask1,
vfe_dev->vfe_base + 0x2C);
}
static void msm_vfe44_get_halt_restart_mask(uint32_t *irq0_mask, static void msm_vfe44_get_halt_restart_mask(uint32_t *irq0_mask,
uint32_t *irq1_mask) uint32_t *irq1_mask)
{ {
@ -1977,7 +1994,6 @@ struct msm_vfe_hardware_info vfe44_hw_info = {
.process_axi_irq = msm_isp_process_axi_irq, .process_axi_irq = msm_isp_process_axi_irq,
.process_stats_irq = msm_isp_process_stats_irq, .process_stats_irq = msm_isp_process_stats_irq,
.process_epoch_irq = msm_vfe44_process_epoch_irq, .process_epoch_irq = msm_vfe44_process_epoch_irq,
.enable_camif_err = msm_vfe44_enable_camif_error,
}, },
.axi_ops = { .axi_ops = {
.reload_wm = msm_vfe44_axi_reload_wm, .reload_wm = msm_vfe44_axi_reload_wm,
@ -2022,7 +2038,6 @@ struct msm_vfe_hardware_info vfe44_hw_info = {
.get_overflow_mask = msm_vfe44_get_overflow_mask, .get_overflow_mask = msm_vfe44_get_overflow_mask,
.get_rdi_wm_mask = msm_vfe44_get_rdi_wm_mask, .get_rdi_wm_mask = msm_vfe44_get_rdi_wm_mask,
.get_irq_mask = msm_vfe44_get_irq_mask, .get_irq_mask = msm_vfe44_get_irq_mask,
.restore_irq_mask = msm_vfe44_restore_irq_mask,
.get_halt_restart_mask = .get_halt_restart_mask =
msm_vfe44_get_halt_restart_mask, msm_vfe44_get_halt_restart_mask,
.process_error_status = msm_vfe44_process_error_status, .process_error_status = msm_vfe44_process_error_status,

View file

@ -86,6 +86,37 @@ static uint8_t stats_pingpong_offset_map[] = {
#define VFE46_CLK_IDX 2 #define VFE46_CLK_IDX 2
static struct msm_cam_clk_info msm_vfe46_clk_info[VFE_CLK_INFO_MAX]; static struct msm_cam_clk_info msm_vfe46_clk_info[VFE_CLK_INFO_MAX];
static void msm_vfe46_config_irq(struct vfe_device *vfe_dev,
uint32_t irq0_mask, uint32_t irq1_mask,
enum msm_isp_irq_operation oper)
{
uint32_t val;
switch (oper) {
case MSM_ISP_IRQ_ENABLE:
val = msm_camera_io_r(vfe_dev->vfe_base + 0x5C);
val |= irq0_mask;
msm_camera_io_w_mb(val, vfe_dev->vfe_base + 0x5C);
val = msm_camera_io_r(vfe_dev->vfe_base + 0x60);
val |= irq1_mask;
msm_camera_io_w_mb(val, vfe_dev->vfe_base + 0x60);
break;
case MSM_ISP_IRQ_DISABLE:
val = msm_camera_io_r(vfe_dev->vfe_base + 0x5C);
val &= ~irq0_mask;
msm_camera_io_w_mb(val, vfe_dev->vfe_base + 0x5C);
val = msm_camera_io_r(vfe_dev->vfe_base + 0x60);
val &= ~irq1_mask;
msm_camera_io_w_mb(val, vfe_dev->vfe_base + 0x60);
break;
case MSM_ISP_IRQ_SET:
msm_camera_io_w_mb(irq0_mask, vfe_dev->vfe_base + 0x5C);
msm_camera_io_w_mb(irq1_mask, vfe_dev->vfe_base + 0x60);
break;
}
}
static int32_t msm_vfe46_init_dt_parms(struct vfe_device *vfe_dev, static int32_t msm_vfe46_init_dt_parms(struct vfe_device *vfe_dev,
struct msm_vfe_hw_init_parms *dt_parms, void __iomem *dev_mem_base) struct msm_vfe_hw_init_parms *dt_parms, void __iomem *dev_mem_base)
{ {
@ -236,8 +267,10 @@ bus_scale_register_failed:
static void msm_vfe46_release_hardware(struct vfe_device *vfe_dev) static void msm_vfe46_release_hardware(struct vfe_device *vfe_dev)
{ {
/* when closing node, disable all irq */ /* when closing node, disable all irq */
msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x5C); vfe_dev->irq0_mask = 0;
msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x60); vfe_dev->irq1_mask = 0;
msm_vfe46_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
MSM_ISP_IRQ_SET);
disable_irq(vfe_dev->vfe_irq->start); disable_irq(vfe_dev->vfe_irq->start);
free_irq(vfe_dev->vfe_irq->start, vfe_dev); free_irq(vfe_dev->vfe_irq->start, vfe_dev);
@ -282,16 +315,20 @@ static void msm_vfe46_init_hardware_reg(struct vfe_device *vfe_dev)
/* BUS_CFG */ /* BUS_CFG */
msm_camera_io_w(0x00000001, vfe_dev->vfe_base + 0x84); msm_camera_io_w(0x00000001, vfe_dev->vfe_base + 0x84);
/* IRQ_MASK/CLEAR */ /* IRQ_MASK/CLEAR */
msm_camera_io_w(0xE00000F1, vfe_dev->vfe_base + 0x5C); vfe_dev->irq0_mask = 0xE00000F1;
msm_camera_io_w_mb(0xE1FFFFFF, vfe_dev->vfe_base + 0x60); vfe_dev->irq1_mask = 0xE1FFFFFF;
msm_vfe46_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
MSM_ISP_IRQ_SET);
msm_camera_io_w(0xFFFFFFFF, vfe_dev->vfe_base + 0x64); msm_camera_io_w(0xFFFFFFFF, vfe_dev->vfe_base + 0x64);
msm_camera_io_w_mb(0xFFFFFFFF, vfe_dev->vfe_base + 0x68); msm_camera_io_w_mb(0xFFFFFFFF, vfe_dev->vfe_base + 0x68);
} }
static void msm_vfe46_clear_status_reg(struct vfe_device *vfe_dev) static void msm_vfe46_clear_status_reg(struct vfe_device *vfe_dev)
{ {
msm_camera_io_w(0x80000000, vfe_dev->vfe_base + 0x5C); vfe_dev->irq0_mask = 0x80000000;
msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x60); vfe_dev->irq1_mask = 0x0;
msm_vfe46_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
MSM_ISP_IRQ_SET);
msm_camera_io_w(0xFFFFFFFF, vfe_dev->vfe_base + 0x64); msm_camera_io_w(0xFFFFFFFF, vfe_dev->vfe_base + 0x64);
msm_camera_io_w_mb(0xFFFFFFFF, vfe_dev->vfe_base + 0x68); msm_camera_io_w_mb(0xFFFFFFFF, vfe_dev->vfe_base + 0x68);
msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x58); msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x58);
@ -410,38 +447,23 @@ static void msm_vfe46_process_error_status(struct vfe_device *vfe_dev)
pr_err("%s: status bf scale bus overflow\n", __func__); pr_err("%s: status bf scale bus overflow\n", __func__);
} }
static void msm_vfe46_enable_camif_error(struct vfe_device *vfe_dev,
int enable)
{
uint32_t val;
val = msm_camera_io_r(vfe_dev->vfe_base + 0x60);
if (enable)
msm_camera_io_w_mb(val | BIT(0), vfe_dev->vfe_base + 0x60);
else
msm_camera_io_w_mb(val & ~(BIT(0)), vfe_dev->vfe_base + 0x60);
}
static void msm_vfe46_read_irq_status(struct vfe_device *vfe_dev, static void msm_vfe46_read_irq_status(struct vfe_device *vfe_dev,
uint32_t *irq_status0, uint32_t *irq_status1) uint32_t *irq_status0, uint32_t *irq_status1)
{ {
uint32_t irq_mask0, irq_mask1;
*irq_status0 = msm_camera_io_r(vfe_dev->vfe_base + 0x6C); *irq_status0 = msm_camera_io_r(vfe_dev->vfe_base + 0x6C);
*irq_status1 = msm_camera_io_r(vfe_dev->vfe_base + 0x70); *irq_status1 = msm_camera_io_r(vfe_dev->vfe_base + 0x70);
msm_camera_io_w(*irq_status0, vfe_dev->vfe_base + 0x64); msm_camera_io_w(*irq_status0, vfe_dev->vfe_base + 0x64);
msm_camera_io_w(*irq_status1, vfe_dev->vfe_base + 0x68); msm_camera_io_w(*irq_status1, vfe_dev->vfe_base + 0x68);
msm_camera_io_w_mb(1, vfe_dev->vfe_base + 0x58); msm_camera_io_w_mb(1, vfe_dev->vfe_base + 0x58);
irq_mask0 = msm_camera_io_r(vfe_dev->vfe_base + 0x5C); *irq_status0 &= vfe_dev->irq0_mask;
irq_mask1 = msm_camera_io_r(vfe_dev->vfe_base + 0x60); *irq_status1 &= vfe_dev->irq1_mask;
*irq_status0 &= irq_mask0;
*irq_status1 &= irq_mask1;
if (*irq_status1 & (1 << 0)) { if (*irq_status1 & (1 << 0)) {
vfe_dev->error_info.camif_status = vfe_dev->error_info.camif_status =
msm_camera_io_r(vfe_dev->vfe_base + 0x3D0); msm_camera_io_r(vfe_dev->vfe_base + 0x3D0);
msm_vfe46_enable_camif_error(vfe_dev, 0); vfe_dev->irq1_mask &= ~(1 << 0);
msm_vfe46_config_irq(vfe_dev, 0, (1 << 0), MSM_ISP_IRQ_DISABLE);
} }
if (*irq_status1 & (1 << 7)) if (*irq_status1 & (1 << 7))
@ -665,7 +687,6 @@ static void msm_vfe46_axi_cfg_comp_mask(struct vfe_device *vfe_dev,
struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
uint32_t comp_mask, comp_mask_index = uint32_t comp_mask, comp_mask_index =
stream_info->comp_mask_index; stream_info->comp_mask_index;
uint32_t irq_mask;
comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x74); comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x74);
comp_mask &= ~(0x7F << (comp_mask_index * 8)); comp_mask &= ~(0x7F << (comp_mask_index * 8));
@ -673,44 +694,39 @@ static void msm_vfe46_axi_cfg_comp_mask(struct vfe_device *vfe_dev,
stream_composite_mask << (comp_mask_index * 8)); stream_composite_mask << (comp_mask_index * 8));
msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x74); msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x74);
irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x5C); vfe_dev->irq0_mask |= 1 << (comp_mask_index + 25);
irq_mask |= 1 << (comp_mask_index + 25); msm_vfe46_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x5C); MSM_ISP_IRQ_SET);
} }
static void msm_vfe46_axi_clear_comp_mask(struct vfe_device *vfe_dev, static void msm_vfe46_axi_clear_comp_mask(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info) struct msm_vfe_axi_stream *stream_info)
{ {
uint32_t comp_mask, comp_mask_index = stream_info->comp_mask_index; uint32_t comp_mask, comp_mask_index = stream_info->comp_mask_index;
uint32_t irq_mask;
comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x74); comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x74);
comp_mask &= ~(0x7F << (comp_mask_index * 8)); comp_mask &= ~(0x7F << (comp_mask_index * 8));
msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x74); msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x74);
irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x5C); vfe_dev->irq0_mask |= 1 << (comp_mask_index + 25);
irq_mask &= ~(1 << (comp_mask_index + 25)); msm_vfe46_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x5C); MSM_ISP_IRQ_SET);
} }
static void msm_vfe46_axi_cfg_wm_irq_mask(struct vfe_device *vfe_dev, static void msm_vfe46_axi_cfg_wm_irq_mask(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info) struct msm_vfe_axi_stream *stream_info)
{ {
uint32_t irq_mask; vfe_dev->irq0_mask |= 1 << (stream_info->wm[0] + 8);
msm_vfe46_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x5C); MSM_ISP_IRQ_SET);
irq_mask |= 1 << (stream_info->wm[0] + 8);
msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x5C);
} }
static void msm_vfe46_axi_clear_wm_irq_mask(struct vfe_device *vfe_dev, static void msm_vfe46_axi_clear_wm_irq_mask(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info) struct msm_vfe_axi_stream *stream_info)
{ {
uint32_t irq_mask; vfe_dev->irq0_mask &= ~(1 << (stream_info->wm[0] + 8));
msm_vfe46_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x5C); MSM_ISP_IRQ_SET);
irq_mask &= ~(1 << (stream_info->wm[0] + 8));
msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x5C);
} }
static void msm_vfe46_cfg_framedrop(void __iomem *vfe_base, static void msm_vfe46_cfg_framedrop(void __iomem *vfe_base,
@ -948,10 +964,10 @@ static void msm_vfe46_cfg_fetch_engine(struct vfe_device *vfe_dev,
temp |= (1 << 1); temp |= (1 << 1);
msm_camera_io_w(temp, vfe_dev->vfe_base + 0x84); msm_camera_io_w(temp, vfe_dev->vfe_base + 0x84);
temp = msm_camera_io_r(vfe_dev->vfe_base + 0x5C); vfe_dev->irq0_mask &= 0xFEFFFFFF;
temp &= 0xFEFFFFFF; vfe_dev->irq0_mask |= (1 << 24);
temp |= (1 << 24); msm_vfe46_config_irq(vfe_dev, vfe_dev->irq0_mask,
msm_camera_io_w(temp, vfe_dev->vfe_base + 0x5C); vfe_dev->irq1_mask, MSM_ISP_IRQ_SET);
temp = fe_cfg->fetch_height - 1; temp = fe_cfg->fetch_height - 1;
msm_camera_io_w(temp & 0x3FFF, vfe_dev->vfe_base + 0x278); msm_camera_io_w(temp & 0x3FFF, vfe_dev->vfe_base + 0x278);
@ -1211,9 +1227,9 @@ static void msm_vfe46_update_camif_state(struct vfe_device *vfe_dev,
return; return;
if (update_state == ENABLE_CAMIF) { if (update_state == ENABLE_CAMIF) {
val = msm_camera_io_r(vfe_dev->vfe_base + 0x5C); vfe_dev->irq0_mask |= 0xF5;
val |= 0xF5; msm_vfe46_config_irq(vfe_dev, vfe_dev->irq0_mask,
msm_camera_io_w_mb(val, vfe_dev->vfe_base + 0x5C); vfe_dev->irq1_mask, MSM_ISP_IRQ_SET);
bus_en = bus_en =
((vfe_dev->axi_data. ((vfe_dev->axi_data.
@ -1233,17 +1249,24 @@ static void msm_vfe46_update_camif_state(struct vfe_device *vfe_dev,
/* testgen GO*/ /* testgen GO*/
if (vfe_dev->axi_data.src_info[VFE_PIX_0].input_mux == TESTGEN) if (vfe_dev->axi_data.src_info[VFE_PIX_0].input_mux == TESTGEN)
msm_camera_io_w(1, vfe_dev->vfe_base + 0xAF4); msm_camera_io_w(1, vfe_dev->vfe_base + 0xAF4);
} else if (update_state == DISABLE_CAMIF) { } else if (update_state == DISABLE_CAMIF ||
msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x3A8); DISABLE_CAMIF_IMMEDIATELY == update_state) {
msm_vfe46_config_irq(vfe_dev, 0, 0, MSM_ISP_IRQ_SET);
/* disable danger signal */
val = msm_camera_io_r(vfe_dev->vfe_base + 0xC18);
val &= ~(1 << 8);
msm_camera_io_w_mb(val, vfe_dev->vfe_base + 0xC18);
msm_camera_io_w_mb((update_state == DISABLE_CAMIF ? 0x0 : 0x6),
vfe_dev->vfe_base + 0x3A8);
vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0; vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0;
/* testgen OFF*/ /* testgen OFF*/
if (vfe_dev->axi_data.src_info[VFE_PIX_0].input_mux == TESTGEN) if (vfe_dev->axi_data.src_info[VFE_PIX_0].input_mux == TESTGEN)
msm_camera_io_w(1 << 1, vfe_dev->vfe_base + 0xAF4); msm_camera_io_w(1 << 1, vfe_dev->vfe_base + 0xAF4);
} else if (update_state == DISABLE_CAMIF_IMMEDIATELY) { msm_camera_io_w(0, vfe_dev->vfe_base + 0x64);
msm_camera_io_w_mb(0x6, vfe_dev->vfe_base + 0x3A8); msm_camera_io_w((1 << 0), vfe_dev->vfe_base + 0x68);
vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0; msm_camera_io_w_mb(1, vfe_dev->vfe_base + 0x58);
if (vfe_dev->axi_data.src_info[VFE_PIX_0].input_mux == TESTGEN) msm_vfe46_config_irq(vfe_dev, vfe_dev->irq0_mask,
msm_camera_io_w(1 << 1, vfe_dev->vfe_base + 0xAF4); vfe_dev->irq1_mask, MSM_ISP_IRQ_SET);
} }
} }
@ -1499,8 +1522,8 @@ static int msm_vfe46_axi_halt(struct vfe_device *vfe_dev,
enum msm_vfe_input_src i; enum msm_vfe_input_src i;
/* Keep only halt and restart mask */ /* Keep only halt and restart mask */
msm_camera_io_w(BIT(31), vfe_dev->vfe_base + 0x5C); msm_vfe46_config_irq(vfe_dev, (1 << 31), (1 << 8),
msm_camera_io_w(BIT(8), vfe_dev->vfe_base + 0x60); MSM_ISP_IRQ_SET);
/*Clear IRQ Status0, only leave reset irq mask*/ /*Clear IRQ Status0, only leave reset irq mask*/
msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x64); msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x64);
@ -1560,7 +1583,8 @@ static int msm_vfe46_axi_halt(struct vfe_device *vfe_dev,
static int msm_vfe46_axi_restart(struct vfe_device *vfe_dev, static int msm_vfe46_axi_restart(struct vfe_device *vfe_dev,
uint32_t blocking, uint32_t enable_camif) uint32_t blocking, uint32_t enable_camif)
{ {
vfe_dev->hw_info->vfe_ops.core_ops.restore_irq_mask(vfe_dev); msm_vfe46_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
MSM_ISP_IRQ_SET);
msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x64); msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x64);
msm_camera_io_w(0xFFFFFEFF, vfe_dev->vfe_base + 0x68); msm_camera_io_w(0xFFFFFEFF, vfe_dev->vfe_base + 0x68);
msm_camera_io_w(0x1, vfe_dev->vfe_base + 0x58); msm_camera_io_w(0x1, vfe_dev->vfe_base + 0x58);
@ -1715,22 +1739,19 @@ static void msm_vfe46_stats_cfg_wm_irq_mask(
struct vfe_device *vfe_dev, struct vfe_device *vfe_dev,
struct msm_vfe_stats_stream *stream_info) struct msm_vfe_stats_stream *stream_info)
{ {
uint32_t irq_mask; vfe_dev->irq0_mask |= 1 << (STATS_IDX(stream_info->stream_handle) + 15);
msm_vfe46_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x5C); MSM_ISP_IRQ_SET);
irq_mask |= 1 << (STATS_IDX(stream_info->stream_handle) + 15);
msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x5C);
} }
static void msm_vfe46_stats_clear_wm_irq_mask( static void msm_vfe46_stats_clear_wm_irq_mask(
struct vfe_device *vfe_dev, struct vfe_device *vfe_dev,
struct msm_vfe_stats_stream *stream_info) struct msm_vfe_stats_stream *stream_info)
{ {
uint32_t irq_mask; vfe_dev->irq0_mask &=
~(1 << (STATS_IDX(stream_info->stream_handle) + 15));
irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x5C); msm_vfe46_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
irq_mask &= ~(1 << (STATS_IDX(stream_info->stream_handle) + 15)); MSM_ISP_IRQ_SET);
msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x5C);
} }
static void msm_vfe46_stats_cfg_wm_reg( static void msm_vfe46_stats_cfg_wm_reg(
@ -2023,19 +2044,10 @@ static void msm_vfe46_get_rdi_wm_mask(struct vfe_device *vfe_dev,
static void msm_vfe46_get_irq_mask(struct vfe_device *vfe_dev, static void msm_vfe46_get_irq_mask(struct vfe_device *vfe_dev,
uint32_t *irq0_mask, uint32_t *irq1_mask) uint32_t *irq0_mask, uint32_t *irq1_mask)
{ {
*irq0_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x5C); *irq0_mask = vfe_dev->irq0_mask;
*irq1_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x60); *irq1_mask = vfe_dev->irq1_mask;
} }
static void msm_vfe46_restore_irq_mask(struct vfe_device *vfe_dev)
{
msm_camera_io_w(vfe_dev->error_info.overflow_recover_irq_mask0,
vfe_dev->vfe_base + 0x5C);
msm_camera_io_w(vfe_dev->error_info.overflow_recover_irq_mask1,
vfe_dev->vfe_base + 0x60);
}
static void msm_vfe46_get_halt_restart_mask(uint32_t *irq0_mask, static void msm_vfe46_get_halt_restart_mask(uint32_t *irq0_mask,
uint32_t *irq1_mask) uint32_t *irq1_mask)
{ {
@ -2081,7 +2093,6 @@ struct msm_vfe_hardware_info vfe46_hw_info = {
.process_axi_irq = msm_isp_process_axi_irq, .process_axi_irq = msm_isp_process_axi_irq,
.process_stats_irq = msm_isp_process_stats_irq, .process_stats_irq = msm_isp_process_stats_irq,
.process_epoch_irq = msm_vfe46_process_epoch_irq, .process_epoch_irq = msm_vfe46_process_epoch_irq,
.enable_camif_err = msm_vfe46_enable_camif_error,
}, },
.axi_ops = { .axi_ops = {
.reload_wm = msm_vfe46_axi_reload_wm, .reload_wm = msm_vfe46_axi_reload_wm,
@ -2126,7 +2137,6 @@ struct msm_vfe_hardware_info vfe46_hw_info = {
.get_overflow_mask = msm_vfe46_get_overflow_mask, .get_overflow_mask = msm_vfe46_get_overflow_mask,
.get_rdi_wm_mask = msm_vfe46_get_rdi_wm_mask, .get_rdi_wm_mask = msm_vfe46_get_rdi_wm_mask,
.get_irq_mask = msm_vfe46_get_irq_mask, .get_irq_mask = msm_vfe46_get_irq_mask,
.restore_irq_mask = msm_vfe46_restore_irq_mask,
.get_halt_restart_mask = .get_halt_restart_mask =
msm_vfe46_get_halt_restart_mask, msm_vfe46_get_halt_restart_mask,
.process_error_status = msm_vfe46_process_error_status, .process_error_status = msm_vfe46_process_error_status,

View file

@ -102,7 +102,39 @@ static uint8_t stats_irq_map_comp_mask[] = {
(~(ping_pong >> (stats_pingpong_offset_map[idx])) & 0x1) * 2) (~(ping_pong >> (stats_pingpong_offset_map[idx])) & 0x1) * 2)
#define VFE47_SRC_CLK_DTSI_IDX 5 #define VFE47_SRC_CLK_DTSI_IDX 5
static struct msm_cam_clk_info msm_vfe47_clk_info[VFE_CLK_INFO_MAX]; static struct msm_cam_clk_info msm_vfe47_clk_info[VFE_CLK_INFO_MAX];
static void msm_vfe47_config_irq(struct vfe_device *vfe_dev,
uint32_t irq0_mask, uint32_t irq1_mask,
enum msm_isp_irq_operation oper)
{
uint32_t val;
switch (oper) {
case MSM_ISP_IRQ_ENABLE:
val = msm_camera_io_r(vfe_dev->vfe_base + 0x5C);
val |= irq0_mask;
msm_camera_io_w_mb(val, vfe_dev->vfe_base + 0x5C);
val = msm_camera_io_r(vfe_dev->vfe_base + 0x60);
val |= irq1_mask;
msm_camera_io_w_mb(val, vfe_dev->vfe_base + 0x60);
break;
case MSM_ISP_IRQ_DISABLE:
val = msm_camera_io_r(vfe_dev->vfe_base + 0x5C);
val &= ~irq0_mask;
msm_camera_io_w_mb(val, vfe_dev->vfe_base + 0x5C);
val = msm_camera_io_r(vfe_dev->vfe_base + 0x60);
val &= ~irq1_mask;
msm_camera_io_w_mb(val, vfe_dev->vfe_base + 0x60);
break;
case MSM_ISP_IRQ_SET:
msm_camera_io_w_mb(irq0_mask, vfe_dev->vfe_base + 0x5C);
msm_camera_io_w_mb(irq1_mask, vfe_dev->vfe_base + 0x60);
break;
}
}
static int32_t msm_vfe47_init_dt_parms(struct vfe_device *vfe_dev, static int32_t msm_vfe47_init_dt_parms(struct vfe_device *vfe_dev,
struct msm_vfe_hw_init_parms *dt_parms, void __iomem *dev_mem_base) struct msm_vfe_hw_init_parms *dt_parms, void __iomem *dev_mem_base)
{ {
@ -334,8 +366,10 @@ static void msm_vfe47_release_hardware(struct vfe_device *vfe_dev)
enum cam_ahb_clk_client id; enum cam_ahb_clk_client id;
/* when closing node, disable all irq */ /* when closing node, disable all irq */
msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x5C); vfe_dev->irq0_mask = 0;
msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x60); vfe_dev->irq1_mask = 0;
msm_vfe47_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
MSM_ISP_IRQ_SET);
disable_irq(vfe_dev->vfe_irq->start); disable_irq(vfe_dev->vfe_irq->start);
free_irq(vfe_dev->vfe_irq->start, vfe_dev); free_irq(vfe_dev->vfe_irq->start, vfe_dev);
@ -403,16 +437,20 @@ static void msm_vfe47_init_hardware_reg(struct vfe_device *vfe_dev)
/* BUS_CFG */ /* BUS_CFG */
msm_camera_io_w(0x00000101, vfe_dev->vfe_base + 0x84); msm_camera_io_w(0x00000101, vfe_dev->vfe_base + 0x84);
/* IRQ_MASK/CLEAR */ /* IRQ_MASK/CLEAR */
msm_camera_io_w(0xE00000F3, vfe_dev->vfe_base + 0x5C); vfe_dev->irq0_mask = 0xE00000F3;
msm_camera_io_w_mb(0xFFFFFFFF, vfe_dev->vfe_base + 0x60); vfe_dev->irq1_mask = 0xFFFFFFFF;
msm_vfe47_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
MSM_ISP_IRQ_SET);
msm_camera_io_w(0xFFFFFFFF, vfe_dev->vfe_base + 0x64); msm_camera_io_w(0xFFFFFFFF, vfe_dev->vfe_base + 0x64);
msm_camera_io_w_mb(0xFFFFFFFF, vfe_dev->vfe_base + 0x68); msm_camera_io_w_mb(0xFFFFFFFF, vfe_dev->vfe_base + 0x68);
} }
static void msm_vfe47_clear_status_reg(struct vfe_device *vfe_dev) static void msm_vfe47_clear_status_reg(struct vfe_device *vfe_dev)
{ {
msm_camera_io_w(0x80000000, vfe_dev->vfe_base + 0x5C); vfe_dev->irq0_mask = 0x80000000;
msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x60); vfe_dev->irq1_mask = 0x0;
msm_vfe47_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
MSM_ISP_IRQ_SET);
msm_camera_io_w(0xFFFFFFFF, vfe_dev->vfe_base + 0x64); msm_camera_io_w(0xFFFFFFFF, vfe_dev->vfe_base + 0x64);
msm_camera_io_w_mb(0xFFFFFFFF, vfe_dev->vfe_base + 0x68); msm_camera_io_w_mb(0xFFFFFFFF, vfe_dev->vfe_base + 0x68);
msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x58); msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x58);
@ -541,39 +579,24 @@ static void msm_vfe47_process_error_status(struct vfe_device *vfe_dev)
pr_err("%s: status dsp error\n", __func__); pr_err("%s: status dsp error\n", __func__);
} }
static void msm_vfe47_enable_camif_error(struct vfe_device *vfe_dev,
int enable)
{
uint32_t val;
val = msm_camera_io_r(vfe_dev->vfe_base + 0x60);
if (enable)
msm_camera_io_w_mb(val | BIT(0), vfe_dev->vfe_base + 0x60);
else
msm_camera_io_w_mb(val & ~(BIT(0)), vfe_dev->vfe_base + 0x60);
}
static void msm_vfe47_read_irq_status(struct vfe_device *vfe_dev, static void msm_vfe47_read_irq_status(struct vfe_device *vfe_dev,
uint32_t *irq_status0, uint32_t *irq_status1) uint32_t *irq_status0, uint32_t *irq_status1)
{ {
uint32_t irq_mask0, irq_mask1;
*irq_status0 = msm_camera_io_r(vfe_dev->vfe_base + 0x6C); *irq_status0 = msm_camera_io_r(vfe_dev->vfe_base + 0x6C);
*irq_status1 = msm_camera_io_r(vfe_dev->vfe_base + 0x70); *irq_status1 = msm_camera_io_r(vfe_dev->vfe_base + 0x70);
/* Mask off bits that are not enabled */ /* Mask off bits that are not enabled */
msm_camera_io_w(*irq_status0, vfe_dev->vfe_base + 0x64); msm_camera_io_w(*irq_status0, vfe_dev->vfe_base + 0x64);
msm_camera_io_w(*irq_status1, vfe_dev->vfe_base + 0x68); msm_camera_io_w(*irq_status1, vfe_dev->vfe_base + 0x68);
msm_camera_io_w_mb(1, vfe_dev->vfe_base + 0x58); msm_camera_io_w_mb(1, vfe_dev->vfe_base + 0x58);
irq_mask0 = msm_camera_io_r(vfe_dev->vfe_base + 0x5C); *irq_status0 &= vfe_dev->irq0_mask;
irq_mask1 = msm_camera_io_r(vfe_dev->vfe_base + 0x60); *irq_status1 &= vfe_dev->irq1_mask;
*irq_status0 &= irq_mask0;
*irq_status1 &= irq_mask1;
if (*irq_status1 & (1 << 0)) { if (*irq_status1 & (1 << 0)) {
vfe_dev->error_info.camif_status = vfe_dev->error_info.camif_status =
msm_camera_io_r(vfe_dev->vfe_base + 0x4A4); msm_camera_io_r(vfe_dev->vfe_base + 0x4A4);
/* mask off camif error after first occurrance */ /* mask off camif error after first occurrance */
msm_vfe47_enable_camif_error(vfe_dev, 0); vfe_dev->irq1_mask &= ~(1 << 0);
msm_vfe47_config_irq(vfe_dev, 0, (1 << 0), MSM_ISP_IRQ_DISABLE);
} }
if (*irq_status1 & (1 << 7)) if (*irq_status1 & (1 << 7))
@ -798,7 +821,6 @@ static void msm_vfe47_axi_cfg_comp_mask(struct vfe_device *vfe_dev,
struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
uint32_t comp_mask, comp_mask_index = uint32_t comp_mask, comp_mask_index =
stream_info->comp_mask_index; stream_info->comp_mask_index;
uint32_t irq_mask;
comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x74); comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x74);
comp_mask &= ~(0x7F << (comp_mask_index * 8)); comp_mask &= ~(0x7F << (comp_mask_index * 8));
@ -806,44 +828,39 @@ static void msm_vfe47_axi_cfg_comp_mask(struct vfe_device *vfe_dev,
stream_composite_mask << (comp_mask_index * 8)); stream_composite_mask << (comp_mask_index * 8));
msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x74); msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x74);
irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x5C); vfe_dev->irq0_mask |= 1 << (comp_mask_index + 25);
irq_mask |= 1 << (comp_mask_index + 25); msm_vfe47_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x5C); MSM_ISP_IRQ_SET);
} }
static void msm_vfe47_axi_clear_comp_mask(struct vfe_device *vfe_dev, static void msm_vfe47_axi_clear_comp_mask(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info) struct msm_vfe_axi_stream *stream_info)
{ {
uint32_t comp_mask, comp_mask_index = stream_info->comp_mask_index; uint32_t comp_mask, comp_mask_index = stream_info->comp_mask_index;
uint32_t irq_mask;
comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x74); comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x74);
comp_mask &= ~(0x7F << (comp_mask_index * 8)); comp_mask &= ~(0x7F << (comp_mask_index * 8));
msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x74); msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x74);
irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x5C); vfe_dev->irq0_mask &= ~(1 << (comp_mask_index + 25));
irq_mask &= ~(1 << (comp_mask_index + 25)); msm_vfe47_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x5C); MSM_ISP_IRQ_SET);
} }
static void msm_vfe47_axi_cfg_wm_irq_mask(struct vfe_device *vfe_dev, static void msm_vfe47_axi_cfg_wm_irq_mask(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info) struct msm_vfe_axi_stream *stream_info)
{ {
uint32_t irq_mask; vfe_dev->irq0_mask |= 1 << (stream_info->wm[0] + 8);
msm_vfe47_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x5C); MSM_ISP_IRQ_SET);
irq_mask |= 1 << (stream_info->wm[0] + 8);
msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x5C);
} }
static void msm_vfe47_axi_clear_wm_irq_mask(struct vfe_device *vfe_dev, static void msm_vfe47_axi_clear_wm_irq_mask(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info) struct msm_vfe_axi_stream *stream_info)
{ {
uint32_t irq_mask; vfe_dev->irq0_mask &= ~(1 << (stream_info->wm[0] + 8));
msm_vfe47_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x5C); MSM_ISP_IRQ_SET);
irq_mask &= ~(1 << (stream_info->wm[0] + 8));
msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x5C);
} }
static void msm_vfe47_cfg_framedrop(void __iomem *vfe_base, static void msm_vfe47_cfg_framedrop(void __iomem *vfe_base,
@ -1090,10 +1107,10 @@ static void msm_vfe47_cfg_fetch_engine(struct vfe_device *vfe_dev,
temp |= (1 << 1); temp |= (1 << 1);
msm_camera_io_w(temp, vfe_dev->vfe_base + 0x84); msm_camera_io_w(temp, vfe_dev->vfe_base + 0x84);
temp = msm_camera_io_r(vfe_dev->vfe_base + 0x5C); vfe_dev->irq0_mask &= 0xFEFFFFFF;
temp &= 0xFEFFFFFF; vfe_dev->irq0_mask |= (1 << 24);
temp |= (1 << 24); msm_vfe47_config_irq(vfe_dev, vfe_dev->irq0_mask,
msm_camera_io_w(temp, vfe_dev->vfe_base + 0x5C); vfe_dev->irq1_mask, MSM_ISP_IRQ_SET);
temp = fe_cfg->fetch_height - 1; temp = fe_cfg->fetch_height - 1;
msm_camera_io_w(temp & 0x3FFF, vfe_dev->vfe_base + 0x308); msm_camera_io_w(temp & 0x3FFF, vfe_dev->vfe_base + 0x308);
@ -1377,9 +1394,9 @@ static void msm_vfe47_update_camif_state(struct vfe_device *vfe_dev,
val = msm_camera_io_r(vfe_dev->vfe_base + 0x47C); val = msm_camera_io_r(vfe_dev->vfe_base + 0x47C);
if (update_state == ENABLE_CAMIF) { if (update_state == ENABLE_CAMIF) {
val = msm_camera_io_r(vfe_dev->vfe_base + 0x5C); vfe_dev->irq0_mask |= 0xF5;
val |= 0xF5; msm_vfe47_config_irq(vfe_dev, vfe_dev->irq0_mask,
msm_camera_io_w_mb(val, vfe_dev->vfe_base + 0x5C); vfe_dev->irq1_mask, MSM_ISP_IRQ_SET);
if ((vfe_dev->hvx_cmd > HVX_DISABLE) && if ((vfe_dev->hvx_cmd > HVX_DISABLE) &&
(vfe_dev->hvx_cmd <= HVX_ROUND_TRIP)) (vfe_dev->hvx_cmd <= HVX_ROUND_TRIP))
@ -1403,8 +1420,15 @@ static void msm_vfe47_update_camif_state(struct vfe_device *vfe_dev,
/* testgen GO*/ /* testgen GO*/
if (vfe_dev->axi_data.src_info[VFE_PIX_0].input_mux == TESTGEN) if (vfe_dev->axi_data.src_info[VFE_PIX_0].input_mux == TESTGEN)
msm_camera_io_w(1, vfe_dev->vfe_base + 0xC58); msm_camera_io_w(1, vfe_dev->vfe_base + 0xC58);
} else if (update_state == DISABLE_CAMIF) { } else if (update_state == DISABLE_CAMIF ||
msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x478); update_state == DISABLE_CAMIF_IMMEDIATELY) {
/* turn off all irq before camif disable */
msm_vfe47_config_irq(vfe_dev, 0, 0, MSM_ISP_IRQ_SET);
val = msm_camera_io_r(vfe_dev->vfe_base + 0x464);
/* disable danger signal */
msm_camera_io_w_mb(val & ~(1 << 8), vfe_dev->vfe_base + 0x464);
msm_camera_io_w_mb((update_state == DISABLE_CAMIF ? 0x0 : 0x6),
vfe_dev->vfe_base + 0x478);
vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0; vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0;
/* testgen OFF*/ /* testgen OFF*/
if (vfe_dev->axi_data.src_info[VFE_PIX_0].input_mux == TESTGEN) if (vfe_dev->axi_data.src_info[VFE_PIX_0].input_mux == TESTGEN)
@ -1413,16 +1437,15 @@ static void msm_vfe47_update_camif_state(struct vfe_device *vfe_dev,
if ((vfe_dev->hvx_cmd > HVX_DISABLE) && if ((vfe_dev->hvx_cmd > HVX_DISABLE) &&
(vfe_dev->hvx_cmd <= HVX_ROUND_TRIP)) (vfe_dev->hvx_cmd <= HVX_ROUND_TRIP))
msm_vfe47_configure_hvx(vfe_dev, 0); msm_vfe47_configure_hvx(vfe_dev, 0);
/*
} else if (update_state == DISABLE_CAMIF_IMMEDIATELY) { * restore the irq that were disabled for camif stop and clear
msm_camera_io_w_mb(0x6, vfe_dev->vfe_base + 0x478); * the camif error interrupts if generated during that period
vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0; */
if (vfe_dev->axi_data.src_info[VFE_PIX_0].input_mux == TESTGEN) msm_camera_io_w(0, vfe_dev->vfe_base + 0x64);
msm_camera_io_w(1 << 1, vfe_dev->vfe_base + 0xC58); msm_camera_io_w(1 << 0, vfe_dev->vfe_base + 0x68);
msm_camera_io_w_mb(1, vfe_dev->vfe_base + 0x58);
if ((vfe_dev->hvx_cmd > HVX_DISABLE) && msm_vfe47_config_irq(vfe_dev, vfe_dev->irq0_mask,
(vfe_dev->hvx_cmd <= HVX_ROUND_TRIP)) vfe_dev->irq1_mask, MSM_ISP_IRQ_SET);
msm_vfe47_configure_hvx(vfe_dev, 0);
} }
} }
@ -1692,8 +1715,8 @@ static int msm_vfe47_axi_halt(struct vfe_device *vfe_dev,
msm_camera_io_w(val, vfe_dev->vfe_vbif_base + VFE47_VBIF_CLK_OFFSET); msm_camera_io_w(val, vfe_dev->vfe_vbif_base + VFE47_VBIF_CLK_OFFSET);
/* Keep only halt and reset mask */ /* Keep only halt and reset mask */
msm_camera_io_w(BIT(31), vfe_dev->vfe_base + 0x5C); msm_vfe47_config_irq(vfe_dev, (1 << 31), (1 << 8),
msm_camera_io_w(BIT(8), vfe_dev->vfe_base + 0x60); MSM_ISP_IRQ_SET);
/*Clear IRQ Status0, only leave reset irq mask*/ /*Clear IRQ Status0, only leave reset irq mask*/
msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x64); msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x64);
@ -1755,7 +1778,8 @@ static int msm_vfe47_axi_halt(struct vfe_device *vfe_dev,
static int msm_vfe47_axi_restart(struct vfe_device *vfe_dev, static int msm_vfe47_axi_restart(struct vfe_device *vfe_dev,
uint32_t blocking, uint32_t enable_camif) uint32_t blocking, uint32_t enable_camif)
{ {
vfe_dev->hw_info->vfe_ops.core_ops.restore_irq_mask(vfe_dev); msm_vfe47_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
MSM_ISP_IRQ_SET);
msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x64); msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x64);
msm_camera_io_w(0xFFFFFEFF, vfe_dev->vfe_base + 0x68); msm_camera_io_w(0xFFFFFEFF, vfe_dev->vfe_base + 0x68);
msm_camera_io_w(0x1, vfe_dev->vfe_base + 0x58); msm_camera_io_w(0x1, vfe_dev->vfe_base + 0x58);
@ -1889,8 +1913,8 @@ static void msm_vfe47_stats_cfg_wm_irq_mask(
uint32_t irq_mask; uint32_t irq_mask;
uint32_t irq_mask_1; uint32_t irq_mask_1;
irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x5C); irq_mask = vfe_dev->irq0_mask;
irq_mask_1 = msm_camera_io_r(vfe_dev->vfe_base + 0x60); irq_mask_1 = vfe_dev->irq1_mask;
switch (STATS_IDX(stream_info->stream_handle)) { switch (STATS_IDX(stream_info->stream_handle)) {
case STATS_COMP_IDX_AEC_BG: case STATS_COMP_IDX_AEC_BG:
@ -1926,8 +1950,9 @@ static void msm_vfe47_stats_cfg_wm_irq_mask(
STATS_IDX(stream_info->stream_handle)); STATS_IDX(stream_info->stream_handle));
} }
msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x5C); msm_vfe47_config_irq(vfe_dev, irq_mask, irq_mask_1, MSM_ISP_IRQ_SET);
msm_camera_io_w(irq_mask_1, vfe_dev->vfe_base + 0x60); vfe_dev->irq0_mask = irq_mask;
vfe_dev->irq1_mask = irq_mask_1;
} }
static void msm_vfe47_stats_clear_wm_irq_mask( static void msm_vfe47_stats_clear_wm_irq_mask(
@ -1936,8 +1961,8 @@ static void msm_vfe47_stats_clear_wm_irq_mask(
{ {
uint32_t irq_mask, irq_mask_1; uint32_t irq_mask, irq_mask_1;
irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x5C); irq_mask = vfe_dev->irq0_mask;
irq_mask_1 = msm_camera_io_r(vfe_dev->vfe_base + 0x60); irq_mask_1 = vfe_dev->irq1_mask;
switch (STATS_IDX(stream_info->stream_handle)) { switch (STATS_IDX(stream_info->stream_handle)) {
case STATS_COMP_IDX_AEC_BG: case STATS_COMP_IDX_AEC_BG:
@ -1973,8 +1998,9 @@ static void msm_vfe47_stats_clear_wm_irq_mask(
STATS_IDX(stream_info->stream_handle)); STATS_IDX(stream_info->stream_handle));
} }
msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x5C); msm_vfe47_config_irq(vfe_dev, irq_mask, irq_mask_1, MSM_ISP_IRQ_SET);
msm_camera_io_w(irq_mask_1, vfe_dev->vfe_base + 0x60); vfe_dev->irq0_mask = irq_mask;
vfe_dev->irq1_mask = irq_mask_1;
} }
static void msm_vfe47_stats_cfg_wm_reg( static void msm_vfe47_stats_cfg_wm_reg(
@ -2262,19 +2288,10 @@ static void msm_vfe47_get_rdi_wm_mask(struct vfe_device *vfe_dev,
static void msm_vfe47_get_irq_mask(struct vfe_device *vfe_dev, static void msm_vfe47_get_irq_mask(struct vfe_device *vfe_dev,
uint32_t *irq0_mask, uint32_t *irq1_mask) uint32_t *irq0_mask, uint32_t *irq1_mask)
{ {
*irq0_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x5C); *irq0_mask = vfe_dev->irq0_mask;
*irq1_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x60); *irq1_mask = vfe_dev->irq1_mask;
} }
static void msm_vfe47_restore_irq_mask(struct vfe_device *vfe_dev)
{
msm_camera_io_w(vfe_dev->error_info.overflow_recover_irq_mask0,
vfe_dev->vfe_base + 0x5C);
msm_camera_io_w(vfe_dev->error_info.overflow_recover_irq_mask1,
vfe_dev->vfe_base + 0x60);
}
static void msm_vfe47_get_halt_restart_mask(uint32_t *irq0_mask, static void msm_vfe47_get_halt_restart_mask(uint32_t *irq0_mask,
uint32_t *irq1_mask) uint32_t *irq1_mask)
{ {
@ -2321,7 +2338,6 @@ struct msm_vfe_hardware_info vfe47_hw_info = {
.process_axi_irq = msm_isp_process_axi_irq, .process_axi_irq = msm_isp_process_axi_irq,
.process_stats_irq = msm_isp_process_stats_irq, .process_stats_irq = msm_isp_process_stats_irq,
.process_epoch_irq = msm_vfe47_process_epoch_irq, .process_epoch_irq = msm_vfe47_process_epoch_irq,
.enable_camif_err = msm_vfe47_enable_camif_error,
}, },
.axi_ops = { .axi_ops = {
.reload_wm = msm_vfe47_axi_reload_wm, .reload_wm = msm_vfe47_axi_reload_wm,
@ -2366,7 +2382,6 @@ struct msm_vfe_hardware_info vfe47_hw_info = {
.get_overflow_mask = msm_vfe47_get_overflow_mask, .get_overflow_mask = msm_vfe47_get_overflow_mask,
.get_rdi_wm_mask = msm_vfe47_get_rdi_wm_mask, .get_rdi_wm_mask = msm_vfe47_get_rdi_wm_mask,
.get_irq_mask = msm_vfe47_get_irq_mask, .get_irq_mask = msm_vfe47_get_irq_mask,
.restore_irq_mask = msm_vfe47_restore_irq_mask,
.get_halt_restart_mask = .get_halt_restart_mask =
msm_vfe47_get_halt_restart_mask, msm_vfe47_get_halt_restart_mask,
.process_error_status = msm_vfe47_process_error_status, .process_error_status = msm_vfe47_process_error_status,

View file

@ -16,7 +16,7 @@
#include "msm_isp_axi_util.h" #include "msm_isp_axi_util.h"
#define HANDLE_TO_IDX(handle) (handle & 0xFF) #define HANDLE_TO_IDX(handle) (handle & 0xFF)
#define ISP_SOF_DEBUG_COUNT 5 #define ISP_SOF_DEBUG_COUNT 0
static int msm_isp_update_dual_HW_ms_info_at_start( static int msm_isp_update_dual_HW_ms_info_at_start(
struct vfe_device *vfe_dev, struct vfe_device *vfe_dev,
@ -2105,26 +2105,18 @@ int msm_isp_axi_halt(struct vfe_device *vfe_dev,
} }
if (halt_cmd->overflow_detected) { if (halt_cmd->overflow_detected) {
/*Store current IRQ mask*/
if (vfe_dev->error_info.overflow_recover_irq_mask0 == 0) {
vfe_dev->hw_info->vfe_ops.core_ops.get_irq_mask(vfe_dev,
&vfe_dev->error_info.overflow_recover_irq_mask0,
&vfe_dev->error_info.overflow_recover_irq_mask1);
}
atomic_cmpxchg(&vfe_dev->error_info.overflow_state, atomic_cmpxchg(&vfe_dev->error_info.overflow_state,
NO_OVERFLOW, OVERFLOW_DETECTED); NO_OVERFLOW, OVERFLOW_DETECTED);
pr_err("%s: VFE%d Bus overflow detected: start recovery!\n", pr_err("%s: VFE%d Bus overflow detected: start recovery!\n",
__func__, vfe_dev->pdev->id); __func__, vfe_dev->pdev->id);
} }
rc = vfe_dev->hw_info->vfe_ops.axi_ops.halt(vfe_dev,
halt_cmd->blocking_halt);
if (halt_cmd->stop_camif) { if (halt_cmd->stop_camif) {
vfe_dev->hw_info->vfe_ops.core_ops. vfe_dev->hw_info->vfe_ops.core_ops.
update_camif_state(vfe_dev, DISABLE_CAMIF_IMMEDIATELY); update_camif_state(vfe_dev, DISABLE_CAMIF_IMMEDIATELY);
} }
rc = vfe_dev->hw_info->vfe_ops.axi_ops.halt(vfe_dev,
halt_cmd->blocking_halt);
return rc; return rc;
} }
@ -2552,7 +2544,6 @@ static int msm_isp_start_axi_stream(struct vfe_device *vfe_dev,
vfe_dev->hw_info->vfe_ops.core_ops. vfe_dev->hw_info->vfe_ops.core_ops.
update_camif_state(vfe_dev, camif_update); update_camif_state(vfe_dev, camif_update);
vfe_dev->axi_data.camif_state = CAMIF_ENABLE; vfe_dev->axi_data.camif_state = CAMIF_ENABLE;
vfe_dev->hw_info->vfe_ops.irq_ops.enable_camif_err(vfe_dev, 1);
} }
if (wait_for_complete) { if (wait_for_complete) {
@ -2714,24 +2705,17 @@ static int msm_isp_stop_axi_stream(struct vfe_device *vfe_dev,
vfe_dev->axi_data.camif_state = CAMIF_DISABLE; vfe_dev->axi_data.camif_state = CAMIF_DISABLE;
} else if ((camif_update == DISABLE_CAMIF_IMMEDIATELY) || } else if ((camif_update == DISABLE_CAMIF_IMMEDIATELY) ||
(ext_read)) { (ext_read)) {
vfe_dev->hw_info->vfe_ops.irq_ops.enable_camif_err(vfe_dev, 0);
vfe_dev->ignore_error = 1;
if (!ext_read) if (!ext_read)
vfe_dev->hw_info->vfe_ops.core_ops. vfe_dev->hw_info->vfe_ops.core_ops.
update_camif_state(vfe_dev, update_camif_state(vfe_dev,
DISABLE_CAMIF_IMMEDIATELY); DISABLE_CAMIF_IMMEDIATELY);
vfe_dev->axi_data.camif_state = CAMIF_STOPPED; vfe_dev->axi_data.camif_state = CAMIF_STOPPED;
vfe_dev->hw_info->vfe_ops.irq_ops.enable_camif_err(vfe_dev, 1);
vfe_dev->ignore_error = 0;
} }
if (halt) { if (halt) {
/*during stop immediately, stop output then stop input*/ /*during stop immediately, stop output then stop input*/
vfe_dev->ignore_error = 1;
vfe_dev->hw_info->vfe_ops.axi_ops.halt(vfe_dev, 1); vfe_dev->hw_info->vfe_ops.axi_ops.halt(vfe_dev, 1);
vfe_dev->hw_info->vfe_ops.core_ops.reset_hw(vfe_dev, 0, 1); vfe_dev->hw_info->vfe_ops.core_ops.reset_hw(vfe_dev, 0, 1);
vfe_dev->hw_info->vfe_ops.core_ops.init_hw_reg(vfe_dev); vfe_dev->hw_info->vfe_ops.core_ops.init_hw_reg(vfe_dev);
vfe_dev->ignore_error = 0;
} }
msm_isp_update_camif_output_count(vfe_dev, stream_cfg_cmd); msm_isp_update_camif_output_count(vfe_dev, stream_cfg_cmd);

View file

@ -1990,8 +1990,7 @@ irqreturn_t msm_isp_process_irq(int irq_num, void *data)
error_mask1 &= irq_status1; error_mask1 &= irq_status1;
irq_status0 &= ~error_mask0; irq_status0 &= ~error_mask0;
irq_status1 &= ~error_mask1; irq_status1 &= ~error_mask1;
if (!vfe_dev->ignore_error && if ((error_mask0 != 0) || (error_mask1 != 0))
((error_mask0 != 0) || (error_mask1 != 0)))
msm_isp_update_error_info(vfe_dev, error_mask0, error_mask1); msm_isp_update_error_info(vfe_dev, error_mask0, error_mask1);
if ((irq_status0 == 0) && (irq_status1 == 0) && if ((irq_status0 == 0) && (irq_status1 == 0) &&