mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 19:08:57 +09:00
media: rockchip: vicap support thunderboot
1.support alloc buffer from reserved mem of thunderboot size of one frame = ceil(w*bit/8/256)*256*h 2.support read back mode change to online mode Signed-off-by: Zefa Chen <zefa.chen@rock-chips.com> Change-Id: I6b4ba18401edcb220ae6e9174afd5a92bfdd31c5
This commit is contained in:
@@ -1265,7 +1265,7 @@ static enum cif_reg_index get_dvp_reg_index_of_frm1_uv_addr(int channel_id)
|
||||
return index;
|
||||
}
|
||||
|
||||
static int rkcif_get_linetime(struct rkcif_stream *stream)
|
||||
int rkcif_get_linetime(struct rkcif_stream *stream)
|
||||
{
|
||||
struct rkcif_device *cif_dev = stream->cifdev;
|
||||
struct rkcif_sensor_info *sensor = &cif_dev->terminal_sensor;
|
||||
@@ -1459,15 +1459,15 @@ static void rkcif_s_rx_buffer(struct rkcif_device *dev, struct rkisp_rx_buf *dbu
|
||||
sd = media_entity_to_v4l2_subdev(pad->entity);
|
||||
else
|
||||
return;
|
||||
|
||||
v4l2_subdev_call(sd, video, s_rx_buffer, dbufs, NULL);
|
||||
if (dev->rdbk_debug &&
|
||||
dbufs->sequence < 15) {
|
||||
rx_buf = to_cif_rx_buf(dbufs);
|
||||
v4l2_info(&dev->v4l2_dev,
|
||||
"s_buf seq %d dma addr %x\n",
|
||||
dbufs->sequence, (u32)rx_buf->dummy.dma_addr);
|
||||
"s_buf seq %d dma addr %x, %lld\n",
|
||||
dbufs->sequence, (u32)rx_buf->dummy.dma_addr,
|
||||
ktime_get_ns());
|
||||
}
|
||||
v4l2_subdev_call(sd, video, s_rx_buffer, dbufs, NULL);
|
||||
}
|
||||
|
||||
static void rkcif_enable_skip_frame(struct rkcif_stream *stream, int cap_m, int skip_n)
|
||||
@@ -1598,9 +1598,12 @@ static int rkcif_assign_new_buffer_update_toisp(struct rkcif_stream *stream,
|
||||
active_buf->dbufs.is_first = true;
|
||||
active_buf->dbufs.sequence = stream->frame_idx - 1;
|
||||
active_buf->dbufs.timestamp = stream->readout.fs_timestamp;
|
||||
stream->last_frame_idx = stream->frame_idx;
|
||||
rkcif_s_rx_buffer(dev, &active_buf->dbufs);
|
||||
stream->buf_num_toisp--;
|
||||
} else {
|
||||
rkcif_s_rx_buffer(dev, &stream->next_buf_toisp->dbufs);
|
||||
stream->buf_num_toisp--;
|
||||
}
|
||||
} else if (stream->frame_phase == CIF_CSI_FRAME1_READY) {
|
||||
if (stream->curr_buf_toisp == stream->next_buf_toisp)
|
||||
@@ -1621,9 +1624,12 @@ static int rkcif_assign_new_buffer_update_toisp(struct rkcif_stream *stream,
|
||||
active_buf->dbufs.is_first = true;
|
||||
active_buf->dbufs.sequence = stream->frame_idx - 1;
|
||||
active_buf->dbufs.timestamp = stream->readout.fs_timestamp;
|
||||
stream->last_frame_idx = stream->frame_idx;
|
||||
rkcif_s_rx_buffer(dev, &active_buf->dbufs);
|
||||
stream->buf_num_toisp--;
|
||||
} else {
|
||||
rkcif_s_rx_buffer(dev, &stream->curr_buf_toisp->dbufs);
|
||||
stream->buf_num_toisp--;
|
||||
}
|
||||
}
|
||||
if (stream->lack_buf_cnt)
|
||||
@@ -1660,6 +1666,7 @@ static int rkcif_assign_new_buffer_update_toisp(struct rkcif_stream *stream,
|
||||
active_buf->dbufs.is_first = true;
|
||||
active_buf->dbufs.sequence = stream->frame_idx - 1;
|
||||
active_buf->dbufs.timestamp = stream->readout.fs_timestamp;
|
||||
stream->last_frame_idx = stream->frame_idx;
|
||||
rkcif_s_rx_buffer(dev, &active_buf->dbufs);
|
||||
} else {
|
||||
if (stream->cifdev->rdbk_debug && dev->dummy_buf.vaddr)
|
||||
@@ -1730,9 +1737,9 @@ void rkcif_assign_check_buffer_update_toisp(struct rkcif_stream *stream)
|
||||
|
||||
if (dev->chip_id > CHIP_RK3568_CIF &&
|
||||
dev->hdr.hdr_mode == NO_HDR &&
|
||||
dev->sensor_linetime > 0 &&
|
||||
cur_time - stream->readout.fe_timestamp < (vblank_ns - 500000) &&
|
||||
stream->lack_buf_cnt == 2) {
|
||||
stream->lack_buf_cnt == 2 &&
|
||||
stream->frame_idx > stream->last_frame_idx) {
|
||||
is_early_update = true;
|
||||
frame_phase = stream->frame_phase & CIF_CSI_FRAME0_READY ?
|
||||
CIF_CSI_FRAME1_READY : CIF_CSI_FRAME0_READY;
|
||||
@@ -1744,8 +1751,9 @@ void rkcif_assign_check_buffer_update_toisp(struct rkcif_stream *stream)
|
||||
if (dev->rdbk_debug > 2 &&
|
||||
stream->frame_idx < 15)
|
||||
v4l2_info(&dev->v4l2_dev,
|
||||
"check update, cur %lld, fe %lld, vb %u\n",
|
||||
cur_time, stream->readout.fe_timestamp, vblank_ns);
|
||||
"check update, cur %lld, fe %lld, vb %u lack_buf %d\n",
|
||||
cur_time, stream->readout.fe_timestamp,
|
||||
vblank_ns, stream->lack_buf_cnt);
|
||||
if (mbus_cfg->type == V4L2_MBUS_CSI2_DPHY ||
|
||||
mbus_cfg->type == V4L2_MBUS_CSI2_CPHY ||
|
||||
mbus_cfg->type == V4L2_MBUS_CCP2) {
|
||||
@@ -1810,6 +1818,7 @@ void rkcif_assign_check_buffer_update_toisp(struct rkcif_stream *stream)
|
||||
if (active_buf) {
|
||||
active_buf->dbufs.sequence = stream->frame_idx - 1;
|
||||
active_buf->dbufs.timestamp = stream->readout.fs_timestamp;
|
||||
stream->last_frame_idx = stream->frame_idx;
|
||||
rkcif_s_rx_buffer(dev, &active_buf->dbufs);
|
||||
}
|
||||
if (dev->dummy_buf.vaddr)
|
||||
@@ -2105,6 +2114,7 @@ static int rkcif_assign_new_buffer_update(struct rkcif_stream *stream,
|
||||
dbufs = &stream->curr_buf_toisp->dbufs;
|
||||
}
|
||||
rkcif_s_rx_buffer(dev, dbufs);
|
||||
stream->buf_num_toisp--;
|
||||
}
|
||||
} else {
|
||||
if (stream->dma_en & RKCIF_DMAEN_BY_ISP) {
|
||||
@@ -2125,6 +2135,7 @@ static int rkcif_assign_new_buffer_update(struct rkcif_stream *stream,
|
||||
dbufs = &stream->curr_buf_toisp->dbufs;
|
||||
}
|
||||
rkcif_s_rx_buffer(dev, dbufs);
|
||||
stream->buf_num_toisp--;
|
||||
if (stream->curr_buf && stream->frame_phase == CIF_CSI_FRAME0_READY) {
|
||||
stream->curr_buf = NULL;
|
||||
if (stream->buf_replace_cnt)
|
||||
@@ -2177,6 +2188,7 @@ stop_dma:
|
||||
dbufs = &stream->curr_buf_toisp->dbufs;
|
||||
}
|
||||
rkcif_s_rx_buffer(dev, dbufs);
|
||||
stream->buf_num_toisp--;
|
||||
if (stream->frame_phase == CIF_CSI_FRAME0_READY) {
|
||||
list_add_tail(&stream->curr_buf->queue, &stream->buf_head);
|
||||
stream->curr_buf = NULL;
|
||||
@@ -3161,6 +3173,8 @@ static int rkcif_csi_stream_start(struct rkcif_stream *stream, unsigned int mode
|
||||
stream->buf_wake_up_cnt = 0;
|
||||
stream->frame_phase = 0;
|
||||
stream->lack_buf_cnt = 0;
|
||||
stream->is_in_vblank = false;
|
||||
stream->is_change_toisp = false;
|
||||
}
|
||||
|
||||
rkcif_csi_get_vc_num(dev, flags);
|
||||
@@ -3572,20 +3586,35 @@ void rkcif_free_rx_buf(struct rkcif_stream *stream, int buf_num)
|
||||
{
|
||||
struct rkcif_rx_buffer *buf;
|
||||
struct rkcif_device *dev = stream->cifdev;
|
||||
struct sditf_priv *priv = dev->sditf[0];
|
||||
int i = 0;
|
||||
unsigned long flags;
|
||||
|
||||
if (!priv)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&stream->vbq_lock, flags);
|
||||
stream->curr_buf_toisp = NULL;
|
||||
stream->next_buf_toisp = NULL;
|
||||
INIT_LIST_HEAD(&stream->rx_buf_head);
|
||||
spin_unlock_irqrestore(&stream->vbq_lock, flags);
|
||||
|
||||
if (dev->is_thunderboot)
|
||||
spin_lock_irqsave(&dev->buffree_lock, flags);
|
||||
for (i = 0; i < buf_num; i++) {
|
||||
buf = &stream->rx_buf[i];
|
||||
if (buf->dummy.is_free)
|
||||
continue;
|
||||
rkcif_free_buffer(dev, &buf->dummy);
|
||||
if (!dev->is_thunderboot)
|
||||
rkcif_free_buffer(dev, &buf->dummy);
|
||||
else
|
||||
list_add_tail(&buf->dbufs.list, &priv->buf_free_list);
|
||||
}
|
||||
|
||||
if (dev->is_thunderboot) {
|
||||
spin_unlock_irqrestore(&dev->buffree_lock, flags);
|
||||
schedule_work(&priv->buffree_work.work);
|
||||
dev->is_thunderboot = false;
|
||||
}
|
||||
stream->dma_en &= ~RKCIF_DMAEN_BY_ISP;
|
||||
v4l2_dbg(3, rkcif_debug, &stream->cifdev->v4l2_dev,
|
||||
@@ -3638,21 +3667,35 @@ int rkcif_init_rx_buf(struct rkcif_stream *stream, int buf_num)
|
||||
dummy->size = pixm->plane_fmt[0].sizeimage;
|
||||
dummy->is_need_vaddr = true;
|
||||
dummy->is_need_dbuf = true;
|
||||
ret = rkcif_alloc_buffer(dev, dummy);
|
||||
if (ret) {
|
||||
priv->buf_num = i;
|
||||
v4l2_err(&dev->v4l2_dev,
|
||||
"alloc buf num %d, require buf num %d\n",
|
||||
i, buf_num);
|
||||
break;
|
||||
if (dev->is_thunderboot) {
|
||||
buf->buf_idx = i;
|
||||
ret = rkcif_alloc_reserved_mem_buf(dev, buf);
|
||||
if (ret) {
|
||||
priv->buf_num = i;
|
||||
v4l2_err(&dev->v4l2_dev,
|
||||
"reserved mem support alloc buf num %d, require buf num %d\n",
|
||||
i, buf_num);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ret = rkcif_alloc_buffer(dev, dummy);
|
||||
if (ret) {
|
||||
priv->buf_num = i;
|
||||
v4l2_err(&dev->v4l2_dev,
|
||||
"alloc buf num %d, require buf num %d\n",
|
||||
i, buf_num);
|
||||
break;
|
||||
}
|
||||
buf->dbufs.dbuf = dummy->dbuf;
|
||||
}
|
||||
buf->dbufs.dbuf = dummy->dbuf;
|
||||
buf->dbufs.is_init = false;
|
||||
buf->dbufs.type = frm_type;
|
||||
list_add_tail(&buf->dbufs.list, &stream->rx_buf_head);
|
||||
dummy->is_free = false;
|
||||
if (priv && priv->mode.rdbk_mode == RKISP_VICAP_ONLINE && i == 0) {
|
||||
buf->dbufs.is_first = true;
|
||||
rkcif_s_rx_buffer(dev, &buf->dbufs);
|
||||
stream->buf_num_toisp--;
|
||||
}
|
||||
v4l2_dbg(3, rkcif_debug, &dev->v4l2_dev,
|
||||
"init rx_buf,dma_addr 0x%llx size: 0x%x\n",
|
||||
@@ -4547,6 +4590,8 @@ static int rkcif_stream_start(struct rkcif_stream *stream, unsigned int mode)
|
||||
stream->buf_wake_up_cnt = 0;
|
||||
stream->lack_buf_cnt = 0;
|
||||
stream->frame_phase = 0;
|
||||
stream->is_in_vblank = false;
|
||||
stream->is_change_toisp = false;
|
||||
}
|
||||
|
||||
sensor_info = dev->active_sensor;
|
||||
@@ -7379,6 +7424,7 @@ static void rkcif_line_wake_up_rdbk(struct rkcif_stream *stream, int mipi_id)
|
||||
u32 mode;
|
||||
struct rkcif_rx_buffer *active_buf = NULL;
|
||||
struct sditf_priv *priv = NULL;
|
||||
unsigned long flags;
|
||||
int ret = 0;
|
||||
|
||||
mode = stream->line_int_cnt % 2;
|
||||
@@ -7402,11 +7448,29 @@ static void rkcif_line_wake_up_rdbk(struct rkcif_stream *stream, int mipi_id)
|
||||
return;
|
||||
}
|
||||
ret = rkcif_get_new_buffer_wake_up_mode_rdbk(stream);
|
||||
v4l2_dbg(3, rkcif_debug, &stream->cifdev->v4l2_dev,
|
||||
"%d frame_idx %d, last_rx_buf_idx %d cur dma buf %x\n",
|
||||
__LINE__, stream->frame_idx, stream->last_rx_buf_idx,
|
||||
(u32)active_buf->dummy.dma_addr);
|
||||
if (!ret) {
|
||||
priv = stream->cifdev->sditf[0];
|
||||
if (priv && priv->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO) {
|
||||
spin_lock_irqsave(&stream->vbq_lock, flags);
|
||||
if ((stream->frame_idx - 1) == stream->last_rx_buf_idx &&
|
||||
stream->cifdev->is_thunderboot) {
|
||||
stream->cur_stream_mode &= ~RKCIF_STREAM_MODE_TOISP_RDBK;
|
||||
stream->cur_stream_mode |= RKCIF_STREAM_MODE_TOISP;
|
||||
if (stream->cifdev->hdr.hdr_mode == NO_HDR)
|
||||
stream->to_stop_dma = RKCIF_DMAEN_BY_ISP;
|
||||
rkcif_stop_dma_capture(stream);
|
||||
active_buf->dbufs.is_switch = true;
|
||||
stream->cifdev->wait_line = 0;
|
||||
stream->is_line_wake_up = false;
|
||||
}
|
||||
spin_unlock_irqrestore(&stream->vbq_lock, flags);
|
||||
active_buf->dbufs.sequence = stream->frame_idx - 1;
|
||||
active_buf->dbufs.timestamp = stream->readout.fs_timestamp;
|
||||
stream->last_frame_idx = stream->frame_idx;
|
||||
rkcif_s_rx_buffer(stream->cifdev, &active_buf->dbufs);
|
||||
stream->buf_num_toisp--;
|
||||
}
|
||||
@@ -8431,6 +8495,13 @@ static void rkcif_toisp_check_stop_status(struct sditf_priv *priv,
|
||||
stream->stopping = false;
|
||||
wake_up(&stream->wq_stopped);
|
||||
}
|
||||
|
||||
if (stream->cifdev->rdbk_debug &&
|
||||
stream->frame_idx < 15)
|
||||
v4l2_info(&priv->cif_dev->v4l2_dev,
|
||||
"toisp fe %d\n",
|
||||
stream->frame_idx - 1);
|
||||
|
||||
if (stream->to_en_dma)
|
||||
rkcif_enable_dma_capture(stream, false);
|
||||
if (stream->to_en_scale) {
|
||||
@@ -8462,6 +8533,11 @@ static void rkcif_toisp_check_stop_status(struct sditf_priv *priv,
|
||||
else
|
||||
stream = &priv->cif_dev->stream[src_id % 4];
|
||||
stream->frame_idx++;
|
||||
if (stream->cifdev->rdbk_debug &&
|
||||
stream->frame_idx < 15)
|
||||
v4l2_info(&priv->cif_dev->v4l2_dev,
|
||||
"toisp sof seq %d\n",
|
||||
stream->frame_idx - 1);
|
||||
switch (ch) {
|
||||
case RKCIF_TOISP_CH0:
|
||||
val = TOISP_FS_CH0(index);
|
||||
@@ -8627,6 +8703,12 @@ static void rkcif_deal_sof(struct rkcif_device *cif_dev)
|
||||
rkcif_send_sof(cif_dev);
|
||||
if (!cif_dev->sditf[0] || cif_dev->sditf[0]->mode.rdbk_mode)
|
||||
detect_stream->frame_idx++;
|
||||
if (detect_stream->cifdev->rdbk_debug &&
|
||||
detect_stream->frame_idx < 15)
|
||||
v4l2_info(&cif_dev->v4l2_dev,
|
||||
"sof %d %lld\n",
|
||||
detect_stream->frame_idx - 1,
|
||||
ktime_get_ns());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8769,7 +8851,7 @@ void rkcif_irq_pingpong_v1(struct rkcif_device *cif_dev)
|
||||
|
||||
if (stream->state != RKCIF_STATE_STREAMING)
|
||||
continue;
|
||||
|
||||
stream->is_in_vblank = true;
|
||||
switch (mipi_id) {
|
||||
case RKCIF_STREAM_MIPI_ID0:
|
||||
stream->frame_phase = SW_FRM_END_ID0(intstat);
|
||||
@@ -8788,6 +8870,14 @@ void rkcif_irq_pingpong_v1(struct rkcif_device *cif_dev)
|
||||
intstat &= ~CSI_FRAME_END_ID3;
|
||||
break;
|
||||
}
|
||||
if (stream->cifdev->rdbk_debug &&
|
||||
stream->frame_idx < 15)
|
||||
v4l2_info(&cif_dev->v4l2_dev,
|
||||
"fe %d, phase %d, %lld\n",
|
||||
stream->frame_idx - 1,
|
||||
stream->frame_phase,
|
||||
ktime_get_ns());
|
||||
|
||||
if (stream->crop_dyn_en)
|
||||
rkcif_dynamic_crop(stream);
|
||||
|
||||
@@ -8802,6 +8892,8 @@ void rkcif_irq_pingpong_v1(struct rkcif_device *cif_dev)
|
||||
rkcif_modify_frame_skip_config(stream);
|
||||
} else if (stream->dma_en & RKCIF_DMAEN_BY_ISP) {
|
||||
rkcif_update_stream_toisp(cif_dev, stream, mipi_id);
|
||||
} else if (stream->is_change_toisp) {
|
||||
sditf_change_to_online(cif_dev->sditf[0]);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&stream->vbq_lock, flags);
|
||||
@@ -8849,6 +8941,7 @@ void rkcif_irq_pingpong_v1(struct rkcif_device *cif_dev)
|
||||
stream->frame_idx++;
|
||||
spin_unlock_irqrestore(&stream->fps_lock, flags);
|
||||
}
|
||||
stream->is_in_vblank = false;
|
||||
if (stream->to_stop_dma) {
|
||||
ret = rkcif_stop_dma_capture(stream);
|
||||
if (!ret)
|
||||
@@ -8859,6 +8952,11 @@ void rkcif_irq_pingpong_v1(struct rkcif_device *cif_dev)
|
||||
stream = &cif_dev->stream[i];
|
||||
if (stream->is_line_inten) {
|
||||
stream->line_int_cnt++;
|
||||
if (cif_dev->rdbk_debug > 1 &&
|
||||
stream->frame_idx < 15)
|
||||
v4l2_info(&cif_dev->v4l2_dev,
|
||||
"line int %lld\n",
|
||||
stream->line_int_cnt);
|
||||
if (cif_dev->sditf[0] && cif_dev->sditf[0]->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO)
|
||||
rkcif_line_wake_up_rdbk(stream, stream->id);
|
||||
else
|
||||
@@ -8924,7 +9022,7 @@ void rkcif_irq_pingpong_v1(struct rkcif_device *cif_dev)
|
||||
|
||||
if (stream->state != RKCIF_STATE_STREAMING)
|
||||
continue;
|
||||
|
||||
stream->is_in_vblank = true;
|
||||
switch (ch_id) {
|
||||
case RKCIF_STREAM_MIPI_ID0:
|
||||
stream->frame_phase = SW_FRM_END_ID0(intstat);
|
||||
@@ -8954,8 +9052,10 @@ void rkcif_irq_pingpong_v1(struct rkcif_device *cif_dev)
|
||||
cif_dev->irq_stats.all_frm_end_cnt++;
|
||||
}
|
||||
|
||||
if (intstat & DVP_FRAME0_START_ID0 || intstat & DVP_FRAME1_START_ID0)
|
||||
if (intstat & DVP_FRAME0_START_ID0 || intstat & DVP_FRAME1_START_ID0) {
|
||||
stream->is_in_vblank = false;
|
||||
rkcif_deal_sof(cif_dev);
|
||||
}
|
||||
|
||||
if (stream->crop_dyn_en)
|
||||
rkcif_dynamic_crop(stream);
|
||||
|
||||
@@ -186,3 +186,181 @@ void rkcif_free_common_dummy_buf(struct rkcif_device *dev, struct rkcif_dummy_bu
|
||||
mutex_unlock(&hw->dev_lock);
|
||||
}
|
||||
|
||||
struct rkcif_shm_data {
|
||||
void *vaddr;
|
||||
int vmap_cnt;
|
||||
int npages;
|
||||
struct page *pages[];
|
||||
};
|
||||
|
||||
static struct sg_table *rkcif_shm_map_dma_buf(struct dma_buf_attachment *attachment,
|
||||
enum dma_data_direction dir)
|
||||
{
|
||||
struct rkcif_shm_data *data = attachment->dmabuf->priv;
|
||||
struct sg_table *table;
|
||||
|
||||
table = kmalloc(sizeof(*table), GFP_KERNEL);
|
||||
if (!table)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
sg_alloc_table_from_pages(table, data->pages, data->npages, 0,
|
||||
data->npages << PAGE_SHIFT, GFP_KERNEL);
|
||||
|
||||
dma_map_sgtable(attachment->dev, table, dir, DMA_ATTR_SKIP_CPU_SYNC);
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
static void rkcif_shm_unmap_dma_buf(struct dma_buf_attachment *attachment,
|
||||
struct sg_table *table,
|
||||
enum dma_data_direction dir)
|
||||
{
|
||||
dma_unmap_sgtable(attachment->dev, table, dir, DMA_ATTR_SKIP_CPU_SYNC);
|
||||
sg_free_table(table);
|
||||
kfree(table);
|
||||
}
|
||||
|
||||
static void *rkcif_shm_vmap(struct dma_buf *dma_buf)
|
||||
{
|
||||
struct rkcif_shm_data *data = dma_buf->priv;
|
||||
|
||||
data->vaddr = vmap(data->pages, data->npages, VM_MAP, PAGE_KERNEL);
|
||||
data->vmap_cnt++;
|
||||
return data->vaddr;
|
||||
}
|
||||
|
||||
static void rkcif_shm_vunmap(struct dma_buf *dma_buf, void *vaddr)
|
||||
{
|
||||
struct rkcif_shm_data *data = dma_buf->priv;
|
||||
|
||||
vunmap(data->vaddr);
|
||||
data->vaddr = NULL;
|
||||
data->vmap_cnt--;
|
||||
}
|
||||
|
||||
static int rkcif_shm_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma)
|
||||
{
|
||||
struct rkcif_shm_data *data = dma_buf->priv;
|
||||
unsigned long vm_start = vma->vm_start;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < data->npages; i++) {
|
||||
remap_pfn_range(vma, vm_start, page_to_pfn(data->pages[i]),
|
||||
PAGE_SIZE, vma->vm_page_prot);
|
||||
vm_start += PAGE_SIZE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rkcif_shm_begin_cpu_access(struct dma_buf *dmabuf, enum dma_data_direction dir)
|
||||
{
|
||||
struct dma_buf_attachment *attachment;
|
||||
struct sg_table *table;
|
||||
|
||||
attachment = list_first_entry(&dmabuf->attachments, struct dma_buf_attachment, node);
|
||||
table = attachment->priv;
|
||||
dma_sync_sg_for_cpu(NULL, table->sgl, table->nents, dir);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rkcif_shm_end_cpu_access(struct dma_buf *dmabuf, enum dma_data_direction dir)
|
||||
{
|
||||
struct dma_buf_attachment *attachment;
|
||||
struct sg_table *table;
|
||||
|
||||
attachment = list_first_entry(&dmabuf->attachments, struct dma_buf_attachment, node);
|
||||
table = attachment->priv;
|
||||
dma_sync_sg_for_device(NULL, table->sgl, table->nents, dir);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rkcif_shm_release(struct dma_buf *dma_buf)
|
||||
{
|
||||
struct rkcif_shm_data *data = dma_buf->priv;
|
||||
|
||||
if (data->vmap_cnt) {
|
||||
WARN(1, "%s: buffer still mapped in the kernel\n", __func__);
|
||||
rkcif_shm_vunmap(dma_buf, data->vaddr);
|
||||
}
|
||||
kfree(data);
|
||||
}
|
||||
|
||||
static const struct dma_buf_ops rkcif_shm_dmabuf_ops = {
|
||||
.map_dma_buf = rkcif_shm_map_dma_buf,
|
||||
.unmap_dma_buf = rkcif_shm_unmap_dma_buf,
|
||||
.release = rkcif_shm_release,
|
||||
.mmap = rkcif_shm_mmap,
|
||||
.vmap = rkcif_shm_vmap,
|
||||
.vunmap = rkcif_shm_vunmap,
|
||||
.begin_cpu_access = rkcif_shm_begin_cpu_access,
|
||||
.end_cpu_access = rkcif_shm_end_cpu_access,
|
||||
};
|
||||
|
||||
static struct dma_buf *rkcif_shm_alloc(struct rkisp_thunderboot_shmem *shmem)
|
||||
{
|
||||
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
|
||||
struct dma_buf *dmabuf;
|
||||
struct rkcif_shm_data *data;
|
||||
int i, npages;
|
||||
|
||||
npages = PAGE_ALIGN(shmem->shm_size) / PAGE_SIZE;
|
||||
data = kmalloc(sizeof(*data) + npages * sizeof(struct page *), GFP_KERNEL);
|
||||
if (!data)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
data->vmap_cnt = 0;
|
||||
data->npages = npages;
|
||||
for (i = 0; i < npages; i++)
|
||||
data->pages[i] = phys_to_page(shmem->shm_start + i * PAGE_SIZE);
|
||||
|
||||
exp_info.ops = &rkcif_shm_dmabuf_ops;
|
||||
exp_info.size = npages * PAGE_SIZE;
|
||||
exp_info.flags = O_RDWR;
|
||||
exp_info.priv = data;
|
||||
|
||||
dmabuf = dma_buf_export(&exp_info);
|
||||
|
||||
return dmabuf;
|
||||
}
|
||||
|
||||
int rkcif_alloc_reserved_mem_buf(struct rkcif_device *dev, struct rkcif_rx_buffer *buf)
|
||||
{
|
||||
struct rkcif_dummy_buffer *dummy = &buf->dummy;
|
||||
|
||||
dummy->dma_addr = dev->resmem_pa + dummy->size * buf->buf_idx;
|
||||
if (dummy->dma_addr + dummy->size > dev->resmem_pa + dev->resmem_size)
|
||||
return -EINVAL;
|
||||
buf->dbufs.dma = dummy->dma_addr;
|
||||
buf->dbufs.is_resmem = true;
|
||||
buf->shmem.shm_start = dummy->dma_addr;
|
||||
buf->shmem.shm_size = dummy->size;
|
||||
dummy->dbuf = rkcif_shm_alloc(&buf->shmem);
|
||||
if (dummy->is_need_vaddr)
|
||||
dummy->vaddr = dummy->dbuf->ops->vmap(dummy->dbuf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rkcif_free_reserved_mem_buf(struct rkcif_device *dev, struct rkcif_rx_buffer *buf)
|
||||
{
|
||||
struct rkcif_dummy_buffer *dummy = &buf->dummy;
|
||||
|
||||
if (buf->dummy.is_free)
|
||||
return;
|
||||
|
||||
if (dev->rdbk_debug)
|
||||
v4l2_info(&dev->v4l2_dev,
|
||||
"free reserved mem addr 0x%x\n",
|
||||
(u32)dummy->dma_addr);
|
||||
|
||||
if (dummy->is_need_vaddr)
|
||||
dummy->dbuf->ops->vunmap(dummy->dbuf, dummy->vaddr);
|
||||
#ifdef CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP
|
||||
free_reserved_area(phys_to_virt(buf->shmem.shm_start),
|
||||
phys_to_virt(buf->shmem.shm_start + buf->shmem.shm_size),
|
||||
-1, "rkisp_thunderboot");
|
||||
#endif
|
||||
buf->dummy.is_free = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,5 +23,8 @@ void rkcif_free_buffer(struct rkcif_device *dev,
|
||||
int rkcif_alloc_common_dummy_buf(struct rkcif_device *dev, struct rkcif_dummy_buffer *buf);
|
||||
void rkcif_free_common_dummy_buf(struct rkcif_device *dev, struct rkcif_dummy_buffer *buf);
|
||||
|
||||
int rkcif_alloc_reserved_mem_buf(struct rkcif_device *dev, struct rkcif_rx_buffer *buf);
|
||||
void rkcif_free_reserved_mem_buf(struct rkcif_device *dev, struct rkcif_rx_buffer *buf);
|
||||
|
||||
#endif /* _RKCIF_COMMON_H */
|
||||
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#include "procfs.h"
|
||||
#include <linux/kthread.h>
|
||||
#include "../../../../phy/rockchip/phy-rockchip-csi2-dphy-common.h"
|
||||
#include <linux/of_reserved_mem.h>
|
||||
#include <linux/of_address.h>
|
||||
|
||||
#define RKCIF_VERNO_LEN 10
|
||||
|
||||
@@ -1833,6 +1835,7 @@ int rkcif_plat_init(struct rkcif_device *cif_dev, struct device_node *node, int
|
||||
mutex_init(&cif_dev->scale_lock);
|
||||
mutex_init(&cif_dev->tools_lock);
|
||||
spin_lock_init(&cif_dev->hdr_lock);
|
||||
spin_lock_init(&cif_dev->buffree_lock);
|
||||
spin_lock_init(&cif_dev->reset_watchdog_timer.timer_lock);
|
||||
spin_lock_init(&cif_dev->reset_watchdog_timer.csi2_err_lock);
|
||||
atomic_set(&cif_dev->pipe.power_cnt, 0);
|
||||
@@ -1849,6 +1852,7 @@ int rkcif_plat_init(struct rkcif_device *cif_dev, struct device_node *node, int
|
||||
cif_dev->is_notifier_isp = false;
|
||||
cif_dev->sensor_linetime = 0;
|
||||
cif_dev->early_line = 0;
|
||||
cif_dev->is_thunderboot = false;
|
||||
cif_dev->rdbk_debug = 0;
|
||||
if (cif_dev->chip_id == CHIP_RV1126_CIF_LITE)
|
||||
cif_dev->isr_hdl = rkcif_irq_lite_handler;
|
||||
@@ -2003,6 +2007,35 @@ static void rkcif_parse_dts(struct rkcif_device *cif_dev)
|
||||
dev_info(cif_dev->dev, "rkcif wait line %d\n", cif_dev->wait_line);
|
||||
}
|
||||
|
||||
static int rkcif_get_reserved_mem(struct rkcif_device *cif_dev)
|
||||
{
|
||||
struct device *dev = cif_dev->dev;
|
||||
struct device_node *np;
|
||||
struct resource r;
|
||||
int ret;
|
||||
|
||||
/* Get reserved memory region from Device-tree */
|
||||
np = of_parse_phandle(dev->of_node, "memory-region-thunderboot", 0);
|
||||
if (!np) {
|
||||
dev_info(dev, "No memory-region-thunderboot specified\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = of_address_to_resource(np, 0, &r);
|
||||
if (ret) {
|
||||
dev_err(dev, "No memory address assigned to the region\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
cif_dev->resmem_pa = r.start;
|
||||
cif_dev->resmem_size = resource_size(&r);
|
||||
cif_dev->is_thunderboot = true;
|
||||
dev_info(dev, "Allocated reserved memory, paddr: 0x%x, size 0x%x\n",
|
||||
(u32)cif_dev->resmem_pa,
|
||||
(u32)cif_dev->resmem_size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rkcif_plat_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct of_device_id *match;
|
||||
@@ -2044,6 +2077,10 @@ static int rkcif_plat_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = rkcif_get_reserved_mem(cif_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (rkcif_proc_init(cif_dev))
|
||||
dev_warn(dev, "dev:%s create proc failed\n", dev_name(dev));
|
||||
|
||||
|
||||
@@ -442,8 +442,10 @@ enum rkcif_capture_mode {
|
||||
};
|
||||
|
||||
struct rkcif_rx_buffer {
|
||||
int buf_idx;
|
||||
struct rkisp_rx_buf dbufs;
|
||||
struct rkcif_dummy_buffer dummy;
|
||||
struct rkisp_thunderboot_shmem shmem;
|
||||
};
|
||||
|
||||
enum rkcif_dma_en_mode {
|
||||
@@ -521,6 +523,8 @@ struct rkcif_stream {
|
||||
int lack_buf_cnt;
|
||||
unsigned int buf_wake_up_cnt;
|
||||
struct rkcif_skip_info skip_info;
|
||||
int last_rx_buf_idx;
|
||||
int last_frame_idx;
|
||||
bool stopping;
|
||||
bool crop_enable;
|
||||
bool crop_dyn_en;
|
||||
@@ -534,6 +538,8 @@ struct rkcif_stream {
|
||||
bool is_high_align;
|
||||
bool to_en_scale;
|
||||
bool is_finish_stop_dma;
|
||||
bool is_in_vblank;
|
||||
bool is_change_toisp;
|
||||
};
|
||||
|
||||
struct rkcif_lvds_subdev {
|
||||
@@ -793,6 +799,7 @@ struct rkcif_device {
|
||||
struct proc_dir_entry *proc_dir;
|
||||
struct rkcif_irq_stats irq_stats;
|
||||
spinlock_t hdr_lock; /* lock for hdr buf sync */
|
||||
spinlock_t buffree_lock;
|
||||
struct rkcif_timer reset_watchdog_timer;
|
||||
struct rkcif_work_struct reset_work;
|
||||
int id_use_cnt;
|
||||
@@ -804,11 +811,14 @@ struct rkcif_device {
|
||||
struct rkcif_dummy_buffer dummy_buf;
|
||||
struct completion cmpl_ntf;
|
||||
struct csi2_dphy_hw *dphy_hw;
|
||||
phys_addr_t resmem_pa;
|
||||
size_t resmem_size;
|
||||
bool is_start_hdr;
|
||||
bool reset_work_cancel;
|
||||
bool iommu_en;
|
||||
bool is_use_dummybuf;
|
||||
bool is_notifier_isp;
|
||||
bool is_thunderboot;
|
||||
int rdbk_debug;
|
||||
int sync_type;
|
||||
int sditf_cnt;
|
||||
@@ -892,6 +902,7 @@ void rkcif_config_dvp_pin(struct rkcif_device *dev, bool on);
|
||||
|
||||
s32 rkcif_get_sensor_vblank_def(struct rkcif_device *dev);
|
||||
s32 rkcif_get_sensor_vblank(struct rkcif_device *dev);
|
||||
int rkcif_get_linetime(struct rkcif_stream *stream);
|
||||
|
||||
void rkcif_assign_check_buffer_update_toisp(struct rkcif_stream *stream);
|
||||
|
||||
|
||||
@@ -22,12 +22,41 @@
|
||||
#include "dev.h"
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/rk-camera-module.h>
|
||||
#include "common.h"
|
||||
|
||||
static inline struct sditf_priv *to_sditf_priv(struct v4l2_subdev *subdev)
|
||||
{
|
||||
return container_of(subdev, struct sditf_priv, sd);
|
||||
}
|
||||
|
||||
void sditf_buffree_work(struct work_struct *work)
|
||||
{
|
||||
struct sditf_work_struct *buffree_work = container_of(work,
|
||||
struct sditf_work_struct,
|
||||
work);
|
||||
struct sditf_priv *priv = container_of(buffree_work,
|
||||
struct sditf_priv,
|
||||
buffree_work);
|
||||
struct rkcif_rx_buffer *rx_buf = NULL;
|
||||
struct rkisp_rx_buf *dbufs = NULL;
|
||||
unsigned long flags;
|
||||
LIST_HEAD(local_list);
|
||||
|
||||
spin_lock_irqsave(&priv->cif_dev->buffree_lock, flags);
|
||||
list_replace_init(&priv->buf_free_list, &local_list);
|
||||
while (!list_empty(&local_list)) {
|
||||
dbufs = list_first_entry(&local_list,
|
||||
struct rkisp_rx_buf, list);
|
||||
if (dbufs) {
|
||||
list_del(&dbufs->list);
|
||||
rx_buf = container_of(dbufs, struct rkcif_rx_buffer, dbufs);
|
||||
if (rx_buf)
|
||||
rkcif_free_reserved_mem_buf(priv->cif_dev, rx_buf);
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&priv->cif_dev->buffree_lock, flags);
|
||||
}
|
||||
|
||||
static void sditf_get_hdr_mode(struct sditf_priv *priv)
|
||||
{
|
||||
struct rkcif_device *cif_dev = priv->cif_dev;
|
||||
@@ -474,6 +503,23 @@ static void sditf_channel_disable(struct sditf_priv *priv, int user)
|
||||
priv->toisp_inf.ch_info[2].is_valid = false;
|
||||
}
|
||||
|
||||
void sditf_change_to_online(struct sditf_priv *priv)
|
||||
{
|
||||
struct rkcif_device *cif_dev = priv->cif_dev;
|
||||
|
||||
priv->mode.rdbk_mode = RKISP_VICAP_ONLINE;
|
||||
if (priv->toisp_inf.link_mode == TOISP0) {
|
||||
sditf_channel_enable(priv, 0);
|
||||
} else if (priv->toisp_inf.link_mode == TOISP1) {
|
||||
sditf_channel_enable(priv, 1);
|
||||
} else if (priv->toisp_inf.link_mode == TOISP_UNITE) {
|
||||
sditf_channel_enable(priv, 0);
|
||||
sditf_channel_enable(priv, 1);
|
||||
}
|
||||
if (priv->hdr_cfg.hdr_mode == NO_HDR)
|
||||
rkcif_free_rx_buf(&cif_dev->stream[0], priv->buf_num);
|
||||
}
|
||||
|
||||
static int sditf_start_stream(struct sditf_priv *priv)
|
||||
{
|
||||
struct rkcif_device *cif_dev = priv->cif_dev;
|
||||
@@ -506,6 +552,7 @@ static int sditf_start_stream(struct sditf_priv *priv)
|
||||
rkcif_do_start_stream(&cif_dev->stream[1], mode);
|
||||
rkcif_do_start_stream(&cif_dev->stream[2], mode);
|
||||
}
|
||||
INIT_LIST_HEAD(&priv->buf_free_list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -604,8 +651,9 @@ static int sditf_s_rx_buffer(struct v4l2_subdev *sd,
|
||||
struct rkcif_stream *stream = NULL;
|
||||
struct rkisp_rx_buf *dbufs;
|
||||
struct rkcif_rx_buffer *rx_buf = NULL;
|
||||
unsigned long flags;
|
||||
unsigned long flags, buffree_flags;
|
||||
u32 diff_time = 1000000;
|
||||
u32 early_time = 0;
|
||||
|
||||
if (!buf) {
|
||||
v4l2_err(&cif_dev->v4l2_dev, "buf is NULL\n");
|
||||
@@ -642,80 +690,88 @@ static int sditf_s_rx_buffer(struct v4l2_subdev *sd,
|
||||
rx_buf = to_cif_rx_buf(dbufs);
|
||||
|
||||
spin_lock_irqsave(&stream->vbq_lock, flags);
|
||||
stream->buf_num_toisp++;
|
||||
stream->last_rx_buf_idx = dbufs->sequence + 1;
|
||||
|
||||
if (!list_empty(&stream->rx_buf_head) &&
|
||||
cif_dev->is_thunderboot) {
|
||||
spin_lock_irqsave(&cif_dev->buffree_lock, buffree_flags);
|
||||
list_add_tail(&dbufs->list, &priv->buf_free_list);
|
||||
spin_unlock_irqrestore(&cif_dev->buffree_lock, buffree_flags);
|
||||
schedule_work(&priv->buffree_work.work);
|
||||
}
|
||||
|
||||
if (!rx_buf->dummy.is_free) {
|
||||
list_add_tail(&dbufs->list, &stream->rx_buf_head);
|
||||
rkcif_assign_check_buffer_update_toisp(stream);
|
||||
if (cif_dev->rdbk_debug)
|
||||
memset(rx_buf->dummy.vaddr + rx_buf->dummy.size - 1920 * 10,
|
||||
0x00, 1920 * 10);
|
||||
if (cif_dev->rdbk_debug) {
|
||||
u32 offset = 0;
|
||||
|
||||
offset = rx_buf->dummy.size - stream->pixm.plane_fmt[0].bytesperline * 3;
|
||||
memset(rx_buf->dummy.vaddr + offset,
|
||||
0x00, stream->pixm.plane_fmt[0].bytesperline * 3);
|
||||
if (cif_dev->is_thunderboot)
|
||||
dma_sync_single_for_device(cif_dev->dev,
|
||||
rx_buf->dummy.dma_addr + rx_buf->dummy.size -
|
||||
stream->pixm.plane_fmt[0].bytesperline * 3,
|
||||
stream->pixm.plane_fmt[0].bytesperline * 3,
|
||||
DMA_FROM_DEVICE);
|
||||
else
|
||||
cif_dev->hw_dev->mem_ops->prepare(rx_buf->dummy.mem_priv);
|
||||
}
|
||||
}
|
||||
|
||||
if (dbufs->is_switch) {
|
||||
if (stream->is_in_vblank)
|
||||
sditf_change_to_online(priv);
|
||||
else
|
||||
stream->is_change_toisp = true;
|
||||
v4l2_dbg(3, rkcif_debug, &cif_dev->v4l2_dev,
|
||||
"switch to online mode\n");
|
||||
}
|
||||
spin_unlock_irqrestore(&stream->vbq_lock, flags);
|
||||
|
||||
if (dbufs->runtime_us && cif_dev->early_line == 0) {
|
||||
u32 numerator, denominator;
|
||||
u32 def_fps = 0;
|
||||
int line_time = 0;
|
||||
int vblank_def = 0;
|
||||
int vblank_curr = 0;
|
||||
|
||||
numerator = sensor->fi.interval.numerator;
|
||||
denominator = sensor->fi.interval.denominator;
|
||||
if (!numerator || !denominator) {
|
||||
v4l2_err(&cif_dev->v4l2_dev,
|
||||
"get frame interval fail, numerator %d, denominator %d\n",
|
||||
numerator, denominator);
|
||||
return -EINVAL;
|
||||
}
|
||||
def_fps = denominator / numerator;
|
||||
if (!def_fps) {
|
||||
v4l2_err(&cif_dev->v4l2_dev,
|
||||
"get fps fail, numerator %d, denominator %d\n",
|
||||
numerator, denominator);
|
||||
return -EINVAL;
|
||||
}
|
||||
vblank_def = rkcif_get_sensor_vblank_def(cif_dev);
|
||||
vblank_curr = rkcif_get_sensor_vblank(cif_dev);
|
||||
if (!vblank_def || !vblank_curr) {
|
||||
v4l2_err(&cif_dev->v4l2_dev,
|
||||
"get vblank fail, vblank_def %d, vblank_curr %d\n",
|
||||
vblank_def, vblank_curr);
|
||||
return -EINVAL;
|
||||
}
|
||||
line_time = div_u64(1000000000, def_fps);
|
||||
line_time = div_u64(line_time, vblank_def + sensor->raw_rect.height);
|
||||
if (!line_time) {
|
||||
v4l2_err(&cif_dev->v4l2_dev,
|
||||
"get line time fail, line_time %d\n",
|
||||
line_time);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (vblank_curr * line_time < 1000)
|
||||
v4l2_warn(&cif_dev->v4l2_dev,
|
||||
"vblank < 1ms, val %d\n",
|
||||
vblank_curr * line_time);
|
||||
if (cif_dev->sensor_linetime)
|
||||
cif_dev->sensor_linetime = rkcif_get_linetime(stream);
|
||||
cif_dev->isp_runtime_max = dbufs->runtime_us;
|
||||
cif_dev->sensor_linetime = line_time;
|
||||
cif_dev->early_line = div_u64(dbufs->runtime_us * 1000 - diff_time, line_time);
|
||||
if (cif_dev->is_thunderboot)
|
||||
diff_time = 200000;
|
||||
else
|
||||
diff_time = 1000000;
|
||||
if (dbufs->runtime_us * 1000 + cif_dev->sensor_linetime > diff_time)
|
||||
early_time = dbufs->runtime_us * 1000 - diff_time;
|
||||
else
|
||||
early_time = diff_time;
|
||||
cif_dev->early_line = div_u64(early_time, cif_dev->sensor_linetime);
|
||||
cif_dev->wait_line_cache = sensor->raw_rect.height - cif_dev->early_line;
|
||||
if (cif_dev->rdbk_debug &&
|
||||
dbufs->sequence < 15)
|
||||
v4l2_info(&cif_dev->v4l2_dev,
|
||||
"%s, isp runtime %d, line time %d, early_line %d, line_intr_cnt %d, seq %d, dma_addr %x\n",
|
||||
__func__, dbufs->runtime_us, line_time,
|
||||
__func__, dbufs->runtime_us, cif_dev->sensor_linetime,
|
||||
cif_dev->early_line, cif_dev->wait_line_cache,
|
||||
dbufs->sequence, (u32)rx_buf->dummy.dma_addr);
|
||||
} else {
|
||||
if (dbufs->runtime_us > cif_dev->isp_runtime_max + cif_dev->sensor_linetime) {
|
||||
if (dbufs->runtime_us < cif_dev->isp_runtime_max) {
|
||||
cif_dev->isp_runtime_max = dbufs->runtime_us;
|
||||
cif_dev->early_line = div_u64(dbufs->runtime_us * 1000 - diff_time, cif_dev->sensor_linetime);
|
||||
if (cif_dev->is_thunderboot)
|
||||
diff_time = 200000;
|
||||
else
|
||||
diff_time = 1000000;
|
||||
if (dbufs->runtime_us * 1000 + cif_dev->sensor_linetime > diff_time)
|
||||
early_time = dbufs->runtime_us * 1000 - diff_time;
|
||||
else
|
||||
early_time = diff_time;
|
||||
cif_dev->early_line = div_u64(early_time, cif_dev->sensor_linetime);
|
||||
cif_dev->wait_line_cache = sensor->raw_rect.height - cif_dev->early_line;
|
||||
}
|
||||
if (cif_dev->rdbk_debug &&
|
||||
dbufs->sequence < 15)
|
||||
v4l2_info(&cif_dev->v4l2_dev,
|
||||
"isp runtime %d, seq %d, dma addr %x\n",
|
||||
dbufs->runtime_us, dbufs->sequence, (u32)rx_buf->dummy.dma_addr);
|
||||
"isp runtime %d, seq %d, early_line %d, dma addr %x\n",
|
||||
dbufs->runtime_us, dbufs->sequence,
|
||||
cif_dev->early_line, (u32)rx_buf->dummy.dma_addr);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -986,7 +1042,7 @@ static int rkcif_subdev_media_init(struct sditf_priv *priv)
|
||||
strncpy(priv->sd.name, dev_name(cif_dev->dev), sizeof(priv->sd.name));
|
||||
priv->cap_info.width = 0;
|
||||
priv->cap_info.height = 0;
|
||||
priv->mode.rdbk_mode = RKISP_VICAP_ONLINE;
|
||||
priv->mode.rdbk_mode = RKISP_VICAP_RDBK_AIQ;
|
||||
priv->toisp_inf.link_mode = TOISP_NONE;
|
||||
priv->toisp_inf.ch_info[0].is_valid = false;
|
||||
priv->toisp_inf.ch_info[1].is_valid = false;
|
||||
@@ -995,6 +1051,8 @@ static int rkcif_subdev_media_init(struct sditf_priv *priv)
|
||||
sditf_subdev_notifier(priv);
|
||||
atomic_set(&priv->power_cnt, 0);
|
||||
atomic_set(&priv->stream_cnt, 0);
|
||||
INIT_WORK(&priv->buffree_work.work, sditf_buffree_work);
|
||||
INIT_LIST_HEAD(&priv->buf_free_list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,11 @@ struct toisp_info {
|
||||
enum toisp_link_mode link_mode;
|
||||
};
|
||||
|
||||
struct sditf_work_struct {
|
||||
struct work_struct work;
|
||||
struct rkisp_rx_buffer *buf;
|
||||
};
|
||||
|
||||
struct sditf_priv {
|
||||
struct device *dev;
|
||||
struct v4l2_async_notifier notifier;
|
||||
@@ -67,6 +72,8 @@ struct sditf_priv {
|
||||
struct v4l2_ctrl *pixel_rate;
|
||||
struct v4l2_ctrl_handler ctrl_handler;
|
||||
struct v4l2_subdev *sensor_sd;
|
||||
struct sditf_work_struct buffree_work;
|
||||
struct list_head buf_free_list;
|
||||
int buf_num;
|
||||
int num_sensors;
|
||||
int combine_index;
|
||||
@@ -76,5 +83,6 @@ struct sditf_priv {
|
||||
};
|
||||
|
||||
extern struct platform_driver rkcif_subdev_driver;
|
||||
void sditf_change_to_online(struct sditf_priv *priv);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user