Commit a1192a17 authored by Philipp Zabel's avatar Philipp Zabel Committed by Mauro Carvalho Chehab

[media] coda: add context ops

Add a struct coda_context_ops that encapsulates context specific operations.
This will simplify adding JPEG support in the future and helps to avoid
exporting all functions individually when they move out of the main code
file.
Signed-off-by: default avatarPhilipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: default avatarKamil Debski <k.debski@samsung.com>
Signed-off-by: default avatarMauro Carvalho Chehab <m.chehab@samsung.com>
parent a2b3e46a
...@@ -800,7 +800,7 @@ static const struct v4l2_ioctl_ops coda_ioctl_ops = { ...@@ -800,7 +800,7 @@ static const struct v4l2_ioctl_ops coda_ioctl_ops = {
.vidioc_unsubscribe_event = v4l2_event_unsubscribe, .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
}; };
static int coda_start_decoding(struct coda_ctx *ctx); static int __coda_start_decoding(struct coda_ctx *ctx);
static inline int coda_get_bitstream_payload(struct coda_ctx *ctx) static inline int coda_get_bitstream_payload(struct coda_ctx *ctx)
{ {
...@@ -976,7 +976,7 @@ static int coda_prepare_decode(struct coda_ctx *ctx) ...@@ -976,7 +976,7 @@ static int coda_prepare_decode(struct coda_ctx *ctx)
/* Run coda_start_decoding (again) if not yet initialized */ /* Run coda_start_decoding (again) if not yet initialized */
if (!ctx->initialized) { if (!ctx->initialized) {
int ret = coda_start_decoding(ctx); int ret = __coda_start_decoding(ctx);
if (ret < 0) { if (ret < 0) {
v4l2_err(&dev->v4l2_dev, "failed to start decoding\n"); v4l2_err(&dev->v4l2_dev, "failed to start decoding\n");
v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx); v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx);
...@@ -1041,7 +1041,7 @@ static int coda_prepare_decode(struct coda_ctx *ctx) ...@@ -1041,7 +1041,7 @@ static int coda_prepare_decode(struct coda_ctx *ctx)
return 0; return 0;
} }
static void coda_prepare_encode(struct coda_ctx *ctx) static int coda_prepare_encode(struct coda_ctx *ctx)
{ {
struct coda_q_data *q_data_src, *q_data_dst; struct coda_q_data *q_data_src, *q_data_dst;
struct vb2_buffer *src_buf, *dst_buf; struct vb2_buffer *src_buf, *dst_buf;
...@@ -1183,6 +1183,8 @@ static void coda_prepare_encode(struct coda_ctx *ctx) ...@@ -1183,6 +1183,8 @@ static void coda_prepare_encode(struct coda_ctx *ctx)
ctx->bit_stream_param |= CODA_BIT_STREAM_END_FLAG; ctx->bit_stream_param |= CODA_BIT_STREAM_END_FLAG;
coda_write(dev, ctx->bit_stream_param, CODA_REG_BIT_BIT_STREAM_PARAM); coda_write(dev, ctx->bit_stream_param, CODA_REG_BIT_BIT_STREAM_PARAM);
} }
return 0;
} }
static void coda_device_run(void *m2m_priv) static void coda_device_run(void *m2m_priv)
...@@ -1233,17 +1235,13 @@ static void coda_pic_run_work(struct work_struct *work) ...@@ -1233,17 +1235,13 @@ static void coda_pic_run_work(struct work_struct *work)
mutex_lock(&ctx->buffer_mutex); mutex_lock(&ctx->buffer_mutex);
mutex_lock(&dev->coda_mutex); mutex_lock(&dev->coda_mutex);
if (ctx->inst_type == CODA_INST_DECODER) { ret = ctx->ops->prepare_run(ctx);
ret = coda_prepare_decode(ctx); if (ret < 0 && ctx->inst_type == CODA_INST_DECODER) {
if (ret < 0) {
mutex_unlock(&dev->coda_mutex); mutex_unlock(&dev->coda_mutex);
mutex_unlock(&ctx->buffer_mutex); mutex_unlock(&ctx->buffer_mutex);
/* job_finish scheduled by prepare_decode */ /* job_finish scheduled by prepare_decode */
return; return;
} }
} else {
coda_prepare_encode(ctx);
}
if (dev->devtype->product != CODA_DX6) if (dev->devtype->product != CODA_DX6)
coda_write(dev, ctx->iram_info.axi_sram_use, coda_write(dev, ctx->iram_info.axi_sram_use,
...@@ -1260,10 +1258,7 @@ static void coda_pic_run_work(struct work_struct *work) ...@@ -1260,10 +1258,7 @@ static void coda_pic_run_work(struct work_struct *work)
coda_hw_reset(ctx); coda_hw_reset(ctx);
} else if (!ctx->aborting) { } else if (!ctx->aborting) {
if (ctx->inst_type == CODA_INST_DECODER) ctx->ops->finish_run(ctx);
coda_finish_decode(ctx);
else
coda_finish_encode(ctx);
} }
if (ctx->aborting || (!ctx->streamon_cap && !ctx->streamon_out)) if (ctx->aborting || (!ctx->streamon_cap && !ctx->streamon_out))
...@@ -1846,7 +1841,7 @@ static int coda_alloc_context_buffers(struct coda_ctx *ctx, ...@@ -1846,7 +1841,7 @@ static int coda_alloc_context_buffers(struct coda_ctx *ctx,
return ret; return ret;
} }
static int coda_start_decoding(struct coda_ctx *ctx) static int __coda_start_decoding(struct coda_ctx *ctx)
{ {
struct coda_q_data *q_data_src, *q_data_dst; struct coda_q_data *q_data_src, *q_data_dst;
u32 bitstream_buf, bitstream_size; u32 bitstream_buf, bitstream_size;
...@@ -2037,6 +2032,18 @@ static int coda_start_decoding(struct coda_ctx *ctx) ...@@ -2037,6 +2032,18 @@ static int coda_start_decoding(struct coda_ctx *ctx)
return 0; return 0;
} }
static int coda_start_decoding(struct coda_ctx *ctx)
{
struct coda_dev *dev = ctx->dev;
int ret;
mutex_lock(&dev->coda_mutex);
ret = __coda_start_decoding(ctx);
mutex_unlock(&dev->coda_mutex);
return ret;
}
static int coda_encode_header(struct coda_ctx *ctx, struct vb2_buffer *buf, static int coda_encode_header(struct coda_ctx *ctx, struct vb2_buffer *buf,
int header_code, u8 *header, int *size) int header_code, u8 *header, int *size)
{ {
...@@ -2081,7 +2088,6 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count) ...@@ -2081,7 +2088,6 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
{ {
struct coda_ctx *ctx = vb2_get_drv_priv(q); struct coda_ctx *ctx = vb2_get_drv_priv(q);
struct v4l2_device *v4l2_dev = &ctx->dev->v4l2_dev; struct v4l2_device *v4l2_dev = &ctx->dev->v4l2_dev;
struct coda_dev *dev = ctx->dev;
struct coda_q_data *q_data_src, *q_data_dst; struct coda_q_data *q_data_src, *q_data_dst;
u32 dst_fourcc; u32 dst_fourcc;
int ret = 0; int ret = 0;
...@@ -2133,16 +2139,12 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count) ...@@ -2133,16 +2139,12 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = ctx->ops->start_streaming(ctx);
if (ctx->inst_type == CODA_INST_DECODER) { if (ctx->inst_type == CODA_INST_DECODER) {
mutex_lock(&dev->coda_mutex);
ret = coda_start_decoding(ctx);
mutex_unlock(&dev->coda_mutex);
if (ret == -EAGAIN) if (ret == -EAGAIN)
return 0; return 0;
else if (ret < 0) else if (ret < 0)
return ret; return ret;
} else {
ret = coda_start_encoding(ctx);
} }
ctx->initialized = 1; ctx->initialized = 1;
...@@ -2737,10 +2739,9 @@ static int coda_next_free_instance(struct coda_dev *dev) ...@@ -2737,10 +2739,9 @@ static int coda_next_free_instance(struct coda_dev *dev)
return idx; return idx;
} }
static int coda_open(struct file *file, enum coda_inst_type inst_type) static int coda_open(struct file *file, enum coda_inst_type inst_type,
const struct coda_context_ops *ctx_ops)
{ {
int (*queue_init)(void *priv, struct vb2_queue *src_vq,
struct vb2_queue *dst_vq);
struct coda_dev *dev = video_drvdata(file); struct coda_dev *dev = video_drvdata(file);
struct coda_ctx *ctx = NULL; struct coda_ctx *ctx = NULL;
char *name; char *name;
...@@ -2763,9 +2764,10 @@ static int coda_open(struct file *file, enum coda_inst_type inst_type) ...@@ -2763,9 +2764,10 @@ static int coda_open(struct file *file, enum coda_inst_type inst_type)
kfree(name); kfree(name);
ctx->inst_type = inst_type; ctx->inst_type = inst_type;
ctx->ops = ctx_ops;
init_completion(&ctx->completion); init_completion(&ctx->completion);
INIT_WORK(&ctx->pic_run_work, coda_pic_run_work); INIT_WORK(&ctx->pic_run_work, coda_pic_run_work);
INIT_WORK(&ctx->seq_end_work, coda_seq_end_work); INIT_WORK(&ctx->seq_end_work, ctx->ops->seq_end_work);
v4l2_fh_init(&ctx->fh, video_devdata(file)); v4l2_fh_init(&ctx->fh, video_devdata(file));
file->private_data = &ctx->fh; file->private_data = &ctx->fh;
v4l2_fh_add(&ctx->fh); v4l2_fh_add(&ctx->fh);
...@@ -2796,11 +2798,8 @@ static int coda_open(struct file *file, enum coda_inst_type inst_type) ...@@ -2796,11 +2798,8 @@ static int coda_open(struct file *file, enum coda_inst_type inst_type)
goto err_clk_ahb; goto err_clk_ahb;
set_default_params(ctx); set_default_params(ctx);
if (inst_type == CODA_INST_ENCODER) ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx,
queue_init = coda_encoder_queue_init; ctx->ops->queue_init);
else
queue_init = coda_decoder_queue_init;
ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, queue_init);
if (IS_ERR(ctx->fh.m2m_ctx)) { if (IS_ERR(ctx->fh.m2m_ctx)) {
ret = PTR_ERR(ctx->fh.m2m_ctx); ret = PTR_ERR(ctx->fh.m2m_ctx);
...@@ -2871,14 +2870,30 @@ static int coda_open(struct file *file, enum coda_inst_type inst_type) ...@@ -2871,14 +2870,30 @@ static int coda_open(struct file *file, enum coda_inst_type inst_type)
return ret; return ret;
} }
struct coda_context_ops coda_encode_ops = {
.queue_init = coda_encoder_queue_init,
.start_streaming = coda_start_encoding,
.prepare_run = coda_prepare_encode,
.finish_run = coda_finish_encode,
.seq_end_work = coda_seq_end_work,
};
struct coda_context_ops coda_decode_ops = {
.queue_init = coda_decoder_queue_init,
.start_streaming = coda_start_decoding,
.prepare_run = coda_prepare_decode,
.finish_run = coda_finish_decode,
.seq_end_work = coda_seq_end_work
};
static int coda_encoder_open(struct file *file) static int coda_encoder_open(struct file *file)
{ {
return coda_open(file, CODA_INST_ENCODER); return coda_open(file, CODA_INST_ENCODER, &coda_encode_ops);
} }
static int coda_decoder_open(struct file *file) static int coda_decoder_open(struct file *file)
{ {
return coda_open(file, CODA_INST_DECODER); return coda_open(file, CODA_INST_DECODER, &coda_decode_ops);
} }
static int coda_release(struct file *file) static int coda_release(struct file *file)
......
...@@ -164,6 +164,18 @@ struct gdi_tiled_map { ...@@ -164,6 +164,18 @@ struct gdi_tiled_map {
#define GDI_LINEAR_FRAME_MAP 0 #define GDI_LINEAR_FRAME_MAP 0
}; };
struct coda_ctx;
struct coda_context_ops {
int (*queue_init)(void *priv, struct vb2_queue *src_vq,
struct vb2_queue *dst_vq);
int (*start_streaming)(struct coda_ctx *ctx);
int (*prepare_run)(struct coda_ctx *ctx);
void (*finish_run)(struct coda_ctx *ctx);
void (*seq_end_work)(struct work_struct *work);
void (*release)(struct coda_ctx *ctx);
};
struct coda_ctx { struct coda_ctx {
struct coda_dev *dev; struct coda_dev *dev;
struct mutex buffer_mutex; struct mutex buffer_mutex;
...@@ -171,6 +183,7 @@ struct coda_ctx { ...@@ -171,6 +183,7 @@ struct coda_ctx {
struct work_struct pic_run_work; struct work_struct pic_run_work;
struct work_struct seq_end_work; struct work_struct seq_end_work;
struct completion completion; struct completion completion;
const struct coda_context_ops *ops;
int aborting; int aborting;
int initialized; int initialized;
int streamon_out; int streamon_out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment