]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
media: mtk-vcodec: move firmware implementations into their own files
authorAlexandre Courbot <acourbot@chromium.org>
Tue, 13 Oct 2020 12:44:27 +0000 (14:44 +0200)
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Thu, 5 Nov 2020 13:31:32 +0000 (14:31 +0100)
mtk-vcodec supports two kinds of firmware, VPU and SCP. Both were
supported from the same source files, but this is clearly unclean and
makes it more difficult to disable support for one or the other.

Move these implementations into their own file, after adding the
necessary private interfaces.

[hverkuil: smatch fix: mtk_vcodec_fw_vpu_init() error: uninitialized symbol 'rst_id'.]

Signed-off-by: Alexandre Courbot <acourbot@chromium.org>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Fixes: bf1d556ad4e0 ("media: mtk-vcodec: abstract firmware interface")
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
drivers/media/platform/mtk-vcodec/Makefile
drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.c
drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.h
drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_priv.h [new file with mode: 0644]
drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_scp.c [new file with mode: 0644]
drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_vpu.c [new file with mode: 0644]

index f679c6e1a3e9be38e040de7f69aee07b68840d83..6e1ea3a9f052bb41ca55abd6629f340d38ff04f8 100644 (file)
@@ -24,4 +24,6 @@ mtk-vcodec-enc-y := venc/venc_vp8_if.o \
 
 mtk-vcodec-common-y := mtk_vcodec_intr.o \
                mtk_vcodec_util.o \
-               mtk_vcodec_fw.o
+               mtk_vcodec_fw.o \
+               mtk_vcodec_fw_vpu.o \
+               mtk_vcodec_fw_scp.o
index d14bc208ea5e3ef1f1313956240c4f1e44801f6c..145686d2c219c49a39438cfe28525ad2c7aef950 100644 (file)
@@ -241,7 +241,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
        }
        dma_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
 
-       dev->fw_handler = mtk_vcodec_fw_select(dev, fw_type, VPU_RST_DEC);
+       dev->fw_handler = mtk_vcodec_fw_select(dev, fw_type, DECODER);
        if (IS_ERR(dev->fw_handler))
                return PTR_ERR(dev->fw_handler);
 
index dcfa2c2d4def3d25dcc56728f47f0307a06b307e..3be8a04c4c67934f6f4bb1caac06baeffc05d645 100644 (file)
@@ -293,7 +293,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
        }
        dma_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
 
-       dev->fw_handler = mtk_vcodec_fw_select(dev, fw_type, VPU_RST_ENC);
+       dev->fw_handler = mtk_vcodec_fw_select(dev, fw_type, ENCODER);
        if (IS_ERR(dev->fw_handler))
                return PTR_ERR(dev->fw_handler);
 
index 6c2a2568d844f7934bd602775bba5503d0682d1b..94b39ae5c2e1e05ac0e8bce3c4a52823b4da64f8 100644 (file)
 // SPDX-License-Identifier: GPL-2.0
 
 #include "mtk_vcodec_fw.h"
+#include "mtk_vcodec_fw_priv.h"
 #include "mtk_vcodec_util.h"
 #include "mtk_vcodec_drv.h"
 
-struct mtk_vcodec_fw_ops {
-       int (*load_firmware)(struct mtk_vcodec_fw *fw);
-       unsigned int (*get_vdec_capa)(struct mtk_vcodec_fw *fw);
-       unsigned int (*get_venc_capa)(struct mtk_vcodec_fw *fw);
-       void * (*map_dm_addr)(struct mtk_vcodec_fw *fw, u32 dtcm_dmem_addr);
-       int (*ipi_register)(struct mtk_vcodec_fw *fw, int id,
-                           mtk_vcodec_ipi_handler handler, const char *name, void *priv);
-       int (*ipi_send)(struct mtk_vcodec_fw *fw, int id, void *buf,
-                       unsigned int len, unsigned int wait);
-};
-
-struct mtk_vcodec_fw {
-       enum mtk_vcodec_fw_type type;
-       const struct mtk_vcodec_fw_ops *ops;
-       struct platform_device *pdev;
-       struct mtk_scp *scp;
-};
-
-static int mtk_vcodec_vpu_load_firmware(struct mtk_vcodec_fw *fw)
-{
-       return vpu_load_firmware(fw->pdev);
-}
-
-static unsigned int mtk_vcodec_vpu_get_vdec_capa(struct mtk_vcodec_fw *fw)
-{
-       return vpu_get_vdec_hw_capa(fw->pdev);
-}
-
-static unsigned int mtk_vcodec_vpu_get_venc_capa(struct mtk_vcodec_fw *fw)
-{
-       return vpu_get_venc_hw_capa(fw->pdev);
-}
-
-static void *mtk_vcodec_vpu_map_dm_addr(struct mtk_vcodec_fw *fw,
-                                       u32 dtcm_dmem_addr)
-{
-       return vpu_mapping_dm_addr(fw->pdev, dtcm_dmem_addr);
-}
-
-static int mtk_vcodec_vpu_set_ipi_register(struct mtk_vcodec_fw *fw, int id,
-                                          mtk_vcodec_ipi_handler handler,
-                                          const char *name, void *priv)
-{
-       /*
-        * The handler we receive takes a void * as its first argument. We
-        * cannot change this because it needs to be passed down to the rproc
-        * subsystem when SCP is used. VPU takes a const argument, which is
-        * more constrained, so the conversion below is safe.
-        */
-       ipi_handler_t handler_const = (ipi_handler_t)handler;
-
-       return vpu_ipi_register(fw->pdev, id, handler_const, name, priv);
-}
-
-static int mtk_vcodec_vpu_ipi_send(struct mtk_vcodec_fw *fw, int id, void *buf,
-                                  unsigned int len, unsigned int wait)
-{
-       return vpu_ipi_send(fw->pdev, id, buf, len);
-}
-
-static const struct mtk_vcodec_fw_ops mtk_vcodec_vpu_msg = {
-       .load_firmware = mtk_vcodec_vpu_load_firmware,
-       .get_vdec_capa = mtk_vcodec_vpu_get_vdec_capa,
-       .get_venc_capa = mtk_vcodec_vpu_get_venc_capa,
-       .map_dm_addr = mtk_vcodec_vpu_map_dm_addr,
-       .ipi_register = mtk_vcodec_vpu_set_ipi_register,
-       .ipi_send = mtk_vcodec_vpu_ipi_send,
-};
-
-static int mtk_vcodec_scp_load_firmware(struct mtk_vcodec_fw *fw)
-{
-       return rproc_boot(scp_get_rproc(fw->scp));
-}
-
-static unsigned int mtk_vcodec_scp_get_vdec_capa(struct mtk_vcodec_fw *fw)
-{
-       return scp_get_vdec_hw_capa(fw->scp);
-}
-
-static unsigned int mtk_vcodec_scp_get_venc_capa(struct mtk_vcodec_fw *fw)
-{
-       return scp_get_venc_hw_capa(fw->scp);
-}
-
-static void *mtk_vcodec_vpu_scp_dm_addr(struct mtk_vcodec_fw *fw,
-                                       u32 dtcm_dmem_addr)
-{
-       return scp_mapping_dm_addr(fw->scp, dtcm_dmem_addr);
-}
-
-static int mtk_vcodec_scp_set_ipi_register(struct mtk_vcodec_fw *fw, int id,
-                                          mtk_vcodec_ipi_handler handler,
-                                          const char *name, void *priv)
-{
-       return scp_ipi_register(fw->scp, id, handler, priv);
-}
-
-static int mtk_vcodec_scp_ipi_send(struct mtk_vcodec_fw *fw, int id, void *buf,
-                                  unsigned int len, unsigned int wait)
-{
-       return scp_ipi_send(fw->scp, id, buf, len, wait);
-}
-
-static const struct mtk_vcodec_fw_ops mtk_vcodec_rproc_msg = {
-       .load_firmware = mtk_vcodec_scp_load_firmware,
-       .get_vdec_capa = mtk_vcodec_scp_get_vdec_capa,
-       .get_venc_capa = mtk_vcodec_scp_get_venc_capa,
-       .map_dm_addr = mtk_vcodec_vpu_scp_dm_addr,
-       .ipi_register = mtk_vcodec_scp_set_ipi_register,
-       .ipi_send = mtk_vcodec_scp_ipi_send,
-};
-
-static void mtk_vcodec_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_ABORT",
-                              ctx->id);
-       }
-       mutex_unlock(&dev->dev_mutex);
-}
-
 struct mtk_vcodec_fw *mtk_vcodec_fw_select(struct mtk_vcodec_dev *dev,
                                           enum mtk_vcodec_fw_type type,
-                                          enum rst_id rst_id)
+                                          enum mtk_vcodec_fw_use fw_use)
 {
-       const struct mtk_vcodec_fw_ops *ops;
-       struct mtk_vcodec_fw *fw;
-       struct platform_device *fw_pdev = NULL;
-       struct mtk_scp *scp = NULL;
-
        switch (type) {
        case VPU:
-               ops = &mtk_vcodec_vpu_msg;
-               fw_pdev = vpu_get_plat_device(dev->plat_dev);
-               if (!fw_pdev) {
-                       mtk_v4l2_err("firmware device is not ready");
-                       return ERR_PTR(-EINVAL);
-               }
-               vpu_wdt_reg_handler(fw_pdev, mtk_vcodec_reset_handler,
-                                   dev, rst_id);
-               break;
+               return mtk_vcodec_fw_vpu_init(dev, fw_use);
        case SCP:
-               ops = &mtk_vcodec_rproc_msg;
-               scp = scp_get(dev->plat_dev);
-               if (!scp) {
-                       mtk_v4l2_err("could not get vdec scp handle");
-                       return ERR_PTR(-EPROBE_DEFER);
-               }
-               break;
+               return mtk_vcodec_fw_scp_init(dev);
        default:
                mtk_v4l2_err("invalid vcodec fw type");
                return ERR_PTR(-EINVAL);
        }
-
-       fw = devm_kzalloc(&dev->plat_dev->dev, sizeof(*fw), GFP_KERNEL);
-       if (!fw)
-               return ERR_PTR(-EINVAL);
-
-       fw->type = type;
-       fw->ops = ops;
-       fw->pdev = fw_pdev;
-       fw->scp = scp;
-
-       return fw;
 }
 EXPORT_SYMBOL_GPL(mtk_vcodec_fw_select);
 
 void mtk_vcodec_fw_release(struct mtk_vcodec_fw *fw)
 {
-       switch (fw->type) {
-       case VPU:
-               put_device(&fw->pdev->dev);
-               break;
-       case SCP:
-               scp_put(fw->scp);
-               break;
-       }
+       fw->ops->release(fw);
 }
 EXPORT_SYMBOL_GPL(mtk_vcodec_fw_release);
 
index fadbbe6ba6cd4102b4440ad371e89fabbd9cb28d..539bb626772cc5d9a00ed386a197644a8dd73aec 100644 (file)
@@ -15,6 +15,11 @@ enum mtk_vcodec_fw_type {
        SCP,
 };
 
+enum mtk_vcodec_fw_use {
+       DECODER,
+       ENCODER,
+};
+
 struct mtk_vcodec_fw;
 
 typedef void (*mtk_vcodec_ipi_handler) (void *data,
@@ -22,7 +27,7 @@ typedef void (*mtk_vcodec_ipi_handler) (void *data,
 
 struct mtk_vcodec_fw *mtk_vcodec_fw_select(struct mtk_vcodec_dev *dev,
                                           enum mtk_vcodec_fw_type type,
-                                          enum rst_id rst_id);
+                                          enum mtk_vcodec_fw_use fw_use);
 void mtk_vcodec_fw_release(struct mtk_vcodec_fw *fw);
 
 int mtk_vcodec_fw_load_firmware(struct mtk_vcodec_fw *fw);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_priv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_priv.h
new file mode 100644 (file)
index 0000000..51f1694
--- /dev/null
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _MTK_VCODEC_FW_PRIV_H_
+#define _MTK_VCODEC_FW_PRIV_H_
+
+#include "mtk_vcodec_fw.h"
+
+struct mtk_vcodec_dev;
+
+struct mtk_vcodec_fw {
+       enum mtk_vcodec_fw_type type;
+       const struct mtk_vcodec_fw_ops *ops;
+       struct platform_device *pdev;
+       struct mtk_scp *scp;
+};
+
+struct mtk_vcodec_fw_ops {
+       int (*load_firmware)(struct mtk_vcodec_fw *fw);
+       unsigned int (*get_vdec_capa)(struct mtk_vcodec_fw *fw);
+       unsigned int (*get_venc_capa)(struct mtk_vcodec_fw *fw);
+       void *(*map_dm_addr)(struct mtk_vcodec_fw *fw, u32 dtcm_dmem_addr);
+       int (*ipi_register)(struct mtk_vcodec_fw *fw, int id,
+                           mtk_vcodec_ipi_handler handler, const char *name,
+                           void *priv);
+       int (*ipi_send)(struct mtk_vcodec_fw *fw, int id, void *buf,
+                       unsigned int len, unsigned int wait);
+       void (*release)(struct mtk_vcodec_fw *fw);
+};
+
+struct mtk_vcodec_fw *mtk_vcodec_fw_vpu_init(struct mtk_vcodec_dev *dev,
+                                            enum mtk_vcodec_fw_use fw_use);
+struct mtk_vcodec_fw *mtk_vcodec_fw_scp_init(struct mtk_vcodec_dev *dev);
+
+#endif /* _MTK_VCODEC_FW_PRIV_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_scp.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_scp.c
new file mode 100644 (file)
index 0000000..d8e66b6
--- /dev/null
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include "mtk_vcodec_fw_priv.h"
+#include "mtk_vcodec_util.h"
+#include "mtk_vcodec_drv.h"
+
+static int mtk_vcodec_scp_load_firmware(struct mtk_vcodec_fw *fw)
+{
+       return rproc_boot(scp_get_rproc(fw->scp));
+}
+
+static unsigned int mtk_vcodec_scp_get_vdec_capa(struct mtk_vcodec_fw *fw)
+{
+       return scp_get_vdec_hw_capa(fw->scp);
+}
+
+static unsigned int mtk_vcodec_scp_get_venc_capa(struct mtk_vcodec_fw *fw)
+{
+       return scp_get_venc_hw_capa(fw->scp);
+}
+
+static void *mtk_vcodec_vpu_scp_dm_addr(struct mtk_vcodec_fw *fw,
+                                       u32 dtcm_dmem_addr)
+{
+       return scp_mapping_dm_addr(fw->scp, dtcm_dmem_addr);
+}
+
+static int mtk_vcodec_scp_set_ipi_register(struct mtk_vcodec_fw *fw, int id,
+                                          mtk_vcodec_ipi_handler handler,
+                                          const char *name, void *priv)
+{
+       return scp_ipi_register(fw->scp, id, handler, priv);
+}
+
+static int mtk_vcodec_scp_ipi_send(struct mtk_vcodec_fw *fw, int id, void *buf,
+                                  unsigned int len, unsigned int wait)
+{
+       return scp_ipi_send(fw->scp, id, buf, len, wait);
+}
+
+static void mtk_vcodec_scp_release(struct mtk_vcodec_fw *fw)
+{
+       scp_put(fw->scp);
+}
+
+static const struct mtk_vcodec_fw_ops mtk_vcodec_rproc_msg = {
+       .load_firmware = mtk_vcodec_scp_load_firmware,
+       .get_vdec_capa = mtk_vcodec_scp_get_vdec_capa,
+       .get_venc_capa = mtk_vcodec_scp_get_venc_capa,
+       .map_dm_addr = mtk_vcodec_vpu_scp_dm_addr,
+       .ipi_register = mtk_vcodec_scp_set_ipi_register,
+       .ipi_send = mtk_vcodec_scp_ipi_send,
+       .release = mtk_vcodec_scp_release,
+};
+
+struct mtk_vcodec_fw *mtk_vcodec_fw_scp_init(struct mtk_vcodec_dev *dev)
+{
+       struct mtk_vcodec_fw *fw;
+       struct mtk_scp *scp;
+
+       scp = scp_get(dev->plat_dev);
+       if (!scp) {
+               mtk_v4l2_err("could not get vdec scp handle");
+               return ERR_PTR(-EPROBE_DEFER);
+       }
+
+       fw = devm_kzalloc(&dev->plat_dev->dev, sizeof(*fw), GFP_KERNEL);
+       fw->type = SCP;
+       fw->ops = &mtk_vcodec_rproc_msg;
+       fw->scp = scp;
+
+       return fw;
+}
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_vpu.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_vpu.c
new file mode 100644 (file)
index 0000000..cd27f63
--- /dev/null
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include "mtk_vcodec_fw_priv.h"
+#include "mtk_vcodec_util.h"
+#include "mtk_vcodec_drv.h"
+
+static int mtk_vcodec_vpu_load_firmware(struct mtk_vcodec_fw *fw)
+{
+       return vpu_load_firmware(fw->pdev);
+}
+
+static unsigned int mtk_vcodec_vpu_get_vdec_capa(struct mtk_vcodec_fw *fw)
+{
+       return vpu_get_vdec_hw_capa(fw->pdev);
+}
+
+static unsigned int mtk_vcodec_vpu_get_venc_capa(struct mtk_vcodec_fw *fw)
+{
+       return vpu_get_venc_hw_capa(fw->pdev);
+}
+
+static void *mtk_vcodec_vpu_map_dm_addr(struct mtk_vcodec_fw *fw,
+                                       u32 dtcm_dmem_addr)
+{
+       return vpu_mapping_dm_addr(fw->pdev, dtcm_dmem_addr);
+}
+
+static int mtk_vcodec_vpu_set_ipi_register(struct mtk_vcodec_fw *fw, int id,
+                                          mtk_vcodec_ipi_handler handler,
+                                          const char *name, void *priv)
+{
+       /*
+        * The handler we receive takes a void * as its first argument. We
+        * cannot change this because it needs to be passed down to the rproc
+        * subsystem when SCP is used. VPU takes a const argument, which is
+        * more constrained, so the conversion below is safe.
+        */
+       ipi_handler_t handler_const = (ipi_handler_t)handler;
+
+       return vpu_ipi_register(fw->pdev, id, handler_const, name, priv);
+}
+
+static int mtk_vcodec_vpu_ipi_send(struct mtk_vcodec_fw *fw, int id, void *buf,
+                                  unsigned int len, unsigned int wait)
+{
+       return vpu_ipi_send(fw->pdev, id, buf, len);
+}
+
+static void mtk_vcodec_vpu_release(struct mtk_vcodec_fw *fw)
+{
+       put_device(&fw->pdev->dev);
+}
+
+static void mtk_vcodec_vpu_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_ABORT",
+                              ctx->id);
+       }
+       mutex_unlock(&dev->dev_mutex);
+}
+
+static const struct mtk_vcodec_fw_ops mtk_vcodec_vpu_msg = {
+       .load_firmware = mtk_vcodec_vpu_load_firmware,
+       .get_vdec_capa = mtk_vcodec_vpu_get_vdec_capa,
+       .get_venc_capa = mtk_vcodec_vpu_get_venc_capa,
+       .map_dm_addr = mtk_vcodec_vpu_map_dm_addr,
+       .ipi_register = mtk_vcodec_vpu_set_ipi_register,
+       .ipi_send = mtk_vcodec_vpu_ipi_send,
+       .release = mtk_vcodec_vpu_release,
+};
+
+struct mtk_vcodec_fw *mtk_vcodec_fw_vpu_init(struct mtk_vcodec_dev *dev,
+                                            enum mtk_vcodec_fw_use fw_use)
+{
+       struct platform_device *fw_pdev;
+       struct mtk_vcodec_fw *fw;
+       enum rst_id rst_id;
+
+       switch (fw_use) {
+       case ENCODER:
+               rst_id = VPU_RST_ENC;
+               break;
+       case DECODER:
+       default:
+               rst_id = VPU_RST_DEC;
+               break;
+       }
+
+       fw_pdev = vpu_get_plat_device(dev->plat_dev);
+       if (!fw_pdev) {
+               mtk_v4l2_err("firmware device is not ready");
+               return ERR_PTR(-EINVAL);
+       }
+       vpu_wdt_reg_handler(fw_pdev, mtk_vcodec_vpu_reset_handler, dev, rst_id);
+
+       fw = devm_kzalloc(&dev->plat_dev->dev, sizeof(*fw), GFP_KERNEL);
+       fw->type = VPU;
+       fw->ops = &mtk_vcodec_vpu_msg;
+       fw->pdev = fw_pdev;
+
+       return fw;
+}