media: mtk-vcodec: abstract firmware interface

MT8183's codec firmware is run by a different remote processor from
MT8173. While the firmware interface is basically the same, the way to
invoke it differs. Abstract all firmware calls under a layer that will
allow us to handle both firmware types transparently.

[acourbot: refactor, cleanup and split]
[pihsun: fix error path and add mtk_vcodec_fw_release]
[hverkuil: fixed some checkpatch alignment warnings]
[hverkuil: fixed merge conflicts]

Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
Co-developed-by: Alexandre Courbot <acourbot@chromium.org>
Signed-off-by: Alexandre Courbot <acourbot@chromium.org>
Signed-off-by: Pi-Hsun Shih <pihsun@chromium.org>
Reviewed-by: Tiffany Lin <tiffany.lin@mediatek.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
This commit is contained in:
Yunfei Dong
2020-08-21 12:35:52 +02:00
committed by Mauro Carvalho Chehab
parent cbd2dca749
commit bf1d556ad4
21 changed files with 293 additions and 102 deletions

View File

@@ -21,7 +21,7 @@
#include "mtk_vcodec_enc_pm.h"
#include "mtk_vcodec_intr.h"
#include "mtk_vcodec_util.h"
#include "mtk_vpu.h"
#include "mtk_vcodec_fw.h"
module_param(mtk_v4l2_dbg_level, int, S_IRUGO | S_IWUSR);
module_param(mtk_vcodec_dbg, bool, S_IRUGO | S_IWUSR);
@@ -101,22 +101,6 @@ static irqreturn_t mtk_vcodec_enc_lt_irq_handler(int irq, void *priv)
return IRQ_HANDLED;
}
static void mtk_vcodec_enc_reset_handler(void *priv)
{
struct mtk_vcodec_dev *dev = priv;
struct mtk_vcodec_ctx *ctx;
mtk_v4l2_debug(0, "Watchdog timeout!!");
mutex_lock(&dev->dev_mutex);
list_for_each_entry(ctx, &dev->ctx_list, list) {
ctx->state = MTK_STATE_ABORT;
mtk_v4l2_debug(0, "[%d] Change to state MTK_STATE_ABORT",
ctx->id);
}
mutex_unlock(&dev->dev_mutex);
}
static int fops_vcodec_open(struct file *file)
{
struct mtk_vcodec_dev *dev = video_drvdata(file);
@@ -159,10 +143,10 @@ static int fops_vcodec_open(struct file *file)
if (v4l2_fh_is_singular(&ctx->fh)) {
/*
* vpu_load_firmware checks if it was loaded already and
* load fireware to checks if it was loaded already and
* does nothing in that case
*/
ret = vpu_load_firmware(dev->vpu_plat_dev);
ret = mtk_vcodec_fw_load_firmware(dev->fw_handler);
if (ret < 0) {
/*
* Return 0 if downloading firmware successfully,
@@ -173,7 +157,7 @@ static int fops_vcodec_open(struct file *file)
}
dev->enc_capability =
vpu_get_venc_hw_capa(dev->vpu_plat_dev);
mtk_vcodec_fw_get_venc_capa(dev->fw_handler);
mtk_v4l2_debug(0, "encoder capability %x", dev->enc_capability);
}
@@ -235,6 +219,8 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
struct mtk_vcodec_dev *dev;
struct video_device *vfd_enc;
struct resource *res;
phandle rproc_phandle;
enum mtk_vcodec_fw_type fw_type;
int i, j, ret;
dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
@@ -244,10 +230,12 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&dev->ctx_list);
dev->plat_dev = pdev;
dev->vpu_plat_dev = vpu_get_plat_device(dev->plat_dev);
if (dev->vpu_plat_dev == NULL) {
mtk_v4l2_err("[VPU] vpu device in not ready");
return -EPROBE_DEFER;
if (!of_property_read_u32(pdev->dev.of_node, "mediatek,vpu",
&rproc_phandle)) {
fw_type = VPU;
} else {
mtk_v4l2_err("Could not get venc IPI device");
return -ENODEV;
}
if (!pdev->dev.dma_parms) {
pdev->dev.dma_parms = devm_kzalloc(&pdev->dev,
@@ -258,13 +246,14 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
}
dma_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
vpu_wdt_reg_handler(dev->vpu_plat_dev, mtk_vcodec_enc_reset_handler,
dev, VPU_RST_ENC);
dev->fw_handler = mtk_vcodec_fw_select(dev, fw_type, VPU_RST_ENC);
if (IS_ERR(dev->fw_handler))
return PTR_ERR(dev->fw_handler);
ret = mtk_vcodec_init_enc_pm(dev);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get mt vcodec clock source!");
return ret;
goto err_enc_pm;
}
for (i = VENC_SYS, j = 0; i < NUM_MAX_VCODEC_REG_BASE; i++, j++) {
@@ -385,6 +374,8 @@ err_enc_alloc:
v4l2_device_unregister(&dev->v4l2_dev);
err_res:
mtk_vcodec_release_enc_pm(dev);
err_enc_pm:
mtk_vcodec_fw_release(dev->fw_handler);
return ret;
}
@@ -409,6 +400,7 @@ static int mtk_vcodec_enc_remove(struct platform_device *pdev)
v4l2_device_unregister(&dev->v4l2_dev);
mtk_vcodec_release_enc_pm(dev);
mtk_vcodec_fw_release(dev->fw_handler);
return 0;
}