mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
media: rockchip: isp: Solve the wrap_line frame rate problem
Change-Id: I6a949723c1b8caa90897b111a37d19f32644b6ba Signed-off-by: Lian Xu <xu.lian@rock-chips.com>
This commit is contained in:
@@ -59,6 +59,11 @@
|
||||
|
||||
struct rkisp_stream;
|
||||
|
||||
enum {
|
||||
ROCKIT_DVBM_END,
|
||||
ROCKIT_DVBM_START,
|
||||
};
|
||||
|
||||
enum {
|
||||
RDBK_L,
|
||||
RDBK_M,
|
||||
|
||||
@@ -992,6 +992,11 @@ static int mi_frame_start(struct rkisp_stream *stream, u32 mis)
|
||||
{
|
||||
unsigned long lock_flags = 0;
|
||||
|
||||
if (stream->ispdev->cap_dev.wrap_line &&
|
||||
stream->id == RKISP_STREAM_MP &&
|
||||
stream->streaming && mis != 0)
|
||||
rkisp_rockit_buf_done(stream, ROCKIT_DVBM_START);
|
||||
|
||||
/* readback start to update stream buf if null */
|
||||
spin_lock_irqsave(&stream->vbq_lock, lock_flags);
|
||||
if (stream->streaming) {
|
||||
@@ -1058,7 +1063,7 @@ static int mi_frame_end(struct rkisp_stream *stream)
|
||||
if (vb2_buf->memory)
|
||||
vb2_buffer_done(vb2_buf, VB2_BUF_STATE_DONE);
|
||||
else
|
||||
rkisp_rockit_buf_done(stream);
|
||||
rkisp_rockit_buf_done(stream, ROCKIT_DVBM_END);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&stream->vbq_lock, lock_flags);
|
||||
@@ -1716,7 +1721,8 @@ void rkisp_mi_v32_isr(u32 mis_val, struct rkisp_device *dev)
|
||||
wake_up(&stream->done);
|
||||
}
|
||||
} else {
|
||||
mi_frame_end(stream);
|
||||
if (stream->id != RKISP_STREAM_MP || !dev->cap_dev.wrap_line)
|
||||
mi_frame_end(stream);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ void rkisp_mipi_v32_isr(u32 phy, u32 packet, u32 overflow, u32 state, struct rki
|
||||
|
||||
int rkisp_rockit_buf_free(struct rkisp_stream *stream);
|
||||
void rkisp_rockit_dev_init(struct rkisp_device *dev);
|
||||
int rkisp_rockit_buf_done(struct rkisp_stream *stream);
|
||||
int rkisp_rockit_buf_done(struct rkisp_stream *stream, int cmd);
|
||||
#else
|
||||
static inline int rkisp_register_stream_v32(struct rkisp_device *dev) { return -EINVAL; }
|
||||
static inline void rkisp_unregister_stream_v32(struct rkisp_device *dev) {}
|
||||
@@ -37,7 +37,7 @@ static inline void rkisp_mipi_v32_isr(u32 phy, u32 packet, u32 overflow, u32 sta
|
||||
|
||||
static inline int rkisp_rockit_buf_free(struct rkisp_stream *stream) { return -EINVAL; }
|
||||
static inline void rkisp_rockit_dev_init(struct rkisp_device *dev) { return; }
|
||||
static inline int rkisp_rockit_buf_done(struct rkisp_stream *stream) { return -EINVAL; }
|
||||
static inline int rkisp_rockit_buf_done(struct rkisp_stream *stream, int cmd) { return -EINVAL; }
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_ROCKCHIP_DVBM)
|
||||
|
||||
@@ -95,8 +95,6 @@ int rkisp_rockit_buf_queue(struct rockit_cfg *input_rockit_cfg)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ispdev = stream->ispdev;
|
||||
g_ops = ispdev->hw_dev->mem_ops;
|
||||
stream_cfg = &rockit_cfg->rkisp_stream_cfg[stream->id];
|
||||
|
||||
for (i = 0; i < ROCKIT_BUF_NUM_MAX; i++) {
|
||||
@@ -107,6 +105,13 @@ int rkisp_rockit_buf_queue(struct rockit_cfg *input_rockit_cfg)
|
||||
}
|
||||
|
||||
stream_cfg->node = input_rockit_cfg->node;
|
||||
|
||||
if (!input_rockit_cfg->buf)
|
||||
return -EINVAL;
|
||||
|
||||
ispdev = stream->ispdev;
|
||||
g_ops = ispdev->hw_dev->mem_ops;
|
||||
|
||||
if (input_rockit_cfg->is_alloc) {
|
||||
for (i = 0; i < ROCKIT_BUF_NUM_MAX; i++) {
|
||||
if (stream_cfg->buff_id[i] == 0) {
|
||||
@@ -124,6 +129,8 @@ int rkisp_rockit_buf_queue(struct rockit_cfg *input_rockit_cfg)
|
||||
return -EINVAL;
|
||||
|
||||
isprk_buf = stream_cfg->rkisp_buff[i];
|
||||
isprk_buf->mpi_buf = input_rockit_cfg->mpibuf;
|
||||
|
||||
mem = g_ops->attach_dmabuf(stream->ispdev->hw_dev->dev,
|
||||
input_rockit_cfg->buf,
|
||||
input_rockit_cfg->buf->size,
|
||||
@@ -133,7 +140,6 @@ int rkisp_rockit_buf_queue(struct rockit_cfg *input_rockit_cfg)
|
||||
|
||||
isprk_buf->mpi_mem = mem;
|
||||
isprk_buf->dmabuf = input_rockit_cfg->buf;
|
||||
isprk_buf->mpi_buf = input_rockit_cfg->mpibuf;
|
||||
|
||||
ret = g_ops->map_dmabuf(mem);
|
||||
if (ret)
|
||||
@@ -153,14 +159,13 @@ int rkisp_rockit_buf_queue(struct rockit_cfg *input_rockit_cfg)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < stream->out_isp_fmt.mplanes; i++)
|
||||
isprk_buf->isp_buf.buff_addr[i] = isprk_buf->buff_addr;
|
||||
|
||||
if (stream->out_isp_fmt.mplanes == 1) {
|
||||
for (i = 0; i < stream->out_isp_fmt.cplanes - 1; i++) {
|
||||
height = stream->out_fmt.height;
|
||||
if (ispdev->cap_dev.wrap_line && stream->id == RKISP_STREAM_MP)
|
||||
height = ispdev->cap_dev.wrap_line;
|
||||
offset = (i == 0) ?
|
||||
stream->out_fmt.plane_fmt[i].bytesperline * height :
|
||||
stream->out_fmt.plane_fmt[i].sizeimage;
|
||||
@@ -189,18 +194,39 @@ int rkisp_rockit_buf_queue(struct rockit_cfg *input_rockit_cfg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rkisp_rockit_buf_done(struct rkisp_stream *stream)
|
||||
int rkisp_rockit_buf_done(struct rkisp_stream *stream, int cmd)
|
||||
{
|
||||
struct rkisp_device *dev = stream->ispdev;
|
||||
struct rkisp_rockit_buffer *isprk_buf =
|
||||
container_of(stream->curr_buf, struct rkisp_rockit_buffer, isp_buf);
|
||||
struct rkisp_rockit_buffer *isprk_buf = NULL;
|
||||
struct rkisp_stream_cfg *stream_cfg = &rockit_cfg->rkisp_stream_cfg[stream->id];
|
||||
u32 seq;
|
||||
u64 ns = 0;
|
||||
|
||||
if (!rockit_cfg->rkisp_rockit_mpibuf_done) {
|
||||
pr_err("mpi_buf_done is null\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (stream->curr_buf != NULL) {
|
||||
isprk_buf =
|
||||
container_of(stream->curr_buf, struct rkisp_rockit_buffer, isp_buf);
|
||||
|
||||
rockit_cfg->mpibuf = isprk_buf->mpi_buf;
|
||||
|
||||
rockit_cfg->frame.u64PTS = stream->curr_buf->vb.vb2_buf.timestamp;
|
||||
|
||||
rockit_cfg->frame.u32TimeRef = stream->curr_buf->vb.sequence;
|
||||
} else {
|
||||
rkisp_dmarx_get_frame(stream->ispdev, &seq, NULL, &ns, true);
|
||||
|
||||
if (!ns)
|
||||
ns = ktime_get_ns();
|
||||
|
||||
rockit_cfg->frame.u64PTS = ns;
|
||||
|
||||
rockit_cfg->frame.u32TimeRef = seq;
|
||||
}
|
||||
|
||||
rockit_cfg->frame.u32Height = stream->out_fmt.height;
|
||||
|
||||
rockit_cfg->frame.u32Width = stream->out_fmt.width;
|
||||
@@ -211,15 +237,11 @@ int rkisp_rockit_buf_done(struct rkisp_stream *stream)
|
||||
|
||||
rockit_cfg->frame.u32VirHeight = stream->out_fmt.height;
|
||||
|
||||
rockit_cfg->frame.u64PTS = stream->curr_buf->vb.vb2_buf.timestamp;
|
||||
|
||||
rockit_cfg->frame.u32TimeRef = stream->curr_buf->vb.sequence;
|
||||
|
||||
rockit_cfg->current_name = dev->name;
|
||||
|
||||
rockit_cfg->node = stream_cfg->node;
|
||||
|
||||
rockit_cfg->mpibuf = isprk_buf->mpi_buf;
|
||||
rockit_cfg->event = cmd;
|
||||
|
||||
if (list_empty(&stream->buf_queue))
|
||||
rockit_cfg->is_empty = true;
|
||||
|
||||
@@ -47,21 +47,22 @@ struct rkisp_dev_cfg {
|
||||
};
|
||||
|
||||
struct rockit_cfg {
|
||||
u32 nick_id;
|
||||
int *buff_id;
|
||||
int mpi_id;
|
||||
void *vvi_dev[ROCKIT_ISP_NUM_MAX];
|
||||
void *node;
|
||||
void *mpibuf;
|
||||
char *current_name;
|
||||
bool is_alloc;
|
||||
bool is_empty;
|
||||
struct dma_buf *buf;
|
||||
char *current_name;
|
||||
dma_addr_t dma_addr;
|
||||
int *buff_id;
|
||||
int mpi_id;
|
||||
int isp_num;
|
||||
u32 nick_id;
|
||||
u32 event;
|
||||
void *node;
|
||||
void *mpibuf;
|
||||
void *vvi_dev[ROCKIT_ISP_NUM_MAX];
|
||||
struct dma_buf *buf;
|
||||
struct ISP_VIDEO_FRAMES frame;
|
||||
struct rkisp_dev_cfg rkisp_dev_cfg[ROCKIT_ISP_NUM_MAX];
|
||||
struct rkisp_stream_cfg rkisp_stream_cfg[ROCKIT_STREAM_NUM_MAX];
|
||||
int isp_num;
|
||||
int (*rkisp_rockit_mpibuf_done)(struct rockit_cfg *rockit_isp_cfg);
|
||||
};
|
||||
|
||||
@@ -73,7 +74,7 @@ int rkisp_rockit_buf_queue(struct rockit_cfg *input_rockit_cfg);
|
||||
|
||||
#else
|
||||
|
||||
static inline void rkisp_rockit_function_register(void *function, int cmd) { return }
|
||||
static inline void *rkisp_rockit_function_register(void *function, int cmd) { return NULL; }
|
||||
static inline int rkisp_rockit_get_ispdev(char **name) { return -EINVAL; }
|
||||
static inline int rkisp_rockit_buf_queue(struct rockit_cfg *input_rockit_cfg)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user