diff options
author | Yunfei Dong <yunfei.dong@mediatek.com> | 2020-08-21 13:35:52 +0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab+huawei@kernel.org> | 2020-09-26 10:53:52 +0300 |
commit | bf1d556ad4e0f8d92753d3b9896d492f4f065822 (patch) | |
tree | 7598e3de946997a6885b1a758b045e6b959c7b21 /drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | |
parent | cbd2dca74926c0e4610c40923cc786b732c9e8ef (diff) | |
download | linux-bf1d556ad4e0f8d92753d3b9896d492f4f065822.tar.xz |
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>
Diffstat (limited to 'drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c')
-rw-r--r-- | drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 49 |
1 files changed, 20 insertions, 29 deletions
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c index 3bbd0bac56d6..93f1b055253a 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c @@ -20,7 +20,7 @@ #include "mtk_vcodec_dec_pm.h" #include "mtk_vcodec_intr.h" #include "mtk_vcodec_util.h" -#include "mtk_vpu.h" +#include "mtk_vcodec_fw.h" #define VDEC_HW_ACTIVE 0x10 #define VDEC_IRQ_CFG 0x11 @@ -77,22 +77,6 @@ static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv) return IRQ_HANDLED; } -static void mtk_vcodec_dec_reset_handler(void *priv) -{ - struct mtk_vcodec_dev *dev = priv; - struct mtk_vcodec_ctx *ctx; - - mtk_v4l2_err("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_ERROR", - ctx->id); - } - mutex_unlock(&dev->dev_mutex); -} - static int fops_vcodec_open(struct file *file) { struct mtk_vcodec_dev *dev = video_drvdata(file); @@ -144,21 +128,20 @@ static int fops_vcodec_open(struct file *file) if (v4l2_fh_is_singular(&ctx->fh)) { mtk_vcodec_dec_pw_on(&dev->pm); /* - * vpu_load_firmware checks if it was loaded already and - * does nothing in that case + * Does nothing if firmware was already loaded. */ - 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, * otherwise it is failed */ - mtk_v4l2_err("vpu_load_firmware failed!"); + mtk_v4l2_err("failed to load firmware!"); goto err_load_fw; } dev->dec_capability = - vpu_get_vdec_hw_capa(dev->vpu_plat_dev); + mtk_vcodec_fw_get_vdec_capa(dev->fw_handler); mtk_v4l2_debug(0, "decoder capability %x", dev->dec_capability); } @@ -228,6 +211,8 @@ static int mtk_vcodec_probe(struct platform_device *pdev) struct mtk_vcodec_dev *dev; struct video_device *vfd_dec; struct resource *res; + phandle rproc_phandle; + enum mtk_vcodec_fw_type fw_type; int i, ret; dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); @@ -237,10 +222,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 vdec IPI device"); + return -ENODEV; } if (!pdev->dev.dma_parms) { pdev->dev.dma_parms = devm_kzalloc(&pdev->dev, @@ -251,13 +238,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_dec_reset_handler, - dev, VPU_RST_DEC); + dev->fw_handler = mtk_vcodec_fw_select(dev, fw_type, VPU_RST_DEC); + if (IS_ERR(dev->fw_handler)) + return PTR_ERR(dev->fw_handler); ret = mtk_vcodec_init_dec_pm(dev); if (ret < 0) { dev_err(&pdev->dev, "Failed to get mt vcodec clock source"); - return ret; + goto err_dec_pm; } for (i = 0; i < NUM_MAX_VDEC_REG_BASE; i++) { @@ -360,6 +348,8 @@ err_dec_alloc: v4l2_device_unregister(&dev->v4l2_dev); err_res: mtk_vcodec_release_dec_pm(dev); +err_dec_pm: + mtk_vcodec_fw_release(dev->fw_handler); return ret; } @@ -384,6 +374,7 @@ static int mtk_vcodec_dec_remove(struct platform_device *pdev) v4l2_device_unregister(&dev->v4l2_dev); mtk_vcodec_release_dec_pm(dev); + mtk_vcodec_fw_release(dev->fw_handler); return 0; } |