Commit 9875c0be authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'media/v6.9-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media

Pull media fixes from Mauro Carvalho Chehab:

 - some fixes for mediatec vcodec encoder/decoder oopses

* tag 'media/v6.9-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media:
  media: mediatek: vcodec: support 36 bits physical address
  media: mediatek: vcodec: adding lock to protect encoder context list
  media: mediatek: vcodec: adding lock to protect decoder context list
  media: mediatek: vcodec: Fix oops when HEVC init fails
  media: mediatek: vcodec: Handle VP9 superframe bitstream with 8 sub-frames
parents fe5b5ef8 d353c3c3
...@@ -50,12 +50,12 @@ static void mtk_vcodec_vpu_reset_dec_handler(void *priv) ...@@ -50,12 +50,12 @@ static void mtk_vcodec_vpu_reset_dec_handler(void *priv)
dev_err(&dev->plat_dev->dev, "Watchdog timeout!!"); dev_err(&dev->plat_dev->dev, "Watchdog timeout!!");
mutex_lock(&dev->dev_mutex); mutex_lock(&dev->dev_ctx_lock);
list_for_each_entry(ctx, &dev->ctx_list, list) { list_for_each_entry(ctx, &dev->ctx_list, list) {
ctx->state = MTK_STATE_ABORT; ctx->state = MTK_STATE_ABORT;
mtk_v4l2_vdec_dbg(0, ctx, "[%d] Change to state MTK_STATE_ABORT", ctx->id); mtk_v4l2_vdec_dbg(0, ctx, "[%d] Change to state MTK_STATE_ABORT", ctx->id);
} }
mutex_unlock(&dev->dev_mutex); mutex_unlock(&dev->dev_ctx_lock);
} }
static void mtk_vcodec_vpu_reset_enc_handler(void *priv) static void mtk_vcodec_vpu_reset_enc_handler(void *priv)
...@@ -65,12 +65,12 @@ static void mtk_vcodec_vpu_reset_enc_handler(void *priv) ...@@ -65,12 +65,12 @@ static void mtk_vcodec_vpu_reset_enc_handler(void *priv)
dev_err(&dev->plat_dev->dev, "Watchdog timeout!!"); dev_err(&dev->plat_dev->dev, "Watchdog timeout!!");
mutex_lock(&dev->dev_mutex); mutex_lock(&dev->dev_ctx_lock);
list_for_each_entry(ctx, &dev->ctx_list, list) { list_for_each_entry(ctx, &dev->ctx_list, list) {
ctx->state = MTK_STATE_ABORT; ctx->state = MTK_STATE_ABORT;
mtk_v4l2_vdec_dbg(0, ctx, "[%d] Change to state MTK_STATE_ABORT", ctx->id); mtk_v4l2_vdec_dbg(0, ctx, "[%d] Change to state MTK_STATE_ABORT", ctx->id);
} }
mutex_unlock(&dev->dev_mutex); mutex_unlock(&dev->dev_ctx_lock);
} }
static const struct mtk_vcodec_fw_ops mtk_vcodec_vpu_msg = { static const struct mtk_vcodec_fw_ops mtk_vcodec_vpu_msg = {
......
...@@ -268,7 +268,9 @@ static int fops_vcodec_open(struct file *file) ...@@ -268,7 +268,9 @@ static int fops_vcodec_open(struct file *file)
ctx->dev->vdec_pdata->init_vdec_params(ctx); ctx->dev->vdec_pdata->init_vdec_params(ctx);
mutex_lock(&dev->dev_ctx_lock);
list_add(&ctx->list, &dev->ctx_list); list_add(&ctx->list, &dev->ctx_list);
mutex_unlock(&dev->dev_ctx_lock);
mtk_vcodec_dbgfs_create(ctx); mtk_vcodec_dbgfs_create(ctx);
mutex_unlock(&dev->dev_mutex); mutex_unlock(&dev->dev_mutex);
...@@ -311,7 +313,9 @@ static int fops_vcodec_release(struct file *file) ...@@ -311,7 +313,9 @@ static int fops_vcodec_release(struct file *file)
v4l2_ctrl_handler_free(&ctx->ctrl_hdl); v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
mtk_vcodec_dbgfs_remove(dev, ctx->id); mtk_vcodec_dbgfs_remove(dev, ctx->id);
mutex_lock(&dev->dev_ctx_lock);
list_del_init(&ctx->list); list_del_init(&ctx->list);
mutex_unlock(&dev->dev_ctx_lock);
kfree(ctx); kfree(ctx);
mutex_unlock(&dev->dev_mutex); mutex_unlock(&dev->dev_mutex);
return 0; return 0;
...@@ -404,6 +408,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev) ...@@ -404,6 +408,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
for (i = 0; i < MTK_VDEC_HW_MAX; i++) for (i = 0; i < MTK_VDEC_HW_MAX; i++)
mutex_init(&dev->dec_mutex[i]); mutex_init(&dev->dec_mutex[i]);
mutex_init(&dev->dev_mutex); mutex_init(&dev->dev_mutex);
mutex_init(&dev->dev_ctx_lock);
spin_lock_init(&dev->irqlock); spin_lock_init(&dev->irqlock);
snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s", snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s",
......
...@@ -241,6 +241,7 @@ struct mtk_vcodec_dec_ctx { ...@@ -241,6 +241,7 @@ struct mtk_vcodec_dec_ctx {
* *
* @dec_mutex: decoder hardware lock * @dec_mutex: decoder hardware lock
* @dev_mutex: video_device lock * @dev_mutex: video_device lock
* @dev_ctx_lock: the lock of context list
* @decode_workqueue: decode work queue * @decode_workqueue: decode work queue
* *
* @irqlock: protect data access by irq handler and work thread * @irqlock: protect data access by irq handler and work thread
...@@ -282,6 +283,7 @@ struct mtk_vcodec_dec_dev { ...@@ -282,6 +283,7 @@ struct mtk_vcodec_dec_dev {
/* decoder hardware mutex lock */ /* decoder hardware mutex lock */
struct mutex dec_mutex[MTK_VDEC_HW_MAX]; struct mutex dec_mutex[MTK_VDEC_HW_MAX];
struct mutex dev_mutex; struct mutex dev_mutex;
struct mutex dev_ctx_lock;
struct workqueue_struct *decode_workqueue; struct workqueue_struct *decode_workqueue;
spinlock_t irqlock; spinlock_t irqlock;
......
...@@ -869,7 +869,6 @@ static int vdec_hevc_slice_init(struct mtk_vcodec_dec_ctx *ctx) ...@@ -869,7 +869,6 @@ static int vdec_hevc_slice_init(struct mtk_vcodec_dec_ctx *ctx)
inst->vpu.codec_type = ctx->current_codec; inst->vpu.codec_type = ctx->current_codec;
inst->vpu.capture_type = ctx->capture_fourcc; inst->vpu.capture_type = ctx->capture_fourcc;
ctx->drv_handle = inst;
err = vpu_dec_init(&inst->vpu); err = vpu_dec_init(&inst->vpu);
if (err) { if (err) {
mtk_vdec_err(ctx, "vdec_hevc init err=%d", err); mtk_vdec_err(ctx, "vdec_hevc init err=%d", err);
...@@ -898,6 +897,7 @@ static int vdec_hevc_slice_init(struct mtk_vcodec_dec_ctx *ctx) ...@@ -898,6 +897,7 @@ static int vdec_hevc_slice_init(struct mtk_vcodec_dec_ctx *ctx)
mtk_vdec_debug(ctx, "lat hevc instance >> %p, codec_type = 0x%x", mtk_vdec_debug(ctx, "lat hevc instance >> %p, codec_type = 0x%x",
inst, inst->vpu.codec_type); inst, inst->vpu.codec_type);
ctx->drv_handle = inst;
return 0; return 0;
error_free_inst: error_free_inst:
kfree(inst); kfree(inst);
......
...@@ -449,7 +449,7 @@ static int vdec_vp8_decode(void *h_vdec, struct mtk_vcodec_mem *bs, ...@@ -449,7 +449,7 @@ static int vdec_vp8_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
inst->frm_cnt, y_fb_dma, c_fb_dma, fb); inst->frm_cnt, y_fb_dma, c_fb_dma, fb);
inst->cur_fb = fb; inst->cur_fb = fb;
dec->bs_dma = (unsigned long)bs->dma_addr; dec->bs_dma = (uint64_t)bs->dma_addr;
dec->bs_sz = bs->size; dec->bs_sz = bs->size;
dec->cur_y_fb_dma = y_fb_dma; dec->cur_y_fb_dma = y_fb_dma;
dec->cur_c_fb_dma = c_fb_dma; dec->cur_c_fb_dma = c_fb_dma;
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "../vdec_drv_base.h" #include "../vdec_drv_base.h"
#include "../vdec_vpu_if.h" #include "../vdec_vpu_if.h"
#define VP9_MAX_SUPER_FRAMES_NUM 8
#define VP9_SUPER_FRAME_BS_SZ 64 #define VP9_SUPER_FRAME_BS_SZ 64
#define MAX_VP9_DPB_SIZE 9 #define MAX_VP9_DPB_SIZE 9
...@@ -133,11 +134,11 @@ struct vp9_sf_ref_fb { ...@@ -133,11 +134,11 @@ struct vp9_sf_ref_fb {
*/ */
struct vdec_vp9_vsi { struct vdec_vp9_vsi {
unsigned char sf_bs_buf[VP9_SUPER_FRAME_BS_SZ]; unsigned char sf_bs_buf[VP9_SUPER_FRAME_BS_SZ];
struct vp9_sf_ref_fb sf_ref_fb[VP9_MAX_FRM_BUF_NUM-1]; struct vp9_sf_ref_fb sf_ref_fb[VP9_MAX_SUPER_FRAMES_NUM];
int sf_next_ref_fb_idx; int sf_next_ref_fb_idx;
unsigned int sf_frm_cnt; unsigned int sf_frm_cnt;
unsigned int sf_frm_offset[VP9_MAX_FRM_BUF_NUM-1]; unsigned int sf_frm_offset[VP9_MAX_SUPER_FRAMES_NUM];
unsigned int sf_frm_sz[VP9_MAX_FRM_BUF_NUM-1]; unsigned int sf_frm_sz[VP9_MAX_SUPER_FRAMES_NUM];
unsigned int sf_frm_idx; unsigned int sf_frm_idx;
unsigned int sf_init; unsigned int sf_init;
struct vdec_fb fb; struct vdec_fb fb;
...@@ -526,7 +527,7 @@ static void vp9_swap_frm_bufs(struct vdec_vp9_inst *inst) ...@@ -526,7 +527,7 @@ static void vp9_swap_frm_bufs(struct vdec_vp9_inst *inst)
/* if this super frame and it is not last sub-frame, get next fb for /* if this super frame and it is not last sub-frame, get next fb for
* sub-frame decode * sub-frame decode
*/ */
if (vsi->sf_frm_cnt > 0 && vsi->sf_frm_idx != vsi->sf_frm_cnt - 1) if (vsi->sf_frm_cnt > 0 && vsi->sf_frm_idx != vsi->sf_frm_cnt)
vsi->sf_next_ref_fb_idx = vp9_get_sf_ref_fb(inst); vsi->sf_next_ref_fb_idx = vp9_get_sf_ref_fb(inst);
} }
...@@ -735,7 +736,7 @@ static void get_free_fb(struct vdec_vp9_inst *inst, struct vdec_fb **out_fb) ...@@ -735,7 +736,7 @@ static void get_free_fb(struct vdec_vp9_inst *inst, struct vdec_fb **out_fb)
static int validate_vsi_array_indexes(struct vdec_vp9_inst *inst, static int validate_vsi_array_indexes(struct vdec_vp9_inst *inst,
struct vdec_vp9_vsi *vsi) { struct vdec_vp9_vsi *vsi) {
if (vsi->sf_frm_idx >= VP9_MAX_FRM_BUF_NUM - 1) { if (vsi->sf_frm_idx > VP9_MAX_SUPER_FRAMES_NUM) {
mtk_vdec_err(inst->ctx, "Invalid vsi->sf_frm_idx=%u.", vsi->sf_frm_idx); mtk_vdec_err(inst->ctx, "Invalid vsi->sf_frm_idx=%u.", vsi->sf_frm_idx);
return -EIO; return -EIO;
} }
......
...@@ -1074,7 +1074,7 @@ static int vdec_vp9_slice_setup_tile_buffer(struct vdec_vp9_slice_instance *inst ...@@ -1074,7 +1074,7 @@ static int vdec_vp9_slice_setup_tile_buffer(struct vdec_vp9_slice_instance *inst
unsigned int mi_row; unsigned int mi_row;
unsigned int mi_col; unsigned int mi_col;
unsigned int offset; unsigned int offset;
unsigned int pa; dma_addr_t pa;
unsigned int size; unsigned int size;
struct vdec_vp9_slice_tiles *tiles; struct vdec_vp9_slice_tiles *tiles;
unsigned char *pos; unsigned char *pos;
...@@ -1109,7 +1109,7 @@ static int vdec_vp9_slice_setup_tile_buffer(struct vdec_vp9_slice_instance *inst ...@@ -1109,7 +1109,7 @@ static int vdec_vp9_slice_setup_tile_buffer(struct vdec_vp9_slice_instance *inst
pos = va + offset; pos = va + offset;
end = va + bs->size; end = va + bs->size;
/* truncated */ /* truncated */
pa = (unsigned int)bs->dma_addr + offset; pa = bs->dma_addr + offset;
tb = instance->tile.va; tb = instance->tile.va;
for (i = 0; i < rows; i++) { for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) { for (j = 0; j < cols; j++) {
......
...@@ -77,12 +77,14 @@ static bool vpu_dec_check_ap_inst(struct mtk_vcodec_dec_dev *dec_dev, struct vde ...@@ -77,12 +77,14 @@ static bool vpu_dec_check_ap_inst(struct mtk_vcodec_dec_dev *dec_dev, struct vde
struct mtk_vcodec_dec_ctx *ctx; struct mtk_vcodec_dec_ctx *ctx;
int ret = false; int ret = false;
mutex_lock(&dec_dev->dev_ctx_lock);
list_for_each_entry(ctx, &dec_dev->ctx_list, list) { list_for_each_entry(ctx, &dec_dev->ctx_list, list) {
if (!IS_ERR_OR_NULL(ctx) && ctx->vpu_inst == vpu) { if (!IS_ERR_OR_NULL(ctx) && ctx->vpu_inst == vpu) {
ret = true; ret = true;
break; break;
} }
} }
mutex_unlock(&dec_dev->dev_ctx_lock);
return ret; return ret;
} }
......
...@@ -177,7 +177,9 @@ static int fops_vcodec_open(struct file *file) ...@@ -177,7 +177,9 @@ static int fops_vcodec_open(struct file *file)
mtk_v4l2_venc_dbg(2, ctx, "Create instance [%d]@%p m2m_ctx=%p ", mtk_v4l2_venc_dbg(2, ctx, "Create instance [%d]@%p m2m_ctx=%p ",
ctx->id, ctx, ctx->m2m_ctx); ctx->id, ctx, ctx->m2m_ctx);
mutex_lock(&dev->dev_ctx_lock);
list_add(&ctx->list, &dev->ctx_list); list_add(&ctx->list, &dev->ctx_list);
mutex_unlock(&dev->dev_ctx_lock);
mutex_unlock(&dev->dev_mutex); mutex_unlock(&dev->dev_mutex);
mtk_v4l2_venc_dbg(0, ctx, "%s encoder [%d]", dev_name(&dev->plat_dev->dev), mtk_v4l2_venc_dbg(0, ctx, "%s encoder [%d]", dev_name(&dev->plat_dev->dev),
...@@ -212,7 +214,9 @@ static int fops_vcodec_release(struct file *file) ...@@ -212,7 +214,9 @@ static int fops_vcodec_release(struct file *file)
v4l2_fh_exit(&ctx->fh); v4l2_fh_exit(&ctx->fh);
v4l2_ctrl_handler_free(&ctx->ctrl_hdl); v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
mutex_lock(&dev->dev_ctx_lock);
list_del_init(&ctx->list); list_del_init(&ctx->list);
mutex_unlock(&dev->dev_ctx_lock);
kfree(ctx); kfree(ctx);
mutex_unlock(&dev->dev_mutex); mutex_unlock(&dev->dev_mutex);
return 0; return 0;
...@@ -294,6 +298,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev) ...@@ -294,6 +298,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
mutex_init(&dev->enc_mutex); mutex_init(&dev->enc_mutex);
mutex_init(&dev->dev_mutex); mutex_init(&dev->dev_mutex);
mutex_init(&dev->dev_ctx_lock);
spin_lock_init(&dev->irqlock); spin_lock_init(&dev->irqlock);
snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s", snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s",
......
...@@ -178,6 +178,7 @@ struct mtk_vcodec_enc_ctx { ...@@ -178,6 +178,7 @@ struct mtk_vcodec_enc_ctx {
* *
* @enc_mutex: encoder hardware lock. * @enc_mutex: encoder hardware lock.
* @dev_mutex: video_device lock * @dev_mutex: video_device lock
* @dev_ctx_lock: the lock of context list
* @encode_workqueue: encode work queue * @encode_workqueue: encode work queue
* *
* @enc_irq: h264 encoder irq resource * @enc_irq: h264 encoder irq resource
...@@ -205,6 +206,7 @@ struct mtk_vcodec_enc_dev { ...@@ -205,6 +206,7 @@ struct mtk_vcodec_enc_dev {
/* encoder hardware mutex lock */ /* encoder hardware mutex lock */
struct mutex enc_mutex; struct mutex enc_mutex;
struct mutex dev_mutex; struct mutex dev_mutex;
struct mutex dev_ctx_lock;
struct workqueue_struct *encode_workqueue; struct workqueue_struct *encode_workqueue;
int enc_irq; int enc_irq;
......
...@@ -47,12 +47,14 @@ static bool vpu_enc_check_ap_inst(struct mtk_vcodec_enc_dev *enc_dev, struct ven ...@@ -47,12 +47,14 @@ static bool vpu_enc_check_ap_inst(struct mtk_vcodec_enc_dev *enc_dev, struct ven
struct mtk_vcodec_enc_ctx *ctx; struct mtk_vcodec_enc_ctx *ctx;
int ret = false; int ret = false;
mutex_lock(&enc_dev->dev_ctx_lock);
list_for_each_entry(ctx, &enc_dev->ctx_list, list) { list_for_each_entry(ctx, &enc_dev->ctx_list, list) {
if (!IS_ERR_OR_NULL(ctx) && ctx->vpu_inst == vpu) { if (!IS_ERR_OR_NULL(ctx) && ctx->vpu_inst == vpu) {
ret = true; ret = true;
break; break;
} }
} }
mutex_unlock(&enc_dev->dev_ctx_lock);
return ret; return ret;
} }
......
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