mirror of
https://github.com/torvalds/linux.git
synced 2026-05-23 06:31:58 +02:00
media: mtk-vcodec: Add irq interface for multi hardware
Adds irq interface for multi hardware. Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
This commit is contained in:
parent
19faef3f6c
commit
770eb47f77
|
|
@ -24,6 +24,19 @@
|
|||
#include "mtk_vcodec_util.h"
|
||||
#include "mtk_vcodec_fw.h"
|
||||
|
||||
static int mtk_vcodec_get_hw_count(struct mtk_vcodec_dev *dev)
|
||||
{
|
||||
switch (dev->vdec_pdata->hw_arch) {
|
||||
case MTK_VDEC_PURE_SINGLE_CORE:
|
||||
return MTK_VDEC_ONE_CORE;
|
||||
case MTK_VDEC_LAT_SINGLE_CORE:
|
||||
return MTK_VDEC_ONE_LAT_ONE_CORE;
|
||||
default:
|
||||
mtk_v4l2_err("hw arch %d not supported", dev->vdec_pdata->hw_arch);
|
||||
return MTK_VDEC_NO_HW;
|
||||
}
|
||||
}
|
||||
|
||||
static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
|
||||
{
|
||||
struct mtk_vcodec_dev *dev = priv;
|
||||
|
|
@ -55,7 +68,7 @@ static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
|
|||
writel((readl(vdec_misc_addr) & ~VDEC_IRQ_CLR),
|
||||
dev->reg_base[VDEC_MISC] + VDEC_IRQ_CFG_REG);
|
||||
|
||||
wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED);
|
||||
wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, 0);
|
||||
|
||||
mtk_v4l2_debug(3,
|
||||
"mtk_vcodec_dec_irq_handler :wake up ctx %d, dec_done_status=%x",
|
||||
|
|
@ -128,7 +141,7 @@ static int fops_vcodec_open(struct file *file)
|
|||
{
|
||||
struct mtk_vcodec_dev *dev = video_drvdata(file);
|
||||
struct mtk_vcodec_ctx *ctx = NULL;
|
||||
int ret = 0;
|
||||
int ret = 0, i, hw_count;
|
||||
struct vb2_queue *src_vq;
|
||||
|
||||
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
|
||||
|
|
@ -142,14 +155,24 @@ static int fops_vcodec_open(struct file *file)
|
|||
v4l2_fh_add(&ctx->fh);
|
||||
INIT_LIST_HEAD(&ctx->list);
|
||||
ctx->dev = dev;
|
||||
init_waitqueue_head(&ctx->queue);
|
||||
mutex_init(&ctx->lock);
|
||||
if (ctx->dev->vdec_pdata->is_subdev_supported) {
|
||||
hw_count = mtk_vcodec_get_hw_count(dev);
|
||||
if (!hw_count || !dev->subdev_prob_done) {
|
||||
ret = -EINVAL;
|
||||
goto err_ctrls_setup;
|
||||
}
|
||||
|
||||
if (dev->vdec_pdata->is_subdev_supported && dev->subdev_prob_done) {
|
||||
ret = dev->subdev_prob_done(dev);
|
||||
if (ret)
|
||||
goto err_ctrls_setup;
|
||||
|
||||
for (i = 0; i < hw_count; i++)
|
||||
init_waitqueue_head(&ctx->queue[i]);
|
||||
} else {
|
||||
init_waitqueue_head(&ctx->queue[0]);
|
||||
}
|
||||
mutex_init(&ctx->lock);
|
||||
|
||||
ctx->type = MTK_INST_DECODER;
|
||||
ret = dev->vdec_pdata->ctrls_setup(ctx);
|
||||
if (ret) {
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ static irqreturn_t mtk_vdec_hw_irq_handler(int irq, void *priv)
|
|||
writel(dec_done_status | VDEC_IRQ_CFG, vdec_misc_addr);
|
||||
writel(dec_done_status & ~VDEC_IRQ_CLR, vdec_misc_addr);
|
||||
|
||||
wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED);
|
||||
wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, dev->hw_idx);
|
||||
|
||||
mtk_v4l2_debug(3, "wake up ctx %d, dec_done_status=%x",
|
||||
ctx->id, dec_done_status);
|
||||
|
|
|
|||
|
|
@ -104,6 +104,16 @@ enum mtk_vdec_hw_id {
|
|||
MTK_VDEC_HW_MAX,
|
||||
};
|
||||
|
||||
/*
|
||||
* enum mtk_vdec_hw_count - Supported hardware count
|
||||
*/
|
||||
enum mtk_vdec_hw_count {
|
||||
MTK_VDEC_NO_HW = 0,
|
||||
MTK_VDEC_ONE_CORE,
|
||||
MTK_VDEC_ONE_LAT_ONE_CORE,
|
||||
MTK_VDEC_MAX_HW_COUNT,
|
||||
};
|
||||
|
||||
/*
|
||||
* struct mtk_video_fmt - Structure used to store information about pixelformats
|
||||
*/
|
||||
|
|
@ -293,9 +303,9 @@ struct mtk_vcodec_ctx {
|
|||
struct vdec_pic_info picinfo;
|
||||
int dpb_size;
|
||||
|
||||
int int_cond;
|
||||
int int_type;
|
||||
wait_queue_head_t queue;
|
||||
int int_cond[MTK_VDEC_HW_MAX];
|
||||
int int_type[MTK_VDEC_HW_MAX];
|
||||
wait_queue_head_t queue[MTK_VDEC_HW_MAX];
|
||||
unsigned int irq_status;
|
||||
|
||||
struct v4l2_ctrl_handler ctrl_hdl;
|
||||
|
|
@ -504,11 +514,12 @@ static inline struct mtk_vcodec_ctx *ctrl_to_ctx(struct v4l2_ctrl *ctrl)
|
|||
}
|
||||
|
||||
/* Wake up context wait_queue */
|
||||
static inline void wake_up_ctx(struct mtk_vcodec_ctx *ctx, unsigned int reason)
|
||||
static inline void
|
||||
wake_up_ctx(struct mtk_vcodec_ctx *ctx, unsigned int reason, unsigned int hw_id)
|
||||
{
|
||||
ctx->int_cond = 1;
|
||||
ctx->int_type = reason;
|
||||
wake_up_interruptible(&ctx->queue);
|
||||
ctx->int_cond[hw_id] = 1;
|
||||
ctx->int_type[hw_id] = reason;
|
||||
wake_up_interruptible(&ctx->queue[hw_id]);
|
||||
}
|
||||
|
||||
#endif /* _MTK_VCODEC_DRV_H_ */
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ static irqreturn_t mtk_vcodec_enc_irq_handler(int irq, void *priv)
|
|||
|
||||
clean_irq_status(ctx->irq_status, addr);
|
||||
|
||||
wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED);
|
||||
wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, 0);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
|
@ -129,7 +129,7 @@ static int fops_vcodec_open(struct file *file)
|
|||
v4l2_fh_add(&ctx->fh);
|
||||
INIT_LIST_HEAD(&ctx->list);
|
||||
ctx->dev = dev;
|
||||
init_waitqueue_head(&ctx->queue);
|
||||
init_waitqueue_head(&ctx->queue[0]);
|
||||
|
||||
ctx->type = MTK_INST_ENCODER;
|
||||
ret = mtk_vcodec_enc_ctrls_setup(ctx);
|
||||
|
|
|
|||
|
|
@ -11,34 +11,32 @@
|
|||
#include "mtk_vcodec_intr.h"
|
||||
#include "mtk_vcodec_util.h"
|
||||
|
||||
int mtk_vcodec_wait_for_done_ctx(struct mtk_vcodec_ctx *ctx, int command,
|
||||
unsigned int timeout_ms)
|
||||
int mtk_vcodec_wait_for_done_ctx(struct mtk_vcodec_ctx *ctx,
|
||||
int command, unsigned int timeout_ms,
|
||||
unsigned int hw_id)
|
||||
{
|
||||
wait_queue_head_t *waitqueue;
|
||||
long timeout_jiff, ret;
|
||||
int status = 0;
|
||||
|
||||
waitqueue = (wait_queue_head_t *)&ctx->queue;
|
||||
timeout_jiff = msecs_to_jiffies(timeout_ms);
|
||||
|
||||
ret = wait_event_interruptible_timeout(*waitqueue,
|
||||
ctx->int_cond,
|
||||
timeout_jiff);
|
||||
ret = wait_event_interruptible_timeout(ctx->queue[hw_id],
|
||||
ctx->int_cond[hw_id],
|
||||
timeout_jiff);
|
||||
|
||||
if (!ret) {
|
||||
status = -1; /* timeout */
|
||||
mtk_v4l2_err("[%d] ctx->type=%d, cmd=%d, wait_event_interruptible_timeout time=%ums out %d %d!",
|
||||
ctx->id, ctx->type, command, timeout_ms,
|
||||
ctx->int_cond, ctx->int_type);
|
||||
mtk_v4l2_err("[%d] cmd=%d, type=%d, dec timeout=%ums (%d %d)",
|
||||
ctx->id, command, ctx->type, timeout_ms,
|
||||
ctx->int_cond[hw_id], ctx->int_type[hw_id]);
|
||||
} else if (-ERESTARTSYS == ret) {
|
||||
mtk_v4l2_err("[%d] ctx->type=%d, cmd=%d, wait_event_interruptible_timeout interrupted by a signal %d %d",
|
||||
ctx->id, ctx->type, command, ctx->int_cond,
|
||||
ctx->int_type);
|
||||
status = -1;
|
||||
mtk_v4l2_err("[%d] cmd=%d, type=%d, dec inter fail (%d %d)",
|
||||
ctx->id, command, ctx->type,
|
||||
ctx->int_cond[hw_id], ctx->int_type[hw_id]);
|
||||
}
|
||||
|
||||
ctx->int_cond = 0;
|
||||
ctx->int_type = 0;
|
||||
ctx->int_cond[hw_id] = 0;
|
||||
ctx->int_type[hw_id] = 0;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@
|
|||
struct mtk_vcodec_ctx;
|
||||
|
||||
/* timeout is ms */
|
||||
int mtk_vcodec_wait_for_done_ctx(struct mtk_vcodec_ctx *data, int command,
|
||||
unsigned int timeout_ms);
|
||||
int mtk_vcodec_wait_for_done_ctx(struct mtk_vcodec_ctx *ctx,
|
||||
int command, unsigned int timeout_ms,
|
||||
unsigned int hw_id);
|
||||
|
||||
#endif /* _MTK_VCODEC_INTR_H_ */
|
||||
|
|
|
|||
|
|
@ -413,7 +413,7 @@ static int vdec_h264_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
|
|||
/* wait decoder done interrupt */
|
||||
err = mtk_vcodec_wait_for_done_ctx(inst->ctx,
|
||||
MTK_INST_IRQ_RECEIVED,
|
||||
WAIT_INTR_TIMEOUT_MS);
|
||||
WAIT_INTR_TIMEOUT_MS, 0);
|
||||
if (err)
|
||||
goto err_free_fb_out;
|
||||
|
||||
|
|
|
|||
|
|
@ -727,7 +727,7 @@ static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
|
|||
/* wait decoder done interrupt */
|
||||
err = mtk_vcodec_wait_for_done_ctx(inst->ctx,
|
||||
MTK_INST_IRQ_RECEIVED,
|
||||
WAIT_INTR_TIMEOUT_MS);
|
||||
WAIT_INTR_TIMEOUT_MS, 0);
|
||||
if (err)
|
||||
goto err_free_fb_out;
|
||||
vpu_dec_end(vpu);
|
||||
|
|
|
|||
|
|
@ -488,7 +488,7 @@ static int vdec_vp8_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
|
|||
|
||||
/* wait decoder done interrupt */
|
||||
mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED,
|
||||
WAIT_INTR_TIMEOUT_MS);
|
||||
WAIT_INTR_TIMEOUT_MS, 0);
|
||||
|
||||
if (inst->vsi->load_data)
|
||||
load_dec_table(inst);
|
||||
|
|
|
|||
|
|
@ -539,7 +539,7 @@ static bool vp9_wait_dec_end(struct vdec_vp9_inst *inst)
|
|||
|
||||
mtk_vcodec_wait_for_done_ctx(inst->ctx,
|
||||
MTK_INST_IRQ_RECEIVED,
|
||||
WAIT_INTR_TIMEOUT_MS);
|
||||
WAIT_INTR_TIMEOUT_MS, 0);
|
||||
|
||||
if (ctx->irq_status & MTK_VDEC_IRQ_STATUS_DEC_SUCCESS)
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -335,7 +335,7 @@ static unsigned int h264_enc_wait_venc_done(struct venc_h264_inst *inst)
|
|||
struct mtk_vcodec_ctx *ctx = (struct mtk_vcodec_ctx *)inst->ctx;
|
||||
|
||||
if (!mtk_vcodec_wait_for_done_ctx(ctx, MTK_INST_IRQ_RECEIVED,
|
||||
WAIT_INTR_TIMEOUT_MS)) {
|
||||
WAIT_INTR_TIMEOUT_MS, 0)) {
|
||||
irq_status = ctx->irq_status;
|
||||
mtk_vcodec_debug(inst, "irq_status %x <-", irq_status);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ static unsigned int vp8_enc_wait_venc_done(struct venc_vp8_inst *inst)
|
|||
struct mtk_vcodec_ctx *ctx = (struct mtk_vcodec_ctx *)inst->ctx;
|
||||
|
||||
if (!mtk_vcodec_wait_for_done_ctx(ctx, MTK_INST_IRQ_RECEIVED,
|
||||
WAIT_INTR_TIMEOUT_MS)) {
|
||||
WAIT_INTR_TIMEOUT_MS, 0)) {
|
||||
irq_status = ctx->irq_status;
|
||||
mtk_vcodec_debug(inst, "isr return %x", irq_status);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user