Loading drivers/media/platform/msm/camera_v2/isp/msm_isp.h +11 −1 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <linux/io.h> #include <linux/list.h> #include <linux/delay.h> #include <linux/avtimer.h> #include <media/v4l2-subdev.h> #include <media/msmb_isp.h> #include <mach/msm_bus.h> Loading @@ -35,6 +36,10 @@ #define MAX_INIT_FRAME_DROP 31 #define ISP_Q2 (1 << 2) #define AVTIMER_MSW_PHY_ADDR 0xFE05300C #define AVTIMER_LSW_PHY_ADDR 0xFE053008 #define AVTIMER_ITERATION_CTR 16 #define VFE_PING_FLAG 0xFFFFFFFF #define VFE_PONG_FLAG 0x0 Loading Loading @@ -69,6 +74,8 @@ enum msm_isp_camif_update_state { struct msm_isp_timestamp { /*Monotonic clock for v4l2 buffer*/ struct timeval buf_time; /*Monotonic clock for VT */ struct timeval vt_time; /*Wall clock for userspace event*/ struct timeval event_time; }; Loading Loading @@ -264,7 +271,7 @@ struct msm_vfe_axi_stream { uint32_t stream_handle; uint8_t buf_divert; enum msm_vfe_axi_stream_type stream_type; uint32_t vt_enable; uint32_t frame_based; uint32_t framedrop_period; uint32_t framedrop_pattern; Loading Loading @@ -437,6 +444,9 @@ struct vfe_device { int dump_reg; int vfe_clk_idx; uint32_t vfe_open_cnt; uint8_t vt_enable; void __iomem *p_avtimer_msw; void __iomem *p_avtimer_lsw; }; #endif drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +29 −4 Original line number Diff line number Diff line Loading @@ -485,6 +485,19 @@ void msm_isp_calculate_bandwidth( } } #ifdef CONFIG_MSM_AVTIMER void msm_isp_start_avtimer(void) { avcs_core_open(); avcs_core_disable_power_collapse(1); } #else void msm_isp_start_avtimer(void) { pr_err("AV Timer is not supported\n"); } #endif int msm_isp_request_axi_stream(struct vfe_device *vfe_dev, void *arg) { int rc = 0, i; Loading Loading @@ -528,7 +541,13 @@ int msm_isp_request_axi_stream(struct vfe_device *vfe_dev, void *arg) } msm_isp_calculate_framedrop(&vfe_dev->axi_data, stream_cfg_cmd); stream_info->vt_enable = stream_cfg_cmd->vt_enable; if (stream_info->vt_enable) { vfe_dev->vt_enable = stream_info->vt_enable; msm_isp_start_avtimer(); vfe_dev->p_avtimer_lsw = ioremap(AVTIMER_LSW_PHY_ADDR, 4); vfe_dev->p_avtimer_msw = ioremap(AVTIMER_MSW_PHY_ADDR, 4); } if (stream_info->num_planes > 1) { msm_isp_axi_reserve_comp_mask( &vfe_dev->axi_data, stream_info); Loading Loading @@ -787,16 +806,22 @@ static void msm_isp_process_done_buf(struct vfe_device *vfe_dev, { int rc; struct msm_isp_event_data buf_event; struct timeval *time_stamp; uint32_t stream_idx = HANDLE_TO_IDX(stream_info->stream_handle); uint32_t frame_id = vfe_dev->axi_data. src_info[SRC_TO_INTF(stream_info->stream_src)].frame_id; memset(&buf_event, 0, sizeof(buf_event)); if (buf && ts) { if (vfe_dev->vt_enable) { time_stamp = &ts->vt_time; } else { time_stamp = &ts->buf_time; } if (stream_info->buf_divert) { rc = vfe_dev->buf_mgr->ops->buf_divert(vfe_dev->buf_mgr, buf->bufq_handle, buf->buf_idx, &ts->buf_time, frame_id); time_stamp, frame_id); /* Buf divert return value represent whether the buf * can be diverted. A positive return value means * other ISP hardware is still processing the frame. Loading @@ -805,7 +830,7 @@ static void msm_isp_process_done_buf(struct vfe_device *vfe_dev, buf_event.input_intf = SRC_TO_INTF(stream_info->stream_src); buf_event.frame_id = frame_id; buf_event.timestamp = ts->buf_time; buf_event.timestamp = *time_stamp; buf_event.u.buf_done.session_id = stream_info->session_id; buf_event.u.buf_done.stream_id = Loading Loading @@ -834,7 +859,7 @@ static void msm_isp_process_done_buf(struct vfe_device *vfe_dev, ISP_EVENT_BUF_DONE, &buf_event); vfe_dev->buf_mgr->ops->buf_done(vfe_dev->buf_mgr, buf->bufq_handle, buf->buf_idx, &ts->buf_time, frame_id, time_stamp, frame_id, stream_info->runtime_output_format); } } Loading drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c +47 −0 Original line number Diff line number Diff line Loading @@ -193,6 +193,30 @@ static inline void msm_isp_get_timestamp(struct msm_isp_timestamp *time_stamp) do_gettimeofday(&(time_stamp->event_time)); } static inline void msm_isp_get_vt_tstamp(struct vfe_device *vfe_dev, struct msm_isp_timestamp *time_stamp) { uint32_t avtimer_msw_1st = 0, avtimer_lsw = 0; uint32_t avtimer_msw_2nd = 0; uint8_t iter = 0; if (!vfe_dev->p_avtimer_msw || !vfe_dev->p_avtimer_lsw) { pr_err("%s: ioremap failed\n", __func__); return; } do { avtimer_msw_1st = msm_camera_io_r(vfe_dev->p_avtimer_msw); avtimer_lsw = msm_camera_io_r(vfe_dev->p_avtimer_lsw); avtimer_msw_2nd = msm_camera_io_r(vfe_dev->p_avtimer_msw); } while ((avtimer_msw_1st != avtimer_msw_2nd) && (iter++ < AVTIMER_ITERATION_CTR)); if (iter >= AVTIMER_ITERATION_CTR) { pr_err("%s: AVTimer MSW TS did not converge !!!\n", __func__); return; } time_stamp->vt_time.tv_sec = avtimer_msw_1st; time_stamp->vt_time.tv_usec = avtimer_lsw; } int msm_isp_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, struct v4l2_event_subscription *sub) { Loading Loading @@ -885,6 +909,8 @@ irqreturn_t msm_isp_process_irq(int irq_num, void *data) queue_cmd->vfeInterruptStatus0 = irq_status0; queue_cmd->vfeInterruptStatus1 = irq_status1; msm_isp_get_timestamp(&queue_cmd->ts); if (vfe_dev->vt_enable) msm_isp_get_vt_tstamp(vfe_dev, &queue_cmd->ts); queue_cmd->cmd_used = 1; vfe_dev->taskletq_idx = (vfe_dev->taskletq_idx + 1) % MSM_VFE_TASKLETQ_SIZE; Loading Loading @@ -998,11 +1024,26 @@ int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) vfe_dev->axi_data.hw_info = vfe_dev->hw_info->axi_hw_info; vfe_dev->vfe_open_cnt++; vfe_dev->taskletq_idx = 0; vfe_dev->vt_enable = 0; vfe_dev->p_avtimer_lsw = NULL; vfe_dev->p_avtimer_msw = NULL; mutex_unlock(&vfe_dev->core_mutex); mutex_unlock(&vfe_dev->realtime_mutex); return 0; } #ifdef CONFIG_MSM_AVTIMER void msm_isp_end_avtimer(void) { avcs_core_disable_power_collapse(0); } #else void msm_isp_end_avtimer(void) { pr_err("AV Timer is not supported\n"); } #endif int msm_isp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { long rc; Loading @@ -1024,6 +1065,12 @@ int msm_isp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) vfe_dev->buf_mgr->ops->buf_mgr_deinit(vfe_dev->buf_mgr); vfe_dev->hw_info->vfe_ops.core_ops.release_hw(vfe_dev); vfe_dev->vfe_open_cnt--; if (vfe_dev->vt_enable) { iounmap(vfe_dev->p_avtimer_lsw); iounmap(vfe_dev->p_avtimer_msw); msm_isp_end_avtimer(); vfe_dev->vt_enable = 0; } mutex_unlock(&vfe_dev->core_mutex); mutex_unlock(&vfe_dev->realtime_mutex); return 0; Loading include/media/msmb_isp.h +1 −0 Original line number Diff line number Diff line Loading @@ -130,6 +130,7 @@ struct msm_vfe_axi_plane_cfg { struct msm_vfe_axi_stream_request_cmd { uint32_t session_id; uint32_t stream_id; uint32_t vt_enable; uint32_t output_format;/*Planar/RAW/Misc*/ enum msm_vfe_axi_stream_src stream_src; /*CAMIF/IDEAL/RDIs*/ struct msm_vfe_axi_plane_cfg plane_cfg[MAX_PLANES_PER_STREAM]; Loading Loading
drivers/media/platform/msm/camera_v2/isp/msm_isp.h +11 −1 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <linux/io.h> #include <linux/list.h> #include <linux/delay.h> #include <linux/avtimer.h> #include <media/v4l2-subdev.h> #include <media/msmb_isp.h> #include <mach/msm_bus.h> Loading @@ -35,6 +36,10 @@ #define MAX_INIT_FRAME_DROP 31 #define ISP_Q2 (1 << 2) #define AVTIMER_MSW_PHY_ADDR 0xFE05300C #define AVTIMER_LSW_PHY_ADDR 0xFE053008 #define AVTIMER_ITERATION_CTR 16 #define VFE_PING_FLAG 0xFFFFFFFF #define VFE_PONG_FLAG 0x0 Loading Loading @@ -69,6 +74,8 @@ enum msm_isp_camif_update_state { struct msm_isp_timestamp { /*Monotonic clock for v4l2 buffer*/ struct timeval buf_time; /*Monotonic clock for VT */ struct timeval vt_time; /*Wall clock for userspace event*/ struct timeval event_time; }; Loading Loading @@ -264,7 +271,7 @@ struct msm_vfe_axi_stream { uint32_t stream_handle; uint8_t buf_divert; enum msm_vfe_axi_stream_type stream_type; uint32_t vt_enable; uint32_t frame_based; uint32_t framedrop_period; uint32_t framedrop_pattern; Loading Loading @@ -437,6 +444,9 @@ struct vfe_device { int dump_reg; int vfe_clk_idx; uint32_t vfe_open_cnt; uint8_t vt_enable; void __iomem *p_avtimer_msw; void __iomem *p_avtimer_lsw; }; #endif
drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +29 −4 Original line number Diff line number Diff line Loading @@ -485,6 +485,19 @@ void msm_isp_calculate_bandwidth( } } #ifdef CONFIG_MSM_AVTIMER void msm_isp_start_avtimer(void) { avcs_core_open(); avcs_core_disable_power_collapse(1); } #else void msm_isp_start_avtimer(void) { pr_err("AV Timer is not supported\n"); } #endif int msm_isp_request_axi_stream(struct vfe_device *vfe_dev, void *arg) { int rc = 0, i; Loading Loading @@ -528,7 +541,13 @@ int msm_isp_request_axi_stream(struct vfe_device *vfe_dev, void *arg) } msm_isp_calculate_framedrop(&vfe_dev->axi_data, stream_cfg_cmd); stream_info->vt_enable = stream_cfg_cmd->vt_enable; if (stream_info->vt_enable) { vfe_dev->vt_enable = stream_info->vt_enable; msm_isp_start_avtimer(); vfe_dev->p_avtimer_lsw = ioremap(AVTIMER_LSW_PHY_ADDR, 4); vfe_dev->p_avtimer_msw = ioremap(AVTIMER_MSW_PHY_ADDR, 4); } if (stream_info->num_planes > 1) { msm_isp_axi_reserve_comp_mask( &vfe_dev->axi_data, stream_info); Loading Loading @@ -787,16 +806,22 @@ static void msm_isp_process_done_buf(struct vfe_device *vfe_dev, { int rc; struct msm_isp_event_data buf_event; struct timeval *time_stamp; uint32_t stream_idx = HANDLE_TO_IDX(stream_info->stream_handle); uint32_t frame_id = vfe_dev->axi_data. src_info[SRC_TO_INTF(stream_info->stream_src)].frame_id; memset(&buf_event, 0, sizeof(buf_event)); if (buf && ts) { if (vfe_dev->vt_enable) { time_stamp = &ts->vt_time; } else { time_stamp = &ts->buf_time; } if (stream_info->buf_divert) { rc = vfe_dev->buf_mgr->ops->buf_divert(vfe_dev->buf_mgr, buf->bufq_handle, buf->buf_idx, &ts->buf_time, frame_id); time_stamp, frame_id); /* Buf divert return value represent whether the buf * can be diverted. A positive return value means * other ISP hardware is still processing the frame. Loading @@ -805,7 +830,7 @@ static void msm_isp_process_done_buf(struct vfe_device *vfe_dev, buf_event.input_intf = SRC_TO_INTF(stream_info->stream_src); buf_event.frame_id = frame_id; buf_event.timestamp = ts->buf_time; buf_event.timestamp = *time_stamp; buf_event.u.buf_done.session_id = stream_info->session_id; buf_event.u.buf_done.stream_id = Loading Loading @@ -834,7 +859,7 @@ static void msm_isp_process_done_buf(struct vfe_device *vfe_dev, ISP_EVENT_BUF_DONE, &buf_event); vfe_dev->buf_mgr->ops->buf_done(vfe_dev->buf_mgr, buf->bufq_handle, buf->buf_idx, &ts->buf_time, frame_id, time_stamp, frame_id, stream_info->runtime_output_format); } } Loading
drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c +47 −0 Original line number Diff line number Diff line Loading @@ -193,6 +193,30 @@ static inline void msm_isp_get_timestamp(struct msm_isp_timestamp *time_stamp) do_gettimeofday(&(time_stamp->event_time)); } static inline void msm_isp_get_vt_tstamp(struct vfe_device *vfe_dev, struct msm_isp_timestamp *time_stamp) { uint32_t avtimer_msw_1st = 0, avtimer_lsw = 0; uint32_t avtimer_msw_2nd = 0; uint8_t iter = 0; if (!vfe_dev->p_avtimer_msw || !vfe_dev->p_avtimer_lsw) { pr_err("%s: ioremap failed\n", __func__); return; } do { avtimer_msw_1st = msm_camera_io_r(vfe_dev->p_avtimer_msw); avtimer_lsw = msm_camera_io_r(vfe_dev->p_avtimer_lsw); avtimer_msw_2nd = msm_camera_io_r(vfe_dev->p_avtimer_msw); } while ((avtimer_msw_1st != avtimer_msw_2nd) && (iter++ < AVTIMER_ITERATION_CTR)); if (iter >= AVTIMER_ITERATION_CTR) { pr_err("%s: AVTimer MSW TS did not converge !!!\n", __func__); return; } time_stamp->vt_time.tv_sec = avtimer_msw_1st; time_stamp->vt_time.tv_usec = avtimer_lsw; } int msm_isp_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, struct v4l2_event_subscription *sub) { Loading Loading @@ -885,6 +909,8 @@ irqreturn_t msm_isp_process_irq(int irq_num, void *data) queue_cmd->vfeInterruptStatus0 = irq_status0; queue_cmd->vfeInterruptStatus1 = irq_status1; msm_isp_get_timestamp(&queue_cmd->ts); if (vfe_dev->vt_enable) msm_isp_get_vt_tstamp(vfe_dev, &queue_cmd->ts); queue_cmd->cmd_used = 1; vfe_dev->taskletq_idx = (vfe_dev->taskletq_idx + 1) % MSM_VFE_TASKLETQ_SIZE; Loading Loading @@ -998,11 +1024,26 @@ int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) vfe_dev->axi_data.hw_info = vfe_dev->hw_info->axi_hw_info; vfe_dev->vfe_open_cnt++; vfe_dev->taskletq_idx = 0; vfe_dev->vt_enable = 0; vfe_dev->p_avtimer_lsw = NULL; vfe_dev->p_avtimer_msw = NULL; mutex_unlock(&vfe_dev->core_mutex); mutex_unlock(&vfe_dev->realtime_mutex); return 0; } #ifdef CONFIG_MSM_AVTIMER void msm_isp_end_avtimer(void) { avcs_core_disable_power_collapse(0); } #else void msm_isp_end_avtimer(void) { pr_err("AV Timer is not supported\n"); } #endif int msm_isp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { long rc; Loading @@ -1024,6 +1065,12 @@ int msm_isp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) vfe_dev->buf_mgr->ops->buf_mgr_deinit(vfe_dev->buf_mgr); vfe_dev->hw_info->vfe_ops.core_ops.release_hw(vfe_dev); vfe_dev->vfe_open_cnt--; if (vfe_dev->vt_enable) { iounmap(vfe_dev->p_avtimer_lsw); iounmap(vfe_dev->p_avtimer_msw); msm_isp_end_avtimer(); vfe_dev->vt_enable = 0; } mutex_unlock(&vfe_dev->core_mutex); mutex_unlock(&vfe_dev->realtime_mutex); return 0; Loading
include/media/msmb_isp.h +1 −0 Original line number Diff line number Diff line Loading @@ -130,6 +130,7 @@ struct msm_vfe_axi_plane_cfg { struct msm_vfe_axi_stream_request_cmd { uint32_t session_id; uint32_t stream_id; uint32_t vt_enable; uint32_t output_format;/*Planar/RAW/Misc*/ enum msm_vfe_axi_stream_src stream_src; /*CAMIF/IDEAL/RDIs*/ struct msm_vfe_axi_plane_cfg plane_cfg[MAX_PLANES_PER_STREAM]; Loading