Loading drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c +75 −7 Original line number Diff line number Diff line Loading @@ -37,7 +37,7 @@ #undef CDBG #define CDBG(fmt, args...) pr_debug(fmt, ##args) static struct msm_isp_bufq *msm_isp_get_bufq( struct msm_isp_bufq *msm_isp_get_bufq( struct msm_isp_buf_mgr *buf_mgr, uint32_t bufq_handle) { Loading Loading @@ -497,6 +497,11 @@ static int msm_isp_put_buf(struct msm_isp_buf_mgr *buf_mgr, return rc; } buf_info->buf_get_count = 0; buf_info->buf_put_count = 0; memset(buf_info->buf_used, 0, sizeof(buf_info->buf_used)); spin_lock_irqsave(&bufq->bufq_lock, flags); switch (buf_info->state) { case MSM_ISP_BUFFER_STATE_PREPARED: Loading Loading @@ -529,6 +534,53 @@ static int msm_isp_put_buf(struct msm_isp_buf_mgr *buf_mgr, return rc; } static int msm_isp_put_buf_unsafe(struct msm_isp_buf_mgr *buf_mgr, uint32_t bufq_handle, uint32_t buf_index) { int rc = -1; struct msm_isp_bufq *bufq = NULL; struct msm_isp_buffer *buf_info = NULL; bufq = msm_isp_get_bufq(buf_mgr, bufq_handle); if (!bufq) { pr_err("%s: Invalid bufq\n", __func__); return rc; } buf_info = msm_isp_get_buf_ptr(buf_mgr, bufq_handle, buf_index); if (!buf_info) { pr_err("%s: buf not found\n", __func__); return rc; } switch (buf_info->state) { case MSM_ISP_BUFFER_STATE_PREPARED: case MSM_ISP_BUFFER_STATE_DEQUEUED: case MSM_ISP_BUFFER_STATE_DIVERTED: if (BUF_SRC(bufq->stream_id)) list_add_tail(&buf_info->list, &bufq->head); else buf_mgr->vb2_ops->put_buf(buf_info->vb2_buf, bufq->session_id, bufq->stream_id); buf_info->state = MSM_ISP_BUFFER_STATE_QUEUED; rc = 0; break; case MSM_ISP_BUFFER_STATE_DISPATCHED: buf_info->state = MSM_ISP_BUFFER_STATE_QUEUED; rc = 0; break; case MSM_ISP_BUFFER_STATE_QUEUED: rc = 0; break; default: pr_err("%s: incorrect state = %d", __func__, buf_info->state); break; } return rc; } static int msm_isp_buf_done(struct msm_isp_buf_mgr *buf_mgr, uint32_t bufq_handle, uint32_t buf_index, struct timeval *tv, uint32_t frame_id, uint32_t output_format) Loading Loading @@ -607,19 +659,34 @@ static int msm_isp_flush_buf(struct msm_isp_buf_mgr *buf_mgr, pr_err("%s: buf not found\n", __func__); continue; } spin_lock_irqsave(&bufq->bufq_lock, flags); if (flush_type == MSM_ISP_BUFFER_FLUSH_DIVERTED && buf_info->state == MSM_ISP_BUFFER_STATE_DIVERTED) { buf_info->state = MSM_ISP_BUFFER_STATE_QUEUED; } else if (flush_type == MSM_ISP_BUFFER_FLUSH_ALL && (buf_info->state == MSM_ISP_BUFFER_STATE_DEQUEUED || buf_info->state == MSM_ISP_BUFFER_STATE_DIVERTED || buf_info->state == MSM_ISP_BUFFER_STATE_DISPATCHED)) { buf_info->state = MSM_ISP_BUFFER_STATE_QUEUED; } else if (flush_type == MSM_ISP_BUFFER_FLUSH_ALL) { if (buf_info->state == MSM_ISP_BUFFER_STATE_DIVERTED) { CDBG("%s: no need to queue Diverted buffer\n", __func__); } else if (buf_info->state == MSM_ISP_BUFFER_STATE_DEQUEUED) { if (buf_info->buf_get_count == ISP_SHARE_BUF_CLIENT) { msm_isp_put_buf_unsafe(buf_mgr, bufq_handle, buf_info->buf_idx); } else { buf_info->state = MSM_ISP_BUFFER_STATE_DEQUEUED; buf_info->buf_get_count = 0; buf_info->buf_put_count = 0; memset(buf_info->buf_used, 0, sizeof(uint8_t) * 2); } } } spin_unlock_irqrestore(&bufq->bufq_lock, flags); } return 0; } Loading Loading @@ -1079,6 +1146,7 @@ static struct msm_isp_buf_ops isp_buf_ops = { .buf_mgr_init = msm_isp_init_isp_buf_mgr, .buf_mgr_deinit = msm_isp_deinit_isp_buf_mgr, .buf_mgr_debug = msm_isp_buf_mgr_debug, .get_bufq = msm_isp_get_bufq, }; int msm_isp_create_isp_buf_mgr( Loading drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h +2 −0 Original line number Diff line number Diff line Loading @@ -146,6 +146,8 @@ struct msm_isp_buf_ops { const char *ctx_name, uint16_t num_buf_q); int (*buf_mgr_deinit) (struct msm_isp_buf_mgr *buf_mgr); int (*buf_mgr_debug) (struct msm_isp_buf_mgr *buf_mgr); struct msm_isp_bufq * (*get_bufq)(struct msm_isp_buf_mgr *buf_mgr, uint32_t bufq_handle); }; struct msm_isp_buf_mgr { Loading drivers/media/platform/msm/camera_v2/isp/msm_isp.h +27 −2 Original line number Diff line number Diff line Loading @@ -154,12 +154,15 @@ struct msm_vfe_axi_ops { uint32_t (*get_wm_mask) (uint32_t irq_status0, uint32_t irq_status1); uint32_t (*get_comp_mask) (uint32_t irq_status0, uint32_t irq_status1); uint32_t (*get_pingpong_status) (struct vfe_device *vfe_dev); long (*halt) (struct vfe_device *vfe_dev); int (*halt) (struct vfe_device *vfe_dev, uint32_t blocking); int (*restart) (struct vfe_device *vfe_dev, uint32_t blocking, uint32_t enable_camif); }; struct msm_vfe_core_ops { void (*reg_update) (struct vfe_device *vfe_dev); long (*reset_hw) (struct vfe_device *vfe_dev); long (*reset_hw) (struct vfe_device *vfe_dev, uint32_t first_start, uint32_t blocking_call); int (*init_hw) (struct vfe_device *vfe_dev); void (*init_hw_reg) (struct vfe_device *vfe_dev); void (*release_hw) (struct vfe_device *vfe_dev); Loading @@ -173,6 +176,14 @@ struct msm_vfe_core_ops { int (*get_platform_data) (struct vfe_device *vfe_dev); void (*get_error_mask) (uint32_t *error_mask0, uint32_t *error_mask1); void (*process_error_status) (struct vfe_device *vfe_dev); void (*get_overflow_mask) (uint32_t *overflow_mask); void (*get_irq_mask) (struct vfe_device *vfe_dev, 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, uint32_t *irq1_mask); void (*get_rdi_wm_mask)(struct vfe_device *vfe_dev, uint32_t *rdi_wm_mask); }; struct msm_vfe_stats_ops { int (*get_stats_idx) (enum msm_isp_stats_type stats_type); Loading Loading @@ -290,6 +301,7 @@ struct msm_vfe_axi_stream { enum msm_vfe_axi_stream_type stream_type; uint32_t vt_enable; uint32_t frame_based; enum msm_vfe_frame_skip_pattern frame_skip_pattern; uint32_t framedrop_period; uint32_t framedrop_pattern; uint32_t num_burst_capture;/*number of frame to capture*/ Loading Loading @@ -343,6 +355,9 @@ struct msm_vfe_axi_shared_data { enum msm_wm_ub_cfg_type wm_ub_cfg_policy; uint8_t num_used_wm; uint8_t num_active_stream; uint8_t num_rdi_stream; uint8_t num_pix_stream; uint32_t rdi_wm_mask; struct msm_vfe_axi_composite_info composite_info[MAX_NUM_COMPOSITE_MASK]; uint8_t num_used_composite_mask; Loading Loading @@ -406,7 +421,17 @@ struct msm_vfe_tasklet_queue_cmd { #define MSM_VFE_TASKLETQ_SIZE 200 enum msm_vfe_overflow_state { NO_OVERFLOW, OVERFLOW_DETECTED, HALT_REQUESTED, RESTART_REQUESTED, }; struct msm_vfe_error_info { atomic_t overflow_state; uint32_t overflow_recover_irq_mask0; uint32_t overflow_recover_irq_mask1; uint32_t error_mask0; uint32_t error_mask1; uint32_t violation_status; Loading drivers/media/platform/msm/camera_v2/isp/msm_isp32.c +3 −7 Original line number Diff line number Diff line Loading @@ -410,7 +410,8 @@ static void msm_vfe32_reg_update( msm_camera_io_w_mb(0xF, vfe_dev->vfe_base + 0x260); } static long msm_vfe32_reset_hardware(struct vfe_device *vfe_dev) static long msm_vfe32_reset_hardware(struct vfe_device *vfe_dev, uint32_t first_start, uint32_t blocking) { init_completion(&vfe_dev->reset_complete); msm_camera_io_w_mb(0x3FF, vfe_dev->vfe_base + 0x4); Loading Loading @@ -676,13 +677,8 @@ static void msm_vfe32_update_camif_state( msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x1E0); vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0; } else if (update_state == DISABLE_CAMIF_IMMEDIATELY) { vfe_dev->ignore_error = 1; msm_camera_io_w_mb(0x6, vfe_dev->vfe_base + 0x1E0); vfe_dev->hw_info->vfe_ops.axi_ops.halt(vfe_dev); vfe_dev->hw_info->vfe_ops.core_ops.reset_hw(vfe_dev); vfe_dev->hw_info->vfe_ops.core_ops.init_hw_reg(vfe_dev); vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0; vfe_dev->ignore_error = 0; } } Loading Loading @@ -907,7 +903,7 @@ static void msm_vfe32_update_ping_pong_addr(struct vfe_device *vfe_dev, VFE32_PING_PONG_BASE(wm_idx, pingpong_status)); } static long msm_vfe32_axi_halt(struct vfe_device *vfe_dev) static int msm_vfe32_axi_halt(struct vfe_device *vfe_dev, uint32_t blocking) { uint32_t halt_mask; uint32_t axi_busy_flag = true; Loading drivers/media/platform/msm/camera_v2/isp/msm_isp40.c +113 −17 Original line number Diff line number Diff line Loading @@ -404,8 +404,10 @@ static void msm_vfe40_process_reset_irq(struct vfe_device *vfe_dev, static void msm_vfe40_process_halt_irq(struct vfe_device *vfe_dev, uint32_t irq_status0, uint32_t irq_status1) { if (irq_status1 & (1 << 8)) if (irq_status1 & (1 << 8)) { complete(&vfe_dev->halt_complete); msm_camera_io_w(0x0, vfe_dev->vfe_base + 0x2C0); } } static void msm_vfe40_process_camif_irq(struct vfe_device *vfe_dev, Loading Loading @@ -655,13 +657,30 @@ static void msm_vfe40_reg_update(struct vfe_device *vfe_dev) msm_camera_io_w_mb(0xF, vfe_dev->vfe_base + 0x378); } static long msm_vfe40_reset_hardware(struct vfe_device *vfe_dev) static long msm_vfe40_reset_hardware(struct vfe_device *vfe_dev, uint32_t first_start, uint32_t blocking_call) { long rc = 0; init_completion(&vfe_dev->reset_complete); if (first_start) { msm_camera_io_w_mb(0x1FF, vfe_dev->vfe_base + 0xC); return wait_for_completion_timeout( } else { msm_camera_io_w_mb(0x1EF, vfe_dev->vfe_base + 0xC); msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x30); msm_camera_io_w(0xFEFFFEFF, vfe_dev->vfe_base + 0x34); msm_camera_io_w(0x1, vfe_dev->vfe_base + 0x24); vfe_dev->hw_info->vfe_ops.axi_ops. reload_wm(vfe_dev, 0x0003FFFF); } if (blocking_call) { rc = wait_for_completion_interruptible_timeout( &vfe_dev->reset_complete, msecs_to_jiffies(50)); } return rc; } static void msm_vfe40_axi_reload_wm( struct vfe_device *vfe_dev, uint32_t reload_mask) Loading Loading @@ -953,19 +972,15 @@ static void msm_vfe40_update_camif_state(struct vfe_device *vfe_dev, val &= 0xFFFFFF3F; val = val | bus_en << 7 | vfe_en << 6; msm_camera_io_w(val, vfe_dev->vfe_base + 0x2F8); msm_camera_io_w_mb(0x4, 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; } else if (update_state == DISABLE_CAMIF) { msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x2F4); vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0; } else if (update_state == DISABLE_CAMIF_IMMEDIATELY) { vfe_dev->ignore_error = 1; msm_camera_io_w_mb(0x6, vfe_dev->vfe_base + 0x2F4); vfe_dev->hw_info->vfe_ops.axi_ops.halt(vfe_dev); vfe_dev->hw_info->vfe_ops.core_ops.reset_hw(vfe_dev); vfe_dev->hw_info->vfe_ops.core_ops.init_hw_reg(vfe_dev); vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0; vfe_dev->ignore_error = 0; } } Loading Loading @@ -1219,17 +1234,56 @@ static void msm_vfe40_update_ping_pong_addr( VFE40_PING_PONG_BASE(wm_idx, pingpong_status)); } static long msm_vfe40_axi_halt(struct vfe_device *vfe_dev) static int msm_vfe40_axi_halt(struct vfe_device *vfe_dev, uint32_t blocking) { uint32_t halt_mask; halt_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x2C); halt_mask |= (1 << 8); msm_camera_io_w_mb(halt_mask, vfe_dev->vfe_base + 0x2C); int rc = 0; /* Keep only halt and restart mask */ msm_camera_io_w(BIT(31), vfe_dev->vfe_base + 0x28); msm_camera_io_w(BIT(8), vfe_dev->vfe_base + 0x2C); /*Clear IRQ Status */ msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x30); msm_camera_io_w(0xFEFFFEFF, vfe_dev->vfe_base + 0x34); msm_camera_io_w(0x1, vfe_dev->vfe_base + 0x24); /* if any stream is waiting for update, signal complete */ if (vfe_dev->axi_data.stream_update) { pr_err("%s: calling complete on stream update\n", __func__); complete(&vfe_dev->stream_config_complete); } /* Halt AXI Bus Bridge */ init_completion(&vfe_dev->halt_complete); msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x2C0); return wait_for_completion_interruptible_timeout( if (blocking) { rc = wait_for_completion_interruptible_timeout( &vfe_dev->halt_complete, msecs_to_jiffies(500)); } return rc; } static int msm_vfe40_axi_restart(struct vfe_device *vfe_dev, uint32_t blocking, uint32_t enable_camif) { vfe_dev->hw_info->vfe_ops.core_ops.restore_irq_mask(vfe_dev); /* Clear IRQ Status */ msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x30); msm_camera_io_w(0xFEFFFEFF, vfe_dev->vfe_base + 0x34); msm_camera_io_w(0x1, vfe_dev->vfe_base + 0x24); /* Start AXI */ msm_camera_io_w(0x0, vfe_dev->vfe_base + 0x2C0); vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev); memset(&vfe_dev->error_info, 0, sizeof(vfe_dev->error_info)); atomic_set(&vfe_dev->error_info.overflow_state, NO_OVERFLOW); if (enable_camif) { vfe_dev->hw_info->vfe_ops.core_ops. update_camif_state(vfe_dev, ENABLE_CAMIF); } return 0; } static uint32_t msm_vfe40_get_wm_mask( uint32_t irq_status0, uint32_t irq_status1) Loading Loading @@ -1550,6 +1604,41 @@ static void msm_vfe40_get_error_mask( *error_mask1 = 0x00FFFEFF; } static void msm_vfe40_get_overflow_mask(uint32_t *overflow_mask) { *overflow_mask = 0x00FFFE7E; } static void msm_vfe40_get_rdi_wm_mask(struct vfe_device *vfe_dev, uint32_t *rdi_wm_mask) { *rdi_wm_mask = vfe_dev->axi_data.rdi_wm_mask; } static void msm_vfe40_get_irq_mask(struct vfe_device *vfe_dev, uint32_t *irq0_mask, uint32_t *irq1_mask) { *irq0_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x28); *irq1_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x2C); } 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, uint32_t *irq1_mask) { *irq0_mask = BIT(31); *irq1_mask = BIT(8); } static struct msm_vfe_axi_hardware_info msm_vfe40_axi_hw_info = { .num_wm = 7, .num_comp_mask = 3, Loading Loading @@ -1620,6 +1709,7 @@ struct msm_vfe_hardware_info vfe40_hw_info = { .get_wm_mask = msm_vfe40_get_wm_mask, .get_pingpong_status = msm_vfe40_get_pingpong_status, .halt = msm_vfe40_axi_halt, .restart = msm_vfe40_axi_restart, }, .core_ops = { .reg_update = msm_vfe40_reg_update, Loading @@ -1632,6 +1722,12 @@ struct msm_vfe_hardware_info vfe40_hw_info = { .release_hw = msm_vfe40_release_hardware, .get_platform_data = msm_vfe40_get_platform_data, .get_error_mask = msm_vfe40_get_error_mask, .get_overflow_mask = msm_vfe40_get_overflow_mask, .get_rdi_wm_mask = msm_vfe40_get_rdi_wm_mask, .get_irq_mask = msm_vfe40_get_irq_mask, .restore_irq_mask = msm_vfe40_restore_irq_mask, .get_halt_restart_mask = msm_vfe40_get_halt_restart_mask, .process_error_status = msm_vfe40_process_error_status, }, .stats_ops = { Loading Loading
drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c +75 −7 Original line number Diff line number Diff line Loading @@ -37,7 +37,7 @@ #undef CDBG #define CDBG(fmt, args...) pr_debug(fmt, ##args) static struct msm_isp_bufq *msm_isp_get_bufq( struct msm_isp_bufq *msm_isp_get_bufq( struct msm_isp_buf_mgr *buf_mgr, uint32_t bufq_handle) { Loading Loading @@ -497,6 +497,11 @@ static int msm_isp_put_buf(struct msm_isp_buf_mgr *buf_mgr, return rc; } buf_info->buf_get_count = 0; buf_info->buf_put_count = 0; memset(buf_info->buf_used, 0, sizeof(buf_info->buf_used)); spin_lock_irqsave(&bufq->bufq_lock, flags); switch (buf_info->state) { case MSM_ISP_BUFFER_STATE_PREPARED: Loading Loading @@ -529,6 +534,53 @@ static int msm_isp_put_buf(struct msm_isp_buf_mgr *buf_mgr, return rc; } static int msm_isp_put_buf_unsafe(struct msm_isp_buf_mgr *buf_mgr, uint32_t bufq_handle, uint32_t buf_index) { int rc = -1; struct msm_isp_bufq *bufq = NULL; struct msm_isp_buffer *buf_info = NULL; bufq = msm_isp_get_bufq(buf_mgr, bufq_handle); if (!bufq) { pr_err("%s: Invalid bufq\n", __func__); return rc; } buf_info = msm_isp_get_buf_ptr(buf_mgr, bufq_handle, buf_index); if (!buf_info) { pr_err("%s: buf not found\n", __func__); return rc; } switch (buf_info->state) { case MSM_ISP_BUFFER_STATE_PREPARED: case MSM_ISP_BUFFER_STATE_DEQUEUED: case MSM_ISP_BUFFER_STATE_DIVERTED: if (BUF_SRC(bufq->stream_id)) list_add_tail(&buf_info->list, &bufq->head); else buf_mgr->vb2_ops->put_buf(buf_info->vb2_buf, bufq->session_id, bufq->stream_id); buf_info->state = MSM_ISP_BUFFER_STATE_QUEUED; rc = 0; break; case MSM_ISP_BUFFER_STATE_DISPATCHED: buf_info->state = MSM_ISP_BUFFER_STATE_QUEUED; rc = 0; break; case MSM_ISP_BUFFER_STATE_QUEUED: rc = 0; break; default: pr_err("%s: incorrect state = %d", __func__, buf_info->state); break; } return rc; } static int msm_isp_buf_done(struct msm_isp_buf_mgr *buf_mgr, uint32_t bufq_handle, uint32_t buf_index, struct timeval *tv, uint32_t frame_id, uint32_t output_format) Loading Loading @@ -607,19 +659,34 @@ static int msm_isp_flush_buf(struct msm_isp_buf_mgr *buf_mgr, pr_err("%s: buf not found\n", __func__); continue; } spin_lock_irqsave(&bufq->bufq_lock, flags); if (flush_type == MSM_ISP_BUFFER_FLUSH_DIVERTED && buf_info->state == MSM_ISP_BUFFER_STATE_DIVERTED) { buf_info->state = MSM_ISP_BUFFER_STATE_QUEUED; } else if (flush_type == MSM_ISP_BUFFER_FLUSH_ALL && (buf_info->state == MSM_ISP_BUFFER_STATE_DEQUEUED || buf_info->state == MSM_ISP_BUFFER_STATE_DIVERTED || buf_info->state == MSM_ISP_BUFFER_STATE_DISPATCHED)) { buf_info->state = MSM_ISP_BUFFER_STATE_QUEUED; } else if (flush_type == MSM_ISP_BUFFER_FLUSH_ALL) { if (buf_info->state == MSM_ISP_BUFFER_STATE_DIVERTED) { CDBG("%s: no need to queue Diverted buffer\n", __func__); } else if (buf_info->state == MSM_ISP_BUFFER_STATE_DEQUEUED) { if (buf_info->buf_get_count == ISP_SHARE_BUF_CLIENT) { msm_isp_put_buf_unsafe(buf_mgr, bufq_handle, buf_info->buf_idx); } else { buf_info->state = MSM_ISP_BUFFER_STATE_DEQUEUED; buf_info->buf_get_count = 0; buf_info->buf_put_count = 0; memset(buf_info->buf_used, 0, sizeof(uint8_t) * 2); } } } spin_unlock_irqrestore(&bufq->bufq_lock, flags); } return 0; } Loading Loading @@ -1079,6 +1146,7 @@ static struct msm_isp_buf_ops isp_buf_ops = { .buf_mgr_init = msm_isp_init_isp_buf_mgr, .buf_mgr_deinit = msm_isp_deinit_isp_buf_mgr, .buf_mgr_debug = msm_isp_buf_mgr_debug, .get_bufq = msm_isp_get_bufq, }; int msm_isp_create_isp_buf_mgr( Loading
drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h +2 −0 Original line number Diff line number Diff line Loading @@ -146,6 +146,8 @@ struct msm_isp_buf_ops { const char *ctx_name, uint16_t num_buf_q); int (*buf_mgr_deinit) (struct msm_isp_buf_mgr *buf_mgr); int (*buf_mgr_debug) (struct msm_isp_buf_mgr *buf_mgr); struct msm_isp_bufq * (*get_bufq)(struct msm_isp_buf_mgr *buf_mgr, uint32_t bufq_handle); }; struct msm_isp_buf_mgr { Loading
drivers/media/platform/msm/camera_v2/isp/msm_isp.h +27 −2 Original line number Diff line number Diff line Loading @@ -154,12 +154,15 @@ struct msm_vfe_axi_ops { uint32_t (*get_wm_mask) (uint32_t irq_status0, uint32_t irq_status1); uint32_t (*get_comp_mask) (uint32_t irq_status0, uint32_t irq_status1); uint32_t (*get_pingpong_status) (struct vfe_device *vfe_dev); long (*halt) (struct vfe_device *vfe_dev); int (*halt) (struct vfe_device *vfe_dev, uint32_t blocking); int (*restart) (struct vfe_device *vfe_dev, uint32_t blocking, uint32_t enable_camif); }; struct msm_vfe_core_ops { void (*reg_update) (struct vfe_device *vfe_dev); long (*reset_hw) (struct vfe_device *vfe_dev); long (*reset_hw) (struct vfe_device *vfe_dev, uint32_t first_start, uint32_t blocking_call); int (*init_hw) (struct vfe_device *vfe_dev); void (*init_hw_reg) (struct vfe_device *vfe_dev); void (*release_hw) (struct vfe_device *vfe_dev); Loading @@ -173,6 +176,14 @@ struct msm_vfe_core_ops { int (*get_platform_data) (struct vfe_device *vfe_dev); void (*get_error_mask) (uint32_t *error_mask0, uint32_t *error_mask1); void (*process_error_status) (struct vfe_device *vfe_dev); void (*get_overflow_mask) (uint32_t *overflow_mask); void (*get_irq_mask) (struct vfe_device *vfe_dev, 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, uint32_t *irq1_mask); void (*get_rdi_wm_mask)(struct vfe_device *vfe_dev, uint32_t *rdi_wm_mask); }; struct msm_vfe_stats_ops { int (*get_stats_idx) (enum msm_isp_stats_type stats_type); Loading Loading @@ -290,6 +301,7 @@ struct msm_vfe_axi_stream { enum msm_vfe_axi_stream_type stream_type; uint32_t vt_enable; uint32_t frame_based; enum msm_vfe_frame_skip_pattern frame_skip_pattern; uint32_t framedrop_period; uint32_t framedrop_pattern; uint32_t num_burst_capture;/*number of frame to capture*/ Loading Loading @@ -343,6 +355,9 @@ struct msm_vfe_axi_shared_data { enum msm_wm_ub_cfg_type wm_ub_cfg_policy; uint8_t num_used_wm; uint8_t num_active_stream; uint8_t num_rdi_stream; uint8_t num_pix_stream; uint32_t rdi_wm_mask; struct msm_vfe_axi_composite_info composite_info[MAX_NUM_COMPOSITE_MASK]; uint8_t num_used_composite_mask; Loading Loading @@ -406,7 +421,17 @@ struct msm_vfe_tasklet_queue_cmd { #define MSM_VFE_TASKLETQ_SIZE 200 enum msm_vfe_overflow_state { NO_OVERFLOW, OVERFLOW_DETECTED, HALT_REQUESTED, RESTART_REQUESTED, }; struct msm_vfe_error_info { atomic_t overflow_state; uint32_t overflow_recover_irq_mask0; uint32_t overflow_recover_irq_mask1; uint32_t error_mask0; uint32_t error_mask1; uint32_t violation_status; Loading
drivers/media/platform/msm/camera_v2/isp/msm_isp32.c +3 −7 Original line number Diff line number Diff line Loading @@ -410,7 +410,8 @@ static void msm_vfe32_reg_update( msm_camera_io_w_mb(0xF, vfe_dev->vfe_base + 0x260); } static long msm_vfe32_reset_hardware(struct vfe_device *vfe_dev) static long msm_vfe32_reset_hardware(struct vfe_device *vfe_dev, uint32_t first_start, uint32_t blocking) { init_completion(&vfe_dev->reset_complete); msm_camera_io_w_mb(0x3FF, vfe_dev->vfe_base + 0x4); Loading Loading @@ -676,13 +677,8 @@ static void msm_vfe32_update_camif_state( msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x1E0); vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0; } else if (update_state == DISABLE_CAMIF_IMMEDIATELY) { vfe_dev->ignore_error = 1; msm_camera_io_w_mb(0x6, vfe_dev->vfe_base + 0x1E0); vfe_dev->hw_info->vfe_ops.axi_ops.halt(vfe_dev); vfe_dev->hw_info->vfe_ops.core_ops.reset_hw(vfe_dev); vfe_dev->hw_info->vfe_ops.core_ops.init_hw_reg(vfe_dev); vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0; vfe_dev->ignore_error = 0; } } Loading Loading @@ -907,7 +903,7 @@ static void msm_vfe32_update_ping_pong_addr(struct vfe_device *vfe_dev, VFE32_PING_PONG_BASE(wm_idx, pingpong_status)); } static long msm_vfe32_axi_halt(struct vfe_device *vfe_dev) static int msm_vfe32_axi_halt(struct vfe_device *vfe_dev, uint32_t blocking) { uint32_t halt_mask; uint32_t axi_busy_flag = true; Loading
drivers/media/platform/msm/camera_v2/isp/msm_isp40.c +113 −17 Original line number Diff line number Diff line Loading @@ -404,8 +404,10 @@ static void msm_vfe40_process_reset_irq(struct vfe_device *vfe_dev, static void msm_vfe40_process_halt_irq(struct vfe_device *vfe_dev, uint32_t irq_status0, uint32_t irq_status1) { if (irq_status1 & (1 << 8)) if (irq_status1 & (1 << 8)) { complete(&vfe_dev->halt_complete); msm_camera_io_w(0x0, vfe_dev->vfe_base + 0x2C0); } } static void msm_vfe40_process_camif_irq(struct vfe_device *vfe_dev, Loading Loading @@ -655,13 +657,30 @@ static void msm_vfe40_reg_update(struct vfe_device *vfe_dev) msm_camera_io_w_mb(0xF, vfe_dev->vfe_base + 0x378); } static long msm_vfe40_reset_hardware(struct vfe_device *vfe_dev) static long msm_vfe40_reset_hardware(struct vfe_device *vfe_dev, uint32_t first_start, uint32_t blocking_call) { long rc = 0; init_completion(&vfe_dev->reset_complete); if (first_start) { msm_camera_io_w_mb(0x1FF, vfe_dev->vfe_base + 0xC); return wait_for_completion_timeout( } else { msm_camera_io_w_mb(0x1EF, vfe_dev->vfe_base + 0xC); msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x30); msm_camera_io_w(0xFEFFFEFF, vfe_dev->vfe_base + 0x34); msm_camera_io_w(0x1, vfe_dev->vfe_base + 0x24); vfe_dev->hw_info->vfe_ops.axi_ops. reload_wm(vfe_dev, 0x0003FFFF); } if (blocking_call) { rc = wait_for_completion_interruptible_timeout( &vfe_dev->reset_complete, msecs_to_jiffies(50)); } return rc; } static void msm_vfe40_axi_reload_wm( struct vfe_device *vfe_dev, uint32_t reload_mask) Loading Loading @@ -953,19 +972,15 @@ static void msm_vfe40_update_camif_state(struct vfe_device *vfe_dev, val &= 0xFFFFFF3F; val = val | bus_en << 7 | vfe_en << 6; msm_camera_io_w(val, vfe_dev->vfe_base + 0x2F8); msm_camera_io_w_mb(0x4, 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; } else if (update_state == DISABLE_CAMIF) { msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x2F4); vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0; } else if (update_state == DISABLE_CAMIF_IMMEDIATELY) { vfe_dev->ignore_error = 1; msm_camera_io_w_mb(0x6, vfe_dev->vfe_base + 0x2F4); vfe_dev->hw_info->vfe_ops.axi_ops.halt(vfe_dev); vfe_dev->hw_info->vfe_ops.core_ops.reset_hw(vfe_dev); vfe_dev->hw_info->vfe_ops.core_ops.init_hw_reg(vfe_dev); vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0; vfe_dev->ignore_error = 0; } } Loading Loading @@ -1219,17 +1234,56 @@ static void msm_vfe40_update_ping_pong_addr( VFE40_PING_PONG_BASE(wm_idx, pingpong_status)); } static long msm_vfe40_axi_halt(struct vfe_device *vfe_dev) static int msm_vfe40_axi_halt(struct vfe_device *vfe_dev, uint32_t blocking) { uint32_t halt_mask; halt_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x2C); halt_mask |= (1 << 8); msm_camera_io_w_mb(halt_mask, vfe_dev->vfe_base + 0x2C); int rc = 0; /* Keep only halt and restart mask */ msm_camera_io_w(BIT(31), vfe_dev->vfe_base + 0x28); msm_camera_io_w(BIT(8), vfe_dev->vfe_base + 0x2C); /*Clear IRQ Status */ msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x30); msm_camera_io_w(0xFEFFFEFF, vfe_dev->vfe_base + 0x34); msm_camera_io_w(0x1, vfe_dev->vfe_base + 0x24); /* if any stream is waiting for update, signal complete */ if (vfe_dev->axi_data.stream_update) { pr_err("%s: calling complete on stream update\n", __func__); complete(&vfe_dev->stream_config_complete); } /* Halt AXI Bus Bridge */ init_completion(&vfe_dev->halt_complete); msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x2C0); return wait_for_completion_interruptible_timeout( if (blocking) { rc = wait_for_completion_interruptible_timeout( &vfe_dev->halt_complete, msecs_to_jiffies(500)); } return rc; } static int msm_vfe40_axi_restart(struct vfe_device *vfe_dev, uint32_t blocking, uint32_t enable_camif) { vfe_dev->hw_info->vfe_ops.core_ops.restore_irq_mask(vfe_dev); /* Clear IRQ Status */ msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x30); msm_camera_io_w(0xFEFFFEFF, vfe_dev->vfe_base + 0x34); msm_camera_io_w(0x1, vfe_dev->vfe_base + 0x24); /* Start AXI */ msm_camera_io_w(0x0, vfe_dev->vfe_base + 0x2C0); vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev); memset(&vfe_dev->error_info, 0, sizeof(vfe_dev->error_info)); atomic_set(&vfe_dev->error_info.overflow_state, NO_OVERFLOW); if (enable_camif) { vfe_dev->hw_info->vfe_ops.core_ops. update_camif_state(vfe_dev, ENABLE_CAMIF); } return 0; } static uint32_t msm_vfe40_get_wm_mask( uint32_t irq_status0, uint32_t irq_status1) Loading Loading @@ -1550,6 +1604,41 @@ static void msm_vfe40_get_error_mask( *error_mask1 = 0x00FFFEFF; } static void msm_vfe40_get_overflow_mask(uint32_t *overflow_mask) { *overflow_mask = 0x00FFFE7E; } static void msm_vfe40_get_rdi_wm_mask(struct vfe_device *vfe_dev, uint32_t *rdi_wm_mask) { *rdi_wm_mask = vfe_dev->axi_data.rdi_wm_mask; } static void msm_vfe40_get_irq_mask(struct vfe_device *vfe_dev, uint32_t *irq0_mask, uint32_t *irq1_mask) { *irq0_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x28); *irq1_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x2C); } 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, uint32_t *irq1_mask) { *irq0_mask = BIT(31); *irq1_mask = BIT(8); } static struct msm_vfe_axi_hardware_info msm_vfe40_axi_hw_info = { .num_wm = 7, .num_comp_mask = 3, Loading Loading @@ -1620,6 +1709,7 @@ struct msm_vfe_hardware_info vfe40_hw_info = { .get_wm_mask = msm_vfe40_get_wm_mask, .get_pingpong_status = msm_vfe40_get_pingpong_status, .halt = msm_vfe40_axi_halt, .restart = msm_vfe40_axi_restart, }, .core_ops = { .reg_update = msm_vfe40_reg_update, Loading @@ -1632,6 +1722,12 @@ struct msm_vfe_hardware_info vfe40_hw_info = { .release_hw = msm_vfe40_release_hardware, .get_platform_data = msm_vfe40_get_platform_data, .get_error_mask = msm_vfe40_get_error_mask, .get_overflow_mask = msm_vfe40_get_overflow_mask, .get_rdi_wm_mask = msm_vfe40_get_rdi_wm_mask, .get_irq_mask = msm_vfe40_get_irq_mask, .restore_irq_mask = msm_vfe40_restore_irq_mask, .get_halt_restart_mask = msm_vfe40_get_halt_restart_mask, .process_error_status = msm_vfe40_process_error_status, }, .stats_ops = { Loading