Loading drivers/media/platform/msm/camera_v2/isp/msm_isp.h +2 −0 Original line number Diff line number Diff line Loading @@ -244,6 +244,8 @@ struct msm_vfe_core_ops { int (*ahb_clk_cfg)(struct vfe_device *vfe_dev, struct msm_isp_ahb_clk_cfg *ahb_cfg); void (*set_halt_restart_mask)(struct vfe_device *vfe_dev); int (*start_fetch_eng_multi_pass)(struct vfe_device *vfe_dev, void *arg); }; struct msm_vfe_stats_ops { int (*get_stats_idx)(enum msm_isp_stats_type stats_type); Loading drivers/media/platform/msm/camera_v2/isp/msm_isp40.c +80 −2 Original line number Diff line number Diff line Loading @@ -1060,11 +1060,71 @@ static int msm_vfe40_start_fetch_engine(struct vfe_device *vfe_dev, return 0; } static int msm_vfe40_start_fetch_engine_multi_pass(struct vfe_device *vfe_dev, void *arg) { int rc = 0; uint32_t bufq_handle = 0; struct msm_isp_buffer *buf = NULL; struct msm_vfe_fetch_eng_multi_pass_start *fe_cfg = arg; struct msm_isp_buffer_mapped_info mapped_info; if (vfe_dev->fetch_engine_info.is_busy == 1) { pr_err("%s: fetch engine busy\n", __func__); return -EINVAL; } memset(&mapped_info, 0, sizeof(struct msm_isp_buffer_mapped_info)); /* There is other option of passing buffer address from user, in such case, driver needs to map the buffer and use it*/ vfe_dev->fetch_engine_info.session_id = fe_cfg->session_id; vfe_dev->fetch_engine_info.stream_id = fe_cfg->stream_id; vfe_dev->fetch_engine_info.offline_mode = fe_cfg->offline_mode; vfe_dev->fetch_engine_info.fd = fe_cfg->fd; if (!fe_cfg->offline_mode) { bufq_handle = vfe_dev->buf_mgr->ops->get_bufq_handle( vfe_dev->buf_mgr, fe_cfg->session_id, fe_cfg->stream_id); vfe_dev->fetch_engine_info.bufq_handle = bufq_handle; rc = vfe_dev->buf_mgr->ops->get_buf_by_index( vfe_dev->buf_mgr, bufq_handle, fe_cfg->buf_idx, &buf); if (rc < 0 || !buf) { pr_err("%s: No fetch buffer rc= %d buf= %p\n", __func__, rc, buf); return -EINVAL; } mapped_info = buf->mapped_info[0]; buf->state = MSM_ISP_BUFFER_STATE_DISPATCHED; } else { rc = vfe_dev->buf_mgr->ops->map_buf(vfe_dev->buf_mgr, &mapped_info, fe_cfg->fd); if (rc < 0) { pr_err("%s: can not map buffer\n", __func__); return -EINVAL; } } vfe_dev->fetch_engine_info.buf_idx = fe_cfg->buf_idx; vfe_dev->fetch_engine_info.is_busy = 1; msm_camera_io_w(mapped_info.paddr + fe_cfg->input_buf_offset, vfe_dev->vfe_base + 0x228); msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x378); msm_camera_io_w_mb(0x10000, vfe_dev->vfe_base + 0x4C); msm_camera_io_w_mb(0x20000, vfe_dev->vfe_base + 0x4C); ISP_DBG("%s:VFE%d Fetch Engine ready\n", __func__, vfe_dev->pdev->id); return 0; } static void msm_vfe40_cfg_fetch_engine(struct vfe_device *vfe_dev, struct msm_vfe_pix_cfg *pix_cfg) { uint32_t x_size_word; uint32_t temp = 0; uint32_t main_unpack_pattern = 0; struct msm_vfe_fetch_engine_cfg *fe_cfg = NULL; if (pix_cfg->input_mux != EXTERNAL_READ) { Loading Loading @@ -1097,10 +1157,14 @@ static void msm_vfe40_cfg_fetch_engine(struct vfe_device *vfe_dev, /* need to update to use formulae to calculate X_SIZE_WORD*/ x_size_word = msm_isp_cal_word_per_line( vfe_dev->axi_data.src_info[VFE_PIX_0].input_format, fe_cfg->fetch_width); fe_cfg->buf_width); msm_camera_io_w((x_size_word - 1) << 16, vfe_dev->vfe_base + 0x23C); x_size_word = msm_isp_cal_word_per_line( vfe_dev->axi_data.src_info[VFE_PIX_0].input_format, fe_cfg->fetch_width); temp = msm_camera_io_r(vfe_dev->vfe_base + 0x1C); temp |= 2 << 16 | pix_cfg->pixel_pattern; msm_camera_io_w(temp, vfe_dev->vfe_base + 0x1C); Loading @@ -1126,7 +1190,19 @@ static void msm_vfe40_cfg_fetch_engine(struct vfe_device *vfe_dev, } /* need to use formulae to calculate MAIN_UNPACK_PATTERN*/ msm_camera_io_w(0xF6543210, vfe_dev->vfe_base + 0x248); switch (vfe_dev->axi_data.src_info[VFE_PIX_0].input_format) { case V4L2_PIX_FMT_P16BGGR10: case V4L2_PIX_FMT_P16GBRG10: case V4L2_PIX_FMT_P16GRBG10: case V4L2_PIX_FMT_P16RGGB10: main_unpack_pattern = 0xB210; break; default: main_unpack_pattern = 0xF6543210; break; } msm_camera_io_w(main_unpack_pattern, vfe_dev->vfe_base + 0x248); msm_camera_io_w(0xF, vfe_dev->vfe_base + 0x264); return; Loading Loading @@ -2254,6 +2330,8 @@ struct msm_vfe_hardware_info vfe40_hw_info = { .ahb_clk_cfg = NULL, .set_halt_restart_mask = msm_vfe40_set_halt_restart_mask, .start_fetch_eng_multi_pass = msm_vfe40_start_fetch_engine_multi_pass, }, .stats_ops = { .get_stats_idx = msm_vfe40_get_stats_idx, Loading drivers/media/platform/msm/camera_v2/isp/msm_isp47.c +63 −1 Original line number Diff line number Diff line Loading @@ -1044,6 +1044,63 @@ int msm_vfe47_start_fetch_engine(struct vfe_device *vfe_dev, return 0; } int msm_vfe47_start_fetch_engine_multi_pass(struct vfe_device *vfe_dev, void *arg) { int rc = 0; uint32_t bufq_handle = 0; struct msm_isp_buffer *buf = NULL; struct msm_vfe_fetch_eng_multi_pass_start *fe_cfg = arg; struct msm_isp_buffer_mapped_info mapped_info; if (vfe_dev->fetch_engine_info.is_busy == 1) { pr_err("%s: fetch engine busy\n", __func__); return -EINVAL; } memset(&mapped_info, 0, sizeof(struct msm_isp_buffer_mapped_info)); vfe_dev->fetch_engine_info.session_id = fe_cfg->session_id; vfe_dev->fetch_engine_info.stream_id = fe_cfg->stream_id; vfe_dev->fetch_engine_info.offline_mode = fe_cfg->offline_mode; vfe_dev->fetch_engine_info.fd = fe_cfg->fd; if (!fe_cfg->offline_mode) { bufq_handle = vfe_dev->buf_mgr->ops->get_bufq_handle( vfe_dev->buf_mgr, fe_cfg->session_id, fe_cfg->stream_id); vfe_dev->fetch_engine_info.bufq_handle = bufq_handle; rc = vfe_dev->buf_mgr->ops->get_buf_by_index( vfe_dev->buf_mgr, bufq_handle, fe_cfg->buf_idx, &buf); if (rc < 0 || !buf) { pr_err("%s: No fetch buffer rc= %d buf= %pK\n", __func__, rc, buf); return -EINVAL; } mapped_info = buf->mapped_info[0]; buf->state = MSM_ISP_BUFFER_STATE_DISPATCHED; } else { rc = vfe_dev->buf_mgr->ops->map_buf(vfe_dev->buf_mgr, &mapped_info, fe_cfg->fd); if (rc < 0) { pr_err("%s: can not map buffer\n", __func__); return -EINVAL; } } vfe_dev->fetch_engine_info.buf_idx = fe_cfg->buf_idx; vfe_dev->fetch_engine_info.is_busy = 1; msm_camera_io_w(mapped_info.paddr + fe_cfg->input_buf_offset, vfe_dev->vfe_base + 0x2F4); msm_camera_io_w_mb(0x100000, vfe_dev->vfe_base + 0x80); msm_camera_io_w_mb(0x200000, vfe_dev->vfe_base + 0x80); ISP_DBG("%s:VFE%d Fetch Engine ready\n", __func__, vfe_dev->pdev->id); return 0; } void msm_vfe47_cfg_fetch_engine(struct vfe_device *vfe_dev, struct msm_vfe_pix_cfg *pix_cfg) { Loading Loading @@ -1075,10 +1132,13 @@ void msm_vfe47_cfg_fetch_engine(struct vfe_device *vfe_dev, x_size_word = msm_isp_cal_word_per_line( vfe_dev->axi_data.src_info[VFE_PIX_0].input_format, fe_cfg->fetch_width); fe_cfg->buf_width); msm_camera_io_w((x_size_word - 1) << 16, vfe_dev->vfe_base + 0x30c); x_size_word = msm_isp_cal_word_per_line( vfe_dev->axi_data.src_info[VFE_PIX_0].input_format, fe_cfg->fetch_width); msm_camera_io_w(x_size_word << 16 | (temp & 0x3FFF) << 2 | VFE47_FETCH_BURST_LEN, vfe_dev->vfe_base + 0x310); Loading Loading @@ -2677,6 +2737,8 @@ struct msm_vfe_hardware_info vfe47_hw_info = { .ahb_clk_cfg = msm_isp47_ahb_clk_cfg, .set_halt_restart_mask = msm_vfe47_set_halt_restart_mask, .start_fetch_eng_multi_pass = msm_vfe47_start_fetch_engine_multi_pass, }, .stats_ops = { .get_stats_idx = msm_vfe47_get_stats_idx, Loading drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +99 −3 Original line number Diff line number Diff line Loading @@ -1658,6 +1658,82 @@ static struct msm_isp_buffer *msm_isp_get_stream_buffer( return buf; } int msm_isp_cfg_offline_ping_pong_address(struct vfe_device *vfe_dev, struct msm_vfe_axi_stream *stream_info, uint32_t pingpong_status, uint32_t buf_idx) { int i, rc = 0; struct msm_isp_buffer *buf = NULL; uint32_t pingpong_bit; uint32_t stream_idx = HANDLE_TO_IDX(stream_info->stream_handle); uint32_t buffer_size_byte = 0; int32_t word_per_line = 0; dma_addr_t paddr; uint32_t bufq_handle = 0; if (stream_idx >= VFE_AXI_SRC_MAX) { pr_err("%s: Invalid stream_idx", __func__); return -EINVAL; } bufq_handle = stream_info->bufq_handle[VFE_BUF_QUEUE_DEFAULT]; if (!vfe_dev->is_split) { rc = vfe_dev->buf_mgr->ops->get_buf_by_index( vfe_dev->buf_mgr, bufq_handle, buf_idx, &buf); if (rc < 0 || !buf) { pr_err("%s: No fetch buffer rc= %d buf= %p\n", __func__, rc, buf); return -EINVAL; } if (buf->num_planes != stream_info->num_planes) { pr_err("%s: Invalid buffer\n", __func__); vfe_dev->buf_mgr->ops->put_buf(vfe_dev->buf_mgr, bufq_handle, buf->buf_idx); return -EINVAL; } pingpong_bit = ((pingpong_status >> stream_info->wm[0]) & 0x1); for (i = 0; i < stream_info->num_planes; i++) { word_per_line = msm_isp_cal_word_per_line( stream_info->output_format, stream_info->plane_cfg[i]. output_stride); if (word_per_line < 0) { /* 0 means no prefetch*/ word_per_line = 0; buffer_size_byte = 0; } else { buffer_size_byte = (word_per_line * 8 * stream_info->plane_cfg[i]. output_scan_lines) - stream_info-> plane_cfg[i].plane_addr_offset; } paddr = buf->mapped_info[i].paddr; vfe_dev->hw_info->vfe_ops.axi_ops. update_ping_pong_addr( vfe_dev->vfe_base, stream_info->wm[i], pingpong_bit, paddr + stream_info-> plane_cfg[i].plane_addr_offset, buffer_size_byte); if (0 == i) { stream_info->buf[!pingpong_bit] = buf; buf->pingpong_bit = !pingpong_bit; } buf->state = MSM_ISP_BUFFER_STATE_DEQUEUED; } } return rc; } static int msm_isp_cfg_ping_pong_address(struct vfe_device *vfe_dev, struct msm_vfe_axi_stream *stream_info, uint32_t pingpong_status, int scratch) Loading Loading @@ -1915,6 +1991,11 @@ static int msm_isp_process_done_buf(struct vfe_device *vfe_dev, buf_event.u.buf_done.buf_idx = buf->buf_idx; buf_event.u.buf_done.output_format = stream_info->runtime_output_format; if (vfe_dev->fetch_engine_info.is_busy && SRC_TO_INTF(stream_info->stream_src) == VFE_PIX_0) { vfe_dev->fetch_engine_info.is_busy = 0; } if (stream_info->buf_divert && buf_src != MSM_ISP_BUFFER_SRC_SCRATCH) { Loading Loading @@ -2768,7 +2849,6 @@ static int msm_isp_stop_axi_stream(struct vfe_device *vfe_dev, } stream_info = &axi_data->stream_info[ HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])]; /* set ping pong address to scratch before stream stop */ spin_lock_irqsave(&stream_info->lock, flags); msm_isp_cfg_stream_scratch(vfe_dev, stream_info, VFE_PING_FLAG); Loading Loading @@ -3148,7 +3228,6 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev, stream_cfg_cmd.frame_skip_pattern = NO_SKIP; stream_cfg_cmd.init_frame_drop = 0; stream_cfg_cmd.burst_count = stream_info->request_q_cnt; if (stream_info->undelivered_request_cnt == 1) { rc = msm_isp_cfg_ping_pong_address(vfe_dev, stream_info, VFE_PING_FLAG, 0); Loading Loading @@ -3518,6 +3597,24 @@ int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg) } break; } case UPDATE_STREAM_OFFLINE_AXI_CONFIG: { for (i = 0; i < update_cmd->num_streams; i++) { update_info = (struct msm_vfe_axi_stream_cfg_update_info *) &update_cmd->update_info[i]; stream_info = &axi_data->stream_info[HANDLE_TO_IDX( update_info->stream_handle)]; for (j = 0; j < stream_info->num_planes; j++) { stream_info->plane_cfg[j] = update_info->plane_cfg[j]; } for (j = 0; j < stream_info->num_planes; j++) { vfe_dev->hw_info->vfe_ops.axi_ops. cfg_wm_reg(vfe_dev, stream_info, j); } } break; } default: pr_err("%s: Invalid update type\n", __func__); return -EINVAL; Loading Loading @@ -3735,7 +3832,6 @@ void msm_isp_process_axi_irq(struct vfe_device *vfe_dev, } stream_idx = HANDLE_TO_IDX(comp_info->stream_handle); stream_info = &axi_data->stream_info[stream_idx]; msm_isp_process_axi_irq_stream(vfe_dev, stream_info, pingpong_status, ts); Loading drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h +3 −0 Original line number Diff line number Diff line Loading @@ -117,4 +117,7 @@ static inline void msm_isp_cfg_stream_scratch(struct vfe_device *vfe_dev, stream_info->buf[pingpong_bit] = NULL; } int msm_isp_cfg_offline_ping_pong_address(struct vfe_device *vfe_dev, struct msm_vfe_axi_stream *stream_info, uint32_t pingpong_status, uint32_t buf_idx); #endif /* __MSM_ISP_AXI_UTIL_H__ */ Loading
drivers/media/platform/msm/camera_v2/isp/msm_isp.h +2 −0 Original line number Diff line number Diff line Loading @@ -244,6 +244,8 @@ struct msm_vfe_core_ops { int (*ahb_clk_cfg)(struct vfe_device *vfe_dev, struct msm_isp_ahb_clk_cfg *ahb_cfg); void (*set_halt_restart_mask)(struct vfe_device *vfe_dev); int (*start_fetch_eng_multi_pass)(struct vfe_device *vfe_dev, void *arg); }; struct msm_vfe_stats_ops { int (*get_stats_idx)(enum msm_isp_stats_type stats_type); Loading
drivers/media/platform/msm/camera_v2/isp/msm_isp40.c +80 −2 Original line number Diff line number Diff line Loading @@ -1060,11 +1060,71 @@ static int msm_vfe40_start_fetch_engine(struct vfe_device *vfe_dev, return 0; } static int msm_vfe40_start_fetch_engine_multi_pass(struct vfe_device *vfe_dev, void *arg) { int rc = 0; uint32_t bufq_handle = 0; struct msm_isp_buffer *buf = NULL; struct msm_vfe_fetch_eng_multi_pass_start *fe_cfg = arg; struct msm_isp_buffer_mapped_info mapped_info; if (vfe_dev->fetch_engine_info.is_busy == 1) { pr_err("%s: fetch engine busy\n", __func__); return -EINVAL; } memset(&mapped_info, 0, sizeof(struct msm_isp_buffer_mapped_info)); /* There is other option of passing buffer address from user, in such case, driver needs to map the buffer and use it*/ vfe_dev->fetch_engine_info.session_id = fe_cfg->session_id; vfe_dev->fetch_engine_info.stream_id = fe_cfg->stream_id; vfe_dev->fetch_engine_info.offline_mode = fe_cfg->offline_mode; vfe_dev->fetch_engine_info.fd = fe_cfg->fd; if (!fe_cfg->offline_mode) { bufq_handle = vfe_dev->buf_mgr->ops->get_bufq_handle( vfe_dev->buf_mgr, fe_cfg->session_id, fe_cfg->stream_id); vfe_dev->fetch_engine_info.bufq_handle = bufq_handle; rc = vfe_dev->buf_mgr->ops->get_buf_by_index( vfe_dev->buf_mgr, bufq_handle, fe_cfg->buf_idx, &buf); if (rc < 0 || !buf) { pr_err("%s: No fetch buffer rc= %d buf= %p\n", __func__, rc, buf); return -EINVAL; } mapped_info = buf->mapped_info[0]; buf->state = MSM_ISP_BUFFER_STATE_DISPATCHED; } else { rc = vfe_dev->buf_mgr->ops->map_buf(vfe_dev->buf_mgr, &mapped_info, fe_cfg->fd); if (rc < 0) { pr_err("%s: can not map buffer\n", __func__); return -EINVAL; } } vfe_dev->fetch_engine_info.buf_idx = fe_cfg->buf_idx; vfe_dev->fetch_engine_info.is_busy = 1; msm_camera_io_w(mapped_info.paddr + fe_cfg->input_buf_offset, vfe_dev->vfe_base + 0x228); msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x378); msm_camera_io_w_mb(0x10000, vfe_dev->vfe_base + 0x4C); msm_camera_io_w_mb(0x20000, vfe_dev->vfe_base + 0x4C); ISP_DBG("%s:VFE%d Fetch Engine ready\n", __func__, vfe_dev->pdev->id); return 0; } static void msm_vfe40_cfg_fetch_engine(struct vfe_device *vfe_dev, struct msm_vfe_pix_cfg *pix_cfg) { uint32_t x_size_word; uint32_t temp = 0; uint32_t main_unpack_pattern = 0; struct msm_vfe_fetch_engine_cfg *fe_cfg = NULL; if (pix_cfg->input_mux != EXTERNAL_READ) { Loading Loading @@ -1097,10 +1157,14 @@ static void msm_vfe40_cfg_fetch_engine(struct vfe_device *vfe_dev, /* need to update to use formulae to calculate X_SIZE_WORD*/ x_size_word = msm_isp_cal_word_per_line( vfe_dev->axi_data.src_info[VFE_PIX_0].input_format, fe_cfg->fetch_width); fe_cfg->buf_width); msm_camera_io_w((x_size_word - 1) << 16, vfe_dev->vfe_base + 0x23C); x_size_word = msm_isp_cal_word_per_line( vfe_dev->axi_data.src_info[VFE_PIX_0].input_format, fe_cfg->fetch_width); temp = msm_camera_io_r(vfe_dev->vfe_base + 0x1C); temp |= 2 << 16 | pix_cfg->pixel_pattern; msm_camera_io_w(temp, vfe_dev->vfe_base + 0x1C); Loading @@ -1126,7 +1190,19 @@ static void msm_vfe40_cfg_fetch_engine(struct vfe_device *vfe_dev, } /* need to use formulae to calculate MAIN_UNPACK_PATTERN*/ msm_camera_io_w(0xF6543210, vfe_dev->vfe_base + 0x248); switch (vfe_dev->axi_data.src_info[VFE_PIX_0].input_format) { case V4L2_PIX_FMT_P16BGGR10: case V4L2_PIX_FMT_P16GBRG10: case V4L2_PIX_FMT_P16GRBG10: case V4L2_PIX_FMT_P16RGGB10: main_unpack_pattern = 0xB210; break; default: main_unpack_pattern = 0xF6543210; break; } msm_camera_io_w(main_unpack_pattern, vfe_dev->vfe_base + 0x248); msm_camera_io_w(0xF, vfe_dev->vfe_base + 0x264); return; Loading Loading @@ -2254,6 +2330,8 @@ struct msm_vfe_hardware_info vfe40_hw_info = { .ahb_clk_cfg = NULL, .set_halt_restart_mask = msm_vfe40_set_halt_restart_mask, .start_fetch_eng_multi_pass = msm_vfe40_start_fetch_engine_multi_pass, }, .stats_ops = { .get_stats_idx = msm_vfe40_get_stats_idx, Loading
drivers/media/platform/msm/camera_v2/isp/msm_isp47.c +63 −1 Original line number Diff line number Diff line Loading @@ -1044,6 +1044,63 @@ int msm_vfe47_start_fetch_engine(struct vfe_device *vfe_dev, return 0; } int msm_vfe47_start_fetch_engine_multi_pass(struct vfe_device *vfe_dev, void *arg) { int rc = 0; uint32_t bufq_handle = 0; struct msm_isp_buffer *buf = NULL; struct msm_vfe_fetch_eng_multi_pass_start *fe_cfg = arg; struct msm_isp_buffer_mapped_info mapped_info; if (vfe_dev->fetch_engine_info.is_busy == 1) { pr_err("%s: fetch engine busy\n", __func__); return -EINVAL; } memset(&mapped_info, 0, sizeof(struct msm_isp_buffer_mapped_info)); vfe_dev->fetch_engine_info.session_id = fe_cfg->session_id; vfe_dev->fetch_engine_info.stream_id = fe_cfg->stream_id; vfe_dev->fetch_engine_info.offline_mode = fe_cfg->offline_mode; vfe_dev->fetch_engine_info.fd = fe_cfg->fd; if (!fe_cfg->offline_mode) { bufq_handle = vfe_dev->buf_mgr->ops->get_bufq_handle( vfe_dev->buf_mgr, fe_cfg->session_id, fe_cfg->stream_id); vfe_dev->fetch_engine_info.bufq_handle = bufq_handle; rc = vfe_dev->buf_mgr->ops->get_buf_by_index( vfe_dev->buf_mgr, bufq_handle, fe_cfg->buf_idx, &buf); if (rc < 0 || !buf) { pr_err("%s: No fetch buffer rc= %d buf= %pK\n", __func__, rc, buf); return -EINVAL; } mapped_info = buf->mapped_info[0]; buf->state = MSM_ISP_BUFFER_STATE_DISPATCHED; } else { rc = vfe_dev->buf_mgr->ops->map_buf(vfe_dev->buf_mgr, &mapped_info, fe_cfg->fd); if (rc < 0) { pr_err("%s: can not map buffer\n", __func__); return -EINVAL; } } vfe_dev->fetch_engine_info.buf_idx = fe_cfg->buf_idx; vfe_dev->fetch_engine_info.is_busy = 1; msm_camera_io_w(mapped_info.paddr + fe_cfg->input_buf_offset, vfe_dev->vfe_base + 0x2F4); msm_camera_io_w_mb(0x100000, vfe_dev->vfe_base + 0x80); msm_camera_io_w_mb(0x200000, vfe_dev->vfe_base + 0x80); ISP_DBG("%s:VFE%d Fetch Engine ready\n", __func__, vfe_dev->pdev->id); return 0; } void msm_vfe47_cfg_fetch_engine(struct vfe_device *vfe_dev, struct msm_vfe_pix_cfg *pix_cfg) { Loading Loading @@ -1075,10 +1132,13 @@ void msm_vfe47_cfg_fetch_engine(struct vfe_device *vfe_dev, x_size_word = msm_isp_cal_word_per_line( vfe_dev->axi_data.src_info[VFE_PIX_0].input_format, fe_cfg->fetch_width); fe_cfg->buf_width); msm_camera_io_w((x_size_word - 1) << 16, vfe_dev->vfe_base + 0x30c); x_size_word = msm_isp_cal_word_per_line( vfe_dev->axi_data.src_info[VFE_PIX_0].input_format, fe_cfg->fetch_width); msm_camera_io_w(x_size_word << 16 | (temp & 0x3FFF) << 2 | VFE47_FETCH_BURST_LEN, vfe_dev->vfe_base + 0x310); Loading Loading @@ -2677,6 +2737,8 @@ struct msm_vfe_hardware_info vfe47_hw_info = { .ahb_clk_cfg = msm_isp47_ahb_clk_cfg, .set_halt_restart_mask = msm_vfe47_set_halt_restart_mask, .start_fetch_eng_multi_pass = msm_vfe47_start_fetch_engine_multi_pass, }, .stats_ops = { .get_stats_idx = msm_vfe47_get_stats_idx, Loading
drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +99 −3 Original line number Diff line number Diff line Loading @@ -1658,6 +1658,82 @@ static struct msm_isp_buffer *msm_isp_get_stream_buffer( return buf; } int msm_isp_cfg_offline_ping_pong_address(struct vfe_device *vfe_dev, struct msm_vfe_axi_stream *stream_info, uint32_t pingpong_status, uint32_t buf_idx) { int i, rc = 0; struct msm_isp_buffer *buf = NULL; uint32_t pingpong_bit; uint32_t stream_idx = HANDLE_TO_IDX(stream_info->stream_handle); uint32_t buffer_size_byte = 0; int32_t word_per_line = 0; dma_addr_t paddr; uint32_t bufq_handle = 0; if (stream_idx >= VFE_AXI_SRC_MAX) { pr_err("%s: Invalid stream_idx", __func__); return -EINVAL; } bufq_handle = stream_info->bufq_handle[VFE_BUF_QUEUE_DEFAULT]; if (!vfe_dev->is_split) { rc = vfe_dev->buf_mgr->ops->get_buf_by_index( vfe_dev->buf_mgr, bufq_handle, buf_idx, &buf); if (rc < 0 || !buf) { pr_err("%s: No fetch buffer rc= %d buf= %p\n", __func__, rc, buf); return -EINVAL; } if (buf->num_planes != stream_info->num_planes) { pr_err("%s: Invalid buffer\n", __func__); vfe_dev->buf_mgr->ops->put_buf(vfe_dev->buf_mgr, bufq_handle, buf->buf_idx); return -EINVAL; } pingpong_bit = ((pingpong_status >> stream_info->wm[0]) & 0x1); for (i = 0; i < stream_info->num_planes; i++) { word_per_line = msm_isp_cal_word_per_line( stream_info->output_format, stream_info->plane_cfg[i]. output_stride); if (word_per_line < 0) { /* 0 means no prefetch*/ word_per_line = 0; buffer_size_byte = 0; } else { buffer_size_byte = (word_per_line * 8 * stream_info->plane_cfg[i]. output_scan_lines) - stream_info-> plane_cfg[i].plane_addr_offset; } paddr = buf->mapped_info[i].paddr; vfe_dev->hw_info->vfe_ops.axi_ops. update_ping_pong_addr( vfe_dev->vfe_base, stream_info->wm[i], pingpong_bit, paddr + stream_info-> plane_cfg[i].plane_addr_offset, buffer_size_byte); if (0 == i) { stream_info->buf[!pingpong_bit] = buf; buf->pingpong_bit = !pingpong_bit; } buf->state = MSM_ISP_BUFFER_STATE_DEQUEUED; } } return rc; } static int msm_isp_cfg_ping_pong_address(struct vfe_device *vfe_dev, struct msm_vfe_axi_stream *stream_info, uint32_t pingpong_status, int scratch) Loading Loading @@ -1915,6 +1991,11 @@ static int msm_isp_process_done_buf(struct vfe_device *vfe_dev, buf_event.u.buf_done.buf_idx = buf->buf_idx; buf_event.u.buf_done.output_format = stream_info->runtime_output_format; if (vfe_dev->fetch_engine_info.is_busy && SRC_TO_INTF(stream_info->stream_src) == VFE_PIX_0) { vfe_dev->fetch_engine_info.is_busy = 0; } if (stream_info->buf_divert && buf_src != MSM_ISP_BUFFER_SRC_SCRATCH) { Loading Loading @@ -2768,7 +2849,6 @@ static int msm_isp_stop_axi_stream(struct vfe_device *vfe_dev, } stream_info = &axi_data->stream_info[ HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])]; /* set ping pong address to scratch before stream stop */ spin_lock_irqsave(&stream_info->lock, flags); msm_isp_cfg_stream_scratch(vfe_dev, stream_info, VFE_PING_FLAG); Loading Loading @@ -3148,7 +3228,6 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev, stream_cfg_cmd.frame_skip_pattern = NO_SKIP; stream_cfg_cmd.init_frame_drop = 0; stream_cfg_cmd.burst_count = stream_info->request_q_cnt; if (stream_info->undelivered_request_cnt == 1) { rc = msm_isp_cfg_ping_pong_address(vfe_dev, stream_info, VFE_PING_FLAG, 0); Loading Loading @@ -3518,6 +3597,24 @@ int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg) } break; } case UPDATE_STREAM_OFFLINE_AXI_CONFIG: { for (i = 0; i < update_cmd->num_streams; i++) { update_info = (struct msm_vfe_axi_stream_cfg_update_info *) &update_cmd->update_info[i]; stream_info = &axi_data->stream_info[HANDLE_TO_IDX( update_info->stream_handle)]; for (j = 0; j < stream_info->num_planes; j++) { stream_info->plane_cfg[j] = update_info->plane_cfg[j]; } for (j = 0; j < stream_info->num_planes; j++) { vfe_dev->hw_info->vfe_ops.axi_ops. cfg_wm_reg(vfe_dev, stream_info, j); } } break; } default: pr_err("%s: Invalid update type\n", __func__); return -EINVAL; Loading Loading @@ -3735,7 +3832,6 @@ void msm_isp_process_axi_irq(struct vfe_device *vfe_dev, } stream_idx = HANDLE_TO_IDX(comp_info->stream_handle); stream_info = &axi_data->stream_info[stream_idx]; msm_isp_process_axi_irq_stream(vfe_dev, stream_info, pingpong_status, ts); Loading
drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h +3 −0 Original line number Diff line number Diff line Loading @@ -117,4 +117,7 @@ static inline void msm_isp_cfg_stream_scratch(struct vfe_device *vfe_dev, stream_info->buf[pingpong_bit] = NULL; } int msm_isp_cfg_offline_ping_pong_address(struct vfe_device *vfe_dev, struct msm_vfe_axi_stream *stream_info, uint32_t pingpong_status, uint32_t buf_idx); #endif /* __MSM_ISP_AXI_UTIL_H__ */