media: rockchip: isp: api get fast stream output info

Change-Id: I770906113078104b22731a83bf3280331f3ac15e
Signed-off-by: Cai YiWei <cyw@rock-chips.com>
This commit is contained in:
Cai YiWei 2022-06-23 16:17:36 +08:00 committed by Tao Huang
parent c10b7526e9
commit 6977a0278f
4 changed files with 81 additions and 12 deletions

View File

@ -1481,6 +1481,24 @@ static int rkisp_get_fps(struct rkisp_stream *stream, int *fps)
return rkisp_rockit_fps_get(fps, stream);
}
static int rkisp_get_tb_stream_info(struct rkisp_stream *stream,
struct rkisp_tb_stream_info *info)
{
struct rkisp_device *dev = stream->ispdev;
if (stream->id != RKISP_STREAM_MP) {
v4l2_err(&dev->v4l2_dev, "fast only support for MP\n");
return -EINVAL;
}
if (!dev->tb_stream_info.buf_max) {
v4l2_err(&dev->v4l2_dev, "thunderboot no enough memory for image\n");
return -EINVAL;
}
memcpy(info, &dev->tb_stream_info, sizeof(*info));
return 0;
}
static long rkisp_ioctl_default(struct file *file, void *fh,
bool valid_prio, unsigned int cmd, void *arg)
{
@ -1545,6 +1563,9 @@ static long rkisp_ioctl_default(struct file *file, void *fh,
case RKISP_CMD_GET_FPS:
ret = rkisp_get_fps(stream, arg);
break;
case RKISP_CMD_GET_TB_STREAM_INFO:
ret = rkisp_get_tb_stream_info(stream, arg);
break;
default:
ret = -EINVAL;
}
@ -1801,6 +1822,8 @@ static void rkisp_stream_fast(struct work_struct *work)
struct rkisp_stream *stream = &cap_dev->stream[0];
struct vb2_queue *q = &stream->vnode.buf_queue;
struct rkisp_device *ispdev = cap_dev->ispdev;
struct rkisp_tb_stream_info *info = &ispdev->tb_stream_info;
u32 i;
v4l2_pipeline_pm_get(&stream->vnode.vdev.entity);
rkisp_chk_tb_over(ispdev);
@ -1810,12 +1833,23 @@ static void rkisp_stream_fast(struct work_struct *work)
}
stream->is_pre_on = true;
stream->is_using_resmem = true;
ispdev->resmem_addr_curr = ispdev->resmem_addr;
if (ispdev->resmem_size < stream->out_fmt.plane_fmt[0].sizeimage) {
info->width = stream->out_fmt.width;
info->height = stream->out_fmt.height;
info->bytesperline = stream->out_fmt.plane_fmt[0].bytesperline;
info->frame_size = info->bytesperline * ALIGN(info->height, 16) * 3 / 2;
info->buf_max = ispdev->resmem_size / info->frame_size;
if (!info->buf_max) {
stream->is_using_resmem = false;
v4l2_warn(&ispdev->v4l2_dev,
"resmem size:%zu no enough for image:%d\n",
ispdev->resmem_size, stream->out_fmt.plane_fmt[0].sizeimage);
ispdev->resmem_size, info->frame_size);
} else {
ispdev->tb_addr_idx = 0;
info->buf_cnt = 0;
if (info->buf_max > RKISP_TB_STREAM_BUF_MAX)
info->buf_max = RKISP_TB_STREAM_BUF_MAX;
for (i = 0; i < info->buf_max; i++)
info->buf[i].dma_addr = ispdev->resmem_addr + i * info->frame_size;
}
q->ops->start_streaming(q, 1);
}

View File

@ -799,20 +799,16 @@ static void update_mi(struct rkisp_stream *stream)
}
} else if (stream->is_using_resmem) {
/* resmem for fast stream NV12 output */
dma_addr_t max_addr = dev->resmem_addr + dev->resmem_size;
u32 bytesperline = stream->out_fmt.plane_fmt[0].bytesperline;
u32 buf_size = bytesperline * ALIGN(stream->out_fmt.height, 16) * 3 / 2;
reg = stream->config->mi.y_base_ad_init;
val = dev->resmem_addr_curr;
val = dev->tb_stream_info.buf[dev->tb_addr_idx].dma_addr;
rkisp_write(dev, reg, val, false);
reg = stream->config->mi.cb_base_ad_init;
val += bytesperline * stream->out_fmt.height;
val += dev->tb_stream_info.bytesperline * stream->out_fmt.height;
rkisp_write(dev, reg, val, false);
if (dev->resmem_addr_curr + buf_size * 2 <= max_addr)
dev->resmem_addr_curr += buf_size;
if (dev->tb_addr_idx < dev->tb_stream_info.buf_max - 1)
dev->tb_addr_idx++;
} else if (!stream->is_pause) {
stream->is_pause = true;
stream->ops->disable_mi(stream);
@ -1759,6 +1755,17 @@ void rkisp_mi_v32_isr(u32 mis_val, struct rkisp_device *dev)
stream->dbg.timestamp = ns;
stream->dbg.id = seq;
if (stream->is_using_resmem) {
struct rkisp_tb_stream_info *tb_info = &dev->tb_stream_info;
u32 idx;
if (tb_info->buf_cnt < tb_info->buf_max)
tb_info->buf_cnt++;
idx = tb_info->buf_cnt - 1;
dev->tb_stream_info.buf[idx].sequence = seq;
dev->tb_stream_info.buf[idx].timestamp = ns;
}
if (stream->stopping) {
/*
* Make sure stream is actually stopped, whose state

View File

@ -210,12 +210,15 @@ struct rkisp_device {
struct mutex apilock; /* mutex to serialize the calls of stream */
struct mutex iqlock; /* mutex to serialize the calls of iq */
wait_queue_head_t sync_onoff;
dma_addr_t resmem_addr;
phys_addr_t resmem_pa;
dma_addr_t resmem_addr_curr;
size_t resmem_size;
struct rkisp_thunderboot_resmem_head tb_head;
bool is_thunderboot;
struct rkisp_tb_stream_info tb_stream_info;
unsigned int tb_addr_idx;
int dev_id;
unsigned int skip_frame;
unsigned int irq_ends;

View File

@ -86,6 +86,9 @@
#define RKISP_CMD_GET_FPS \
_IOR('V', BASE_VIDIOC_PRIVATE + 110, int)
#define RKISP_CMD_GET_TB_STREAM_INFO \
_IOR('V', BASE_VIDIOC_PRIVATE + 111, struct rkisp_tb_stream_info)
/*************************************************************/
#define ISP2X_ID_DPCC (0)
@ -368,6 +371,28 @@ struct rkisp_mirror_flip {
unsigned char flip;
} __attribute__ ((packed));
#define RKISP_TB_STREAM_BUF_MAX 5
struct rkisp_tb_stream_buf {
unsigned int dma_addr;
unsigned int sequence;
long long timestamp;
} __attribute__ ((packed));
/* struct rkisp_tb_stream_info
* frame_size: nv12 frame buf size, bytesperline * height_16align * 1.5
* buf_max: memory size / frame_size
* buf_cnt: the num of frame write to buf.
*/
struct rkisp_tb_stream_info {
unsigned int width;
unsigned int height;
unsigned int bytesperline;
unsigned int frame_size;
unsigned int buf_max;
unsigned int buf_cnt;
struct rkisp_tb_stream_buf buf[RKISP_TB_STREAM_BUF_MAX];
} __attribute__ ((packed));
/* trigger event mode
* T_TRY: trigger maybe with retry
* T_TRY_YES: trigger to retry