Merge "msm: isp: Add support to multipass offline ISP"
This commit is contained in:
commit
d43553d47d
9 changed files with 338 additions and 5 deletions
|
@ -243,6 +243,8 @@ struct msm_vfe_core_ops {
|
|||
bool (*is_module_cfg_lock_needed)(uint32_t reg_offset);
|
||||
int (*ahb_clk_cfg)(struct vfe_device *vfe_dev,
|
||||
struct msm_isp_ahb_clk_cfg *ahb_cfg);
|
||||
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);
|
||||
|
|
|
@ -1054,11 +1054,72 @@ 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) {
|
||||
|
@ -1089,10 +1150,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);
|
||||
|
@ -1118,7 +1183,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;
|
||||
|
@ -2261,6 +2338,8 @@ struct msm_vfe_hardware_info vfe40_hw_info = {
|
|||
.is_module_cfg_lock_needed =
|
||||
msm_vfe40_is_module_cfg_lock_needed,
|
||||
.ahb_clk_cfg = NULL,
|
||||
.start_fetch_eng_multi_pass =
|
||||
msm_vfe40_start_fetch_engine_multi_pass,
|
||||
},
|
||||
.stats_ops = {
|
||||
.get_stats_idx = msm_vfe40_get_stats_idx,
|
||||
|
|
|
@ -1077,11 +1077,70 @@ 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)
|
||||
{
|
||||
uint32_t x_size_word, temp;
|
||||
struct msm_vfe_fetch_engine_cfg *fe_cfg = NULL;
|
||||
uint32_t main_unpack_pattern = 0;
|
||||
|
||||
if (pix_cfg->input_mux == EXTERNAL_READ) {
|
||||
fe_cfg = &pix_cfg->fetch_engine_cfg;
|
||||
|
@ -1107,10 +1166,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);
|
||||
|
@ -1120,7 +1182,19 @@ void msm_vfe47_cfg_fetch_engine(struct vfe_device *vfe_dev,
|
|||
msm_camera_io_w(temp, vfe_dev->vfe_base + 0x314);
|
||||
|
||||
/* need to use formulae to calculate MAIN_UNPACK_PATTERN*/
|
||||
msm_camera_io_w(0xF6543210, vfe_dev->vfe_base + 0x318);
|
||||
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 + 0x318);
|
||||
msm_camera_io_w(0xF, vfe_dev->vfe_base + 0x334);
|
||||
|
||||
temp = msm_camera_io_r(vfe_dev->vfe_base + 0x50);
|
||||
|
@ -2721,6 +2795,8 @@ struct msm_vfe_hardware_info vfe47_hw_info = {
|
|||
.is_module_cfg_lock_needed =
|
||||
msm_vfe47_is_module_cfg_lock_needed,
|
||||
.ahb_clk_cfg = msm_isp47_ahb_clk_cfg,
|
||||
.start_fetch_eng_multi_pass =
|
||||
msm_vfe47_start_fetch_engine_multi_pass,
|
||||
},
|
||||
.stats_ops = {
|
||||
.get_stats_idx = msm_vfe47_get_stats_idx,
|
||||
|
|
|
@ -65,6 +65,8 @@ int32_t msm_vfe47_cfg_io_format(struct vfe_device *vfe_dev,
|
|||
enum msm_vfe_axi_stream_src stream_src, uint32_t io_format);
|
||||
int msm_vfe47_start_fetch_engine(struct vfe_device *vfe_dev,
|
||||
void *arg);
|
||||
int msm_vfe47_start_fetch_engine_multi_pass(struct vfe_device *vfe_dev,
|
||||
void *arg);
|
||||
void msm_vfe47_cfg_fetch_engine(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_pix_cfg *pix_cfg);
|
||||
void msm_vfe47_cfg_testgen(struct vfe_device *vfe_dev,
|
||||
|
|
|
@ -309,6 +309,8 @@ struct msm_vfe_hardware_info vfe48_hw_info = {
|
|||
.is_module_cfg_lock_needed =
|
||||
msm_vfe47_is_module_cfg_lock_needed,
|
||||
.ahb_clk_cfg = msm_isp47_ahb_clk_cfg,
|
||||
.start_fetch_eng_multi_pass =
|
||||
msm_vfe47_start_fetch_engine_multi_pass,
|
||||
},
|
||||
.stats_ops = {
|
||||
.get_stats_idx = msm_vfe47_get_stats_idx,
|
||||
|
|
|
@ -1691,6 +1691,76 @@ 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 buffer_size_byte = 0;
|
||||
int32_t word_per_line = 0;
|
||||
dma_addr_t paddr;
|
||||
uint32_t bufq_handle = 0;
|
||||
int vfe_idx;
|
||||
|
||||
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;
|
||||
}
|
||||
vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
|
||||
pingpong_bit = ((pingpong_status >>
|
||||
stream_info->wm[vfe_idx][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[vfe_idx][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[vfe_idx][i].
|
||||
output_scan_lines) -
|
||||
stream_info->
|
||||
plane_cfg[vfe_idx][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[vfe_idx][i],
|
||||
pingpong_bit, paddr +
|
||||
stream_info->
|
||||
plane_cfg[vfe_idx][i].plane_addr_offset,
|
||||
buffer_size_byte);
|
||||
stream_info->buf[!pingpong_bit] = buf;
|
||||
buf->pingpong_bit = !pingpong_bit;
|
||||
}
|
||||
buf->state = MSM_ISP_BUFFER_STATE_DEQUEUED;
|
||||
stream_info->buf[!pingpong_bit] = buf;
|
||||
buf->pingpong_bit = !pingpong_bit;
|
||||
}
|
||||
return rc;
|
||||
|
||||
}
|
||||
|
||||
static int msm_isp_cfg_ping_pong_address(
|
||||
struct msm_vfe_axi_stream *stream_info, uint32_t pingpong_status)
|
||||
{
|
||||
|
@ -1888,6 +1958,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) {
|
||||
|
||||
|
@ -2065,7 +2140,8 @@ static void msm_isp_input_enable(struct vfe_device *vfe_dev,
|
|||
continue;
|
||||
/* activate the input since it is deactivated */
|
||||
axi_data->src_info[i].frame_id = 0;
|
||||
axi_data->src_info[i].active = 1;
|
||||
if (axi_data->src_info[i].input_mux != EXTERNAL_READ)
|
||||
axi_data->src_info[i].active = 1;
|
||||
if (i >= VFE_RAW_0 && sync_frame_id_src) {
|
||||
/*
|
||||
* Incase PIX and RDI streams are part
|
||||
|
@ -3534,6 +3610,7 @@ int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg)
|
|||
unsigned long flags;
|
||||
struct msm_isp_timestamp timestamp;
|
||||
uint32_t frame_id;
|
||||
int vfe_idx;
|
||||
|
||||
/*num_stream is uint32 and update_info[] bound by MAX_NUM_STREAM*/
|
||||
if (update_cmd->num_streams > MAX_NUM_STREAM)
|
||||
|
@ -3746,6 +3823,20 @@ int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg)
|
|||
__func__);
|
||||
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 = msm_isp_get_stream_common_data(vfe_dev,
|
||||
HANDLE_TO_IDX(update_info->stream_handle));
|
||||
vfe_idx = msm_isp_get_vfe_idx_for_stream(
|
||||
vfe_dev, stream_info);
|
||||
msm_isp_stream_axi_cfg_update(vfe_dev, stream_info,
|
||||
update_info);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
pr_err("%s: Invalid update type %d\n", __func__,
|
||||
update_cmd->update_type);
|
||||
|
|
|
@ -157,4 +157,7 @@ static inline struct msm_vfe_axi_stream *msm_isp_vfe_get_stream(
|
|||
index);
|
||||
}
|
||||
|
||||
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__ */
|
||||
|
|
|
@ -375,6 +375,47 @@ static int msm_isp_start_fetch_engine(struct vfe_device *vfe_dev,
|
|||
start_fetch_eng(vfe_dev, arg);
|
||||
}
|
||||
|
||||
static int msm_isp_start_fetch_engine_multi_pass(struct vfe_device *vfe_dev,
|
||||
void *arg)
|
||||
{
|
||||
struct msm_vfe_fetch_eng_multi_pass_start *fe_cfg = arg;
|
||||
struct msm_vfe_axi_stream *stream_info = NULL;
|
||||
int i = 0, rc;
|
||||
uint32_t wm_reload_mask = 0;
|
||||
int vfe_idx;
|
||||
/*
|
||||
* For Offline VFE, HAL expects same frame id
|
||||
* for offline output which it requested in do_reprocess.
|
||||
*/
|
||||
vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id =
|
||||
fe_cfg->frame_id;
|
||||
if (fe_cfg->offline_pass == OFFLINE_SECOND_PASS) {
|
||||
stream_info = msm_isp_get_stream_common_data(vfe_dev,
|
||||
HANDLE_TO_IDX(fe_cfg->output_stream_id));
|
||||
if (stream_info == NULL) {
|
||||
pr_err("%s: Error in Offline process\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
|
||||
msm_isp_reset_framedrop(vfe_dev, stream_info);
|
||||
|
||||
rc = msm_isp_cfg_offline_ping_pong_address(vfe_dev, stream_info,
|
||||
VFE_PING_FLAG, fe_cfg->output_buf_idx);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: Fetch engine config failed\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
for (i = 0; i < stream_info->num_planes; i++)
|
||||
wm_reload_mask |= (1 << stream_info->wm[vfe_idx][i]);
|
||||
vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev,
|
||||
VFE_SRC_MAX);
|
||||
vfe_dev->hw_info->vfe_ops.axi_ops.reload_wm(vfe_dev,
|
||||
vfe_dev->vfe_base, wm_reload_mask);
|
||||
}
|
||||
return vfe_dev->hw_info->vfe_ops.core_ops.
|
||||
start_fetch_eng_multi_pass(vfe_dev, arg);
|
||||
}
|
||||
|
||||
void msm_isp_fetch_engine_done_notify(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_fetch_engine_info *fetch_engine_info)
|
||||
{
|
||||
|
@ -880,6 +921,13 @@ static long msm_isp_ioctl_unlocked(struct v4l2_subdev *sd,
|
|||
rc = msm_isp_start_fetch_engine(vfe_dev, arg);
|
||||
mutex_unlock(&vfe_dev->core_mutex);
|
||||
break;
|
||||
|
||||
case VIDIOC_MSM_ISP_FETCH_ENG_MULTI_PASS_START:
|
||||
case VIDIOC_MSM_ISP_MAP_BUF_START_MULTI_PASS_FE:
|
||||
mutex_lock(&vfe_dev->core_mutex);
|
||||
rc = msm_isp_start_fetch_engine_multi_pass(vfe_dev, arg);
|
||||
mutex_unlock(&vfe_dev->core_mutex);
|
||||
break;
|
||||
case VIDIOC_MSM_ISP_REG_UPDATE_CMD:
|
||||
if (arg) {
|
||||
enum msm_vfe_input_src frame_src =
|
||||
|
|
|
@ -261,6 +261,26 @@ struct msm_vfe_fetch_eng_start {
|
|||
uint32_t frame_id;
|
||||
};
|
||||
|
||||
enum msm_vfe_fetch_eng_pass {
|
||||
OFFLINE_FIRST_PASS,
|
||||
OFFLINE_SECOND_PASS,
|
||||
OFFLINE_MAX_PASS,
|
||||
};
|
||||
|
||||
struct msm_vfe_fetch_eng_multi_pass_start {
|
||||
uint32_t session_id;
|
||||
uint32_t stream_id;
|
||||
uint32_t buf_idx;
|
||||
uint8_t offline_mode;
|
||||
uint32_t fd;
|
||||
uint32_t buf_addr;
|
||||
uint32_t frame_id;
|
||||
uint32_t output_buf_idx;
|
||||
uint32_t input_buf_offset;
|
||||
enum msm_vfe_fetch_eng_pass offline_pass;
|
||||
uint32_t output_stream_id;
|
||||
};
|
||||
|
||||
struct msm_vfe_axi_plane_cfg {
|
||||
uint32_t output_width; /*Include padding*/
|
||||
uint32_t output_height;
|
||||
|
@ -328,6 +348,7 @@ enum msm_vfe_axi_stream_update_type {
|
|||
UPDATE_STREAM_REMOVE_BUFQ,
|
||||
UPDATE_STREAM_SW_FRAME_DROP,
|
||||
UPDATE_STREAM_REQUEST_FRAMES_VER2,
|
||||
UPDATE_STREAM_OFFLINE_AXI_CONFIG,
|
||||
};
|
||||
#define UPDATE_STREAM_REQUEST_FRAMES_VER2 UPDATE_STREAM_REQUEST_FRAMES_VER2
|
||||
|
||||
|
@ -853,6 +874,8 @@ enum msm_isp_ioctl_cmd_code {
|
|||
MSM_ISP_SET_DUAL_HW_MASTER_SLAVE,
|
||||
MSM_ISP_MAP_BUF_START_FE,
|
||||
MSM_ISP_UNMAP_BUF,
|
||||
MSM_ISP_FETCH_ENG_MULTI_PASS_START,
|
||||
MSM_ISP_MAP_BUF_START_MULTI_PASS_FE,
|
||||
};
|
||||
|
||||
#define VIDIOC_MSM_VFE_REG_CFG \
|
||||
|
@ -958,4 +981,11 @@ enum msm_isp_ioctl_cmd_code {
|
|||
#define VIDIOC_MSM_ISP_AHB_CLK_CFG \
|
||||
_IOWR('V', BASE_VIDIOC_PRIVATE+25, struct msm_isp_ahb_clk_cfg)
|
||||
|
||||
#define VIDIOC_MSM_ISP_FETCH_ENG_MULTI_PASS_START \
|
||||
_IOWR('V', MSM_ISP_FETCH_ENG_MULTI_PASS_START, \
|
||||
struct msm_vfe_fetch_eng_multi_pass_start)
|
||||
|
||||
#define VIDIOC_MSM_ISP_MAP_BUF_START_MULTI_PASS_FE \
|
||||
_IOWR('V', MSM_ISP_MAP_BUF_START_MULTI_PASS_FE, \
|
||||
struct msm_vfe_fetch_eng_multi_pass_start)
|
||||
#endif /* __MSMB_ISP__ */
|
||||
|
|
Loading…
Add table
Reference in a new issue