linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v7, 00/15] Support multi hardware decode using of_platform_populate
@ 2021-10-11  7:02 Yunfei Dong
  2021-10-11  7:02 ` [PATCH v7, 01/15] media: mtk-vcodec: Get numbers of register bases from DT Yunfei Dong
                   ` (15 more replies)
  0 siblings, 16 replies; 43+ messages in thread
From: Yunfei Dong @ 2021-10-11  7:02 UTC (permalink / raw)
  To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

This series adds support for multi hardware decode into mtk-vcodec, by first
adding use of_platform_populate to manage each hardware information: interrupt,
clock, register bases and power. Secondly add core thread to deal with core
hardware message, at the same time, add msg queue for different hardware
share messages. Lastly, the architecture of different specs are not the same,
using specs type to separate them.

This series has been tested with both MT8183 and MT8173. Decoding was working
for both chips.

Patches 1~3 rewrite get register bases and power on/off interface.

Patch 4 add to support multi hardware.

Patch 5 separate video encoder and decoder document

Patches 6-15 add interfaces to support core hardware.
----
Changes compared with v6:
- Use of_platform_populate to manage multi hardware, not component framework for patch 4/15
- Re-write dtsi document for hardware architecture changed for patch 13/15
-The dtsi will write like below in patch 13/15:
    vcodec_dec: vcodec_dec@16000000 {
        compatible = "mediatek,mt8192-vcodec-dec";
        #address-cells = <2>;
        #size-cells = <2>;
        ranges;
        reg = <0 0x16000000 0 0x1000>;		/* VDEC_SYS */
        mediatek,scp = <&scp>;
        iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>;
        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
        vcodec_lat {
            compatible = "mediatek,mtk-vcodec-lat";
            reg = <0 0x16010000 0 0x800>;		/* VDEC_MISC */
            reg-name = "reg-misc";
            interrupts = <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH 0>;
            iommus = <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD_EXT>,
                 <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD2_EXT>,
                 <&iommu0 M4U_PORT_L5_VDEC_LAT0_AVC_MV_EXT>,
                 <&iommu0 M4U_PORT_L5_VDEC_LAT0_PRED_RD_EXT>,
                 <&iommu0 M4U_PORT_L5_VDEC_LAT0_TILE_EXT>,
                 <&iommu0 M4U_PORT_L5_VDEC_LAT0_WDMA_EXT>,
                 <&iommu0 M4U_PORT_L5_VDEC_LAT0_RG_CTRL_DMA_EXT>,
                 <&iommu0 M4U_PORT_L5_VDEC_UFO_ENC_EXT>;
            clocks = <&topckgen CLK_TOP_VDEC_SEL>,
                 <&vdecsys_soc CLK_VDEC_SOC_VDEC>,
                 <&vdecsys_soc CLK_VDEC_SOC_LAT>,
                 <&vdecsys_soc CLK_VDEC_SOC_LARB1>,
                 <&topckgen CLK_TOP_MAINPLL_D4>;
            clock-names = "vdec-sel", "vdec-soc-vdec", "vdec-soc-lat",
                  "vdec-vdec", "vdec-top";
            assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
            assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
            power-domains = <&spm MT8192_POWER_DOMAIN_VDEC>;
        };

        vcodec_core {
            compatible = "mediatek,mtk-vcodec-core";
            reg = <0 0x16025000 0 0x1000>;		/* VDEC_CORE_MISC */
            reg-names = "reg-misc";
            interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH 0>;
            iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>,
                 <&iommu0 M4U_PORT_L4_VDEC_UFO_EXT>,
                 <&iommu0 M4U_PORT_L4_VDEC_PP_EXT>,
                 <&iommu0 M4U_PORT_L4_VDEC_PRED_RD_EXT>,
                 <&iommu0 M4U_PORT_L4_VDEC_PRED_WR_EXT>,
                 <&iommu0 M4U_PORT_L4_VDEC_PPWRAP_EXT>,
                 <&iommu0 M4U_PORT_L4_VDEC_TILE_EXT>,
                 <&iommu0 M4U_PORT_L4_VDEC_VLD_EXT>,
                 <&iommu0 M4U_PORT_L4_VDEC_VLD2_EXT>,
                 <&iommu0 M4U_PORT_L4_VDEC_AVC_MV_EXT>,
                 <&iommu0 M4U_PORT_L4_VDEC_RG_CTRL_DMA_EXT>;
            clocks = <&topckgen CLK_TOP_VDEC_SEL>,
                 <&vdecsys CLK_VDEC_VDEC>,
                 <&vdecsys CLK_VDEC_LAT>,
                 <&vdecsys CLK_VDEC_LARB1>,
                 <&topckgen CLK_TOP_MAINPLL_D4>;
            clock-names = "vdec-sel", "vdec-soc-vdec", "vdec-soc-lat",
                  "vdec-vdec", "vdec-top";
            assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
            assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
            power-domains = <&spm MT8192_POWER_DOMAIN_VDEC2>;
        };
    };

Changes compared with v5:
- Add decoder hardware block diagram for patch 13/15

Changes compared with v4:
- Fix comments for patch 4/15
  >> +     if (dev->is_comp_supported) {
  >> +             ret = mtk_vcodec_init_master(dev);
  >> +             if (ret < 0)
  >> +                     goto err_component_match;
  >> +     } else {
  >> +             platform_set_drvdata(pdev, dev);
  >> +     }
  Fix platform_set_drvdata.
- Fix build error for patch 9/15
- Add depend patch in case of error header file for patch 13/15

Changes compared with v3:
- Fix return value for patch 1/15
- Fix comments for patch 4/15
  > Looking up "mediatek,mtk-vcodec-core" to determine if it uses component framwork sounds like...
  Add prameter in pdata, for all platform will use compoent after mt8183

  >> +     if (dev->is_comp_supported) {
  >> +             ret = mtk_vcodec_init_master(dev);
  >> +             if (ret < 0)
  >> +                     goto err_component_match;
  >> +     } else {
  >> +             platform_set_drvdata(pdev, dev);
  >> +     }
  > + Has asked the same question in [1].  Why it removes the
  > +platform_set_drvdata() above?  mtk_vcodec_init_master() also calls platform_set_drvdata().
  Must call component_master_add_with_match after platform_set_drvdata for component architecture.
- Fix yaml files check fail for patch 5/15
- Fix yaml file check fail for patch 14/15

Changes compared with v1:
- Fix many comments for patch 3/14
- Remove unnecessary code for patch 4/14
- Using enum mtk_vdec_hw_count instead of magic numbers for patch 6/14
- Reconstructed get/put lat buffer for lat and core hardware for patch 7/14
- Using yaml format to instead of txt file for patch 12/14

Yunfei Dong (15):
  media: mtk-vcodec: Get numbers of register bases from DT
  media: mtk-vcodec: Align vcodec wake up interrupt interface
  media: mtk-vcodec: Refactor vcodec pm interface
  media: mtk-vcodec: Manage multi hardware information
  dt-bindings: media: mtk-vcodec: Separate video encoder and decoder
    dt-bindings
  media: mtk-vcodec: Use pure single core for MT8183
  media: mtk-vcodec: Add irq interface for multi hardware
  media: mtk-vcodec: Add msg queue feature for lat and core architecture
  media: mtk-vcodec: Generalize power and clock on/off interfaces
  media: mtk-vcodec: Add new interface to lock different hardware
  media: mtk-vcodec: Add core thread
  media: mtk-vcodec: Support 34bits dma address for vdec
  dt-bindings: media: mtk-vcodec: Adds decoder dt-bindings for mt8192
  media: mtk-vcodec: Add core dec and dec end ipi msg
  media: mtk-vcodec: Use codec type to separate different hardware

 .../media/mediatek,vcodec-comp-decoder.yaml   | 193 ++++++++++++
 .../media/mediatek,vcodec-decoder.yaml        | 175 +++++++++++
 .../media/mediatek,vcodec-encoder.yaml        | 185 +++++++++++
 .../bindings/media/mediatek-vcodec.txt        | 130 --------
 drivers/media/platform/mtk-vcodec/Makefile    |   2 +
 .../platform/mtk-vcodec/mtk_vcodec_dec.c      |   4 +-
 .../platform/mtk-vcodec/mtk_vcodec_dec.h      |   1 +
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 233 +++++++++++---
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   | 165 ++++++++++
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.h   |  53 ++++
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   |  98 ++++--
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h   |  13 +-
 .../mtk-vcodec/mtk_vcodec_dec_stateful.c      |   2 +
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     |   2 +
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  75 ++++-
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |  12 +-
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c   |   1 -
 .../platform/mtk-vcodec/mtk_vcodec_intr.c     |  27 +-
 .../platform/mtk-vcodec/mtk_vcodec_intr.h     |   4 +-
 .../platform/mtk-vcodec/mtk_vcodec_util.c     |  87 +++++-
 .../platform/mtk-vcodec/mtk_vcodec_util.h     |   8 +-
 .../platform/mtk-vcodec/vdec/vdec_h264_if.c   |   2 +-
 .../mtk-vcodec/vdec/vdec_h264_req_if.c        |   2 +-
 .../platform/mtk-vcodec/vdec/vdec_vp8_if.c    |   2 +-
 .../platform/mtk-vcodec/vdec/vdec_vp9_if.c    |   2 +-
 .../media/platform/mtk-vcodec/vdec_drv_if.c   |  21 +-
 .../media/platform/mtk-vcodec/vdec_ipi_msg.h  |  16 +-
 .../platform/mtk-vcodec/vdec_msg_queue.c      | 290 ++++++++++++++++++
 .../platform/mtk-vcodec/vdec_msg_queue.h      | 157 ++++++++++
 .../media/platform/mtk-vcodec/vdec_vpu_if.c   |  46 ++-
 .../media/platform/mtk-vcodec/vdec_vpu_if.h   |  22 ++
 .../platform/mtk-vcodec/venc/venc_h264_if.c   |   2 +-
 .../platform/mtk-vcodec/venc/venc_vp8_if.c    |   2 +-
 33 files changed, 1756 insertions(+), 278 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
 delete mode 100644 Documentation/devicetree/bindings/media/mediatek-vcodec.txt
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec_msg_queue.h

-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v7, 01/15] media: mtk-vcodec: Get numbers of register bases from DT
  2021-10-11  7:02 [PATCH v7, 00/15] Support multi hardware decode using of_platform_populate Yunfei Dong
@ 2021-10-11  7:02 ` Yunfei Dong
  2021-10-11  7:02 ` [PATCH v7, 02/15] media: mtk-vcodec: Align vcodec wake up interrupt interface Yunfei Dong
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 43+ messages in thread
From: Yunfei Dong @ 2021-10-11  7:02 UTC (permalink / raw)
  To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Tzung-Bi Shih

Different platform may has different numbers of register bases. Gets the
numbers of register bases from DT (sizeof(u32) * 4 bytes for each).

Reviewed-by: Tzung-Bi Shih<tzungbi@google.com>
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 37 ++++++++++++++-----
 1 file changed, 28 insertions(+), 9 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 55ae198dbcf9..983e0f2831af 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -78,6 +78,30 @@ static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
 	return IRQ_HANDLED;
 }
 
+static int mtk_vcodec_get_reg_bases(struct mtk_vcodec_dev *dev)
+{
+	struct platform_device *pdev = dev->plat_dev;
+	int reg_num, i;
+
+	/* Sizeof(u32) * 4 bytes for each register base. */
+	reg_num = of_property_count_elems_of_size(pdev->dev.of_node, "reg",
+		sizeof(u32) * 4);
+	if (reg_num <= 0 || reg_num > NUM_MAX_VDEC_REG_BASE) {
+		dev_err(&pdev->dev, "Invalid register property size: %d\n", reg_num);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < reg_num; i++) {
+		dev->reg_base[i] = devm_platform_ioremap_resource(pdev, i);
+		if (IS_ERR(dev->reg_base[i]))
+			return PTR_ERR(dev->reg_base[i]);
+
+		mtk_v4l2_debug(2, "reg[%d] base=%p", i, dev->reg_base[i]);
+	}
+
+	return 0;
+}
+
 static int fops_vcodec_open(struct file *file)
 {
 	struct mtk_vcodec_dev *dev = video_drvdata(file);
@@ -206,7 +230,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	struct resource *res;
 	phandle rproc_phandle;
 	enum mtk_vcodec_fw_type fw_type;
-	int i, ret;
+	int ret;
 
 	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
 	if (!dev)
@@ -238,14 +262,9 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		goto err_dec_pm;
 	}
 
-	for (i = 0; i < NUM_MAX_VDEC_REG_BASE; i++) {
-		dev->reg_base[i] = devm_platform_ioremap_resource(pdev, i);
-		if (IS_ERR((__force void *)dev->reg_base[i])) {
-			ret = PTR_ERR((__force void *)dev->reg_base[i]);
-			goto err_res;
-		}
-		mtk_v4l2_debug(2, "reg[%d] base=%p", i, dev->reg_base[i]);
-	}
+	ret = mtk_vcodec_get_reg_bases(dev);
+	if (ret)
+		goto err_res;
 
 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (res == NULL) {
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v7, 02/15] media: mtk-vcodec: Align vcodec wake up interrupt interface
  2021-10-11  7:02 [PATCH v7, 00/15] Support multi hardware decode using of_platform_populate Yunfei Dong
  2021-10-11  7:02 ` [PATCH v7, 01/15] media: mtk-vcodec: Get numbers of register bases from DT Yunfei Dong
@ 2021-10-11  7:02 ` Yunfei Dong
  2021-10-14 11:12   ` AngeloGioacchino Del Regno
  2021-10-11  7:02 ` [PATCH v7, 03/15] media: mtk-vcodec: Refactor vcodec pm interface Yunfei Dong
                   ` (13 subsequent siblings)
  15 siblings, 1 reply; 43+ messages in thread
From: Yunfei Dong @ 2021-10-11  7:02 UTC (permalink / raw)
  To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Tzung-Bi Shih

Vdec and venc can use the same function to wake up interrupt event.

Reviewed-by: Tzung-Bi Shih <tzungbi@google.com>
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 9 +--------
 drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h     | 8 ++++++++
 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c | 8 --------
 3 files changed, 9 insertions(+), 16 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 983e0f2831af..8db9cdc66043 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -31,13 +31,6 @@
 module_param(mtk_v4l2_dbg_level, int, 0644);
 module_param(mtk_vcodec_dbg, bool, 0644);
 
-/* Wake up context wait_queue */
-static void wake_up_ctx(struct mtk_vcodec_ctx *ctx)
-{
-	ctx->int_cond = 1;
-	wake_up_interruptible(&ctx->queue);
-}
-
 static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
 {
 	struct mtk_vcodec_dev *dev = priv;
@@ -69,7 +62,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);
+	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED);
 
 	mtk_v4l2_debug(3,
 			"mtk_vcodec_dec_irq_handler :wake up ctx %d, dec_done_status=%x",
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index d4f840a7bbcb..3b1e5e3a450e 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -472,4 +472,12 @@ static inline struct mtk_vcodec_ctx *ctrl_to_ctx(struct v4l2_ctrl *ctrl)
 	return container_of(ctrl->handler, struct mtk_vcodec_ctx, ctrl_hdl);
 }
 
+/* Wake up context wait_queue */
+static inline void wake_up_ctx(struct mtk_vcodec_ctx *ctx, unsigned int reason)
+{
+	ctx->int_cond = 1;
+	ctx->int_type = reason;
+	wake_up_interruptible(&ctx->queue);
+}
+
 #endif /* _MTK_VCODEC_DRV_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index 4167e865b23f..2828df77020c 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -73,14 +73,6 @@ static const struct mtk_video_fmt mtk_video_formats_capture_mt8183[] =  {
 	},
 };
 
-/* Wake up context wait_queue */
-static void wake_up_ctx(struct mtk_vcodec_ctx *ctx, unsigned int reason)
-{
-	ctx->int_cond = 1;
-	ctx->int_type = reason;
-	wake_up_interruptible(&ctx->queue);
-}
-
 static void clean_irq_status(unsigned int irq_status, void __iomem *addr)
 {
 	if (irq_status & MTK_VENC_IRQ_STATUS_PAUSE)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v7, 03/15] media: mtk-vcodec: Refactor vcodec pm interface
  2021-10-11  7:02 [PATCH v7, 00/15] Support multi hardware decode using of_platform_populate Yunfei Dong
  2021-10-11  7:02 ` [PATCH v7, 01/15] media: mtk-vcodec: Get numbers of register bases from DT Yunfei Dong
  2021-10-11  7:02 ` [PATCH v7, 02/15] media: mtk-vcodec: Align vcodec wake up interrupt interface Yunfei Dong
@ 2021-10-11  7:02 ` Yunfei Dong
  2021-10-14 11:12   ` AngeloGioacchino Del Regno
  2021-10-14 13:44   ` Dafna Hirschfeld
  2021-10-11  7:02 ` [PATCH v7, 04/15] media: mtk-vcodec: Manage multi hardware information Yunfei Dong
                   ` (12 subsequent siblings)
  15 siblings, 2 replies; 43+ messages in thread
From: Yunfei Dong @ 2021-10-11  7:02 UTC (permalink / raw)
  To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Tzung-Bi Shih

Using the needed param for pm init/release function and remove unused
param mtkdev in 'struct mtk_vcodec_pm'.

Reviewed-by: Tzung-Bi Shih <tzungbi@google.com>
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |  6 ++---
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 22 ++++++++-----------
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h   |  5 +++--
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  1 -
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c   |  1 -
 5 files changed, 15 insertions(+), 20 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 8db9cdc66043..dd749d41c75a 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -249,7 +249,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	if (IS_ERR(dev->fw_handler))
 		return PTR_ERR(dev->fw_handler);
 
-	ret = mtk_vcodec_init_dec_pm(dev);
+	ret = mtk_vcodec_init_dec_pm(dev->plat_dev, &dev->pm);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "Failed to get mt vcodec clock source");
 		goto err_dec_pm;
@@ -379,7 +379,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 err_dec_alloc:
 	v4l2_device_unregister(&dev->v4l2_dev);
 err_res:
-	mtk_vcodec_release_dec_pm(dev);
+	mtk_vcodec_release_dec_pm(&dev->pm);
 err_dec_pm:
 	mtk_vcodec_fw_release(dev->fw_handler);
 	return ret;
@@ -422,7 +422,7 @@ static int mtk_vcodec_dec_remove(struct platform_device *pdev)
 		video_unregister_device(dev->vfd_dec);
 
 	v4l2_device_unregister(&dev->v4l2_dev);
-	mtk_vcodec_release_dec_pm(dev);
+	mtk_vcodec_release_dec_pm(&dev->pm);
 	mtk_vcodec_fw_release(dev->fw_handler);
 	return 0;
 }
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
index 6038db96f71c..20bd157a855c 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
@@ -13,18 +13,15 @@
 #include "mtk_vcodec_dec_pm.h"
 #include "mtk_vcodec_util.h"
 
-int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
+int mtk_vcodec_init_dec_pm(struct platform_device *pdev,
+	struct mtk_vcodec_pm *pm)
 {
 	struct device_node *node;
-	struct platform_device *pdev;
-	struct mtk_vcodec_pm *pm;
+	struct platform_device *larb_pdev;
 	struct mtk_vcodec_clk *dec_clk;
 	struct mtk_vcodec_clk_info *clk_info;
 	int i = 0, ret = 0;
 
-	pdev = mtkdev->plat_dev;
-	pm = &mtkdev->pm;
-	pm->mtkdev = mtkdev;
 	dec_clk = &pm->vdec_clk;
 	node = of_parse_phandle(pdev->dev.of_node, "mediatek,larb", 0);
 	if (!node) {
@@ -32,13 +29,12 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
 		return -1;
 	}
 
-	pdev = of_find_device_by_node(node);
+	larb_pdev = of_find_device_by_node(node);
 	of_node_put(node);
-	if (WARN_ON(!pdev)) {
+	if (WARN_ON(!larb_pdev)) {
 		return -1;
 	}
-	pm->larbvdec = &pdev->dev;
-	pdev = mtkdev->plat_dev;
+	pm->larbvdec = &larb_pdev->dev;
 	pm->dev = &pdev->dev;
 
 	dec_clk->clk_num =
@@ -82,10 +78,10 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
 	return ret;
 }
 
-void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev)
+void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm)
 {
-	pm_runtime_disable(dev->pm.dev);
-	put_device(dev->pm.larbvdec);
+	pm_runtime_disable(pm->dev);
+	put_device(pm->larbvdec);
 }
 
 int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
index 280aeaefdb65..a3df6aef6cb9 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
@@ -9,8 +9,9 @@
 
 #include "mtk_vcodec_drv.h"
 
-int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *dev);
-void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev);
+int mtk_vcodec_init_dec_pm(struct platform_device *pdev,
+	struct mtk_vcodec_pm *pm);
+void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm);
 
 int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm);
 void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 3b1e5e3a450e..973b0b3649c6 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -195,7 +195,6 @@ struct mtk_vcodec_pm {
 	struct mtk_vcodec_clk	venc_clk;
 	struct device	*larbvenc;
 	struct device	*dev;
-	struct mtk_vcodec_dev	*mtkdev;
 };
 
 /**
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
index 1b2e4930ed27..0c8c8f86788c 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
@@ -26,7 +26,6 @@ int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *mtkdev)
 	pdev = mtkdev->plat_dev;
 	pm = &mtkdev->pm;
 	memset(pm, 0, sizeof(struct mtk_vcodec_pm));
-	pm->mtkdev = mtkdev;
 	pm->dev = &pdev->dev;
 	dev = &pdev->dev;
 	enc_clk = &pm->venc_clk;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v7, 04/15] media: mtk-vcodec: Manage multi hardware information
  2021-10-11  7:02 [PATCH v7, 00/15] Support multi hardware decode using of_platform_populate Yunfei Dong
                   ` (2 preceding siblings ...)
  2021-10-11  7:02 ` [PATCH v7, 03/15] media: mtk-vcodec: Refactor vcodec pm interface Yunfei Dong
@ 2021-10-11  7:02 ` Yunfei Dong
  2021-10-14  9:20   ` AngeloGioacchino Del Regno
  2021-10-14  9:30   ` AngeloGioacchino Del Regno
  2021-10-11  7:02 ` [PATCH v7, 05/15] dt-bindings: media: mtk-vcodec: Separate video encoder and decoder dt-bindings Yunfei Dong
                   ` (11 subsequent siblings)
  15 siblings, 2 replies; 43+ messages in thread
From: Yunfei Dong @ 2021-10-11  7:02 UTC (permalink / raw)
  To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

Manage each hardware information which includes irq/power/clk.
The hardware includes LAT0, LAT1 and CORE.

Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
v7: Using of_platform_populate not component framework to manage multi hardware.
---
 drivers/media/platform/mtk-vcodec/Makefile    |   1 +
 .../platform/mtk-vcodec/mtk_vcodec_dec.h      |   1 +
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 151 ++++++++++++----
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   | 165 ++++++++++++++++++
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.h   |  49 ++++++
 .../mtk-vcodec/mtk_vcodec_dec_stateful.c      |   1 +
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     |   1 +
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  23 +++
 8 files changed, 359 insertions(+), 33 deletions(-)
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h

diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index ca8e9e7a9c4e..edeb3b66e9e9 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -15,6 +15,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 		mtk_vcodec_dec_stateful.o \
 		mtk_vcodec_dec_stateless.o \
 		mtk_vcodec_dec_pm.o \
+		mtk_vcodec_dec_hw.o \
 
 mtk-vcodec-enc-y := venc/venc_vp8_if.o \
 		venc/venc_h264_if.o \
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
index 9fbd24186c1a..c509224cbff4 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
@@ -66,6 +66,7 @@ extern const struct v4l2_ioctl_ops mtk_vdec_ioctl_ops;
 extern const struct v4l2_m2m_ops mtk_vdec_m2m_ops;
 extern const struct media_device_ops mtk_vcodec_media_ops;
 
+extern struct platform_driver mtk_vdec_comp_driver;
 
 /*
  * mtk_vdec_lock/mtk_vdec_unlock are for ctx instance to
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 dd749d41c75a..17cb3e3519eb 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -18,19 +18,61 @@
 
 #include "mtk_vcodec_drv.h"
 #include "mtk_vcodec_dec.h"
+#include "mtk_vcodec_dec_hw.h"
 #include "mtk_vcodec_dec_pm.h"
 #include "mtk_vcodec_intr.h"
-#include "mtk_vcodec_util.h"
 #include "mtk_vcodec_fw.h"
 
-#define VDEC_HW_ACTIVE	0x10
-#define VDEC_IRQ_CFG	0x11
-#define VDEC_IRQ_CLR	0x10
-#define VDEC_IRQ_CFG_REG	0xa4
-
 module_param(mtk_v4l2_dbg_level, int, 0644);
 module_param(mtk_vcodec_dbg, bool, 0644);
 
+static struct of_device_id mtk_vdec_drv_ids[] = {
+	{
+		.compatible = "mediatek,mtk-vcodec-lat",
+		.data = (void *)MTK_VDEC_LAT0,
+	},
+	{
+		.compatible = "mediatek,mtk-vcodec-core",
+		.data = (void *)MTK_VDEC_CORE,
+	},
+	{},
+};
+
+static int mtk_vcodec_comp_device_check(struct mtk_vcodec_ctx *ctx)
+ {
+	struct mtk_vcodec_dev *vdec_dev = ctx->dev;
+	struct platform_device *pdev = vdec_dev->plat_dev;
+	struct device_node *comp_node;
+	enum mtk_vdec_hw_id comp_idx;
+	const struct of_device_id *of_id;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(mtk_vdec_drv_ids); i++) {
+		of_id = &mtk_vdec_drv_ids[i];
+		comp_node = of_find_compatible_node(NULL, NULL,
+			of_id->compatible);
+		if (!comp_node)
+			continue;
+
+		if (!of_device_is_available(comp_node)) {
+			of_node_put(comp_node);
+			dev_err(&pdev->dev, "Fail to get MMSYS node\n");
+			continue;
+		}
+
+		comp_idx = (enum mtk_vdec_hw_id)of_id->data;
+		vdec_dev->component_node[comp_idx] = comp_node;
+
+		if (!test_bit(comp_idx, vdec_dev->hardware_bitmap)) {
+			dev_err(&pdev->dev, "Vdec comp_idx is not ready %d.",
+				comp_idx);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
 static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
 {
 	struct mtk_vcodec_dev *dev = priv;
@@ -95,6 +137,41 @@ static int mtk_vcodec_get_reg_bases(struct mtk_vcodec_dev *dev)
 	return 0;
 }
 
+static int mtk_vcodec_init_dec_params(struct mtk_vcodec_dev *dev)
+{
+	struct platform_device *pdev = dev->plat_dev;
+	int ret;
+
+	ret = mtk_vcodec_get_reg_bases(dev);
+	if (ret)
+		return ret;
+
+	if (!dev->vdec_pdata->is_comp_supported) {
+		dev->dec_irq = platform_get_irq(pdev, 0);
+		if (dev->dec_irq < 0) {
+			dev_err(&pdev->dev, "failed to get irq number");
+			return dev->dec_irq;
+		}
+
+		irq_set_status_flags(dev->dec_irq, IRQ_NOAUTOEN);
+		ret = devm_request_irq(&pdev->dev, dev->dec_irq,
+			mtk_vcodec_dec_irq_handler, 0, pdev->name, dev);
+		if (ret) {
+			dev_err(&pdev->dev, "failed to install dev->dec_irq %d (%d)",
+				dev->dec_irq, ret);
+			return ret;
+		}
+
+		ret = mtk_vcodec_init_dec_pm(pdev, &dev->pm);
+		if (ret < 0) {
+			dev_err(&pdev->dev, "failed to get mt vcodec clock source");
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
 static int fops_vcodec_open(struct file *file)
 {
 	struct mtk_vcodec_dev *dev = video_drvdata(file);
@@ -116,6 +193,12 @@ static int fops_vcodec_open(struct file *file)
 	init_waitqueue_head(&ctx->queue);
 	mutex_init(&ctx->lock);
 
+	ret = mtk_vcodec_comp_device_check(ctx);
+	if (ret) {
+		mtk_v4l2_err("Failed to check vdec comp device.");
+		goto err_ctrls_setup;
+	}
+
 	ctx->type = MTK_INST_DECODER;
 	ret = dev->vdec_pdata->ctrls_setup(ctx);
 	if (ret) {
@@ -220,7 +303,6 @@ 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 ret;
@@ -249,32 +331,10 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	if (IS_ERR(dev->fw_handler))
 		return PTR_ERR(dev->fw_handler);
 
-	ret = mtk_vcodec_init_dec_pm(dev->plat_dev, &dev->pm);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "Failed to get mt vcodec clock source");
-		goto err_dec_pm;
-	}
-
-	ret = mtk_vcodec_get_reg_bases(dev);
-	if (ret)
-		goto err_res;
-
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (res == NULL) {
-		dev_err(&pdev->dev, "failed to get irq resource");
-		ret = -ENOENT;
-		goto err_res;
-	}
-
-	dev->dec_irq = platform_get_irq(pdev, 0);
-	irq_set_status_flags(dev->dec_irq, IRQ_NOAUTOEN);
-	ret = devm_request_irq(&pdev->dev, dev->dec_irq,
-			mtk_vcodec_dec_irq_handler, 0, pdev->name, dev);
+	ret = mtk_vcodec_init_dec_params(dev);
 	if (ret) {
-		dev_err(&pdev->dev, "Failed to install dev->dec_irq %d (%d)",
-			dev->dec_irq,
-			ret);
-		goto err_res;
+		dev_err(&pdev->dev, "Failed to init pm and registers");
+		goto err_dec_pm;
 	}
 
 	mutex_init(&dev->dec_mutex);
@@ -329,6 +389,13 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		goto err_event_workq;
 	}
 
+	ret = of_platform_populate(pdev->dev.of_node, NULL, NULL,
+		&pdev->dev);
+	if (ret) {
+		mtk_v4l2_err("Master device of_platform_populate failed.");
+		goto err_event_workq;
+	}
+
 	if (dev->vdec_pdata->uses_stateless_api) {
 		dev->mdev_dec.dev = &pdev->dev;
 		strscpy(dev->mdev_dec.model, MTK_VCODEC_DEC_NAME,
@@ -436,7 +503,25 @@ static struct platform_driver mtk_vcodec_dec_driver = {
 	},
 };
 
-module_platform_driver(mtk_vcodec_dec_driver);
+static struct platform_driver * const mtk_vdec_drivers[] = {
+	&mtk_vdec_comp_driver,
+	&mtk_vcodec_dec_driver,
+};
+
+static int __init mtk_vdec_init(void)
+{
+	return platform_register_drivers(mtk_vdec_drivers,
+					 ARRAY_SIZE(mtk_vdec_drivers));
+}
+
+static void __exit mtk_vdec_exit(void)
+{
+	platform_unregister_drivers(mtk_vdec_drivers,
+				    ARRAY_SIZE(mtk_vdec_drivers));
+}
+
+module_init(mtk_vdec_init);
+module_exit(mtk_vdec_exit);
 
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("Mediatek video codec V4L2 decoder driver");
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
new file mode 100644
index 000000000000..3752ccaea284
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
@@ -0,0 +1,165 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong@mediatek.com>
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+
+#include "mtk_vcodec_drv.h"
+#include "mtk_vcodec_dec.h"
+#include "mtk_vcodec_dec_hw.h"
+#include "mtk_vcodec_dec_pm.h"
+#include "mtk_vcodec_intr.h"
+#include "mtk_vcodec_util.h"
+
+static const struct of_device_id mtk_vdec_comp_ids[] = {
+	{
+		.compatible = "mediatek,mtk-vcodec-lat",
+	},
+	{
+		.compatible = "mediatek,mtk-vcodec-core",
+	},
+	{},
+};
+
+static irqreturn_t mtk_vdec_comp_irq_handler(int irq, void *priv)
+{
+	struct mtk_vdec_comp_dev *dev = priv;
+	struct mtk_vcodec_ctx *ctx;
+	u32 cg_status;
+	unsigned int dec_done_status;
+	void __iomem *vdec_misc_addr = dev->reg_base[VDEC_COMP_MISC] +
+					VDEC_IRQ_CFG_REG;
+
+	ctx = mtk_vcodec_get_curr_ctx(dev->master_dev);
+
+	/* check if HW active or not */
+	cg_status = readl(dev->reg_base[VDEC_COMP_SYS]);
+	if ((cg_status & VDEC_HW_ACTIVE) != 0) {
+		mtk_v4l2_err("vdec active is not 0x0 (0x%08x)",
+			cg_status);
+		return IRQ_HANDLED;
+	}
+
+	dec_done_status = readl(vdec_misc_addr);
+	if ((dec_done_status & MTK_VDEC_IRQ_STATUS_DEC_SUCCESS) !=
+		MTK_VDEC_IRQ_STATUS_DEC_SUCCESS)
+		return IRQ_HANDLED;
+
+	/* clear interrupt */
+	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);
+
+	mtk_v4l2_debug(3, "wake up ctx %d, dec_done_status=%x",
+		ctx->id, dec_done_status);
+
+	return IRQ_HANDLED;
+}
+
+static int mtk_vdec_comp_init_irq(struct mtk_vdec_comp_dev *dev)
+{
+	struct platform_device *pdev = dev->plat_dev;
+	int ret;
+
+	dev->dec_irq = platform_get_irq(pdev, 0);
+	if (dev->dec_irq < 0) {
+		dev_err(&pdev->dev, "Failed to get irq resource");
+		return dev->dec_irq;
+	}
+
+	irq_set_status_flags(dev->dec_irq, IRQ_NOAUTOEN);
+	ret = devm_request_irq(&pdev->dev, dev->dec_irq,
+				mtk_vdec_comp_irq_handler, 0, pdev->name, dev);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to install dev->dec_irq %d (%d)",
+			dev->dec_irq, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int mtk_vdec_comp_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_vdec_comp_dev *comp_dev;
+	struct mtk_vcodec_dev *master_dev;
+	const struct of_device_id *of_id;
+	int comp_idx;
+	int ret;
+
+	if (!dev->parent) {
+		dev_err(dev, "Vdec parent prob is not ready.");
+		return -EPROBE_DEFER;
+	}
+
+	master_dev = dev_get_drvdata(dev->parent);
+	if (!master_dev) {
+		dev_err(dev, "Failed to get master device.");
+		return -EPROBE_DEFER;
+	}
+
+	comp_dev = devm_kzalloc(dev, sizeof(*comp_dev), GFP_KERNEL);
+	if (!comp_dev)
+		return -ENOMEM;
+
+	comp_dev->plat_dev = pdev;
+	ret = mtk_vcodec_init_dec_pm(pdev, &comp_dev->pm);
+	if (ret) {
+		dev_err(dev, "Failed to get mt vcodec clock source.");
+		return ret;
+	}
+
+	comp_dev->reg_base[VDEC_COMP_MISC] =
+		devm_platform_ioremap_resource_byname(pdev, "reg-misc");
+	if (IS_ERR((__force void *)comp_dev->reg_base[VDEC_COMP_MISC])) {
+		ret = PTR_ERR((__force void *)comp_dev->reg_base[VDEC_COMP_MISC]);
+		goto err;
+	}
+
+	ret = mtk_vdec_comp_init_irq(comp_dev);
+	if (ret) {
+		dev_err(dev, "Failed to register irq handler.\n");
+		goto err;
+	}
+
+	of_id = of_match_device(mtk_vdec_comp_ids, dev);
+	if (!of_id) {
+		dev_err(dev, "Can't get vdec comp device id.\n");
+		ret = -EINVAL;
+		goto err;
+	}
+
+	comp_idx = (enum mtk_vdec_hw_id)of_id->data;
+	if (comp_idx < MTK_VDEC_HW_MAX) {
+		master_dev->comp_dev[comp_idx] = comp_dev;
+		comp_dev->comp_idx = comp_idx;
+		comp_dev->master_dev = master_dev;
+		comp_dev->reg_base[VDEC_COMP_SYS] =
+			master_dev->reg_base[VDEC_COMP_SYS];
+		set_bit(comp_dev->comp_idx, master_dev->hardware_bitmap);
+	}
+
+	platform_set_drvdata(pdev, comp_dev);
+	return 0;
+err:
+	mtk_vcodec_release_dec_pm(&comp_dev->pm);
+	return ret;
+}
+
+MODULE_DEVICE_TABLE(of, mtk_vdec_comp_ids);
+struct platform_driver mtk_vdec_comp_driver = {
+	.probe	= mtk_vdec_comp_probe,
+	.driver	= {
+		.name	= "mtk-vdec-comp",
+		.of_match_table = mtk_vdec_comp_ids,
+	},
+};
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
new file mode 100644
index 000000000000..8d6e818a3474
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong@mediatek.com>
+ */
+
+#ifndef _MTK_VCODEC_DEC_HW_H_
+#define _MTK_VCODEC_DEC_HW_H_
+
+#include <linux/io.h>
+#include <linux/platform_device.h>
+
+#include "mtk_vcodec_drv.h"
+
+#define VDEC_HW_ACTIVE	0x10
+#define VDEC_IRQ_CFG	0x11
+#define VDEC_IRQ_CLR	0x10
+#define VDEC_IRQ_CFG_REG	0xa4
+
+/**
+ * enum mtk_comp_hw_reg_idx - component register base index
+ */
+enum mtk_comp_hw_reg_idx {
+	VDEC_COMP_SYS,
+	VDEC_COMP_MISC,
+	VDEC_COMP_MAX
+};
+
+/**
+ * struct mtk_vdec_comp_dev - component framwork driver data
+ * @plat_dev: platform device
+ * @master_dev: master device
+ * @reg_base: Mapped address of MTK Vcodec registers.
+ *
+ * @dec_irq: decoder irq resource
+ * @pm: power management control
+ * @comp_idx: component index
+ */
+struct mtk_vdec_comp_dev {
+	struct platform_device *plat_dev;
+	struct mtk_vcodec_dev *master_dev;
+	void __iomem *reg_base[VDEC_COMP_MAX];
+
+	int dec_irq;
+	struct mtk_vcodec_pm pm;
+	int comp_idx;
+};
+
+#endif /* _MTK_VCODEC_DEC_HW_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
index 59c24b22ab6d..4f9a80ce15d8 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
@@ -623,4 +623,5 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata = {
 	.num_framesizes = NUM_SUPPORTED_FRAMESIZE,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
+	.is_comp_supported = false,
 };
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 8f4a1f0a0769..762633572b49 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -357,4 +357,5 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
 	.uses_stateless_api = true,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
+	.is_comp_supported = false,
 };
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 973b0b3649c6..ec3850b4c638 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -93,6 +93,17 @@ enum mtk_fmt_type {
 	MTK_FMT_FRAME = 2,
 };
 
+/**
+ * struct mtk_vdec_hw_id - Hardware index used to separate
+ *                         different hardware
+ */
+enum mtk_vdec_hw_id {
+	MTK_VDEC_CORE,
+	MTK_VDEC_LAT0,
+	MTK_VDEC_LAT1,
+	MTK_VDEC_HW_MAX,
+};
+
 /*
  * struct mtk_video_fmt - Structure used to store information about pixelformats
  */
@@ -331,6 +342,7 @@ enum mtk_chip {
  *
  * @chip: chip this decoder is compatible with
  *
+ * @is_comp_supported: true: using compoent framework, false: not support
  * @uses_stateless_api: whether the decoder uses the stateless API with requests
  */
 
@@ -352,6 +364,7 @@ struct mtk_vcodec_dec_pdata {
 
 	enum mtk_chip chip;
 
+	bool is_comp_supported;
 	bool uses_stateless_api;
 };
 
@@ -422,6 +435,11 @@ struct mtk_vcodec_enc_pdata {
  * @pm: power management control
  * @dec_capability: used to identify decode capability, ex: 4k
  * @enc_capability: used to identify encode capability
+ *
+ * @comp_dev: component hardware device
+ * @component_node: component node
+ *
+ * @hardware_bitmap: used to record hardware is ready or not
  */
 struct mtk_vcodec_dev {
 	struct v4l2_device v4l2_dev;
@@ -459,6 +477,11 @@ struct mtk_vcodec_dev {
 	struct mtk_vcodec_pm pm;
 	unsigned int dec_capability;
 	unsigned int enc_capability;
+
+	void *comp_dev[MTK_VDEC_HW_MAX];
+	struct device_node *component_node[MTK_VDEC_HW_MAX];
+
+	DECLARE_BITMAP(hardware_bitmap, MTK_VDEC_HW_MAX);
 };
 
 static inline struct mtk_vcodec_ctx *fh_to_ctx(struct v4l2_fh *fh)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v7, 05/15] dt-bindings: media: mtk-vcodec: Separate video encoder and decoder dt-bindings
  2021-10-11  7:02 [PATCH v7, 00/15] Support multi hardware decode using of_platform_populate Yunfei Dong
                   ` (3 preceding siblings ...)
  2021-10-11  7:02 ` [PATCH v7, 04/15] media: mtk-vcodec: Manage multi hardware information Yunfei Dong
@ 2021-10-11  7:02 ` Yunfei Dong
  2021-10-11  7:02 ` [PATCH v7, 06/15] media: mtk-vcodec: Use pure single core for MT8183 Yunfei Dong
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 43+ messages in thread
From: Yunfei Dong @ 2021-10-11  7:02 UTC (permalink / raw)
  To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Rob Herring

Decoder will use component framework to manage hardware, it is big
difference with encoder.

Reviewed-by: Rob Herring<robh@kernel.org>
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
 .../media/mediatek,vcodec-decoder.yaml        | 175 +++++++++++++++++
 .../media/mediatek,vcodec-encoder.yaml        | 185 ++++++++++++++++++
 .../bindings/media/mediatek-vcodec.txt        | 130 ------------
 3 files changed, 360 insertions(+), 130 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
 delete mode 100644 Documentation/devicetree/bindings/media/mediatek-vcodec.txt

diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
new file mode 100644
index 000000000000..b6b97110024d
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
@@ -0,0 +1,175 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iommu/mediatek,vcodec-encoder.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Video Decode Accelerator With Component
+
+maintainers:
+  - Yunfei Dong <yunfei.dong@mediatek.com>
+
+description: |+
+  Mediatek Video Decode is the video decode hardware present in Mediatek
+  SoCs which supports high resolution decoding functionalities.
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt8173-vcodec-dec
+      - mediatek,mt8183-vcodec-dec
+
+  reg:
+    maxItems: 12
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 8
+
+  clock-names:
+    items:
+      - const: vcodecpll
+      - const: univpll_d2
+      - const: clk_cci400_sel
+      - const: vdec_sel
+      - const: vdecpll
+      - const: vencpll
+      - const: venc_lt_sel
+      - const: vdec_bus_clk_src
+
+  assigned-clocks: true
+
+  assigned-clock-parents: true
+
+  assigned-clock-rates: true
+
+  power-domains:
+    maxItems: 1
+
+  iommus:
+    minItems: 1
+    maxItems: 32
+    description: |
+      List of the hardware port in respective IOMMU block for current Socs.
+      Refer to bindings/iommu/mediatek,iommu.yaml.
+
+  dma-ranges:
+    maxItems: 1
+    description: |
+      Describes the physical address space of IOMMU maps to memory.
+
+  mediatek,larb:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description: |
+      Must contain the local arbiters in the current Socs.
+
+  mediatek,vpu:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description:
+      Describes point to vpu.
+
+  mediatek,scp:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description:
+      Describes point to scp.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - iommus
+  - assigned-clocks
+  - assigned-clock-parents
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mt8183-vcodec-dec
+
+    then:
+      required:
+        - mediatek,scp
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mt8173-vcodec-dec
+
+    then:
+      required:
+        - mediatek,vpu
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/mt8173-clk.h>
+    #include <dt-bindings/memory/mt8173-larb-port.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/power/mt8173-power.h>
+
+    vcodec_dec: vcodec@16000000 {
+      compatible = "mediatek,mt8173-vcodec-dec";
+      reg = <0 0x16000000 0 0x100>,   /*VDEC_SYS*/
+          <0 0x16020000 0 0x1000>,  /*VDEC_MISC*/
+          <0 0x16021000 0 0x800>,   /*VDEC_LD*/
+          <0 0x16021800 0 0x800>,   /*VDEC_TOP*/
+          <0 0x16022000 0 0x1000>,  /*VDEC_CM*/
+          <0 0x16023000 0 0x1000>,  /*VDEC_AD*/
+          <0 0x16024000 0 0x1000>,  /*VDEC_AV*/
+          <0 0x16025000 0 0x1000>,  /*VDEC_PP*/
+          <0 0x16026800 0 0x800>,   /*VP8_VD*/
+          <0 0x16027000 0 0x800>,   /*VP6_VD*/
+          <0 0x16027800 0 0x800>,   /*VP8_VL*/
+          <0 0x16028400 0 0x400>;   /*VP9_VD*/
+      interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_LOW>;
+      mediatek,larb = <&larb1>;
+      iommus = <&iommu M4U_PORT_HW_VDEC_MC_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_PP_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_AVC_MV_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_PRED_RD_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_PRED_WR_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_UFO_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_VLD_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_VLD2_EXT>;
+      mediatek,vpu = <&vpu>;
+      power-domains = <&scpsys MT8173_POWER_DOMAIN_VDEC>;
+      clocks = <&apmixedsys CLK_APMIXED_VCODECPLL>,
+             <&topckgen CLK_TOP_UNIVPLL_D2>,
+             <&topckgen CLK_TOP_CCI400_SEL>,
+             <&topckgen CLK_TOP_VDEC_SEL>,
+             <&topckgen CLK_TOP_VCODECPLL>,
+             <&apmixedsys CLK_APMIXED_VENCPLL>,
+             <&topckgen CLK_TOP_VENC_LT_SEL>,
+             <&topckgen CLK_TOP_VCODECPLL_370P5>;
+      clock-names = "vcodecpll",
+                  "univpll_d2",
+                  "clk_cci400_sel",
+                  "vdec_sel",
+                  "vdecpll",
+                  "vencpll",
+                  "venc_lt_sel",
+                  "vdec_bus_clk_src";
+      assigned-clocks = <&topckgen CLK_TOP_VENC_LT_SEL>,
+                      <&topckgen CLK_TOP_CCI400_SEL>,
+                      <&topckgen CLK_TOP_VDEC_SEL>,
+                      <&apmixedsys CLK_APMIXED_VCODECPLL>,
+                      <&apmixedsys CLK_APMIXED_VENCPLL>;
+      assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL_370P5>,
+                             <&topckgen CLK_TOP_UNIVPLL_D2>,
+                             <&topckgen CLK_TOP_VCODECPLL>;
+      assigned-clock-rates = <0>, <0>, <0>, <1482000000>, <800000000>;
+    };
diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
new file mode 100644
index 000000000000..6f28394e8ce3
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
@@ -0,0 +1,185 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iommu/mediatek,vcodec-encoder.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Video Encode Accelerator With Component
+
+maintainers:
+  - Yunfei Dong <yunfei.dong@mediatek.com>
+
+description: |+
+  Mediatek Video Encode is the video encode hardware present in Mediatek
+  SoCs which supports high resolution encoding functionalities.
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt8173-vcodec-enc-vp8
+      - mediatek,mt8173-vcodec-enc
+      - mediatek,mt8183-vcodec-enc
+      - mediatek,mt8192-vcodec-enc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    minItems: 1
+    maxItems: 5
+
+  clock-names:
+    minItems: 1
+    maxItems: 5
+
+  assigned-clocks: true
+
+  assigned-clock-parents: true
+
+  iommus:
+    minItems: 1
+    maxItems: 32
+    description: |
+      List of the hardware port in respective IOMMU block for current Socs.
+      Refer to bindings/iommu/mediatek,iommu.yaml.
+
+  dma-ranges:
+    maxItems: 1
+    description: |
+      Describes the physical address space of IOMMU maps to memory.
+
+  mediatek,larb:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description: |
+      Must contain the local arbiters in the current Socs.
+
+  mediatek,vpu:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description:
+      Describes point to vpu.
+
+  mediatek,scp:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description:
+      Describes point to scp.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - iommus
+  - assigned-clocks
+  - assigned-clock-parents
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mt8183-vcodec-enc
+              - mediatek,mt8192-vcodec-enc
+
+    then:
+      required:
+        - mediatek,scp
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mt8173-vcodec-enc-vp8
+              - mediatek,mt8173-vcodec-enc
+
+    then:
+      required:
+        - mediatek,vpu
+
+  - if:
+      properties:
+        compatible:
+          enum:
+            - mediatek,mt8173-vcodec-enc
+            - mediatek,mt8192-vcodec-enc
+            - mediatek,mt8173-vcodec-enc
+
+    then:
+      properties:
+        clock:
+          items:
+            minItems: 1
+            maxItems: 1
+        clock-names:
+          items:
+            - const: venc_sel
+    else:  # for vp8 hw decoder
+      properties:
+        clock:
+          items:
+            minItems: 1
+            maxItems: 1
+        clock-names:
+          items:
+            - const: venc_lt_sel
+ 
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/mt8173-clk.h>
+    #include <dt-bindings/memory/mt8173-larb-port.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    vcodec_enc_avc: vcodec@18002000 {
+      compatible = "mediatek,mt8173-vcodec-enc";
+      reg = <0 0x18002000 0 0x1000>;
+      interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_LOW>;
+      iommus = <&iommu M4U_PORT_VENC_RCPU>,
+             <&iommu M4U_PORT_VENC_REC>,
+             <&iommu M4U_PORT_VENC_BSDMA>,
+             <&iommu M4U_PORT_VENC_SV_COMV>,
+             <&iommu M4U_PORT_VENC_RD_COMV>,
+             <&iommu M4U_PORT_VENC_CUR_LUMA>,
+             <&iommu M4U_PORT_VENC_CUR_CHROMA>,
+             <&iommu M4U_PORT_VENC_REF_LUMA>,
+             <&iommu M4U_PORT_VENC_REF_CHROMA>,
+             <&iommu M4U_PORT_VENC_NBM_RDMA>,
+             <&iommu M4U_PORT_VENC_NBM_WDMA>;
+      mediatek,larb = <&larb3>;
+      mediatek,vpu = <&vpu>;
+      clocks = <&topckgen CLK_TOP_VENC_SEL>;
+      clock-names = "venc_sel";
+      assigned-clocks = <&topckgen CLK_TOP_VENC_SEL>;
+      assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL>;
+    };
+
+    vcodec_enc_vp8: vcodec@19002000 {
+      compatible = "mediatek,mt8173-vcodec-enc-vp8";
+      reg =  <0 0x19002000 0 0x1000>;	/* VENC_LT_SYS */
+      interrupts = <GIC_SPI 202 IRQ_TYPE_LEVEL_LOW>;
+      iommus = <&iommu M4U_PORT_VENC_RCPU_SET2>,
+             <&iommu M4U_PORT_VENC_REC_FRM_SET2>,
+             <&iommu M4U_PORT_VENC_BSDMA_SET2>,
+             <&iommu M4U_PORT_VENC_SV_COMA_SET2>,
+             <&iommu M4U_PORT_VENC_RD_COMA_SET2>,
+             <&iommu M4U_PORT_VENC_CUR_LUMA_SET2>,
+             <&iommu M4U_PORT_VENC_CUR_CHROMA_SET2>,
+             <&iommu M4U_PORT_VENC_REF_LUMA_SET2>,
+             <&iommu M4U_PORT_VENC_REC_CHROMA_SET2>;
+      mediatek,larb = <&larb5>;
+      mediatek,vpu = <&vpu>;
+      clocks = <&topckgen CLK_TOP_VENC_LT_SEL>;
+      clock-names = "venc_lt_sel";
+      assigned-clocks = <&topckgen CLK_TOP_VENC_LT_SEL>;
+      assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL_370P5>;
+    };
diff --git a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt b/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
deleted file mode 100644
index c44a6e6943af..000000000000
--- a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
+++ /dev/null
@@ -1,130 +0,0 @@
-Mediatek Video Codec
-
-Mediatek Video Codec is the video codec hw present in Mediatek SoCs which
-supports high resolution encoding and decoding functionalities.
-
-Required properties:
-- compatible : must be one of the following string:
-  "mediatek,mt8173-vcodec-enc-vp8" for mt8173 vp8 encoder.
-  "mediatek,mt8173-vcodec-enc" for mt8173 avc encoder.
-  "mediatek,mt8183-vcodec-enc" for MT8183 encoder.
-  "mediatek,mt8173-vcodec-dec" for MT8173 decoder.
-  "mediatek,mt8192-vcodec-enc" for MT8192 encoder.
-  "mediatek,mt8183-vcodec-dec" for MT8183 decoder.
-- reg : Physical base address of the video codec registers and length of
-  memory mapped region.
-- interrupts : interrupt number to the cpu.
-- mediatek,larb : must contain the local arbiters in the current Socs.
-- clocks : list of clock specifiers, corresponding to entries in
-  the clock-names property.
-- clock-names: avc encoder must contain "venc_sel", vp8 encoder must
-  contain "venc_lt_sel", decoder must contain "vcodecpll", "univpll_d2",
-  "clk_cci400_sel", "vdec_sel", "vdecpll", "vencpll", "venc_lt_sel",
-  "vdec_bus_clk_src".
-- iommus : should point to the respective IOMMU block with master port as
-  argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
-  for details.
-- dma-ranges : describes the dma address range space that the codec hw access.
-One of the two following nodes:
-- mediatek,vpu : the node of the video processor unit, if using VPU.
-- mediatek,scp : the node of the SCP unit, if using SCP.
-
-
-Example:
-
-vcodec_dec: vcodec@16000000 {
-    compatible = "mediatek,mt8173-vcodec-dec";
-    reg = <0 0x16000000 0 0x100>,   /*VDEC_SYS*/
-          <0 0x16020000 0 0x1000>,  /*VDEC_MISC*/
-          <0 0x16021000 0 0x800>,   /*VDEC_LD*/
-          <0 0x16021800 0 0x800>,   /*VDEC_TOP*/
-          <0 0x16022000 0 0x1000>,  /*VDEC_CM*/
-          <0 0x16023000 0 0x1000>,  /*VDEC_AD*/
-          <0 0x16024000 0 0x1000>,  /*VDEC_AV*/
-          <0 0x16025000 0 0x1000>,  /*VDEC_PP*/
-          <0 0x16026800 0 0x800>,   /*VP8_VD*/
-          <0 0x16027000 0 0x800>,   /*VP6_VD*/
-          <0 0x16027800 0 0x800>,   /*VP8_VL*/
-          <0 0x16028400 0 0x400>;   /*VP9_VD*/
-    interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_LOW>;
-    mediatek,larb = <&larb1>;
-    iommus = <&iommu M4U_PORT_HW_VDEC_MC_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_PP_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_AVC_MV_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_PRED_RD_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_PRED_WR_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_UFO_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_VLD_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_VLD2_EXT>;
-    mediatek,vpu = <&vpu>;
-    power-domains = <&scpsys MT8173_POWER_DOMAIN_VDEC>;
-    clocks = <&apmixedsys CLK_APMIXED_VCODECPLL>,
-             <&topckgen CLK_TOP_UNIVPLL_D2>,
-             <&topckgen CLK_TOP_CCI400_SEL>,
-             <&topckgen CLK_TOP_VDEC_SEL>,
-             <&topckgen CLK_TOP_VCODECPLL>,
-             <&apmixedsys CLK_APMIXED_VENCPLL>,
-             <&topckgen CLK_TOP_VENC_LT_SEL>,
-             <&topckgen CLK_TOP_VCODECPLL_370P5>;
-    clock-names = "vcodecpll",
-                  "univpll_d2",
-                  "clk_cci400_sel",
-                  "vdec_sel",
-                  "vdecpll",
-                  "vencpll",
-                  "venc_lt_sel",
-                  "vdec_bus_clk_src";
-    assigned-clocks = <&topckgen CLK_TOP_VENC_LT_SEL>,
-                      <&topckgen CLK_TOP_CCI400_SEL>,
-                      <&topckgen CLK_TOP_VDEC_SEL>,
-                      <&apmixedsys CLK_APMIXED_VCODECPLL>,
-                      <&apmixedsys CLK_APMIXED_VENCPLL>;
-    assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL_370P5>,
-                             <&topckgen CLK_TOP_UNIVPLL_D2>,
-                             <&topckgen CLK_TOP_VCODECPLL>;
-    assigned-clock-rates = <0>, <0>, <0>, <1482000000>, <800000000>;
-  };
-
-vcodec_enc_avc: vcodec@18002000 {
-    compatible = "mediatek,mt8173-vcodec-enc";
-    reg = <0 0x18002000 0 0x1000>;
-    interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_LOW>;
-    iommus = <&iommu M4U_PORT_VENC_RCPU>,
-             <&iommu M4U_PORT_VENC_REC>,
-             <&iommu M4U_PORT_VENC_BSDMA>,
-             <&iommu M4U_PORT_VENC_SV_COMV>,
-             <&iommu M4U_PORT_VENC_RD_COMV>,
-             <&iommu M4U_PORT_VENC_CUR_LUMA>,
-             <&iommu M4U_PORT_VENC_CUR_CHROMA>,
-             <&iommu M4U_PORT_VENC_REF_LUMA>,
-             <&iommu M4U_PORT_VENC_REF_CHROMA>,
-             <&iommu M4U_PORT_VENC_NBM_RDMA>,
-             <&iommu M4U_PORT_VENC_NBM_WDMA>;
-    mediatek,larb = <&larb3>;
-    mediatek,vpu = <&vpu>;
-    clocks = <&topckgen CLK_TOP_VENC_SEL>;
-    clock-names = "venc_sel";
-    assigned-clocks = <&topckgen CLK_TOP_VENC_SEL>;
-    assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL>;
-  };
-
-vcodec_enc_vp8: vcodec@19002000 {
-    compatible = "mediatek,mt8173-vcodec-enc-vp8";
-    reg =  <0 0x19002000 0 0x1000>;	/* VENC_LT_SYS */
-    interrupts = <GIC_SPI 202 IRQ_TYPE_LEVEL_LOW>;
-    iommus = <&iommu M4U_PORT_VENC_RCPU_SET2>,
-             <&iommu M4U_PORT_VENC_REC_FRM_SET2>,
-             <&iommu M4U_PORT_VENC_BSDMA_SET2>,
-             <&iommu M4U_PORT_VENC_SV_COMA_SET2>,
-             <&iommu M4U_PORT_VENC_RD_COMA_SET2>,
-             <&iommu M4U_PORT_VENC_CUR_LUMA_SET2>,
-             <&iommu M4U_PORT_VENC_CUR_CHROMA_SET2>,
-             <&iommu M4U_PORT_VENC_REF_LUMA_SET2>,
-             <&iommu M4U_PORT_VENC_REC_CHROMA_SET2>;
-    mediatek,larb = <&larb5>;
-    mediatek,vpu = <&vpu>;
-    clocks = <&topckgen CLK_TOP_VENC_LT_SEL>;
-    clock-names = "venc_lt_sel";
-    assigned-clocks = <&topckgen CLK_TOP_VENC_LT_SEL>;
-    assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL_370P5>;
-  };
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v7, 06/15] media: mtk-vcodec: Use pure single core for MT8183
  2021-10-11  7:02 [PATCH v7, 00/15] Support multi hardware decode using of_platform_populate Yunfei Dong
                   ` (4 preceding siblings ...)
  2021-10-11  7:02 ` [PATCH v7, 05/15] dt-bindings: media: mtk-vcodec: Separate video encoder and decoder dt-bindings Yunfei Dong
@ 2021-10-11  7:02 ` Yunfei Dong
  2021-10-14 11:13   ` AngeloGioacchino Del Regno
  2021-10-11  7:02 ` [PATCH v7, 07/15] media: mtk-vcodec: Add irq interface for multi hardware Yunfei Dong
                   ` (9 subsequent siblings)
  15 siblings, 1 reply; 43+ messages in thread
From: Yunfei Dong @ 2021-10-11  7:02 UTC (permalink / raw)
  To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

Separates different architecture for hardware: pure_sin_core
and lat_sin_core. MT8183 is pure single core. Uses .hw_arch to
distinguish.

Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_stateful.c      |  1 +
 .../platform/mtk-vcodec/mtk_vcodec_dec_stateless.c     |  1 +
 drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h     | 10 ++++++++++
 3 files changed, 12 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
index 4f9a80ce15d8..138f6fcb36bb 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
@@ -624,4 +624,5 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata = {
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
 	.is_comp_supported = false,
+	.hw_arch = MTK_VDEC_PURE_SINGLE_CORE,
 };
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 762633572b49..12c243d6dff3 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -358,4 +358,5 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
 	.is_comp_supported = false,
+	.hw_arch = MTK_VDEC_PURE_SINGLE_CORE,
 };
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index ec3850b4c638..140f1a761942 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -323,6 +323,14 @@ enum mtk_chip {
 	MTK_MT8192,
 };
 
+/**
+ * struct mtk_vdec_hw_arch - Used to separate different hardware architecture
+ */
+enum mtk_vdec_hw_arch {
+	MTK_VDEC_PURE_SINGLE_CORE,
+	MTK_VDEC_LAT_SINGLE_CORE,
+};
+
 /**
  * struct mtk_vcodec_dec_pdata - compatible data for each IC
  * @init_vdec_params: init vdec params
@@ -341,6 +349,7 @@ enum mtk_chip {
  * @num_framesizes: count of video decoder frame sizes
  *
  * @chip: chip this decoder is compatible with
+ * @hw_arch: hardware arch is used to separate pure_sin_core and lat_sin_core
  *
  * @is_comp_supported: true: using compoent framework, false: not support
  * @uses_stateless_api: whether the decoder uses the stateless API with requests
@@ -363,6 +372,7 @@ struct mtk_vcodec_dec_pdata {
 	const int num_framesizes;
 
 	enum mtk_chip chip;
+	enum mtk_vdec_hw_arch hw_arch;
 
 	bool is_comp_supported;
 	bool uses_stateless_api;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v7, 07/15] media: mtk-vcodec: Add irq interface for multi hardware
  2021-10-11  7:02 [PATCH v7, 00/15] Support multi hardware decode using of_platform_populate Yunfei Dong
                   ` (5 preceding siblings ...)
  2021-10-11  7:02 ` [PATCH v7, 06/15] media: mtk-vcodec: Use pure single core for MT8183 Yunfei Dong
@ 2021-10-11  7:02 ` Yunfei Dong
  2021-10-14 10:04   ` AngeloGioacchino Del Regno
  2021-10-11  7:02 ` [PATCH v7, 08/15] media: mtk-vcodec: Add msg queue feature for lat and core architecture Yunfei Dong
                   ` (8 subsequent siblings)
  15 siblings, 1 reply; 43+ messages in thread
From: Yunfei Dong @ 2021-10-11  7:02 UTC (permalink / raw)
  To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

Adds irq interface for multi hardware.

Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 33 +++++++++++++++++--
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   |  2 +-
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      | 25 ++++++++++----
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |  4 +--
 .../platform/mtk-vcodec/mtk_vcodec_intr.c     | 27 +++++++--------
 .../platform/mtk-vcodec/mtk_vcodec_intr.h     |  4 +--
 .../platform/mtk-vcodec/vdec/vdec_h264_if.c   |  2 +-
 .../mtk-vcodec/vdec/vdec_h264_req_if.c        |  2 +-
 .../platform/mtk-vcodec/vdec/vdec_vp8_if.c    |  2 +-
 .../platform/mtk-vcodec/vdec/vdec_vp9_if.c    |  2 +-
 .../platform/mtk-vcodec/venc/venc_h264_if.c   |  2 +-
 .../platform/mtk-vcodec/venc/venc_vp8_if.c    |  2 +-
 12 files changed, 71 insertions(+), 36 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 17cb3e3519eb..ff70fa5b34e3 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -73,6 +73,20 @@ static int mtk_vcodec_comp_device_check(struct mtk_vcodec_ctx *ctx)
 	return 0;
 }
 
+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("not support hw arch:%d",
+			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;
@@ -104,7 +118,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",
@@ -176,7 +190,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);
@@ -190,7 +204,19 @@ 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);
+
+	if (ctx->dev->vdec_pdata->is_comp_supported) {
+		hw_count = mtk_vcodec_get_hw_count(dev);
+		if (!hw_count) {
+			ret = -EINVAL;
+			goto err_init_queue;
+		}
+		for (i = 0; i < hw_count; i++)
+			init_waitqueue_head(&ctx->queue[i]);
+	} else {
+			init_waitqueue_head(&ctx->queue[0]);
+	}
+
 	mutex_init(&ctx->lock);
 
 	ret = mtk_vcodec_comp_device_check(ctx);
@@ -253,6 +279,7 @@ static int fops_vcodec_open(struct file *file)
 err_m2m_ctx_init:
 	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
 err_ctrls_setup:
+err_init_queue:
 	v4l2_fh_del(&ctx->fh);
 	v4l2_fh_exit(&ctx->fh);
 	kfree(ctx);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
index 3752ccaea284..0997a5a08156 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
@@ -56,7 +56,7 @@ static irqreturn_t mtk_vdec_comp_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->comp_idx);
 
 	mtk_v4l2_debug(3, "wake up ctx %d, dec_done_status=%x",
 		ctx->id, dec_done_status);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 140f1a761942..f8e8b5ba408b 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -104,6 +104,16 @@ enum mtk_vdec_hw_id {
 	MTK_VDEC_HW_MAX,
 };
 
+/**
+ * struct 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;
@@ -505,11 +515,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_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index 2828df77020c..c7540c0cdcea 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -114,7 +114,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;
 }
 
@@ -140,7 +140,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);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c
index 70580c2525ba..8147533da98b 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c
@@ -11,34 +11,31 @@
 #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 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,
+	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;
 }
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h
index 638cd1f3526a..2bf4cabfaa43 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h
@@ -12,7 +12,7 @@
 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_ */
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c
index 40d6e6c5ac7a..481655bb6016 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c
@@ -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;
 
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
index 4dde9ee786b4..d23baa364246 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
@@ -724,7 +724,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);
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c
index e5393f841080..88c046731754 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c
@@ -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);
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c
index 71cdc3ddafcb..70b8383f7c8e 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c
@@ -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;
diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
index b6a4f2074fa5..9ae1bd8dbc32 100644
--- a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
@@ -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);
 	}
diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
index 8267a9c4fd25..f96564277577 100644
--- a/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
@@ -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);
 	}
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v7, 08/15] media: mtk-vcodec: Add msg queue feature for lat and core architecture
  2021-10-11  7:02 [PATCH v7, 00/15] Support multi hardware decode using of_platform_populate Yunfei Dong
                   ` (6 preceding siblings ...)
  2021-10-11  7:02 ` [PATCH v7, 07/15] media: mtk-vcodec: Add irq interface for multi hardware Yunfei Dong
@ 2021-10-11  7:02 ` Yunfei Dong
  2021-10-14 10:35   ` AngeloGioacchino Del Regno
  2021-10-11  7:02 ` [PATCH v7, 09/15] media: mtk-vcodec: Generalize power and clock on/off interfaces Yunfei Dong
                   ` (7 subsequent siblings)
  15 siblings, 1 reply; 43+ messages in thread
From: Yunfei Dong @ 2021-10-11  7:02 UTC (permalink / raw)
  To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

For lat and core architecture, lat thread will send message to core
thread when lat decode done. Core hardware will use the message
from lat to decode, then free message to lat thread when decode done.

Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
 drivers/media/platform/mtk-vcodec/Makefile    |   1 +
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |   5 +
 .../platform/mtk-vcodec/vdec_msg_queue.c      | 258 ++++++++++++++++++
 .../platform/mtk-vcodec/vdec_msg_queue.h      | 151 ++++++++++
 4 files changed, 415 insertions(+)
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec_msg_queue.h

diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index edeb3b66e9e9..5000e59da576 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -11,6 +11,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 		mtk_vcodec_dec_drv.o \
 		vdec_drv_if.o \
 		vdec_vpu_if.o \
+		vdec_msg_queue.o \
 		mtk_vcodec_dec.o \
 		mtk_vcodec_dec_stateful.o \
 		mtk_vcodec_dec_stateless.o \
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index f8e8b5ba408b..ab401b2db30e 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -15,7 +15,9 @@
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-mem2mem.h>
 #include <media/videobuf2-core.h>
+
 #include "mtk_vcodec_util.h"
+#include "vdec_msg_queue.h"
 
 #define MTK_VCODEC_DRV_NAME	"mtk_vcodec_drv"
 #define MTK_VCODEC_DEC_NAME	"mtk-vcodec-dec"
@@ -282,6 +284,8 @@ struct vdec_pic_info {
  * @decoded_frame_cnt: number of decoded frames
  * @lock: protect variables accessed by V4L2 threads and worker thread such as
  *	  mtk_video_dec_buf.
+ *
+ * @msg_queue: msg queue used to store lat buffer information.
  */
 struct mtk_vcodec_ctx {
 	enum mtk_instance_type type;
@@ -325,6 +329,7 @@ struct mtk_vcodec_ctx {
 	int decoded_frame_cnt;
 	struct mutex lock;
 
+	struct vdec_msg_queue msg_queue;
 };
 
 enum mtk_chip {
diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
new file mode 100644
index 000000000000..d66ed98c79a9
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
@@ -0,0 +1,258 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong@mediatek.com>
+ */
+
+#include <linux/freezer.h>
+#include <linux/interrupt.h>
+#include <linux/kthread.h>
+
+#include "mtk_vcodec_dec_pm.h"
+#include "mtk_vcodec_drv.h"
+#include "vdec_msg_queue.h"
+
+#define VDEC_LAT_SLICE_HEADER_SZ    (640 * 1024)
+#define VDEC_ERR_MAP_SZ_AVC         ((8192 / 16) * (4352 / 16) / 8)
+
+/* lat write decoded hardware information to trans buffer,
+ * and core will read the trans buffer to decode again. The
+ * trans buffer size of FHD and 4K bitstreams are different.
+ */
+static int vde_msg_queue_get_trans_size(int width, int height)
+{
+	if (width > 1920 || height > 1088)
+		return (30 * 1024 * 1024);
+	else
+		return 6 * 1024 * 1024;
+}
+
+void vdec_msg_queue_init_ctx(struct vdec_msg_queue_ctx *ctx,
+	int hardware_index)
+{
+	init_waitqueue_head(&ctx->ready_to_use);
+	INIT_LIST_HEAD(&ctx->ready_queue);
+	spin_lock_init(&ctx->ready_lock);
+	ctx->ready_num = 0;
+	ctx->hardware_index = hardware_index;
+}
+
+int vdec_msg_queue_init(
+	struct vdec_msg_queue *msg_queue,
+	struct mtk_vcodec_ctx *ctx,
+	core_decode_cb_t core_decode,
+	int private_size)
+{
+	struct vdec_lat_buf *lat_buf;
+	int i, err;
+
+	/* already init msg queue */
+	if (msg_queue->wdma_addr.size)
+		return 0;
+
+	vdec_msg_queue_init_ctx(&msg_queue->lat_ctx, MTK_VDEC_LAT0);
+	msg_queue->wdma_addr.size = vde_msg_queue_get_trans_size(
+		ctx->picinfo.buf_w, ctx->picinfo.buf_h);
+
+	err = mtk_vcodec_mem_alloc(ctx, &msg_queue->wdma_addr);
+	if (err) {
+		mtk_v4l2_err("failed to allocate wdma_addr buf");
+		return -ENOMEM;
+	}
+	msg_queue->wdma_rptr_addr = msg_queue->wdma_addr.dma_addr;
+	msg_queue->wdma_wptr_addr = msg_queue->wdma_addr.dma_addr;
+
+	for (i = 0; i < NUM_BUFFER_COUNT; i++) {
+		lat_buf = &msg_queue->lat_buf[i];
+
+		lat_buf->wdma_err_addr.size = VDEC_ERR_MAP_SZ_AVC;
+		err = mtk_vcodec_mem_alloc(ctx, &lat_buf->wdma_err_addr);
+		if (err) {
+			mtk_v4l2_err("failed to allocate wdma_err_addr buf[%d]", i);
+			goto mem_alloc_err;
+		}
+
+		lat_buf->slice_bc_addr.size = VDEC_LAT_SLICE_HEADER_SZ;
+		err = mtk_vcodec_mem_alloc(ctx, &lat_buf->slice_bc_addr);
+		if (err) {
+			mtk_v4l2_err("failed to allocate wdma_addr buf[%d]", i);
+			goto mem_alloc_err;
+		}
+
+		lat_buf->private_data = kzalloc(private_size, GFP_KERNEL);
+		if (!lat_buf->private_data) {
+			mtk_v4l2_err("failed to allocate private_data[%d]", i);
+			goto mem_alloc_err;
+		}
+
+		lat_buf->ctx = ctx;
+		lat_buf->core_decode = core_decode;
+		vdec_msg_queue_qbuf(&msg_queue->lat_ctx, lat_buf);
+	}
+	return 0;
+
+mem_alloc_err:
+	vdec_msg_queue_deinit(msg_queue, ctx);
+	return -ENOMEM;
+}
+
+static struct list_head *vdec_get_buf_list(int hardware_index,
+	struct vdec_lat_buf *buf)
+{
+	switch (hardware_index) {
+	case MTK_VDEC_CORE:
+		return &buf->core_list;
+	case MTK_VDEC_LAT0:
+		return &buf->lat_list;
+	default:
+		return NULL;
+	}
+}
+
+void vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *ctx,
+	struct vdec_lat_buf *buf)
+{
+	struct list_head *head;
+
+	head = vdec_get_buf_list(ctx->hardware_index, buf);
+	if (!head) {
+		mtk_v4l2_err("fail to qbuf: %d",ctx->hardware_index);
+		return;
+	}
+
+	spin_lock(&ctx->ready_lock);
+	list_add_tail(head, &ctx->ready_queue);
+	ctx->ready_num++;
+
+	wake_up_all(&ctx->ready_to_use);
+
+	mtk_v4l2_debug(3, "enqueue buf type: %d addr: 0x%p num: %d",
+		ctx->hardware_index, buf, ctx->ready_num);
+	spin_unlock(&ctx->ready_lock);
+}
+
+static bool vdec_msg_queue_wait_event(struct vdec_msg_queue_ctx *ctx)
+{
+	long timeout_jiff;
+	int ret;
+
+	if (ctx->hardware_index == MTK_VDEC_CORE) {
+		ret = wait_event_freezable(ctx->ready_to_use,
+			!list_empty(&ctx->ready_queue));
+		if (ret)
+			return false;
+	} else {
+		timeout_jiff = msecs_to_jiffies(1500);
+		ret = wait_event_timeout(ctx->ready_to_use,
+			!list_empty(&ctx->ready_queue), timeout_jiff);
+		if (!ret)
+			return false;
+	}
+
+	return true;
+}
+
+struct vdec_lat_buf *vdec_msg_queue_dqbuf(struct vdec_msg_queue_ctx *ctx)
+{
+	struct vdec_lat_buf *buf;
+	struct list_head *head;
+	int ret;
+
+	spin_lock(&ctx->ready_lock);
+	if (list_empty(&ctx->ready_queue)) {
+		mtk_v4l2_debug(3, "queue is NULL, type:%d num: %d",
+			ctx->hardware_index, ctx->ready_num);
+		spin_unlock(&ctx->ready_lock);
+		ret = vdec_msg_queue_wait_event(ctx);
+		if (!ret)
+			return NULL;
+		spin_lock(&ctx->ready_lock);
+	}
+
+	if (ctx->hardware_index == MTK_VDEC_CORE)
+		buf = list_first_entry(&ctx->ready_queue,
+			struct vdec_lat_buf, core_list);
+	else
+		buf = list_first_entry(&ctx->ready_queue,
+			struct vdec_lat_buf, lat_list);
+
+	head = vdec_get_buf_list(ctx->hardware_index, buf);
+	if (!head) {
+		mtk_v4l2_err("fail to dqbuf: %d",ctx->hardware_index);
+		return NULL;
+	}
+	list_del(head);
+
+	ctx->ready_num--;
+	mtk_v4l2_debug(3, "dqueue buf type:%d addr: 0x%p num: %d",
+		ctx->hardware_index, buf, ctx->ready_num);
+	spin_unlock(&ctx->ready_lock);
+
+	return buf;
+}
+
+void vdec_msg_queue_update_ube_rptr(struct vdec_msg_queue *msg_queue,
+	uint64_t ube_rptr)
+{
+	spin_lock(&msg_queue->lat_ctx.ready_lock);
+	msg_queue->wdma_rptr_addr = ube_rptr;
+	mtk_v4l2_debug(3, "update ube rprt (0x%llx)", ube_rptr);
+	spin_unlock(&msg_queue->lat_ctx.ready_lock);
+}
+
+void vdec_msg_queue_update_ube_wptr(struct vdec_msg_queue *msg_queue,
+	uint64_t ube_wptr)
+{
+	spin_lock(&msg_queue->lat_ctx.ready_lock);
+	msg_queue->wdma_wptr_addr = ube_wptr;
+	mtk_v4l2_debug(3, "update ube wprt: (0x%llx 0x%llx) offset: 0x%llx",
+		msg_queue->wdma_rptr_addr, msg_queue->wdma_wptr_addr, ube_wptr);
+	spin_unlock(&msg_queue->lat_ctx.ready_lock);
+}
+
+bool vdec_msg_queue_wait_lat_buf_full(struct vdec_msg_queue *msg_queue)
+{
+	long timeout_jiff;
+	int ret;
+
+	timeout_jiff = msecs_to_jiffies(1000 * (NUM_BUFFER_COUNT + 2));
+
+	ret = wait_event_timeout(msg_queue->lat_ctx.ready_to_use,
+		msg_queue->lat_ctx.ready_num == NUM_BUFFER_COUNT,
+		timeout_jiff);
+	if (ret) {
+		mtk_v4l2_debug(3, "success to get lat buf: %d",
+			msg_queue->lat_ctx.ready_num);
+		return true;
+	}
+	mtk_v4l2_err("failed with lat buf isn't full: %d",
+		msg_queue->lat_ctx.ready_num);
+	return false;
+}
+
+void vdec_msg_queue_deinit(
+	struct vdec_msg_queue *msg_queue,
+	struct mtk_vcodec_ctx *ctx)
+{
+	struct vdec_lat_buf *lat_buf;
+	struct mtk_vcodec_mem *mem;
+	int i;
+
+	mem = &msg_queue->wdma_addr;
+	if (mem->va)
+		mtk_vcodec_mem_free(ctx, mem);
+	for (i = 0; i < NUM_BUFFER_COUNT; i++) {
+		lat_buf = &msg_queue->lat_buf[i];
+
+		mem = &lat_buf->wdma_err_addr;
+		if (mem->va)
+			mtk_vcodec_mem_free(ctx, mem);
+
+		mem = &lat_buf->slice_bc_addr;
+		if (mem->va)
+			mtk_vcodec_mem_free(ctx, mem);
+
+		if (lat_buf->private_data)
+			kfree(lat_buf->private_data);
+	}
+}
diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
new file mode 100644
index 000000000000..1905ce713592
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong@mediatek.com>
+ */
+
+#ifndef _VDEC_MSG_QUEUE_H_
+#define _VDEC_MSG_QUEUE_H_
+
+#include <linux/sched.h>
+#include <linux/semaphore.h>
+#include <linux/slab.h>
+#include <media/videobuf2-v4l2.h>
+
+#include "mtk_vcodec_util.h"
+
+#define NUM_BUFFER_COUNT 3
+
+struct vdec_lat_buf;
+struct mtk_vcodec_ctx;
+struct mtk_vcodec_dev;
+typedef int (*core_decode_cb_t)(struct vdec_lat_buf *lat_buf);
+
+/**
+ * struct vdec_msg_queue_ctx - represents a queue for buffers ready to be
+ *	                           processed
+ * @ready_used: ready used queue used to signalize when get a job queue
+ * @ready_queue: list of ready lat buffer queues
+ * @ready_lock: spin lock to protect the lat buffer usage
+ * @ready_num: number of buffers ready to be processed
+ * @hardware_index: hardware id that this queue is used for
+ */
+struct vdec_msg_queue_ctx {
+	wait_queue_head_t ready_to_use;
+	struct list_head ready_queue;
+	spinlock_t ready_lock;
+	int ready_num;
+	int hardware_index;
+};
+
+/**
+ * struct vdec_lat_buf - lat buffer message used to store lat
+ *                       info for core decode
+ * @wdma_err_addr: wdma error address used for lat hardware
+ * @slice_bc_addr: slice bc address used for lat hardware
+ * @ts_info: need to set timestamp from output to capture
+ *
+ * @private_data: shared information used to lat and core hardware
+ * @ctx: mtk vcodec context information
+ * @core_decode: different codec use different decode callback function
+ * @lat_list: add lat buffer to lat head list
+ * @core_list: add lat buffer to core head list
+ */
+struct vdec_lat_buf {
+	struct mtk_vcodec_mem wdma_err_addr;
+	struct mtk_vcodec_mem slice_bc_addr;
+	struct vb2_v4l2_buffer ts_info;
+
+	void *private_data;
+	struct mtk_vcodec_ctx *ctx;
+	core_decode_cb_t core_decode;
+	struct list_head lat_list;
+	struct list_head core_list;
+};
+
+/**
+ * struct vdec_msg_queue - used to store lat buffer message
+ * @lat_buf: lat buffer used to store lat buffer information
+ * @wdma_addr: wdma address used for ube
+ * @wdma_rptr_addr: ube read point
+ * @wdma_wptr_addr: ube write point
+ * @lat_ctx: used to store lat buffer list
+ */
+struct vdec_msg_queue {
+	struct vdec_lat_buf lat_buf[NUM_BUFFER_COUNT];
+
+	struct mtk_vcodec_mem wdma_addr;
+	uint64_t wdma_rptr_addr;
+	uint64_t wdma_wptr_addr;
+
+	struct vdec_msg_queue_ctx lat_ctx;
+};
+
+/**
+ * vdec_msg_queue_init - init lat buffer information.
+ * @msg_queue: used to store the lat buffer information
+ * @ctx: v4l2 ctx
+ * @core_decode: core decode callback for each codec
+ * @private_size: the private data size used to share with core
+ */
+int vdec_msg_queue_init(
+	struct vdec_msg_queue *msg_queue,
+	struct mtk_vcodec_ctx *ctx,
+	core_decode_cb_t core_decode,
+	int private_size);
+
+/**
+ * vdec_msg_queue_init_ctx - used to init msg queue context information.
+ * @ctx: message queue context
+ * @hardware_index: hardware index
+ */
+void vdec_msg_queue_init_ctx(struct vdec_msg_queue_ctx *ctx,
+	int hardware_index);
+
+/**
+ * vdec_msg_queue_qbuf - enqueue lat buffer to queue list.
+ * @ctx: message queue context
+ * @buf: current lat buffer
+ */
+void vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *ctx,
+	struct vdec_lat_buf *buf);
+
+/**
+ * vdec_msg_queue_dqbuf - dequeue lat buffer from queue list.
+ * @ctx: message queue context
+ */
+struct vdec_lat_buf *vdec_msg_queue_dqbuf(struct vdec_msg_queue_ctx *ctx);
+
+/**
+ * vdec_msg_queue_update_ube_rptr - used to updata the ube read point.
+ * @msg_queue: used to store the lat buffer information
+ * @ube_rptr: current ube read point
+ */
+void vdec_msg_queue_update_ube_rptr(struct vdec_msg_queue *msg_queue,
+	uint64_t ube_rptr);
+
+/**
+ * vdec_msg_queue_update_ube_wptr - used to updata the ube write point.
+ * @msg_queue: used to store the lat buffer information
+ * @ube_wptr: current ube write point
+ */
+void vdec_msg_queue_update_ube_wptr(struct vdec_msg_queue *msg_queue,
+	uint64_t ube_wptr);
+
+/**
+ * vdec_msg_queue_wait_lat_buf_full - used to check whether all lat buffer
+ *                                    in lat list.
+ * @msg_queue: used to store the lat buffer information
+ */
+bool vdec_msg_queue_wait_lat_buf_full(struct vdec_msg_queue *msg_queue);
+
+/**
+ * vdec_msg_queue_deinit - deinit lat buffer information.
+ * @msg_queue: used to store the lat buffer information
+ * @ctx: v4l2 ctx
+ */
+void vdec_msg_queue_deinit(
+	struct vdec_msg_queue *msg_queue,
+	struct mtk_vcodec_ctx *ctx);
+
+#endif
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v7, 09/15] media: mtk-vcodec: Generalize power and clock on/off interfaces
  2021-10-11  7:02 [PATCH v7, 00/15] Support multi hardware decode using of_platform_populate Yunfei Dong
                   ` (7 preceding siblings ...)
  2021-10-11  7:02 ` [PATCH v7, 08/15] media: mtk-vcodec: Add msg queue feature for lat and core architecture Yunfei Dong
@ 2021-10-11  7:02 ` Yunfei Dong
  2021-10-14 10:44   ` AngeloGioacchino Del Regno
  2021-10-11  7:02 ` [PATCH v7, 10/15] media: mtk-vcodec: Add new interface to lock different hardware Yunfei Dong
                   ` (6 subsequent siblings)
  15 siblings, 1 reply; 43+ messages in thread
From: Yunfei Dong @ 2021-10-11  7:02 UTC (permalink / raw)
  To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

Generalizes power and clock on/off interfaces to support different hardware.

Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |  6 +-
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   |  2 +-
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.h   |  4 +
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 76 ++++++++++++++--
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h   |  8 +-
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  2 +
 .../platform/mtk-vcodec/mtk_vcodec_util.c     | 87 ++++++++++++++++---
 .../platform/mtk-vcodec/mtk_vcodec_util.h     |  8 +-
 .../media/platform/mtk-vcodec/vdec_drv_if.c   | 21 ++---
 9 files changed, 174 insertions(+), 40 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 ff70fa5b34e3..3ea1e96e0ec0 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -96,7 +96,7 @@ static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
 	void __iomem *vdec_misc_addr = dev->reg_base[VDEC_MISC] +
 					VDEC_IRQ_CFG_REG;
 
-	ctx = mtk_vcodec_get_curr_ctx(dev);
+	ctx = mtk_vcodec_get_curr_ctx(dev, MTK_VDEC_CORE);
 
 	/* check if HW active or not */
 	cg_status = readl(dev->reg_base[0]);
@@ -245,7 +245,7 @@ static int fops_vcodec_open(struct file *file)
 	mtk_vcodec_dec_set_default_params(ctx);
 
 	if (v4l2_fh_is_singular(&ctx->fh)) {
-		ret = mtk_vcodec_dec_pw_on(&dev->pm);
+		ret = mtk_vcodec_dec_pw_on(dev, MTK_VDEC_LAT0);
 		if (ret < 0)
 			goto err_load_fw;
 		/*
@@ -306,7 +306,7 @@ static int fops_vcodec_release(struct file *file)
 	mtk_vcodec_dec_release(ctx);
 
 	if (v4l2_fh_is_singular(&ctx->fh))
-		mtk_vcodec_dec_pw_off(&dev->pm);
+		mtk_vcodec_dec_pw_off(dev, MTK_VDEC_LAT0);
 	v4l2_fh_del(&ctx->fh);
 	v4l2_fh_exit(&ctx->fh);
 	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
index 0997a5a08156..78d25916395d 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
@@ -37,7 +37,7 @@ static irqreturn_t mtk_vdec_comp_irq_handler(int irq, void *priv)
 	void __iomem *vdec_misc_addr = dev->reg_base[VDEC_COMP_MISC] +
 					VDEC_IRQ_CFG_REG;
 
-	ctx = mtk_vcodec_get_curr_ctx(dev->master_dev);
+	ctx = mtk_vcodec_get_curr_ctx(dev->master_dev, dev->comp_idx);
 
 	/* check if HW active or not */
 	cg_status = readl(dev->reg_base[VDEC_COMP_SYS]);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
index 8d6e818a3474..0a4c2e6f5df2 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
@@ -32,6 +32,8 @@ enum mtk_comp_hw_reg_idx {
  * @master_dev: master device
  * @reg_base: Mapped address of MTK Vcodec registers.
  *
+ * @curr_ctx: The context that is waiting for codec hardware
+ *
  * @dec_irq: decoder irq resource
  * @pm: power management control
  * @comp_idx: component index
@@ -41,6 +43,8 @@ struct mtk_vdec_comp_dev {
 	struct mtk_vcodec_dev *master_dev;
 	void __iomem *reg_base[VDEC_COMP_MAX];
 
+	struct mtk_vcodec_ctx *curr_ctx;
+
 	int dec_irq;
 	struct mtk_vcodec_pm pm;
 	int comp_idx;
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
index 20bd157a855c..183d4c4e36f0 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
@@ -5,11 +5,13 @@
  */
 
 #include <linux/clk.h>
+#include <linux/interrupt.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/pm_runtime.h>
 #include <soc/mediatek/smi.h>
 
+#include "mtk_vcodec_dec_hw.h"
 #include "mtk_vcodec_dec_pm.h"
 #include "mtk_vcodec_util.h"
 
@@ -84,10 +86,23 @@ void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm)
 	put_device(pm->larbvdec);
 }
 
-int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
+int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int comp_idx)
 {
+	struct mtk_vdec_comp_dev *comp_dev;
+	struct mtk_vcodec_pm *pm;
 	int ret;
 
+	if (vdec_dev->vdec_pdata->is_comp_supported) {
+		comp_dev = mtk_vcodec_get_hw_dev(vdec_dev, comp_idx);
+		if (!comp_dev) {
+			mtk_v4l2_err("Failed to get hw dev\n");
+			return -EINVAL;
+		}
+		pm = &comp_dev->pm;
+	} else {
+		pm = &vdec_dev->pm;
+	}
+
 	ret = pm_runtime_resume_and_get(pm->dev);
 	if (ret)
 		mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret);
@@ -95,20 +110,49 @@ int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
 	return ret;
 }
 
-void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm)
+void mtk_vcodec_dec_pw_off(struct mtk_vcodec_dev *vdec_dev, int comp_idx)
 {
+	struct mtk_vdec_comp_dev *comp_dev;
+	struct mtk_vcodec_pm *pm;
 	int ret;
 
+	if (vdec_dev->vdec_pdata->is_comp_supported) {
+		comp_dev = mtk_vcodec_get_hw_dev(vdec_dev, comp_idx);
+		if (!comp_dev) {
+			mtk_v4l2_err("Failed to get hw dev\n");
+			return;
+		}
+		pm = &comp_dev->pm;
+	} else {
+		pm = &vdec_dev->pm;
+	}
+
 	ret = pm_runtime_put_sync(pm->dev);
 	if (ret)
 		mtk_v4l2_err("pm_runtime_put_sync fail %d", ret);
 }
 
-void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm)
+void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int comp_idx)
 {
-	struct mtk_vcodec_clk *dec_clk = &pm->vdec_clk;
-	int ret, i = 0;
+	struct mtk_vdec_comp_dev *comp_dev;
+	struct mtk_vcodec_pm *pm;
+	struct mtk_vcodec_clk *dec_clk;
+	int ret, i;
+
+	if (vdec_dev->vdec_pdata->is_comp_supported) {
+		comp_dev = mtk_vcodec_get_hw_dev(vdec_dev, comp_idx);
+		if (!comp_dev) {
+			mtk_v4l2_err("Failed to get hw dev\n");
+			return;
+		}
+		pm = &comp_dev->pm;
+		enable_irq(comp_dev->dec_irq);
+	} else {
+		pm = &vdec_dev->pm;
+		enable_irq(vdec_dev->dec_irq);
+	}
 
+	dec_clk = &pm->vdec_clk;
 	for (i = 0; i < dec_clk->clk_num; i++) {
 		ret = clk_prepare_enable(dec_clk->clk_info[i].vcodec_clk);
 		if (ret) {
@@ -130,11 +174,27 @@ void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm)
 		clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
 }
 
-void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm)
+void mtk_vcodec_dec_clock_off(struct mtk_vcodec_dev *vdec_dev, int comp_idx)
 {
-	struct mtk_vcodec_clk *dec_clk = &pm->vdec_clk;
-	int i = 0;
+	struct mtk_vdec_comp_dev *comp_dev;
+	struct mtk_vcodec_pm *pm;
+	struct mtk_vcodec_clk *dec_clk;
+	int i;
 
+	if (vdec_dev->vdec_pdata->is_comp_supported) {
+		comp_dev = mtk_vcodec_get_hw_dev(vdec_dev, comp_idx);
+		if (!comp_dev) {
+			mtk_v4l2_err("Failed to get hw dev\n");
+			return;
+		}
+		pm = &comp_dev->pm;
+		disable_irq(comp_dev->dec_irq);
+	} else {
+		pm = &vdec_dev->pm;
+		disable_irq(vdec_dev->dec_irq);
+	}
+
+	dec_clk = &pm->vdec_clk;
 	mtk_smi_larb_put(pm->larbvdec);
 	for (i = dec_clk->clk_num - 1; i >= 0; i--)
 		clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
index a3df6aef6cb9..698750572b57 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
@@ -13,9 +13,9 @@ int mtk_vcodec_init_dec_pm(struct platform_device *pdev,
 	struct mtk_vcodec_pm *pm);
 void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm);
 
-int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm);
-void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm);
-void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm);
-void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm);
+int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int comp_idx);
+void mtk_vcodec_dec_pw_off(struct mtk_vcodec_dev *vdec_dev, int comp_idx);
+void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int comp_idx);
+void mtk_vcodec_dec_clock_off(struct mtk_vcodec_dev *vdec_dev, int comp_idx);
 
 #endif /* _MTK_VCODEC_DEC_PM_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index ab401b2db30e..95c82cb4e568 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -284,6 +284,7 @@ struct vdec_pic_info {
  * @decoded_frame_cnt: number of decoded frames
  * @lock: protect variables accessed by V4L2 threads and worker thread such as
  *	  mtk_video_dec_buf.
+ * @hw_id: hardware index used to identify different hardware.
  *
  * @msg_queue: msg queue used to store lat buffer information.
  */
@@ -328,6 +329,7 @@ struct mtk_vcodec_ctx {
 
 	int decoded_frame_cnt;
 	struct mutex lock;
+	int hw_id;
 
 	struct vdec_msg_queue msg_queue;
 };
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
index ac5973b6735f..511b75e49fe7 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
@@ -6,7 +6,10 @@
 */
 
 #include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
+#include "mtk_vcodec_dec_hw.h"
 #include "mtk_vcodec_drv.h"
 #include "mtk_vcodec_util.h"
 
@@ -81,25 +84,87 @@ void mtk_vcodec_mem_free(struct mtk_vcodec_ctx *data,
 }
 EXPORT_SYMBOL(mtk_vcodec_mem_free);
 
-void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *dev,
-	struct mtk_vcodec_ctx *ctx)
+void *mtk_vcodec_get_hw_dev(struct mtk_vcodec_dev *dev, int comp_idx)
 {
-	unsigned long flags;
+	struct platform_device *hw_pdev;
+	struct device_node *node;
+	struct mtk_vdec_comp_dev *master_dev;
+
+	if (comp_idx >= MTK_VDEC_HW_MAX || comp_idx < 0) {
+		mtk_v4l2_err("Comp idx is out of range:%d", comp_idx);
+		return NULL;
+	}
+
+	if (dev->comp_dev[comp_idx])
+		return dev->comp_dev[comp_idx];
+
+	node = dev->component_node[comp_idx];
+	if (!node) {
+		mtk_v4l2_err("Get lat node fail:%d", comp_idx);
+		return NULL;
+	}
+
+	hw_pdev = of_find_device_by_node(node);
+	of_node_put(node);
+
+	if (WARN_ON(!hw_pdev)) {
+		mtk_v4l2_err("Get hw id(%d) node fail", comp_idx);
+		return NULL;
+	}
+
+	master_dev = platform_get_drvdata(hw_pdev);
+	if (!master_dev) {
+		mtk_v4l2_err("Get hw id(%d) pdev fail", comp_idx);
+		return NULL;
+	}
 
-	spin_lock_irqsave(&dev->irqlock, flags);
-	dev->curr_ctx = ctx;
-	spin_unlock_irqrestore(&dev->irqlock, flags);
+	dev->comp_dev[master_dev->comp_idx] = master_dev;
+	return master_dev;
+}
+EXPORT_SYMBOL(mtk_vcodec_get_hw_dev);
+
+void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *vdec_dev,
+	struct mtk_vcodec_ctx *ctx, int comp_idx)
+{
+	unsigned long flags;
+	struct mtk_vdec_comp_dev *comp_dev;
+
+	spin_lock_irqsave(&vdec_dev->irqlock, flags);
+	if (vdec_dev->vdec_pdata->is_comp_supported) {
+		comp_dev = mtk_vcodec_get_hw_dev(vdec_dev, comp_idx);
+		if (!comp_dev) {
+			mtk_v4l2_err("Failed to get hw dev");
+			spin_unlock_irqrestore(&vdec_dev->irqlock, flags);
+			return;
+		}
+		comp_dev->curr_ctx = ctx;
+	} else {
+		vdec_dev->curr_ctx = ctx;
+	}
+	spin_unlock_irqrestore(&vdec_dev->irqlock, flags);
 }
 EXPORT_SYMBOL(mtk_vcodec_set_curr_ctx);
 
-struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *dev)
+struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *vdec_dev,
+	unsigned int comp_idx)
 {
 	unsigned long flags;
 	struct mtk_vcodec_ctx *ctx;
-
-	spin_lock_irqsave(&dev->irqlock, flags);
-	ctx = dev->curr_ctx;
-	spin_unlock_irqrestore(&dev->irqlock, flags);
+	struct mtk_vdec_comp_dev *comp_dev;
+
+	spin_lock_irqsave(&vdec_dev->irqlock, flags);
+	if (vdec_dev->vdec_pdata->is_comp_supported) {
+		comp_dev = mtk_vcodec_get_hw_dev(vdec_dev, comp_idx);
+		if (!comp_dev) {
+			mtk_v4l2_err("Failed to get hw dev");
+			spin_unlock_irqrestore(&vdec_dev->irqlock, flags);
+			return NULL;
+		}
+		ctx = comp_dev->curr_ctx;
+	} else {
+		ctx = vdec_dev->curr_ctx;
+	}
+	spin_unlock_irqrestore(&vdec_dev->irqlock, flags);
 	return ctx;
 }
 EXPORT_SYMBOL(mtk_vcodec_get_curr_ctx);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
index b999d7b84ed1..4cb0fc60c94f 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
@@ -79,8 +79,10 @@ int mtk_vcodec_mem_alloc(struct mtk_vcodec_ctx *data,
 				struct mtk_vcodec_mem *mem);
 void mtk_vcodec_mem_free(struct mtk_vcodec_ctx *data,
 				struct mtk_vcodec_mem *mem);
-void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *dev,
-	struct mtk_vcodec_ctx *ctx);
-struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *dev);
+void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *vdec_dev,
+				struct mtk_vcodec_ctx *ctx, int comp_idx);
+struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *vdec_dev,
+	unsigned int comp_idx);
+void *mtk_vcodec_get_hw_dev(struct mtk_vcodec_dev *dev, int comp_idx);
 
 #endif /* _MTK_VCODEC_UTIL_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
index 42008243ceac..05a5b240e906 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
@@ -24,21 +24,24 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
 		break;
 	case V4L2_PIX_FMT_H264:
 		ctx->dec_if = &vdec_h264_if;
+		ctx->hw_id = MTK_VDEC_CORE;
 		break;
 	case V4L2_PIX_FMT_VP8:
 		ctx->dec_if = &vdec_vp8_if;
+		ctx->hw_id = MTK_VDEC_CORE;
 		break;
 	case V4L2_PIX_FMT_VP9:
 		ctx->dec_if = &vdec_vp9_if;
+		ctx->hw_id = MTK_VDEC_CORE;
 		break;
 	default:
 		return -EINVAL;
 	}
 
 	mtk_vdec_lock(ctx);
-	mtk_vcodec_dec_clock_on(&ctx->dev->pm);
+	mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
 	ret = ctx->dec_if->init(ctx);
-	mtk_vcodec_dec_clock_off(&ctx->dev->pm);
+	mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
 	mtk_vdec_unlock(ctx);
 
 	return ret;
@@ -69,13 +72,11 @@ int vdec_if_decode(struct mtk_vcodec_ctx *ctx, struct mtk_vcodec_mem *bs,
 
 	mtk_vdec_lock(ctx);
 
-	mtk_vcodec_set_curr_ctx(ctx->dev, ctx);
-	mtk_vcodec_dec_clock_on(&ctx->dev->pm);
-	enable_irq(ctx->dev->dec_irq);
+	mtk_vcodec_set_curr_ctx(ctx->dev, ctx, ctx->hw_id);
+	mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
 	ret = ctx->dec_if->decode(ctx->drv_handle, bs, fb, res_chg);
-	disable_irq(ctx->dev->dec_irq);
-	mtk_vcodec_dec_clock_off(&ctx->dev->pm);
-	mtk_vcodec_set_curr_ctx(ctx->dev, NULL);
+	mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
+	mtk_vcodec_set_curr_ctx(ctx->dev, NULL, ctx->hw_id);
 
 	mtk_vdec_unlock(ctx);
 
@@ -103,9 +104,9 @@ void vdec_if_deinit(struct mtk_vcodec_ctx *ctx)
 		return;
 
 	mtk_vdec_lock(ctx);
-	mtk_vcodec_dec_clock_on(&ctx->dev->pm);
+	mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
 	ctx->dec_if->deinit(ctx->drv_handle);
-	mtk_vcodec_dec_clock_off(&ctx->dev->pm);
+	mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
 	mtk_vdec_unlock(ctx);
 
 	ctx->drv_handle = NULL;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v7, 10/15] media: mtk-vcodec: Add new interface to lock different hardware
  2021-10-11  7:02 [PATCH v7, 00/15] Support multi hardware decode using of_platform_populate Yunfei Dong
                   ` (8 preceding siblings ...)
  2021-10-11  7:02 ` [PATCH v7, 09/15] media: mtk-vcodec: Generalize power and clock on/off interfaces Yunfei Dong
@ 2021-10-11  7:02 ` Yunfei Dong
  2021-10-14 10:47   ` AngeloGioacchino Del Regno
  2021-10-11  7:02 ` [PATCH v7, 11/15] media: mtk-vcodec: Add core thread Yunfei Dong
                   ` (5 subsequent siblings)
  15 siblings, 1 reply; 43+ messages in thread
From: Yunfei Dong @ 2021-10-11  7:02 UTC (permalink / raw)
  To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

For add new hardware, not only need to lock lat hardware, also
need to lock core hardware in case of different instance start
to decoder at the same time.

Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c     | 4 ++--
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 6 +++---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h     | 2 +-
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index 2b334a8a81c6..130ecef2e766 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -105,12 +105,12 @@ static int vidioc_decoder_cmd(struct file *file, void *priv,
 
 void mtk_vdec_unlock(struct mtk_vcodec_ctx *ctx)
 {
-	mutex_unlock(&ctx->dev->dec_mutex);
+	mutex_unlock(&ctx->dev->dec_mutex[ctx->hw_id]);
 }
 
 void mtk_vdec_lock(struct mtk_vcodec_ctx *ctx)
 {
-	mutex_lock(&ctx->dev->dec_mutex);
+	mutex_lock(&ctx->dev->dec_mutex[ctx->hw_id]);
 }
 
 void mtk_vcodec_dec_release(struct mtk_vcodec_ctx *ctx)
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 3ea1e96e0ec0..e21e0c4bcd86 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -332,7 +332,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	struct video_device *vfd_dec;
 	phandle rproc_phandle;
 	enum mtk_vcodec_fw_type fw_type;
-	int ret;
+	int i, ret;
 
 	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
 	if (!dev)
@@ -364,8 +364,8 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		goto err_dec_pm;
 	}
 
-	mutex_init(&dev->dec_mutex);
-	mutex_init(&dev->dev_mutex);
+	for (i = 0; i < MTK_VDEC_HW_MAX; i++)
+		mutex_init(&dev->dec_mutex[i]);
 	spin_lock_init(&dev->irqlock);
 
 	snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s",
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 95c82cb4e568..9d072c082f73 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -498,7 +498,7 @@ struct mtk_vcodec_dev {
 	int dec_irq;
 	int enc_irq;
 
-	struct mutex dec_mutex;
+	struct mutex dec_mutex[MTK_VDEC_HW_MAX];
 	struct mutex enc_mutex;
 
 	struct mtk_vcodec_pm pm;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v7, 11/15] media: mtk-vcodec: Add core thread
  2021-10-11  7:02 [PATCH v7, 00/15] Support multi hardware decode using of_platform_populate Yunfei Dong
                   ` (9 preceding siblings ...)
  2021-10-11  7:02 ` [PATCH v7, 10/15] media: mtk-vcodec: Add new interface to lock different hardware Yunfei Dong
@ 2021-10-11  7:02 ` Yunfei Dong
  2021-10-14 10:56   ` AngeloGioacchino Del Regno
  2021-10-14 12:29   ` Ezequiel Garcia
  2021-10-11  7:02 ` [PATCH v7, 12/15] media: mtk-vcodec: Support 34bits dma address for vdec Yunfei Dong
                   ` (4 subsequent siblings)
  15 siblings, 2 replies; 43+ messages in thread
From: Yunfei Dong @ 2021-10-11  7:02 UTC (permalink / raw)
  To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

Core thread:
1. Gets lat_buf from core msg queue.
2. Proceeds core decode.
3. Puts the lat_buf back to lat msg queue.

Both H264 and VP9 rely on the core thread.

Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 12 +++++++
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  7 ++++
 .../platform/mtk-vcodec/vdec_msg_queue.c      | 32 +++++++++++++++++++
 .../platform/mtk-vcodec/vdec_msg_queue.h      |  6 ++++
 4 files changed, 57 insertions(+)

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 e21e0c4bcd86..de83e3b821b4 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -364,6 +364,18 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		goto err_dec_pm;
 	}
 
+	if (VDEC_LAT_ARCH(dev->vdec_pdata->hw_arch)) {
+		vdec_msg_queue_init_ctx(&dev->msg_queue_core_ctx,
+			MTK_VDEC_CORE);
+		dev->kthread_core = kthread_run(vdec_msg_queue_core_thead, dev,
+			"mtk-%s", "core");
+		if (IS_ERR(dev->kthread_core)) {
+			dev_err(&pdev->dev, "Failed to create core thread");
+			ret = PTR_ERR(dev->kthread_core);
+			goto err_res;
+		}
+	}
+
 	for (i = 0; i < MTK_VDEC_HW_MAX; i++)
 		mutex_init(&dev->dec_mutex[i]);
 	spin_lock_init(&dev->irqlock);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 9d072c082f73..68a9b1a2d3b3 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -27,6 +27,7 @@
 #define MTK_VCODEC_MAX_PLANES	3
 #define MTK_V4L2_BENCHMARK	0
 #define WAIT_INTR_TIMEOUT_MS	1000
+#define VDEC_LAT_ARCH(hw_arch) ((hw_arch) >= MTK_VDEC_LAT_SINGLE_CORE)
 
 /*
  * enum mtk_hw_reg_idx - MTK hw register base index
@@ -466,6 +467,9 @@ struct mtk_vcodec_enc_pdata {
  * @comp_dev: component hardware device
  * @component_node: component node
  *
+ * @kthread_core: thread used for core hardware decode
+ * @msg_queue_core_ctx: msg queue context used for core thread
+ *
  * @hardware_bitmap: used to record hardware is ready or not
  */
 struct mtk_vcodec_dev {
@@ -508,6 +512,9 @@ struct mtk_vcodec_dev {
 	void *comp_dev[MTK_VDEC_HW_MAX];
 	struct device_node *component_node[MTK_VDEC_HW_MAX];
 
+	struct task_struct *kthread_core;
+	struct vdec_msg_queue_ctx msg_queue_core_ctx;
+
 	DECLARE_BITMAP(hardware_bitmap, MTK_VDEC_HW_MAX);
 };
 
diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
index d66ed98c79a9..665f571eab4b 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
@@ -256,3 +256,35 @@ void vdec_msg_queue_deinit(
 			kfree(lat_buf->private_data);
 	}
 }
+
+int vdec_msg_queue_core_thead(void *data)
+{
+	struct mtk_vcodec_dev *dev = data;
+	struct vdec_lat_buf *lat_buf;
+	struct mtk_vcodec_ctx *ctx;
+
+	set_freezable();
+	for (;;) {
+		try_to_freeze();
+		if (kthread_should_stop())
+			break;
+
+		lat_buf = vdec_msg_queue_dqbuf(&dev->msg_queue_core_ctx);
+		if (!lat_buf)
+			continue;
+
+		ctx = lat_buf->ctx;
+		mtk_vcodec_set_curr_ctx(dev, ctx, MTK_VDEC_CORE);
+
+		if (!lat_buf->core_decode)
+			mtk_v4l2_err("Core decode callback func is NULL");
+		else
+			lat_buf->core_decode(lat_buf);
+
+		mtk_vcodec_set_curr_ctx(dev, NULL, MTK_VDEC_CORE);
+		vdec_msg_queue_qbuf(&ctx->msg_queue.lat_ctx, lat_buf);
+	}
+
+	mtk_v4l2_debug(3, "Video Capture Thread End");
+	return 0;
+}
diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
index 1905ce713592..b5745b144140 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
@@ -148,4 +148,10 @@ void vdec_msg_queue_deinit(
 	struct vdec_msg_queue *msg_queue,
 	struct mtk_vcodec_ctx *ctx);
 
+/**
+ * vdec_msg_queue_core_thead - used for core decoder.
+ * @data: private data used for each codec
+ */
+int vdec_msg_queue_core_thead(void *data);
+
 #endif
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v7, 12/15] media: mtk-vcodec: Support 34bits dma address for vdec
  2021-10-11  7:02 [PATCH v7, 00/15] Support multi hardware decode using of_platform_populate Yunfei Dong
                   ` (10 preceding siblings ...)
  2021-10-11  7:02 ` [PATCH v7, 11/15] media: mtk-vcodec: Add core thread Yunfei Dong
@ 2021-10-11  7:02 ` Yunfei Dong
  2021-10-14 11:02   ` AngeloGioacchino Del Regno
  2021-10-11  7:02 ` [PATCH v7, 13/15] dt-bindings: media: mtk-vcodec: Adds decoder dt-bindings for mt8192 Yunfei Dong
                   ` (3 subsequent siblings)
  15 siblings, 1 reply; 43+ messages in thread
From: Yunfei Dong @ 2021-10-11  7:02 UTC (permalink / raw)
  To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

Use the dma_set_mask_and_coherent helper to set vdec
DMA bit mask to support 34bits iova space(16GB) that
the mt8192 iommu HW support.

Whole the iova range separate to 0~4G/4G~8G/8G~12G/12G~16G,
regarding which iova range VDEC actually locate, it
depends on the dma-ranges property of vdec dtsi node.

Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 3 +++
 1 file changed, 3 insertions(+)

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 de83e3b821b4..da963cdac96b 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -376,6 +376,9 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		}
 	}
 
+	if (of_get_property(pdev->dev.of_node, "dma-ranges", NULL))
+		dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(34));
+
 	for (i = 0; i < MTK_VDEC_HW_MAX; i++)
 		mutex_init(&dev->dec_mutex[i]);
 	spin_lock_init(&dev->irqlock);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v7, 13/15] dt-bindings: media: mtk-vcodec: Adds decoder dt-bindings for mt8192
  2021-10-11  7:02 [PATCH v7, 00/15] Support multi hardware decode using of_platform_populate Yunfei Dong
                   ` (11 preceding siblings ...)
  2021-10-11  7:02 ` [PATCH v7, 12/15] media: mtk-vcodec: Support 34bits dma address for vdec Yunfei Dong
@ 2021-10-11  7:02 ` Yunfei Dong
  2021-10-11 13:36   ` Rob Herring
  2021-10-11  7:02 ` [PATCH v7, 14/15] media: mtk-vcodec: Add core dec and dec end ipi msg Yunfei Dong
                   ` (2 subsequent siblings)
  15 siblings, 1 reply; 43+ messages in thread
From: Yunfei Dong @ 2021-10-11  7:02 UTC (permalink / raw)
  To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

Adds decoder dt-bindings for mt8192.

Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
v7: Re-write dtsi for hardware architecture changed
---
 .../media/mediatek,vcodec-comp-decoder.yaml   | 193 ++++++++++++++++++
 1 file changed, 193 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml

diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml
new file mode 100644
index 000000000000..7c2a85afbf90
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml
@@ -0,0 +1,193 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iommu/mediatek,vcodec-comp-decoder.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Video Decode Accelerator With Multi Hardware
+
+maintainers:
+  - Yunfei Dong <yunfei.dong@mediatek.com>
+
+description: |
+  Mediatek Video Decode is the video decode hardware present in Mediatek
+  SoCs which supports high resolution decoding functionalities. Required
+  master and component node.
+
+  About the Decoder Hardware Block Diagram, please check below:
+
+    +---------------------------------+------------------------------------+
+    |                                 |                                    |
+    | input -> lat HW -> lat buffer --|--> lat buffer -> core HW -> output |
+    |            ||                   |                     ||             |
+    +------------||-------------------+---------------------||-------------+
+                 ||       lat thread  |  core thread        ||     <master>
+    -------------||-----------------------------------------||----------------
+                 ||                                         ||     <component>
+                 \/ <----------------HW index-------------->\/
+           +------------------------------------------------------+
+           |                    enable/disable                    |
+           |           clk     power    irq    iommu port         |
+           |                 (lat/lat soc/core0/core1)            |
+           +------------------------------------------------------+
+
+  As above, <master> mean in master device, <component> mean in component device.
+  The information of each hardware will be stored in each component device. There
+  are two thread in master device: lat and core. Enable/disable the lat clk/power/irq
+  when lat hardware need to work through hardware index, core is the same.
+
+  Normally the smi common may not the same for each hardware, can't combine all
+  hardware in one node, or leading to iommu fault when access dram data.
+
+properties:
+  compatible:
+      - enum:
+          - mediatek,mt8192-vcodec-dec  # for lat hardware
+          - mediatek,mtk-vcodec-lat     # for core hardware
+          - mediatek,mtk-vcodec-core
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 5
+
+  clock-names:
+    items:
+      - const: vdec-sel
+      - const: vdec-soc-vdec
+      - const: vdec-soc-lat
+      - const: vdec-vdec
+      - const: vdec-top
+
+  power-domains:
+    maxItems: 1
+
+  iommus:
+    minItems: 1
+    maxItems: 32
+    description: |
+      List of the hardware port in respective IOMMU block for current Socs.
+      Refer to bindings/iommu/mediatek,iommu.yaml.
+
+  dma-ranges:
+    maxItems: 1
+    description: |
+      Describes the physical address space of IOMMU maps to memory.
+
+  mediatek,scp:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description:
+      Describes point to scp.
+
+required:
+      - compatible
+      - reg
+      - iommus
+
+allOf:
+  - if: #master node
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mt8192-vcodec-dec  # for lat hardware
+
+    then:
+      required:
+        - mediatek,scp
+        - dma-ranges
+
+  - if: #component node
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mtk-vcodec-lat     # for core hardware
+              - mediatek,mtk-vcodec-core
+
+    then:
+      required:
+        - interrupts
+        - clocks
+        - clock-names
+        - assigned-clocks
+        - assigned-clock-parents
+        - power-domains
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/memory/mt8192-larb-port.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/clock/mt8192-clk.h>
+    #include <dt-bindings/power/mt8192-power.h>
+
+    vcodec_dec: vcodec_dec@16000000 {
+        compatible = "mediatek,mt8192-vcodec-dec";
+        #address-cells = <2>;
+        #size-cells = <2>;
+        ranges;
+        reg = <0 0x16000000 0 0x1000>;		/* VDEC_SYS */
+        mediatek,scp = <&scp>;
+        iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>;
+        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
+        vcodec_lat {
+            compatible = "mediatek,mtk-vcodec-lat";
+            reg = <0 0x16010000 0 0x800>;		/* VDEC_MISC */
+            reg-name = "reg-misc";
+            interrupts = <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH 0>;
+            iommus = <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD_EXT>,
+                 <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD2_EXT>,
+                 <&iommu0 M4U_PORT_L5_VDEC_LAT0_AVC_MV_EXT>,
+                 <&iommu0 M4U_PORT_L5_VDEC_LAT0_PRED_RD_EXT>,
+                 <&iommu0 M4U_PORT_L5_VDEC_LAT0_TILE_EXT>,
+                 <&iommu0 M4U_PORT_L5_VDEC_LAT0_WDMA_EXT>,
+                 <&iommu0 M4U_PORT_L5_VDEC_LAT0_RG_CTRL_DMA_EXT>,
+                 <&iommu0 M4U_PORT_L5_VDEC_UFO_ENC_EXT>;
+            clocks = <&topckgen CLK_TOP_VDEC_SEL>,
+                 <&vdecsys_soc CLK_VDEC_SOC_VDEC>,
+                 <&vdecsys_soc CLK_VDEC_SOC_LAT>,
+                 <&vdecsys_soc CLK_VDEC_SOC_LARB1>,
+                 <&topckgen CLK_TOP_MAINPLL_D4>;
+            clock-names = "vdec-sel", "vdec-soc-vdec", "vdec-soc-lat",
+                  "vdec-vdec", "vdec-top";
+            assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
+            assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
+            power-domains = <&spm MT8192_POWER_DOMAIN_VDEC>;
+        };
+
+        vcodec_core {
+            compatible = "mediatek,mtk-vcodec-core";
+            reg = <0 0x16025000 0 0x1000>;		/* VDEC_CORE_MISC */
+            reg-names = "reg-misc";
+            interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH 0>;
+            iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>,
+                 <&iommu0 M4U_PORT_L4_VDEC_UFO_EXT>,
+                 <&iommu0 M4U_PORT_L4_VDEC_PP_EXT>,
+                 <&iommu0 M4U_PORT_L4_VDEC_PRED_RD_EXT>,
+                 <&iommu0 M4U_PORT_L4_VDEC_PRED_WR_EXT>,
+                 <&iommu0 M4U_PORT_L4_VDEC_PPWRAP_EXT>,
+                 <&iommu0 M4U_PORT_L4_VDEC_TILE_EXT>,
+                 <&iommu0 M4U_PORT_L4_VDEC_VLD_EXT>,
+                 <&iommu0 M4U_PORT_L4_VDEC_VLD2_EXT>,
+                 <&iommu0 M4U_PORT_L4_VDEC_AVC_MV_EXT>,
+                 <&iommu0 M4U_PORT_L4_VDEC_RG_CTRL_DMA_EXT>;
+            clocks = <&topckgen CLK_TOP_VDEC_SEL>,
+                 <&vdecsys CLK_VDEC_VDEC>,
+                 <&vdecsys CLK_VDEC_LAT>,
+                 <&vdecsys CLK_VDEC_LARB1>,
+                 <&topckgen CLK_TOP_MAINPLL_D4>;
+            clock-names = "vdec-sel", "vdec-soc-vdec", "vdec-soc-lat",
+                  "vdec-vdec", "vdec-top";
+            assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
+            assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
+            power-domains = <&spm MT8192_POWER_DOMAIN_VDEC2>;
+        };
+    };
\ No newline at end of file
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v7, 14/15] media: mtk-vcodec: Add core dec and dec end ipi msg
  2021-10-11  7:02 [PATCH v7, 00/15] Support multi hardware decode using of_platform_populate Yunfei Dong
                   ` (12 preceding siblings ...)
  2021-10-11  7:02 ` [PATCH v7, 13/15] dt-bindings: media: mtk-vcodec: Adds decoder dt-bindings for mt8192 Yunfei Dong
@ 2021-10-11  7:02 ` Yunfei Dong
  2021-10-14 11:04   ` AngeloGioacchino Del Regno
  2021-10-11  7:02 ` [PATCH v7, 15/15] media: mtk-vcodec: Use codec type to separate different hardware Yunfei Dong
  2021-10-12 14:27 ` [PATCH v7, 00/15] Support multi hardware decode using of_platform_populate Andrzej Pietrasiewicz
  15 siblings, 1 reply; 43+ messages in thread
From: Yunfei Dong @ 2021-10-11  7:02 UTC (permalink / raw)
  To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

Add core dec and dec end ipi msg: AP_IPIMSG_DEC_CORE/AP_IPIMSG_DEC_CORE_END.

Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
 .../media/platform/mtk-vcodec/vdec_ipi_msg.h   |  4 ++++
 .../media/platform/mtk-vcodec/vdec_vpu_if.c    | 12 ++++++++++++
 .../media/platform/mtk-vcodec/vdec_vpu_if.h    | 18 ++++++++++++++++++
 3 files changed, 34 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
index 5f45a537beb4..9d8079c4f976 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
@@ -18,12 +18,16 @@ enum vdec_ipi_msgid {
 	AP_IPIMSG_DEC_END = 0xA002,
 	AP_IPIMSG_DEC_DEINIT = 0xA003,
 	AP_IPIMSG_DEC_RESET = 0xA004,
+	AP_IPIMSG_DEC_CORE = 0xA005,
+	AP_IPIMSG_DEC_CORE_END = 0xA006,
 
 	VPU_IPIMSG_DEC_INIT_ACK = 0xB000,
 	VPU_IPIMSG_DEC_START_ACK = 0xB001,
 	VPU_IPIMSG_DEC_END_ACK = 0xB002,
 	VPU_IPIMSG_DEC_DEINIT_ACK = 0xB003,
 	VPU_IPIMSG_DEC_RESET_ACK = 0xB004,
+	VPU_IPIMSG_DEC_CORE_ACK = 0xB005,
+	VPU_IPIMSG_DEC_CORE_END_ACK = 0xB006,
 };
 
 /**
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
index 5dffc459a33d..bfd8e87dceff 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
@@ -85,6 +85,8 @@ static void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv)
 		case VPU_IPIMSG_DEC_END_ACK:
 		case VPU_IPIMSG_DEC_DEINIT_ACK:
 		case VPU_IPIMSG_DEC_RESET_ACK:
+		case VPU_IPIMSG_DEC_CORE_ACK:
+		case VPU_IPIMSG_DEC_CORE_END_ACK:
 			break;
 
 		default:
@@ -191,11 +193,21 @@ int vpu_dec_start(struct vdec_vpu_inst *vpu, uint32_t *data, unsigned int len)
 	return err;
 }
 
+int vpu_dec_core(struct vdec_vpu_inst *vpu)
+{
+	return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_CORE);
+}
+
 int vpu_dec_end(struct vdec_vpu_inst *vpu)
 {
 	return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_END);
 }
 
+int vpu_dec_core_end(struct vdec_vpu_inst *vpu)
+{
+	return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_CORE_END);
+}
+
 int vpu_dec_deinit(struct vdec_vpu_inst *vpu)
 {
 	return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_DEINIT);
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
index c2ed5b6cab8b..ae24b75d1649 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
@@ -82,4 +82,22 @@ int vpu_dec_deinit(struct vdec_vpu_inst *vpu);
  */
 int vpu_dec_reset(struct vdec_vpu_inst *vpu);
 
+/**
+ * vpu_dec_core - core start decoding, basically the function will be invoked once
+ *                 every frame.
+ *
+ * @vpu : instance for vdec_vpu_inst
+ */
+int vpu_dec_core(struct vdec_vpu_inst *vpu);
+
+/**
+ * vpu_dec_core_end - core end decoding, basically the function will be invoked once
+ *               when core HW decoding done and receive interrupt successfully. The
+ *               decoder in VPU will updata hardware information and deinit hardware
+ *               and check if there is a new decoded frame available to display.
+ *
+ * @vpu : instance for vdec_vpu_inst
+ */
+int vpu_dec_core_end(struct vdec_vpu_inst *vpu);
+
 #endif
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v7, 15/15] media: mtk-vcodec: Use codec type to separate different hardware
  2021-10-11  7:02 [PATCH v7, 00/15] Support multi hardware decode using of_platform_populate Yunfei Dong
                   ` (13 preceding siblings ...)
  2021-10-11  7:02 ` [PATCH v7, 14/15] media: mtk-vcodec: Add core dec and dec end ipi msg Yunfei Dong
@ 2021-10-11  7:02 ` Yunfei Dong
  2021-10-14 11:08   ` AngeloGioacchino Del Regno
  2021-10-12 14:27 ` [PATCH v7, 00/15] Support multi hardware decode using of_platform_populate Andrzej Pietrasiewicz
  15 siblings, 1 reply; 43+ messages in thread
From: Yunfei Dong @ 2021-10-11  7:02 UTC (permalink / raw)
  To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

There are just one core thread, in order to separeate different
hardware, using codec type to separeate it in scp driver.

Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
 .../media/platform/mtk-vcodec/vdec_ipi_msg.h  | 12 ++++---
 .../media/platform/mtk-vcodec/vdec_vpu_if.c   | 34 ++++++++++++++++---
 .../media/platform/mtk-vcodec/vdec_vpu_if.h   |  4 +++
 3 files changed, 41 insertions(+), 9 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
index 9d8079c4f976..c488f0c40190 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
@@ -35,6 +35,8 @@ enum vdec_ipi_msgid {
  * @msg_id	: vdec_ipi_msgid
  * @vpu_inst_addr : VPU decoder instance address. Used if ABI version < 2.
  * @inst_id     : instance ID. Used if the ABI version >= 2.
+ * @codec_type	: Codec fourcc
+ * @reserved	: reserved param
  */
 struct vdec_ap_ipi_cmd {
 	uint32_t msg_id;
@@ -42,6 +44,8 @@ struct vdec_ap_ipi_cmd {
 		uint32_t vpu_inst_addr;
 		uint32_t inst_id;
 	};
+	uint32_t codec_type;
+	uint32_t reserved;
 };
 
 /**
@@ -59,12 +63,12 @@ struct vdec_vpu_ipi_ack {
 /**
  * struct vdec_ap_ipi_init - for AP_IPIMSG_DEC_INIT
  * @msg_id	: AP_IPIMSG_DEC_INIT
- * @reserved	: Reserved field
+ * @codec_type	: Codec fourcc
  * @ap_inst_addr	: AP video decoder instance address
  */
 struct vdec_ap_ipi_init {
 	uint32_t msg_id;
-	uint32_t reserved;
+	uint32_t codec_type;
 	uint64_t ap_inst_addr;
 };
 
@@ -77,7 +81,7 @@ struct vdec_ap_ipi_init {
  *	H264 decoder [0]:buf_sz [1]:nal_start
  *	VP8 decoder  [0]:width/height
  *	VP9 decoder  [0]:profile, [1][2] width/height
- * @reserved	: Reserved field
+ * @codec_type	: Codec fourcc
  */
 struct vdec_ap_ipi_dec_start {
 	uint32_t msg_id;
@@ -86,7 +90,7 @@ struct vdec_ap_ipi_dec_start {
 		uint32_t inst_id;
 	};
 	uint32_t data[3];
-	uint32_t reserved;
+	uint32_t codec_type;
 };
 
 /**
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
index bfd8e87dceff..c84fac52fe26 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
@@ -100,18 +100,29 @@ static void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv)
 
 static int vcodec_vpu_send_msg(struct vdec_vpu_inst *vpu, void *msg, int len)
 {
-	int err;
+	int err, id, msgid;
 
-	mtk_vcodec_debug(vpu, "id=%X", *(uint32_t *)msg);
+	msgid = *(uint32_t *)msg;
+	mtk_vcodec_debug(vpu, "id=%X", msgid);
 
 	vpu->failure = 0;
 	vpu->signaled = 0;
 
-	err = mtk_vcodec_fw_ipi_send(vpu->ctx->dev->fw_handler, vpu->id, msg,
+	if (vpu->ctx->dev->vdec_pdata->hw_arch == MTK_VDEC_LAT_SINGLE_CORE) {
+		if (msgid == AP_IPIMSG_DEC_CORE ||
+			msgid == AP_IPIMSG_DEC_CORE_END)
+			id = vpu->core_id;
+		else
+			id = vpu->id;
+	} else {
+		id = vpu->id;
+	}
+
+	err = mtk_vcodec_fw_ipi_send(vpu->ctx->dev->fw_handler, id, msg,
 				     len, 2000);
 	if (err) {
 		mtk_vcodec_err(vpu, "send fail vpu_id=%d msg_id=%X status=%d",
-			       vpu->id, *(uint32_t *)msg, err);
+			       id, msgid, err);
 		return err;
 	}
 
@@ -131,6 +142,7 @@ static int vcodec_send_ap_ipi(struct vdec_vpu_inst *vpu, unsigned int msg_id)
 		msg.vpu_inst_addr = vpu->inst_addr;
 	else
 		msg.inst_id = vpu->inst_id;
+	msg.codec_type = vpu->codec_type;
 
 	err = vcodec_vpu_send_msg(vpu, &msg, sizeof(msg));
 	mtk_vcodec_debug(vpu, "- id=%X ret=%d", msg_id, err);
@@ -149,14 +161,25 @@ int vpu_dec_init(struct vdec_vpu_inst *vpu)
 
 	err = mtk_vcodec_fw_ipi_register(vpu->ctx->dev->fw_handler, vpu->id,
 					 vpu->handler, "vdec", NULL);
-	if (err != 0) {
+	if (err) {
 		mtk_vcodec_err(vpu, "vpu_ipi_register fail status=%d", err);
 		return err;
 	}
 
+	if (vpu->ctx->dev->vdec_pdata->hw_arch == MTK_VDEC_LAT_SINGLE_CORE) {
+		err = mtk_vcodec_fw_ipi_register(vpu->ctx->dev->fw_handler,
+					 vpu->core_id, vpu->handler,
+					 "vdec", NULL);
+		if (err) {
+			mtk_vcodec_err(vpu, "vpu_ipi_register core fail status=%d", err);
+			return err;
+		}
+	}
+
 	memset(&msg, 0, sizeof(msg));
 	msg.msg_id = AP_IPIMSG_DEC_INIT;
 	msg.ap_inst_addr = (unsigned long)vpu;
+	msg.codec_type = vpu->codec_type;
 
 	mtk_vcodec_debug(vpu, "vdec_inst=%p", vpu);
 
@@ -187,6 +210,7 @@ int vpu_dec_start(struct vdec_vpu_inst *vpu, uint32_t *data, unsigned int len)
 
 	for (i = 0; i < len; i++)
 		msg.data[i] = data[i];
+	msg.codec_type = vpu->codec_type;
 
 	err = vcodec_vpu_send_msg(vpu, (void *)&msg, sizeof(msg));
 	mtk_vcodec_debug(vpu, "- ret=%d", err);
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
index ae24b75d1649..802660770a87 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
@@ -14,6 +14,7 @@ struct mtk_vcodec_ctx;
 /**
  * struct vdec_vpu_inst - VPU instance for video codec
  * @id          : ipi msg id for each decoder
+ * @core_id     : core id used to separate different hardware
  * @vsi         : driver structure allocated by VPU side and shared to AP side
  *                for control and info share
  * @failure     : VPU execution result status, 0: success, others: fail
@@ -26,9 +27,11 @@ struct mtk_vcodec_ctx;
  * @dev		: platform device of VPU
  * @wq          : wait queue to wait VPU message ack
  * @handler     : ipi handler for each decoder
+ * @codec_type     : used codec type to separate different codecs
  */
 struct vdec_vpu_inst {
 	int id;
+	int core_id;
 	void *vsi;
 	int32_t failure;
 	uint32_t inst_addr;
@@ -38,6 +41,7 @@ struct vdec_vpu_inst {
 	struct mtk_vcodec_ctx *ctx;
 	wait_queue_head_t wq;
 	mtk_vcodec_ipi_handler handler;
+	unsigned int codec_type;
 };
 
 /**
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* Re: [PATCH v7, 13/15] dt-bindings: media: mtk-vcodec: Adds decoder dt-bindings for mt8192
  2021-10-11  7:02 ` [PATCH v7, 13/15] dt-bindings: media: mtk-vcodec: Adds decoder dt-bindings for mt8192 Yunfei Dong
@ 2021-10-11 13:36   ` Rob Herring
  0 siblings, 0 replies; 43+ messages in thread
From: Rob Herring @ 2021-10-11 13:36 UTC (permalink / raw)
  To: Yunfei Dong
  Cc: dri-devel, linux-mediatek, linux-arm-kernel,
	Project_Global_Chrome_Upstream_Group, Benjamin Gaignard,
	Rob Herring, Matthias Brugger, Hsin-Yi Wang, Alexandre Courbot,
	Hans Verkuil, Tomasz Figa, Daniel Vetter, Andrew-CT Chen,
	Irui Wang, linux-media, linux-kernel, devicetree, Tzung-Bi Shih,
	srv_heupstream, Dafna Hirschfeld, Tiffany Lin, Fritz Koenig,
	Mauro Carvalho Chehab

On Mon, 11 Oct 2021 15:02:45 +0800, Yunfei Dong wrote:
> Adds decoder dt-bindings for mt8192.
> 
> Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
> ---
> v7: Re-write dtsi for hardware architecture changed
> ---
>  .../media/mediatek,vcodec-comp-decoder.yaml   | 193 ++++++++++++++++++
>  1 file changed, 193 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:
./Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml:44:7: [warning] wrong indentation: expected 4 but found 6 (indentation)
./Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml:88:7: [warning] wrong indentation: expected 2 but found 6 (indentation)
./Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml:193:7: [error] no new line character at the end of file (new-line-at-end-of-file)

dtschema/dtc warnings/errors:
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml: properties:compatible: [{'enum': ['mediatek,mt8192-vcodec-dec', 'mediatek,mtk-vcodec-lat', 'mediatek,mtk-vcodec-core']}] is not of type 'object', 'boolean'
	from schema $id: http://json-schema.org/draft-07/schema#
./Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml: $id: relative path/filename doesn't match actual path or filename
	expected: http://devicetree.org/schemas/media/mediatek,vcodec-comp-decoder.yaml#
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml: ignoring, error in schema: properties: compatible
warning: no schema found in file: ./Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml
Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.example.dts:29.13-20: Warning (ranges_format): /example-0/vcodec_dec@16000000:ranges: empty "ranges" property but its #address-cells (2) differs from /example-0 (1)
Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.example.dts:29.13-20: Warning (ranges_format): /example-0/vcodec_dec@16000000:ranges: empty "ranges" property but its #size-cells (2) differs from /example-0 (1)
Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.example.dts:33.13-66: Warning (dma_ranges_format): /example-0/vcodec_dec@16000000:dma-ranges: "dma-ranges" property has invalid length (24 bytes) (parent #address-cells == 1, child #address-cells == 2, #size-cells == 2)
Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.example.dts:34.24-57.15: Warning (unit_address_vs_reg): /example-0/vcodec_dec@16000000/vcodec_lat: node has a reg or ranges property, but no unit name
Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.example.dts:59.25-85.15: Warning (unit_address_vs_reg): /example-0/vcodec_dec@16000000/vcodec_core: node has a reg or ranges property, but no unit name
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.example.dt.yaml: example-0: vcodec_dec@16000000:reg:0: [0, 369098752, 0, 4096] is too long
	From schema: /usr/local/lib/python3.8/dist-packages/dtschema/schemas/reg.yaml
Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.example.dt.yaml:0:0: /example-0/vcodec_dec@16000000: failed to match any schema with compatible: ['mediatek,mt8192-vcodec-dec']
Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.example.dt.yaml:0:0: /example-0/vcodec_dec@16000000/vcodec_lat: failed to match any schema with compatible: ['mediatek,mtk-vcodec-lat']
Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.example.dt.yaml:0:0: /example-0/vcodec_dec@16000000/vcodec_core: failed to match any schema with compatible: ['mediatek,mtk-vcodec-core']

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1539139

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v7, 00/15] Support multi hardware decode using of_platform_populate
  2021-10-11  7:02 [PATCH v7, 00/15] Support multi hardware decode using of_platform_populate Yunfei Dong
                   ` (14 preceding siblings ...)
  2021-10-11  7:02 ` [PATCH v7, 15/15] media: mtk-vcodec: Use codec type to separate different hardware Yunfei Dong
@ 2021-10-12 14:27 ` Andrzej Pietrasiewicz
  2021-10-13  1:08   ` yunfei.dong
  15 siblings, 1 reply; 43+ messages in thread
From: Andrzej Pietrasiewicz @ 2021-10-12 14:27 UTC (permalink / raw)
  To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

Hi Yunfei Dong,

W dniu 11.10.2021 o 09:02, Yunfei Dong pisze:
> This series adds support for multi hardware decode into mtk-vcodec, by first
> adding use of_platform_populate to manage each hardware information: interrupt,
> clock, register bases and power. Secondly add core thread to deal with core
> hardware message, at the same time, add msg queue for different hardware
> share messages. Lastly, the architecture of different specs are not the same,
> using specs type to separate them.
> 
> This series has been tested with both MT8183 and MT8173. Decoding was working
> for both chips.
> 
> Patches 1~3 rewrite get register bases and power on/off interface.
> 
> Patch 4 add to support multi hardware.
> 
> Patch 5 separate video encoder and decoder document
> 
> Patches 6-15 add interfaces to support core hardware.

Which tree does the series apply to?

Regards,

Andrzej

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v7, 00/15] Support multi hardware decode using of_platform_populate
  2021-10-12 14:27 ` [PATCH v7, 00/15] Support multi hardware decode using of_platform_populate Andrzej Pietrasiewicz
@ 2021-10-13  1:08   ` yunfei.dong
  2021-10-13 10:55     ` Andrzej Pietrasiewicz
  0 siblings, 1 reply; 43+ messages in thread
From: yunfei.dong @ 2021-10-13  1:08 UTC (permalink / raw)
  To: Andrzej Pietrasiewicz, Alexandre Courbot, Hans Verkuil,
	Tzung-Bi Shih, Tiffany Lin, Andrew-CT Chen,
	Mauro Carvalho Chehab, Rob Herring, Matthias Brugger,
	Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

Hi Andrzej,


On Tue, 2021-10-12 at 16:27 +0200, Andrzej Pietrasiewicz wrote:
> Hi Yunfei Dong,
> 
> W dniu 11.10.2021 o 09:02, Yunfei Dong pisze:
> > This series adds support for multi hardware decode into mtk-vcodec, 
> > by first
> > adding use of_platform_populate to manage each hardware
> > information: interrupt,
> > clock, register bases and power. Secondly add core thread to deal
> > with core
> > hardware message, at the same time, add msg queue for different
> > hardware
> > share messages. Lastly, the architecture of different specs are not
> > the same,
> > using specs type to separate them.
> > 
> > This series has been tested with both MT8183 and MT8173. Decoding
> > was working
> > for both chips.
> > 
> > Patches 1~3 rewrite get register bases and power on/off interface.
> > 
> > Patch 4 add to support multi hardware.
> > 
> > Patch 5 separate video encoder and decoder document
> > 
> > Patches 6-15 add interfaces to support core hardware.
> 
> Which tree does the series apply to?

I don't understand your mean clearly. Media tree?

You can get the patches from this link:

https://patchwork.linuxtv.org/project/linux-media/cover/20211011070247.792-1-yunfei.dong@mediatek.com/

Thanks,
Yunfei Dong
> 
> Regards,
> 
> Andrzej

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v7, 00/15] Support multi hardware decode using of_platform_populate
  2021-10-13  1:08   ` yunfei.dong
@ 2021-10-13 10:55     ` Andrzej Pietrasiewicz
  0 siblings, 0 replies; 43+ messages in thread
From: Andrzej Pietrasiewicz @ 2021-10-13 10:55 UTC (permalink / raw)
  To: yunfei.dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

Hi,

W dniu 13.10.2021 o 03:08, yunfei.dong@mediatek.com pisze:
> Hi Andrzej,
> 
> 
> On Tue, 2021-10-12 at 16:27 +0200, Andrzej Pietrasiewicz wrote:
>> Hi Yunfei Dong,
>>
>> W dniu 11.10.2021 o 09:02, Yunfei Dong pisze:
>>> This series adds support for multi hardware decode into mtk-vcodec,
>>> by first
>>> adding use of_platform_populate to manage each hardware
>>> information: interrupt,
>>> clock, register bases and power. Secondly add core thread to deal
>>> with core
>>> hardware message, at the same time, add msg queue for different
>>> hardware
>>> share messages. Lastly, the architecture of different specs are not
>>> the same,
>>> using specs type to separate them.
>>>
>>> This series has been tested with both MT8183 and MT8173. Decoding
>>> was working
>>> for both chips.
>>>
>>> Patches 1~3 rewrite get register bases and power on/off interface.
>>>
>>> Patch 4 add to support multi hardware.
>>>
>>> Patch 5 separate video encoder and decoder document
>>>
>>> Patches 6-15 add interfaces to support core hardware.
>>
>> Which tree does the series apply to?
> 
> I don't understand your mean clearly. Media tree?
> 
> You can get the patches from this link:
> 
> https://patchwork.linuxtv.org/project/linux-media/cover/20211011070247.792-1-yunfei.dong@mediatek.com/
> 

Here's what I get:

$ git remote update media_tree
Fetching media_tree

$ git branch
   master
* media_tree
   mediatek-master

$ git-pw --server https://patchwork.linuxtv.org/api/1.1 --project linux-media 
series apply 6465 -3
Failed to apply patch:
Applying: media: mtk-vcodec: Get numbers of register bases from DT
Applying: media: mtk-vcodec: Align vcodec wake up interrupt interface
Applying: media: mtk-vcodec: Refactor vcodec pm interface
Applying: media: mtk-vcodec: Manage multi hardware information
error: sha1 information is lacking or useless 
(drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c).
error: could not build fake ancestor
Patch failed at 0004 media: mtk-vcodec: Manage multi hardware information
Use 'git am --show-current-patch' to see the failed patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".

Regards,

Andrzej

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v7, 04/15] media: mtk-vcodec: Manage multi hardware information
  2021-10-11  7:02 ` [PATCH v7, 04/15] media: mtk-vcodec: Manage multi hardware information Yunfei Dong
@ 2021-10-14  9:20   ` AngeloGioacchino Del Regno
  2021-10-29  3:05     ` yunfei.dong
  2021-10-14  9:30   ` AngeloGioacchino Del Regno
  1 sibling, 1 reply; 43+ messages in thread
From: AngeloGioacchino Del Regno @ 2021-10-14  9:20 UTC (permalink / raw)
  To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

> Manage each hardware information which includes irq/power/clk.
> The hardware includes LAT0, LAT1 and CORE.
> 
> Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
> ---
> v7: Using of_platform_populate not component framework to manage multi hardware.
> ---
>   drivers/media/platform/mtk-vcodec/Makefile    |   1 +
>   .../platform/mtk-vcodec/mtk_vcodec_dec.h      |   1 +
>   .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 151 ++++++++++++----
>   .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   | 165 ++++++++++++++++++
>   .../platform/mtk-vcodec/mtk_vcodec_dec_hw.h   |  49 ++++++
>   .../mtk-vcodec/mtk_vcodec_dec_stateful.c      |   1 +
>   .../mtk-vcodec/mtk_vcodec_dec_stateless.c     |   1 +
>   .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  23 +++
>   8 files changed, 359 insertions(+), 33 deletions(-)
>   create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
>   create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
> 



Hello Yunfei,

thanks for this great series! However, there are a few things to improve...

> diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
> index ca8e9e7a9c4e..edeb3b66e9e9 100644
> --- a/drivers/media/platform/mtk-vcodec/Makefile
> +++ b/drivers/media/platform/mtk-vcodec/Makefile
> @@ -15,6 +15,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
>   		mtk_vcodec_dec_stateful.o \
>   		mtk_vcodec_dec_stateless.o \
>   		mtk_vcodec_dec_pm.o \
> +		mtk_vcodec_dec_hw.o \
>   
>   mtk-vcodec-enc-y := venc/venc_vp8_if.o \
>   		venc/venc_h264_if.o \
> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
> index 9fbd24186c1a..c509224cbff4 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
> @@ -66,6 +66,7 @@ extern const struct v4l2_ioctl_ops mtk_vdec_ioctl_ops;
>   extern const struct v4l2_m2m_ops mtk_vdec_m2m_ops;
>   extern const struct media_device_ops mtk_vcodec_media_ops;
>   
> +extern struct platform_driver mtk_vdec_comp_driver;

This may be useless... more on that later in this review.

>   
>   /*
>    * mtk_vdec_lock/mtk_vdec_unlock are for ctx instance to
> 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 dd749d41c75a..17cb3e3519eb 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
> @@ -18,19 +18,61 @@
>   
>   #include "mtk_vcodec_drv.h"
>   #include "mtk_vcodec_dec.h"
> +#include "mtk_vcodec_dec_hw.h"
>   #include "mtk_vcodec_dec_pm.h"
>   #include "mtk_vcodec_intr.h"
> -#include "mtk_vcodec_util.h"
>   #include "mtk_vcodec_fw.h"
>   
> -#define VDEC_HW_ACTIVE	0x10
> -#define VDEC_IRQ_CFG	0x11
> -#define VDEC_IRQ_CLR	0x10
> -#define VDEC_IRQ_CFG_REG	0xa4
> -
>   module_param(mtk_v4l2_dbg_level, int, 0644);
>   module_param(mtk_vcodec_dbg, bool, 0644);
>   
> +static struct of_device_id mtk_vdec_drv_ids[] = {
> +	{
> +		.compatible = "mediatek,mtk-vcodec-lat",
> +		.data = (void *)MTK_VDEC_LAT0,
> +	},
> +	{
> +		.compatible = "mediatek,mtk-vcodec-core",
> +		.data = (void *)MTK_VDEC_CORE,
> +	},
> +	{},
> +};

Is this a duplicate of "mtk_vdec_comp_ids", found in mtk_vcodec_dec_hw.c?!

> +
> +static int mtk_vcodec_comp_device_check(struct mtk_vcodec_ctx *ctx)
> + {
> +	struct mtk_vcodec_dev *vdec_dev = ctx->dev;
> +	struct platform_device *pdev = vdec_dev->plat_dev;
> +	struct device_node *comp_node;
> +	enum mtk_vdec_hw_id comp_idx;
> +	const struct of_device_id *of_id;
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(mtk_vdec_drv_ids); i++) {
> +		of_id = &mtk_vdec_drv_ids[i];
> +		comp_node = of_find_compatible_node(NULL, NULL,
> +			of_id->compatible);
> +		if (!comp_node)
> +			continue;
> +
> +		if (!of_device_is_available(comp_node)) {
> +			of_node_put(comp_node);
> +			dev_err(&pdev->dev, "Fail to get MMSYS node\n");
> +			continue;
> +		}
> +
> +		comp_idx = (enum mtk_vdec_hw_id)of_id->data;
> +		vdec_dev->component_node[comp_idx] = comp_node;
> +
> +		if (!test_bit(comp_idx, vdec_dev->hardware_bitmap)) {
> +			dev_err(&pdev->dev, "Vdec comp_idx is not ready %d.",
> +				comp_idx);
> +			return -EINVAL;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
>   static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
>   {
>   	struct mtk_vcodec_dev *dev = priv;
> @@ -95,6 +137,41 @@ static int mtk_vcodec_get_reg_bases(struct mtk_vcodec_dev *dev)
>   	return 0;
>   }
>   
> +static int mtk_vcodec_init_dec_params(struct mtk_vcodec_dev *dev)
> +{
> +	struct platform_device *pdev = dev->plat_dev;
> +	int ret;
> +
> +	ret = mtk_vcodec_get_reg_bases(dev);
> +	if (ret)
> +		return ret;
> +
> +	if (!dev->vdec_pdata->is_comp_supported) {

component is never supported (is_comp_supported is always false), so this check
is useless.

> +		dev->dec_irq = platform_get_irq(pdev, 0);
> +		if (dev->dec_irq < 0) {
> +			dev_err(&pdev->dev, "failed to get irq number");
> +			return dev->dec_irq;
> +		}
> +
> +		irq_set_status_flags(dev->dec_irq, IRQ_NOAUTOEN);
> +		ret = devm_request_irq(&pdev->dev, dev->dec_irq,
> +			mtk_vcodec_dec_irq_handler, 0, pdev->name, dev);
> +		if (ret) {
> +			dev_err(&pdev->dev, "failed to install dev->dec_irq %d (%d)",
> +				dev->dec_irq, ret);
> +			return ret;
> +		}
> +
> +		ret = mtk_vcodec_init_dec_pm(pdev, &dev->pm);
> +		if (ret < 0) {
> +			dev_err(&pdev->dev, "failed to get mt vcodec clock source");
> +			return ret;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
>   static int fops_vcodec_open(struct file *file)
>   {
>   	struct mtk_vcodec_dev *dev = video_drvdata(file);
> @@ -116,6 +193,12 @@ static int fops_vcodec_open(struct file *file)
>   	init_waitqueue_head(&ctx->queue);
>   	mutex_init(&ctx->lock);
>   
> +	ret = mtk_vcodec_comp_device_check(ctx);

Are you checking available devices outside of a probe function?
 From what I can see, you require that the MMSYS device is available at this
time, but that's something that should be granted if we reach this point.

I would say that this driver probe should be deferred until the MMSYS device
becomes available, since it's required for this to work and since, once that
device gets registered and probed successfully, it'll never go away (unless
module unloaded, but you can't unload module A if module B is using it, or
depends on it, unless you also unload module B): like this, you will avoid
performing N useless checks, everytime the userspace opens the vdec device.

> +	if (ret) {
> +		mtk_v4l2_err("Failed to check vdec comp device.");
> +		goto err_ctrls_setup;
> +	}
> +
>   	ctx->type = MTK_INST_DECODER;
>   	ret = dev->vdec_pdata->ctrls_setup(ctx);
>   	if (ret) {
> @@ -220,7 +303,6 @@ 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 ret;
> @@ -249,32 +331,10 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
>   	if (IS_ERR(dev->fw_handler))
>   		return PTR_ERR(dev->fw_handler);
>   
> -	ret = mtk_vcodec_init_dec_pm(dev->plat_dev, &dev->pm);
> -	if (ret < 0) {
> -		dev_err(&pdev->dev, "Failed to get mt vcodec clock source");
> -		goto err_dec_pm;
> -	}
> -
> -	ret = mtk_vcodec_get_reg_bases(dev);
> -	if (ret)
> -		goto err_res;
> -
> -	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
> -	if (res == NULL) {
> -		dev_err(&pdev->dev, "failed to get irq resource");
> -		ret = -ENOENT;
> -		goto err_res;
> -	}
> -
> -	dev->dec_irq = platform_get_irq(pdev, 0);
> -	irq_set_status_flags(dev->dec_irq, IRQ_NOAUTOEN);
> -	ret = devm_request_irq(&pdev->dev, dev->dec_irq,
> -			mtk_vcodec_dec_irq_handler, 0, pdev->name, dev);
> +	ret = mtk_vcodec_init_dec_params(dev);
>   	if (ret) {
> -		dev_err(&pdev->dev, "Failed to install dev->dec_irq %d (%d)",
> -			dev->dec_irq,
> -			ret);
> -		goto err_res;
> +		dev_err(&pdev->dev, "Failed to init pm and registers");
> +		goto err_dec_pm;
>   	}
>   
>   	mutex_init(&dev->dec_mutex);
> @@ -329,6 +389,13 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
>   		goto err_event_workq;
>   	}
>   
> +	ret = of_platform_populate(pdev->dev.of_node, NULL, NULL,
> +		&pdev->dev);
> +	if (ret) {
> +		mtk_v4l2_err("Master device of_platform_populate failed.");
> +		goto err_event_workq;
> +	}
> +
>   	if (dev->vdec_pdata->uses_stateless_api) {
>   		dev->mdev_dec.dev = &pdev->dev;
>   		strscpy(dev->mdev_dec.model, MTK_VCODEC_DEC_NAME,
> @@ -436,7 +503,25 @@ static struct platform_driver mtk_vcodec_dec_driver = {
>   	},
>   };
>   
> -module_platform_driver(mtk_vcodec_dec_driver);
> +static struct platform_driver * const mtk_vdec_drivers[] = {
> +	&mtk_vdec_comp_driver,
> +	&mtk_vcodec_dec_driver,
> +};

I would say that this is not a good idea, since you can simply register
your mtk_vdec_comp_driver in mtk_vcodec_dec_hw.c.

> +
> +static int __init mtk_vdec_init(void)
> +{
> +	return platform_register_drivers(mtk_vdec_drivers,
> +					 ARRAY_SIZE(mtk_vdec_drivers));
> +}
> +
> +static void __exit mtk_vdec_exit(void)
> +{
> +	platform_unregister_drivers(mtk_vdec_drivers,
> +				    ARRAY_SIZE(mtk_vdec_drivers));
> +}
> +
> +module_init(mtk_vdec_init);
> +module_exit(mtk_vdec_exit);
>   
>   MODULE_LICENSE("GPL v2");
>   MODULE_DESCRIPTION("Mediatek video codec V4L2 decoder driver");
> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
> new file mode 100644
> index 000000000000..3752ccaea284
> --- /dev/null
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
> @@ -0,0 +1,165 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2021 MediaTek Inc.
> + * Author: Yunfei Dong <yunfei.dong@mediatek.com>
> + */
> +
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/slab.h>
> +
> +#include "mtk_vcodec_drv.h"
> +#include "mtk_vcodec_dec.h"
> +#include "mtk_vcodec_dec_hw.h"
> +#include "mtk_vcodec_dec_pm.h"
> +#include "mtk_vcodec_intr.h"
> +#include "mtk_vcodec_util.h"
> +
> +static const struct of_device_id mtk_vdec_comp_ids[] = {
> +	{
> +		.compatible = "mediatek,mtk-vcodec-lat",
> +	},
> +	{
> +		.compatible = "mediatek,mtk-vcodec-core",
> +	},
> +	{},
> +};

I think that you forgot some ".data = " here...

> +
> +static irqreturn_t mtk_vdec_comp_irq_handler(int irq, void *priv)
> +{
> +	struct mtk_vdec_comp_dev *dev = priv;
> +	struct mtk_vcodec_ctx *ctx;
> +	u32 cg_status;
> +	unsigned int dec_done_status;
> +	void __iomem *vdec_misc_addr = dev->reg_base[VDEC_COMP_MISC] +
> +					VDEC_IRQ_CFG_REG;
> +
> +	ctx = mtk_vcodec_get_curr_ctx(dev->master_dev);
> +
> +	/* check if HW active or not */
> +	cg_status = readl(dev->reg_base[VDEC_COMP_SYS]);
> +	if ((cg_status & VDEC_HW_ACTIVE) != 0) {

The "!= 0" can be dropped here, since cg_status is unsigned.

> +		mtk_v4l2_err("vdec active is not 0x0 (0x%08x)",
> +			cg_status);
> +		return IRQ_HANDLED;
> +	}
> +
> +	dec_done_status = readl(vdec_misc_addr);
> +	if ((dec_done_status & MTK_VDEC_IRQ_STATUS_DEC_SUCCESS) !=
> +		MTK_VDEC_IRQ_STATUS_DEC_SUCCESS)

I suggest to fix the indentation here to increase human readability, like so:

	if ((dec_done_status & MTK_VDEC_IRQ_STATUS_DEC_SUCCESS) !=

	    MTK_VDEC_IRQ_STATUS_DEC_SUCCESS)


> +		return IRQ_HANDLED;
> +
> +	/* clear interrupt */
> +	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);
> +
> +	mtk_v4l2_debug(3, "wake up ctx %d, dec_done_status=%x",
> +		ctx->id, dec_done_status);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int mtk_vdec_comp_init_irq(struct mtk_vdec_comp_dev *dev)
> +{
> +	struct platform_device *pdev = dev->plat_dev;
> +	int ret;
> +
> +	dev->dec_irq = platform_get_irq(pdev, 0);
> +	if (dev->dec_irq < 0) {
> +		dev_err(&pdev->dev, "Failed to get irq resource");
> +		return dev->dec_irq;
> +	}
> +
> +	irq_set_status_flags(dev->dec_irq, IRQ_NOAUTOEN);
> +	ret = devm_request_irq(&pdev->dev, dev->dec_irq,
> +				mtk_vdec_comp_irq_handler, 0, pdev->name, dev);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Failed to install dev->dec_irq %d (%d)",
> +			dev->dec_irq, ret);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int mtk_vdec_comp_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct mtk_vdec_comp_dev *comp_dev;
> +	struct mtk_vcodec_dev *master_dev;
> +	const struct of_device_id *of_id;
> +	int comp_idx;
> +	int ret;
> +
> +	if (!dev->parent) {
> +		dev_err(dev, "Vdec parent prob is not ready.");

This is not an error, since it's not a "critical" error, until it becomes one (so,
after max deferral count has been reached).
I would remove this message entirely, however, if you really want this message to
be here, you should use dev_dbg.

> +		return -EPROBE_DEFER;
> +	}
> +
> +	master_dev = dev_get_drvdata(dev->parent);
> +	if (!master_dev) {
> +		dev_err(dev, "Failed to get master device.");

Same here.

> +		return -EPROBE_DEFER;
> +	}
> +
> +	comp_dev = devm_kzalloc(dev, sizeof(*comp_dev), GFP_KERNEL);
> +	if (!comp_dev)
> +		return -ENOMEM;
> +
> +	comp_dev->plat_dev = pdev;
> +	ret = mtk_vcodec_init_dec_pm(pdev, &comp_dev->pm);
> +	if (ret) {
> +		dev_err(dev, "Failed to get mt vcodec clock source.");

As far as I can see, you have failure prints all over in function 
mtk_vcodec_init_dec_pm, so there's no need to add another print here:
you can simply return the error value here.

> +		return ret;
> +	}
> +
> +	comp_dev->reg_base[VDEC_COMP_MISC] =
> +		devm_platform_ioremap_resource_byname(pdev, "reg-misc");
> +	if (IS_ERR((__force void *)comp_dev->reg_base[VDEC_COMP_MISC])) {
> +		ret = PTR_ERR((__force void *)comp_dev->reg_base[VDEC_COMP_MISC]);
> +		goto err;
> +	}
> +
> +	ret = mtk_vdec_comp_init_irq(comp_dev);
> +	if (ret) {
> +		dev_err(dev, "Failed to register irq handler.\n");
> +		goto err;
> +	}

...and the same applies here: mtk_vdec_comp_init_irq already prints on its own.

> +
> +	of_id = of_match_device(mtk_vdec_comp_ids, dev);
> +	if (!of_id) {
> +		dev_err(dev, "Can't get vdec comp device id.\n");
> +		ret = -EINVAL;
> +		goto err;
> +	}
> +
> +	comp_idx = (enum mtk_vdec_hw_id)of_id->data;

Are you sure that this one is working as expected?
The only driver that registers compatibles mediatek,mtk-vcodec-lat and
mediatek,mtk-vcodec-core is exactly this one, but there's no .data assigned
to any of the of_device_id entries... and this means that your of_id->data
will not contain the expected value of type enum mtk_vdec_hw_id.

> +	if (comp_idx < MTK_VDEC_HW_MAX) {
> +		master_dev->comp_dev[comp_idx] = comp_dev;
> +		comp_dev->comp_idx = comp_idx;
> +		comp_dev->master_dev = master_dev;
> +		comp_dev->reg_base[VDEC_COMP_SYS] =
> +			master_dev->reg_base[VDEC_COMP_SYS];
> +		set_bit(comp_dev->comp_idx, master_dev->hardware_bitmap);
> +	}
> +
> +	platform_set_drvdata(pdev, comp_dev);
> +	return 0;
> +err:
> +	mtk_vcodec_release_dec_pm(&comp_dev->pm);
> +	return ret;
> +}
> +
> +MODULE_DEVICE_TABLE(of, mtk_vdec_comp_ids);
> +struct platform_driver mtk_vdec_comp_driver = {

The `_comp` here is a name that's making a logical reference to that: in this case,

that may confuse developers around. Can you please drop that `_comp`?

That would become `mtk_vdec_driver` instead.


Logically, the same applies for the rest - always assuming that it's referencing to
the Linux component API.

> +	.probe	= mtk_vdec_comp_probe,
> +	.driver	= {
> +		.name	= "mtk-vdec-comp",
> +		.of_match_table = mtk_vdec_comp_ids,
> +	},
> +};

Since you're using of_platform_populate, there is no need to register this driver
externally: you can simply register it here (module_platform_driver) and it will
be probed at of_platform_populate time in your parent.

> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
> new file mode 100644
> index 000000000000..8d6e818a3474
> --- /dev/null
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
> @@ -0,0 +1,49 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2021 MediaTek Inc.
> + * Author: Yunfei Dong <yunfei.dong@mediatek.com>
> + */
> +
> +#ifndef _MTK_VCODEC_DEC_HW_H_
> +#define _MTK_VCODEC_DEC_HW_H_
> +
> +#include <linux/io.h>
> +#include <linux/platform_device.h>
> +
> +#include "mtk_vcodec_drv.h"
> +
> +#define VDEC_HW_ACTIVE	0x10
> +#define VDEC_IRQ_CFG	0x11
> +#define VDEC_IRQ_CLR	0x10
> +#define VDEC_IRQ_CFG_REG	0xa4

Cosmetic nitpick: either all values in the same column, or simply use a space
instead of tabulations.

> +
> +/**
> + * enum mtk_comp_hw_reg_idx - component register base index
> + */
> +enum mtk_comp_hw_reg_idx {
> +	VDEC_COMP_SYS,
> +	VDEC_COMP_MISC,
> +	VDEC_COMP_MAX
> +};
> +
> +/**
> + * struct mtk_vdec_comp_dev - component framwork driver data

You've switched away from the component framework... so this structure's
description seems to be a bit misleading now...

> + * @plat_dev: platform device
> + * @master_dev: master device
> + * @reg_base: Mapped address of MTK Vcodec registers.
> + *
> + * @dec_irq: decoder irq resource
> + * @pm: power management control
> + * @comp_idx: component index
> + */
> +struct mtk_vdec_comp_dev {
> +	struct platform_device *plat_dev;
> +	struct mtk_vcodec_dev *master_dev;
> +	void __iomem *reg_base[VDEC_COMP_MAX];
> +
> +	int dec_irq;
> +	struct mtk_vcodec_pm pm;
> +	int comp_idx;
> +};
> +
> +#endif /* _MTK_VCODEC_DEC_HW_H_ */
> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
> index 59c24b22ab6d..4f9a80ce15d8 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
> @@ -623,4 +623,5 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata = {
>   	.num_framesizes = NUM_SUPPORTED_FRAMESIZE,
>   	.worker = mtk_vdec_worker,
>   	.flush_decoder = mtk_vdec_flush_decoder,
> +	.is_comp_supported = false,
>   };
> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
> index 8f4a1f0a0769..762633572b49 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
> @@ -357,4 +357,5 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
>   	.uses_stateless_api = true,
>   	.worker = mtk_vdec_worker,
>   	.flush_decoder = mtk_vdec_flush_decoder,
> +	.is_comp_supported = false,

component is not supported anywhere, since you've switched away from it?!

>   };
> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> index 973b0b3649c6..ec3850b4c638 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> @@ -93,6 +93,17 @@ enum mtk_fmt_type {
>   	MTK_FMT_FRAME = 2,
>   };
>   
> +/**
> + * struct mtk_vdec_hw_id - Hardware index used to separate
> + *                         different hardware
> + */
> +enum mtk_vdec_hw_id {
> +	MTK_VDEC_CORE,
> +	MTK_VDEC_LAT0,
> +	MTK_VDEC_LAT1,
> +	MTK_VDEC_HW_MAX,
> +};
> +
>   /*
>    * struct mtk_video_fmt - Structure used to store information about pixelformats
>    */
> @@ -331,6 +342,7 @@ enum mtk_chip {
>    *
>    * @chip: chip this decoder is compatible with
>    *
> + * @is_comp_supported: true: using compoent framework, false: not support
>    * @uses_stateless_api: whether the decoder uses the stateless API with requests
>    */
>   
> @@ -352,6 +364,7 @@ struct mtk_vcodec_dec_pdata {
>   
>   	enum mtk_chip chip;
>   
> +	bool is_comp_supported;

Adding this member looks useless: there's nothing declaring is_comp_supported as
true... not here, not in any other patch of this entire series!


Regards,
- Angelo


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v7, 04/15] media: mtk-vcodec: Manage multi hardware information
  2021-10-11  7:02 ` [PATCH v7, 04/15] media: mtk-vcodec: Manage multi hardware information Yunfei Dong
  2021-10-14  9:20   ` AngeloGioacchino Del Regno
@ 2021-10-14  9:30   ` AngeloGioacchino Del Regno
  1 sibling, 0 replies; 43+ messages in thread
From: AngeloGioacchino Del Regno @ 2021-10-14  9:30 UTC (permalink / raw)
  To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group



 > Manage each hardware information which includes irq/power/clk.

 > The hardware includes LAT0, LAT1 and CORE.

 >

 > Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>

 > ---

 > v7: Using of_platform_populate not component framework to manage multi hardware.

 > ---

 >   drivers/media/platform/mtk-vcodec/Makefile    |   1 +

 >   .../platform/mtk-vcodec/mtk_vcodec_dec.h      |   1 +

 >   .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 151 ++++++++++++----

 >   .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   | 165 ++++++++++++++++++

 >   .../platform/mtk-vcodec/mtk_vcodec_dec_hw.h   |  49 ++++++

 >   .../mtk-vcodec/mtk_vcodec_dec_stateful.c      |   1 +

 >   .../mtk-vcodec/mtk_vcodec_dec_stateless.c     |   1 +

 >   .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  23 +++

 >   8 files changed, 359 insertions(+), 33 deletions(-)

 >   create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c

 >   create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h

 >







Hello Yunfei,



thanks for this great series! However, there are a few things to improve...



 > diff --git a/drivers/media/platform/mtk-vcodec/Makefile 
b/drivers/media/platform/mtk-vcodec/Makefile

 > index ca8e9e7a9c4e..edeb3b66e9e9 100644

 > --- a/drivers/media/platform/mtk-vcodec/Makefile

 > +++ b/drivers/media/platform/mtk-vcodec/Makefile

 > @@ -15,6 +15,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \

 >           mtk_vcodec_dec_stateful.o \

 >           mtk_vcodec_dec_stateless.o \

 >           mtk_vcodec_dec_pm.o \

 > +        mtk_vcodec_dec_hw.o \

 >     mtk-vcodec-enc-y := venc/venc_vp8_if.o \

 >           venc/venc_h264_if.o \

 > diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h 
b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h

 > index 9fbd24186c1a..c509224cbff4 100644

 > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h

 > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h

 > @@ -66,6 +66,7 @@ extern const struct v4l2_ioctl_ops mtk_vdec_ioctl_ops;

 >   extern const struct v4l2_m2m_ops mtk_vdec_m2m_ops;

 >   extern const struct media_device_ops mtk_vcodec_media_ops;

 >   +extern struct platform_driver mtk_vdec_comp_driver;



This may be useless... more on that later in this review.



 >     /*

 >    * mtk_vdec_lock/mtk_vdec_unlock are for ctx instance to

 > 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 dd749d41c75a..17cb3e3519eb 100644

 > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c

 > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c

 > @@ -18,19 +18,61 @@

 >     #include "mtk_vcodec_drv.h"

 >   #include "mtk_vcodec_dec.h"

 > +#include "mtk_vcodec_dec_hw.h"

 >   #include "mtk_vcodec_dec_pm.h"

 >   #include "mtk_vcodec_intr.h"

 > -#include "mtk_vcodec_util.h"

 >   #include "mtk_vcodec_fw.h"

 >   -#define VDEC_HW_ACTIVE    0x10

 > -#define VDEC_IRQ_CFG    0x11

 > -#define VDEC_IRQ_CLR    0x10

 > -#define VDEC_IRQ_CFG_REG    0xa4

 > -

 >   module_param(mtk_v4l2_dbg_level, int, 0644);

 >   module_param(mtk_vcodec_dbg, bool, 0644);

 >   +static struct of_device_id mtk_vdec_drv_ids[] = {

 > +    {

 > +        .compatible = "mediatek,mtk-vcodec-lat",

 > +        .data = (void *)MTK_VDEC_LAT0,

 > +    },

 > +    {

 > +        .compatible = "mediatek,mtk-vcodec-core",

 > +        .data = (void *)MTK_VDEC_CORE,

 > +    },

 > +    {},

 > +};



Is this a duplicate of "mtk_vdec_comp_ids", found in mtk_vcodec_dec_hw.c?!



 > +

 > +static int mtk_vcodec_comp_device_check(struct mtk_vcodec_ctx *ctx)

 > + {

 > +    struct mtk_vcodec_dev *vdec_dev = ctx->dev;

 > +    struct platform_device *pdev = vdec_dev->plat_dev;

 > +    struct device_node *comp_node;

 > +    enum mtk_vdec_hw_id comp_idx;

 > +    const struct of_device_id *of_id;

 > +    int i;

 > +

 > +    for (i = 0; i < ARRAY_SIZE(mtk_vdec_drv_ids); i++) {

 > +        of_id = &mtk_vdec_drv_ids[i];

 > +        comp_node = of_find_compatible_node(NULL, NULL,

 > +            of_id->compatible);

 > +        if (!comp_node)

 > +            continue;

 > +

 > +        if (!of_device_is_available(comp_node)) {

 > +            of_node_put(comp_node);

 > +            dev_err(&pdev->dev, "Fail to get MMSYS node\n");

 > +            continue;

 > +        }

 > +

 > +        comp_idx = (enum mtk_vdec_hw_id)of_id->data;

 > +        vdec_dev->component_node[comp_idx] = comp_node;

 > +

 > +        if (!test_bit(comp_idx, vdec_dev->hardware_bitmap)) {

 > +            dev_err(&pdev->dev, "Vdec comp_idx is not ready %d.",

 > +                comp_idx);

 > +            return -EINVAL;

 > +        }

 > +    }

 > +

 > +    return 0;

 > +}

 > +

 >   static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)

 >   {

 >       struct mtk_vcodec_dev *dev = priv;

 > @@ -95,6 +137,41 @@ static int mtk_vcodec_get_reg_bases(struct mtk_vcodec_dev *dev)

 >       return 0;

 >   }

 >   +static int mtk_vcodec_init_dec_params(struct mtk_vcodec_dev *dev)

 > +{

 > +    struct platform_device *pdev = dev->plat_dev;

 > +    int ret;

 > +

 > +    ret = mtk_vcodec_get_reg_bases(dev);

 > +    if (ret)

 > +        return ret;

 > +

 > +    if (!dev->vdec_pdata->is_comp_supported) {



component is never supported (is_comp_supported is always false), so this check

is useless.



 > +        dev->dec_irq = platform_get_irq(pdev, 0);

 > +        if (dev->dec_irq < 0) {

 > +            dev_err(&pdev->dev, "failed to get irq number");

 > +            return dev->dec_irq;

 > +        }

 > +

 > +        irq_set_status_flags(dev->dec_irq, IRQ_NOAUTOEN);

 > +        ret = devm_request_irq(&pdev->dev, dev->dec_irq,

 > +            mtk_vcodec_dec_irq_handler, 0, pdev->name, dev);

 > +        if (ret) {

 > +            dev_err(&pdev->dev, "failed to install dev->dec_irq %d (%d)",

 > +                dev->dec_irq, ret);

 > +            return ret;

 > +        }

 > +

 > +        ret = mtk_vcodec_init_dec_pm(pdev, &dev->pm);

 > +        if (ret < 0) {

 > +            dev_err(&pdev->dev, "failed to get mt vcodec clock source");

 > +            return ret;

 > +        }

 > +    }

 > +

 > +    return 0;

 > +}

 > +

 >   static int fops_vcodec_open(struct file *file)

 >   {

 >       struct mtk_vcodec_dev *dev = video_drvdata(file);

 > @@ -116,6 +193,12 @@ static int fops_vcodec_open(struct file *file)

 >       init_waitqueue_head(&ctx->queue);

 >       mutex_init(&ctx->lock);

 >   +    ret = mtk_vcodec_comp_device_check(ctx);



Are you checking available devices outside of a probe function?

 From what I can see, you require that the MMSYS device is available at this

time, but that's something that should be granted if we reach this point.



I would say that this driver probe should be deferred until the MMSYS device

becomes available, since it's required for this to work and since, once that

device gets registered and probed successfully, it'll never go away (unless

module unloaded, but you can't unload module A if module B is using it, or

depends on it, unless you also unload module B): like this, you will avoid

performing N useless checks, everytime the userspace opens the vdec device.



 > +    if (ret) {

 > +        mtk_v4l2_err("Failed to check vdec comp device.");

 > +        goto err_ctrls_setup;

 > +    }

 > +

 >       ctx->type = MTK_INST_DECODER;

 >       ret = dev->vdec_pdata->ctrls_setup(ctx);

 >       if (ret) {

 > @@ -220,7 +303,6 @@ 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 ret;

 > @@ -249,32 +331,10 @@ static int mtk_vcodec_probe(struct platform_device *pdev)

 >       if (IS_ERR(dev->fw_handler))

 >           return PTR_ERR(dev->fw_handler);

 >   -    ret = mtk_vcodec_init_dec_pm(dev->plat_dev, &dev->pm);

 > -    if (ret < 0) {

 > -        dev_err(&pdev->dev, "Failed to get mt vcodec clock source");

 > -        goto err_dec_pm;

 > -    }

 > -

 > -    ret = mtk_vcodec_get_reg_bases(dev);

 > -    if (ret)

 > -        goto err_res;

 > -

 > -    res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);

 > -    if (res == NULL) {

 > -        dev_err(&pdev->dev, "failed to get irq resource");

 > -        ret = -ENOENT;

 > -        goto err_res;

 > -    }

 > -

 > -    dev->dec_irq = platform_get_irq(pdev, 0);

 > -    irq_set_status_flags(dev->dec_irq, IRQ_NOAUTOEN);

 > -    ret = devm_request_irq(&pdev->dev, dev->dec_irq,

 > -            mtk_vcodec_dec_irq_handler, 0, pdev->name, dev);

 > +    ret = mtk_vcodec_init_dec_params(dev);

 >       if (ret) {

 > -        dev_err(&pdev->dev, "Failed to install dev->dec_irq %d (%d)",

 > -            dev->dec_irq,

 > -            ret);

 > -        goto err_res;

 > +        dev_err(&pdev->dev, "Failed to init pm and registers");

 > +        goto err_dec_pm;

 >       }

 >         mutex_init(&dev->dec_mutex);

 > @@ -329,6 +389,13 @@ static int mtk_vcodec_probe(struct platform_device *pdev)

 >           goto err_event_workq;

 >       }

 >   +    ret = of_platform_populate(pdev->dev.of_node, NULL, NULL,

 > +        &pdev->dev);

 > +    if (ret) {

 > +        mtk_v4l2_err("Master device of_platform_populate failed.");

 > +        goto err_event_workq;

 > +    }

 > +

 >       if (dev->vdec_pdata->uses_stateless_api) {

 >           dev->mdev_dec.dev = &pdev->dev;

 >           strscpy(dev->mdev_dec.model, MTK_VCODEC_DEC_NAME,

 > @@ -436,7 +503,25 @@ static struct platform_driver mtk_vcodec_dec_driver = {

 >       },

 >   };

 >   -module_platform_driver(mtk_vcodec_dec_driver);

 > +static struct platform_driver * const mtk_vdec_drivers[] = {

 > +    &mtk_vdec_comp_driver,

 > +    &mtk_vcodec_dec_driver,

 > +};



I would say that this is not a good idea, since you can simply register

your mtk_vdec_comp_driver in mtk_vcodec_dec_hw.c.



 > +

 > +static int __init mtk_vdec_init(void)

 > +{

 > +    return platform_register_drivers(mtk_vdec_drivers,

 > +                     ARRAY_SIZE(mtk_vdec_drivers));

 > +}

 > +

 > +static void __exit mtk_vdec_exit(void)

 > +{

 > +    platform_unregister_drivers(mtk_vdec_drivers,

 > +                    ARRAY_SIZE(mtk_vdec_drivers));

 > +}

 > +

 > +module_init(mtk_vdec_init);

 > +module_exit(mtk_vdec_exit);

 >     MODULE_LICENSE("GPL v2");

 >   MODULE_DESCRIPTION("Mediatek video codec V4L2 decoder driver");

 > diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c 
b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c

 > new file mode 100644

 > index 000000000000..3752ccaea284

 > --- /dev/null

 > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c

 > @@ -0,0 +1,165 @@

 > +// SPDX-License-Identifier: GPL-2.0

 > +/*

 > + * Copyright (c) 2021 MediaTek Inc.

 > + * Author: Yunfei Dong <yunfei.dong@mediatek.com>

 > + */

 > +

 > +#include <linux/interrupt.h>

 > +#include <linux/irq.h>

 > +#include <linux/module.h>

 > +#include <linux/of.h>

 > +#include <linux/of_device.h>

 > +#include <linux/slab.h>

 > +

 > +#include "mtk_vcodec_drv.h"

 > +#include "mtk_vcodec_dec.h"

 > +#include "mtk_vcodec_dec_hw.h"

 > +#include "mtk_vcodec_dec_pm.h"

 > +#include "mtk_vcodec_intr.h"

 > +#include "mtk_vcodec_util.h"

 > +

 > +static const struct of_device_id mtk_vdec_comp_ids[] = {

 > +    {

 > +        .compatible = "mediatek,mtk-vcodec-lat",

 > +    },

 > +    {

 > +        .compatible = "mediatek,mtk-vcodec-core",

 > +    },

 > +    {},

 > +};



I think that you forgot some ".data = " here...



 > +

 > +static irqreturn_t mtk_vdec_comp_irq_handler(int irq, void *priv)

 > +{

 > +    struct mtk_vdec_comp_dev *dev = priv;

 > +    struct mtk_vcodec_ctx *ctx;

 > +    u32 cg_status;

 > +    unsigned int dec_done_status;

 > +    void __iomem *vdec_misc_addr = dev->reg_base[VDEC_COMP_MISC] +

 > +                    VDEC_IRQ_CFG_REG;

 > +

 > +    ctx = mtk_vcodec_get_curr_ctx(dev->master_dev);

 > +

 > +    /* check if HW active or not */

 > +    cg_status = readl(dev->reg_base[VDEC_COMP_SYS]);

 > +    if ((cg_status & VDEC_HW_ACTIVE) != 0) {



The "!= 0" can be dropped here, since cg_status is unsigned.



 > +        mtk_v4l2_err("vdec active is not 0x0 (0x%08x)",

 > +            cg_status);

 > +        return IRQ_HANDLED;

 > +    }

 > +

 > +    dec_done_status = readl(vdec_misc_addr);

 > +    if ((dec_done_status & MTK_VDEC_IRQ_STATUS_DEC_SUCCESS) !=

 > +        MTK_VDEC_IRQ_STATUS_DEC_SUCCESS)



I suggest to fix the indentation here to increase human readability, like so:



     if ((dec_done_status & MTK_VDEC_IRQ_STATUS_DEC_SUCCESS) !=



         MTK_VDEC_IRQ_STATUS_DEC_SUCCESS)





 > +        return IRQ_HANDLED;

 > +

 > +    /* clear interrupt */

 > +    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);

 > +

 > +    mtk_v4l2_debug(3, "wake up ctx %d, dec_done_status=%x",

 > +        ctx->id, dec_done_status);

 > +

 > +    return IRQ_HANDLED;

 > +}

 > +

 > +static int mtk_vdec_comp_init_irq(struct mtk_vdec_comp_dev *dev)

 > +{

 > +    struct platform_device *pdev = dev->plat_dev;

 > +    int ret;

 > +

 > +    dev->dec_irq = platform_get_irq(pdev, 0);

 > +    if (dev->dec_irq < 0) {

 > +        dev_err(&pdev->dev, "Failed to get irq resource");

 > +        return dev->dec_irq;

 > +    }

 > +

 > +    irq_set_status_flags(dev->dec_irq, IRQ_NOAUTOEN);

 > +    ret = devm_request_irq(&pdev->dev, dev->dec_irq,

 > +                mtk_vdec_comp_irq_handler, 0, pdev->name, dev);

 > +    if (ret) {

 > +        dev_err(&pdev->dev, "Failed to install dev->dec_irq %d (%d)",

 > +            dev->dec_irq, ret);

 > +        return ret;

 > +    }

 > +

 > +    return 0;

 > +}

 > +

 > +static int mtk_vdec_comp_probe(struct platform_device *pdev)

 > +{

 > +    struct device *dev = &pdev->dev;

 > +    struct mtk_vdec_comp_dev *comp_dev;

 > +    struct mtk_vcodec_dev *master_dev;

 > +    const struct of_device_id *of_id;

 > +    int comp_idx;

 > +    int ret;

 > +

 > +    if (!dev->parent) {

 > +        dev_err(dev, "Vdec parent prob is not ready.");



This is not an error, since it's not a "critical" error, until it becomes one (so,

after max deferral count has been reached).

I would remove this message entirely, however, if you really want this message to

be here, you should use dev_dbg.



 > +        return -EPROBE_DEFER;

 > +    }

 > +

 > +    master_dev = dev_get_drvdata(dev->parent);

 > +    if (!master_dev) {

 > +        dev_err(dev, "Failed to get master device.");



Same here.



 > +        return -EPROBE_DEFER;

 > +    }

 > +

 > +    comp_dev = devm_kzalloc(dev, sizeof(*comp_dev), GFP_KERNEL);

 > +    if (!comp_dev)

 > +        return -ENOMEM;

 > +

 > +    comp_dev->plat_dev = pdev;

 > +    ret = mtk_vcodec_init_dec_pm(pdev, &comp_dev->pm);

 > +    if (ret) {

 > +        dev_err(dev, "Failed to get mt vcodec clock source.");



As far as I can see, you have failure prints all over in function 
mtk_vcodec_init_dec_pm, so there's no need to add another print here:

you can simply return the error value here.



 > +        return ret;

 > +    }

 > +

 > +    comp_dev->reg_base[VDEC_COMP_MISC] =

 > +        devm_platform_ioremap_resource_byname(pdev, "reg-misc");

 > +    if (IS_ERR((__force void *)comp_dev->reg_base[VDEC_COMP_MISC])) {

 > +        ret = PTR_ERR((__force void *)comp_dev->reg_base[VDEC_COMP_MISC]);

 > +        goto err;

 > +    }

 > +

 > +    ret = mtk_vdec_comp_init_irq(comp_dev);

 > +    if (ret) {

 > +        dev_err(dev, "Failed to register irq handler.\n");

 > +        goto err;

 > +    }



...and the same applies here: mtk_vdec_comp_init_irq already prints on its own.



 > +

 > +    of_id = of_match_device(mtk_vdec_comp_ids, dev);

 > +    if (!of_id) {

 > +        dev_err(dev, "Can't get vdec comp device id.\n");

 > +        ret = -EINVAL;

 > +        goto err;

 > +    }

 > +

 > +    comp_idx = (enum mtk_vdec_hw_id)of_id->data;



Are you sure that this one is working as expected?

The only driver that registers compatibles mediatek,mtk-vcodec-lat and

mediatek,mtk-vcodec-core is exactly this one, but there's no .data assigned

to any of the of_device_id entries... and this means that your of_id->data

will not contain the expected value of type enum mtk_vdec_hw_id.



 > +    if (comp_idx < MTK_VDEC_HW_MAX) {

 > +        master_dev->comp_dev[comp_idx] = comp_dev;

 > +        comp_dev->comp_idx = comp_idx;

 > +        comp_dev->master_dev = master_dev;

 > +        comp_dev->reg_base[VDEC_COMP_SYS] =

 > +            master_dev->reg_base[VDEC_COMP_SYS];

 > +        set_bit(comp_dev->comp_idx, master_dev->hardware_bitmap);

 > +    }

 > +

 > +    platform_set_drvdata(pdev, comp_dev);

 > +    return 0;

 > +err:

 > +    mtk_vcodec_release_dec_pm(&comp_dev->pm);

 > +    return ret;

 > +}

 > +

 > +MODULE_DEVICE_TABLE(of, mtk_vdec_comp_ids);

 > +struct platform_driver mtk_vdec_comp_driver = {



The `_comp` here is a name that's making a logical reference to that: in this case,



that may confuse developers around. Can you please drop that `_comp`?



That would become `mtk_vdec_driver` instead.





Logically, the same applies for the rest - always assuming that it's referencing to

the Linux component API.



 > +    .probe    = mtk_vdec_comp_probe,

 > +    .driver    = {

 > +        .name    = "mtk-vdec-comp",

 > +        .of_match_table = mtk_vdec_comp_ids,

 > +    },

 > +};



Since you're using of_platform_populate, there is no need to register this driver

externally: you can simply register it here (module_platform_driver) and it will

be probed at of_platform_populate time in your parent.



 > diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h 
b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h

 > new file mode 100644

 > index 000000000000..8d6e818a3474

 > --- /dev/null

 > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h

 > @@ -0,0 +1,49 @@

 > +// SPDX-License-Identifier: GPL-2.0

 > +/*

 > + * Copyright (c) 2021 MediaTek Inc.

 > + * Author: Yunfei Dong <yunfei.dong@mediatek.com>

 > + */

 > +

 > +#ifndef _MTK_VCODEC_DEC_HW_H_

 > +#define _MTK_VCODEC_DEC_HW_H_

 > +

 > +#include <linux/io.h>

 > +#include <linux/platform_device.h>

 > +

 > +#include "mtk_vcodec_drv.h"

 > +

 > +#define VDEC_HW_ACTIVE    0x10

 > +#define VDEC_IRQ_CFG    0x11

 > +#define VDEC_IRQ_CLR    0x10

 > +#define VDEC_IRQ_CFG_REG    0xa4



Cosmetic nitpick: either all values in the same column, or simply use a space

instead of tabulations.



 > +

 > +/**

 > + * enum mtk_comp_hw_reg_idx - component register base index

 > + */

 > +enum mtk_comp_hw_reg_idx {

 > +    VDEC_COMP_SYS,

 > +    VDEC_COMP_MISC,

 > +    VDEC_COMP_MAX

 > +};

 > +

 > +/**

 > + * struct mtk_vdec_comp_dev - component framwork driver data



You've switched away from the component framework... so this structure's

description seems to be a bit misleading now...



 > + * @plat_dev: platform device

 > + * @master_dev: master device

 > + * @reg_base: Mapped address of MTK Vcodec registers.

 > + *

 > + * @dec_irq: decoder irq resource

 > + * @pm: power management control

 > + * @comp_idx: component index

 > + */

 > +struct mtk_vdec_comp_dev {

 > +    struct platform_device *plat_dev;

 > +    struct mtk_vcodec_dev *master_dev;

 > +    void __iomem *reg_base[VDEC_COMP_MAX];

 > +

 > +    int dec_irq;

 > +    struct mtk_vcodec_pm pm;

 > +    int comp_idx;

 > +};

 > +

 > +#endif /* _MTK_VCODEC_DEC_HW_H_ */

 > diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c 
b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c

 > index 59c24b22ab6d..4f9a80ce15d8 100644

 > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c

 > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c

 > @@ -623,4 +623,5 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata = {

 >       .num_framesizes = NUM_SUPPORTED_FRAMESIZE,

 >       .worker = mtk_vdec_worker,

 >       .flush_decoder = mtk_vdec_flush_decoder,

 > +    .is_comp_supported = false,

 >   };

 > diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c 
b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c

 > index 8f4a1f0a0769..762633572b49 100644

 > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c

 > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c

 > @@ -357,4 +357,5 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {

 >       .uses_stateless_api = true,

 >       .worker = mtk_vdec_worker,

 >       .flush_decoder = mtk_vdec_flush_decoder,

 > +    .is_comp_supported = false,



component is not supported anywhere, since you've switched away from it?!



 >   };

 > diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h 
b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h

 > index 973b0b3649c6..ec3850b4c638 100644

 > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h

 > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h

 > @@ -93,6 +93,17 @@ enum mtk_fmt_type {

 >       MTK_FMT_FRAME = 2,

 >   };

 >   +/**

 > + * struct mtk_vdec_hw_id - Hardware index used to separate

 > + *                         different hardware

 > + */

 > +enum mtk_vdec_hw_id {

 > +    MTK_VDEC_CORE,

 > +    MTK_VDEC_LAT0,

 > +    MTK_VDEC_LAT1,

 > +    MTK_VDEC_HW_MAX,

 > +};

 > +

 >   /*

 >    * struct mtk_video_fmt - Structure used to store information about pixelformats

 >    */

 > @@ -331,6 +342,7 @@ enum mtk_chip {

 >    *

 >    * @chip: chip this decoder is compatible with

 >    *

 > + * @is_comp_supported: true: using compoent framework, false: not support

 >    * @uses_stateless_api: whether the decoder uses the stateless API with requests

 >    */

 >   @@ -352,6 +364,7 @@ struct mtk_vcodec_dec_pdata {

 >         enum mtk_chip chip;

 >   +    bool is_comp_supported;



Adding this member looks useless: there's nothing declaring is_comp_supported as

true... not here, not in any other patch of this entire series!





Regards,

- Angelo




-- 
AngeloGioacchino Del Regno
Software Engineer

Collabora Ltd.
Platinum Building, St John's Innovation Park, Cambridge CB4 0DS, UK
Registered in England & Wales, no. 5513718

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v7, 07/15] media: mtk-vcodec: Add irq interface for multi hardware
  2021-10-11  7:02 ` [PATCH v7, 07/15] media: mtk-vcodec: Add irq interface for multi hardware Yunfei Dong
@ 2021-10-14 10:04   ` AngeloGioacchino Del Regno
  2021-10-27 11:36     ` yunfei.dong
  0 siblings, 1 reply; 43+ messages in thread
From: AngeloGioacchino Del Regno @ 2021-10-14 10:04 UTC (permalink / raw)
  To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

> Adds irq interface for multi hardware.
> 
> Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
> ---
>   .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 33 +++++++++++++++++--
>   .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   |  2 +-
>   .../platform/mtk-vcodec/mtk_vcodec_drv.h      | 25 ++++++++++----
>   .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |  4 +--
>   .../platform/mtk-vcodec/mtk_vcodec_intr.c     | 27 +++++++--------
>   .../platform/mtk-vcodec/mtk_vcodec_intr.h     |  4 +--
>   .../platform/mtk-vcodec/vdec/vdec_h264_if.c   |  2 +-
>   .../mtk-vcodec/vdec/vdec_h264_req_if.c        |  2 +-
>   .../platform/mtk-vcodec/vdec/vdec_vp8_if.c    |  2 +-
>   .../platform/mtk-vcodec/vdec/vdec_vp9_if.c    |  2 +-
>   .../platform/mtk-vcodec/venc/venc_h264_if.c   |  2 +-
>   .../platform/mtk-vcodec/venc/venc_vp8_if.c    |  2 +-
>   12 files changed, 71 insertions(+), 36 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 17cb3e3519eb..ff70fa5b34e3 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
> @@ -73,6 +73,20 @@ static int mtk_vcodec_comp_device_check(struct mtk_vcodec_ctx *ctx)
>   	return 0;
>   }
>   
> +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("not support hw arch:%d",
> +			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;
> @@ -104,7 +118,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",
> @@ -176,7 +190,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);
> @@ -190,7 +204,19 @@ 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);
> +
> +	if (ctx->dev->vdec_pdata->is_comp_supported) {

As pointed out in the review for patch 04/15 of this series, is_comp_supported
is always false since you moved away from the component framework.

That means that this code can be removed, as nothing ever hits that.

Please note that other patches in this series are following similar/same patterns,
so this comment applies to the entire series.

> +		hw_count = mtk_vcodec_get_hw_count(dev);
> +		if (!hw_count) {
> +			ret = -EINVAL;
> +			goto err_init_queue;
> +		}
> +		for (i = 0; i < hw_count; i++)
> +			init_waitqueue_head(&ctx->queue[i]);
> +	} else {
> +			init_waitqueue_head(&ctx->queue[0]);
> +	}
> +
>   	mutex_init(&ctx->lock);
>   
>   	ret = mtk_vcodec_comp_device_check(ctx);
> @@ -253,6 +279,7 @@ static int fops_vcodec_open(struct file *file)
>   err_m2m_ctx_init:
>   	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
>   err_ctrls_setup:
> +err_init_queue:

...and if that unused component code gets removed, this label can also be removed.

>   	v4l2_fh_del(&ctx->fh);
>   	v4l2_fh_exit(&ctx->fh);
>   	kfree(ctx);
> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
> index 3752ccaea284..0997a5a08156 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
> @@ -56,7 +56,7 @@ static irqreturn_t mtk_vdec_comp_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->comp_idx);
>   
>   	mtk_v4l2_debug(3, "wake up ctx %d, dec_done_status=%x",
>   		ctx->id, dec_done_status);
> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> index 140f1a761942..f8e8b5ba408b 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> @@ -104,6 +104,16 @@ enum mtk_vdec_hw_id {
>   	MTK_VDEC_HW_MAX,
>   };
>   
> +/**
> + * struct 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;
> @@ -505,11 +515,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_ */
> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
> index 2828df77020c..c7540c0cdcea 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
> @@ -114,7 +114,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;
>   }
>   
> @@ -140,7 +140,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);
> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c
> index 70580c2525ba..8147533da98b 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c
> @@ -11,34 +11,31 @@
>   #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 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,
> +	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;
>   }
> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h
> index 638cd1f3526a..2bf4cabfaa43 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h
> @@ -12,7 +12,7 @@
>   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_ */
> diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c
> index 40d6e6c5ac7a..481655bb6016 100644
> --- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c
> +++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c
> @@ -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;
>   
> diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
> index 4dde9ee786b4..d23baa364246 100644
> --- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
> +++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
> @@ -724,7 +724,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);
> diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c
> index e5393f841080..88c046731754 100644
> --- a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c
> +++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c
> @@ -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);
> diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c
> index 71cdc3ddafcb..70b8383f7c8e 100644
> --- a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c
> +++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c
> @@ -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;
> diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
> index b6a4f2074fa5..9ae1bd8dbc32 100644
> --- a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
> +++ b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
> @@ -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);
>   	}
> diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
> index 8267a9c4fd25..f96564277577 100644
> --- a/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
> +++ b/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
> @@ -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);
>   	}
> 

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v7, 08/15] media: mtk-vcodec: Add msg queue feature for lat and core architecture
  2021-10-11  7:02 ` [PATCH v7, 08/15] media: mtk-vcodec: Add msg queue feature for lat and core architecture Yunfei Dong
@ 2021-10-14 10:35   ` AngeloGioacchino Del Regno
  2021-10-27  4:01     ` yunfei.dong
  0 siblings, 1 reply; 43+ messages in thread
From: AngeloGioacchino Del Regno @ 2021-10-14 10:35 UTC (permalink / raw)
  To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

> For lat and core architecture, lat thread will send message to core
> thread when lat decode done. Core hardware will use the message
> from lat to decode, then free message to lat thread when decode done.
> 
> Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
> ---
>   drivers/media/platform/mtk-vcodec/Makefile    |   1 +
>   .../platform/mtk-vcodec/mtk_vcodec_drv.h      |   5 +
>   .../platform/mtk-vcodec/vdec_msg_queue.c      | 258 ++++++++++++++++++
>   .../platform/mtk-vcodec/vdec_msg_queue.h      | 151 ++++++++++
>   4 files changed, 415 insertions(+)
>   create mode 100644 drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
>   create mode 100644 drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
> 
> diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
> index edeb3b66e9e9..5000e59da576 100644
> --- a/drivers/media/platform/mtk-vcodec/Makefile
> +++ b/drivers/media/platform/mtk-vcodec/Makefile
> @@ -11,6 +11,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
>   		mtk_vcodec_dec_drv.o \
>   		vdec_drv_if.o \
>   		vdec_vpu_if.o \
> +		vdec_msg_queue.o \
>   		mtk_vcodec_dec.o \
>   		mtk_vcodec_dec_stateful.o \
>   		mtk_vcodec_dec_stateless.o \
> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> index f8e8b5ba408b..ab401b2db30e 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> @@ -15,7 +15,9 @@
>   #include <media/v4l2-ioctl.h>
>   #include <media/v4l2-mem2mem.h>
>   #include <media/videobuf2-core.h>
> +
>   #include "mtk_vcodec_util.h"
> +#include "vdec_msg_queue.h"
>   
>   #define MTK_VCODEC_DRV_NAME	"mtk_vcodec_drv"
>   #define MTK_VCODEC_DEC_NAME	"mtk-vcodec-dec"
> @@ -282,6 +284,8 @@ struct vdec_pic_info {
>    * @decoded_frame_cnt: number of decoded frames
>    * @lock: protect variables accessed by V4L2 threads and worker thread such as
>    *	  mtk_video_dec_buf.
> + *
> + * @msg_queue: msg queue used to store lat buffer information.
>    */
>   struct mtk_vcodec_ctx {
>   	enum mtk_instance_type type;
> @@ -325,6 +329,7 @@ struct mtk_vcodec_ctx {
>   	int decoded_frame_cnt;
>   	struct mutex lock;
>   
> +	struct vdec_msg_queue msg_queue;
>   };
>   
>   enum mtk_chip {
> diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
> new file mode 100644
> index 000000000000..d66ed98c79a9
> --- /dev/null
> +++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
> @@ -0,0 +1,258 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2021 MediaTek Inc.
> + * Author: Yunfei Dong <yunfei.dong@mediatek.com>
> + */
> +
> +#include <linux/freezer.h>
> +#include <linux/interrupt.h>
> +#include <linux/kthread.h>
> +
> +#include "mtk_vcodec_dec_pm.h"
> +#include "mtk_vcodec_drv.h"
> +#include "vdec_msg_queue.h"
> +
> +#define VDEC_LAT_SLICE_HEADER_SZ    (640 * 1024)

This can be 640 * SZ_1K, or 5 * SZ_128K....
...if applicable, please multiply as value * alignment, such that, for example,
if the data needs to be 1K aligned, you should prefer writing it as 640 * SZ_1K.

> +#define VDEC_ERR_MAP_SZ_AVC         ((8192 / 16) * (4352 / 16) / 8)

...and you could do the same here... except, I see some sizes here being divided
and multiplied and I take that as a hint.
In that case, when you convert it to use sizes definitions, it would be very nice
if you keep that hint / better describe it in a comment.

> +
> +/* lat write decoded hardware information to trans buffer,
> + * and core will read the trans buffer to decode again. The
> + * trans buffer size of FHD and 4K bitstreams are different.
> + */
> +static int vde_msg_queue_get_trans_size(int width, int height)
> +{
> +	if (width > 1920 || height > 1088)
> +		return (30 * 1024 * 1024);

So here we're referring to buffer sizes. 1024 * 1024 is SZ_1M, as defined in
linux/sizes.h.

Means that this can be simply

		return 30 * SZ_1M;

> +	else
> +		return 6 * 1024 * 1024;

		return 6 * SZ_1M;

> +}
> +
> +void vdec_msg_queue_init_ctx(struct vdec_msg_queue_ctx *ctx,
> +	int hardware_index)
> +{
> +	init_waitqueue_head(&ctx->ready_to_use);
> +	INIT_LIST_HEAD(&ctx->ready_queue);
> +	spin_lock_init(&ctx->ready_lock);
> +	ctx->ready_num = 0;
> +	ctx->hardware_index = hardware_index;
> +}
> +
> +int vdec_msg_queue_init(
> +	struct vdec_msg_queue *msg_queue,
> +	struct mtk_vcodec_ctx *ctx,
> +	core_decode_cb_t core_decode,
> +	int private_size)
> +{
> +	struct vdec_lat_buf *lat_buf;
> +	int i, err;
> +
> +	/* already init msg queue */
> +	if (msg_queue->wdma_addr.size)
> +		return 0;
> +
> +	vdec_msg_queue_init_ctx(&msg_queue->lat_ctx, MTK_VDEC_LAT0);
> +	msg_queue->wdma_addr.size = vde_msg_queue_get_trans_size(
> +		ctx->picinfo.buf_w, ctx->picinfo.buf_h);
> +
> +	err = mtk_vcodec_mem_alloc(ctx, &msg_queue->wdma_addr);
> +	if (err) {
> +		mtk_v4l2_err("failed to allocate wdma_addr buf");
> +		return -ENOMEM;
> +	}
> +	msg_queue->wdma_rptr_addr = msg_queue->wdma_addr.dma_addr;
> +	msg_queue->wdma_wptr_addr = msg_queue->wdma_addr.dma_addr;
> +
> +	for (i = 0; i < NUM_BUFFER_COUNT; i++) {
> +		lat_buf = &msg_queue->lat_buf[i];
> +
> +		lat_buf->wdma_err_addr.size = VDEC_ERR_MAP_SZ_AVC;
> +		err = mtk_vcodec_mem_alloc(ctx, &lat_buf->wdma_err_addr);
> +		if (err) {
> +			mtk_v4l2_err("failed to allocate wdma_err_addr buf[%d]", i);
> +			goto mem_alloc_err;
> +		}
> +
> +		lat_buf->slice_bc_addr.size = VDEC_LAT_SLICE_HEADER_SZ;
> +		err = mtk_vcodec_mem_alloc(ctx, &lat_buf->slice_bc_addr);
> +		if (err) {
> +			mtk_v4l2_err("failed to allocate wdma_addr buf[%d]", i);
> +			goto mem_alloc_err;
> +		}
> +
> +		lat_buf->private_data = kzalloc(private_size, GFP_KERNEL);
> +		if (!lat_buf->private_data) {
> +			mtk_v4l2_err("failed to allocate private_data[%d]", i);
> +			goto mem_alloc_err;
> +		}
> +
> +		lat_buf->ctx = ctx;
> +		lat_buf->core_decode = core_decode;
> +		vdec_msg_queue_qbuf(&msg_queue->lat_ctx, lat_buf);
> +	}
> +	return 0;
> +
> +mem_alloc_err:
> +	vdec_msg_queue_deinit(msg_queue, ctx);
> +	return -ENOMEM;
> +}
> +
> +static struct list_head *vdec_get_buf_list(int hardware_index,
> +	struct vdec_lat_buf *buf)
> +{
> +	switch (hardware_index) {
> +	case MTK_VDEC_CORE:
> +		return &buf->core_list;
> +	case MTK_VDEC_LAT0:
> +		return &buf->lat_list;
> +	default:
> +		return NULL;
> +	}
> +}
> +
> +void vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *ctx,
> +	struct vdec_lat_buf *buf)
> +{
> +	struct list_head *head;
> +
> +	head = vdec_get_buf_list(ctx->hardware_index, buf);
> +	if (!head) {
> +		mtk_v4l2_err("fail to qbuf: %d",ctx->hardware_index);
> +		return;
> +	}
> +
> +	spin_lock(&ctx->ready_lock);
> +	list_add_tail(head, &ctx->ready_queue);
> +	ctx->ready_num++;
> +
> +	wake_up_all(&ctx->ready_to_use);
> +
> +	mtk_v4l2_debug(3, "enqueue buf type: %d addr: 0x%p num: %d",
> +		ctx->hardware_index, buf, ctx->ready_num);
> +	spin_unlock(&ctx->ready_lock);
> +}
> +
> +static bool vdec_msg_queue_wait_event(struct vdec_msg_queue_ctx *ctx)
> +{
> +	long timeout_jiff;
> +	int ret;
> +
> +	if (ctx->hardware_index == MTK_VDEC_CORE) {
> +		ret = wait_event_freezable(ctx->ready_to_use,
> +			!list_empty(&ctx->ready_queue));
> +		if (ret)
> +			return false;
> +	} else {
> +		timeout_jiff = msecs_to_jiffies(1500);
> +		ret = wait_event_timeout(ctx->ready_to_use,
> +			!list_empty(&ctx->ready_queue), timeout_jiff);

Suggestion (feel free to not follow this one): since you're using that
msecs_to_jiffies(1500) return value only for this wait_event_timeout call,
you may as well remove the timeout_jiff variable and simply do

		ret = wait_event_timeout(ctx->ready_to_use,

					 !list_empty(&ctx->ready_queue),
					 msecs_to_jiffies(1500));

> +		if (!ret)
> +			return false;
> +	}
> +
> +	return true;
> +}
> +
> +struct vdec_lat_buf *vdec_msg_queue_dqbuf(struct vdec_msg_queue_ctx *ctx)
> +{
> +	struct vdec_lat_buf *buf;
> +	struct list_head *head;
> +	int ret;
> +
> +	spin_lock(&ctx->ready_lock);
> +	if (list_empty(&ctx->ready_queue)) {
> +		mtk_v4l2_debug(3, "queue is NULL, type:%d num: %d",
> +			ctx->hardware_index, ctx->ready_num);
> +		spin_unlock(&ctx->ready_lock);
> +		ret = vdec_msg_queue_wait_event(ctx);
> +		if (!ret)
> +			return NULL;
> +		spin_lock(&ctx->ready_lock);
> +	}
> +
> +	if (ctx->hardware_index == MTK_VDEC_CORE)
> +		buf = list_first_entry(&ctx->ready_queue,
> +			struct vdec_lat_buf, core_list);
> +	else
> +		buf = list_first_entry(&ctx->ready_queue,
> +			struct vdec_lat_buf, lat_list);
> +
> +	head = vdec_get_buf_list(ctx->hardware_index, buf);
> +	if (!head) {
> +		mtk_v4l2_err("fail to dqbuf: %d",ctx->hardware_index);
> +		return NULL;
> +	}
> +	list_del(head);
> +
> +	ctx->ready_num--;
> +	mtk_v4l2_debug(3, "dqueue buf type:%d addr: 0x%p num: %d",
> +		ctx->hardware_index, buf, ctx->ready_num);
> +	spin_unlock(&ctx->ready_lock);
> +
> +	return buf;
> +}
> +
> +void vdec_msg_queue_update_ube_rptr(struct vdec_msg_queue *msg_queue,
> +	uint64_t ube_rptr)
> +{
> +	spin_lock(&msg_queue->lat_ctx.ready_lock);
> +	msg_queue->wdma_rptr_addr = ube_rptr;
> +	mtk_v4l2_debug(3, "update ube rprt (0x%llx)", ube_rptr);
> +	spin_unlock(&msg_queue->lat_ctx.ready_lock);
> +}
> +
> +void vdec_msg_queue_update_ube_wptr(struct vdec_msg_queue *msg_queue,
> +	uint64_t ube_wptr)
> +{
> +	spin_lock(&msg_queue->lat_ctx.ready_lock);
> +	msg_queue->wdma_wptr_addr = ube_wptr;
> +	mtk_v4l2_debug(3, "update ube wprt: (0x%llx 0x%llx) offset: 0x%llx",
> +		msg_queue->wdma_rptr_addr, msg_queue->wdma_wptr_addr, ube_wptr);
> +	spin_unlock(&msg_queue->lat_ctx.ready_lock);
> +}
> +
> +bool vdec_msg_queue_wait_lat_buf_full(struct vdec_msg_queue *msg_queue)
> +{
> +	long timeout_jiff;
> +	int ret;
> +
> +	timeout_jiff = msecs_to_jiffies(1000 * (NUM_BUFFER_COUNT + 2));
> +
> +	ret = wait_event_timeout(msg_queue->lat_ctx.ready_to_use,
> +		msg_queue->lat_ctx.ready_num == NUM_BUFFER_COUNT,
> +		timeout_jiff);
> +	if (ret) {
> +		mtk_v4l2_debug(3, "success to get lat buf: %d",
> +			msg_queue->lat_ctx.ready_num);
> +		return true;
> +	}
> +	mtk_v4l2_err("failed with lat buf isn't full: %d",
> +		msg_queue->lat_ctx.ready_num);
> +	return false;
> +}
> +
> +void vdec_msg_queue_deinit(
> +	struct vdec_msg_queue *msg_queue,
> +	struct mtk_vcodec_ctx *ctx)
> +{
> +	struct vdec_lat_buf *lat_buf;
> +	struct mtk_vcodec_mem *mem;
> +	int i;
> +
> +	mem = &msg_queue->wdma_addr;
> +	if (mem->va)
> +		mtk_vcodec_mem_free(ctx, mem);
> +	for (i = 0; i < NUM_BUFFER_COUNT; i++) {
> +		lat_buf = &msg_queue->lat_buf[i];
> +
> +		mem = &lat_buf->wdma_err_addr;
> +		if (mem->va)
> +			mtk_vcodec_mem_free(ctx, mem);
> +
> +		mem = &lat_buf->slice_bc_addr;
> +		if (mem->va)
> +			mtk_vcodec_mem_free(ctx, mem);
> +
> +		if (lat_buf->private_data)
> +			kfree(lat_buf->private_data);
> +	}
> +}
> diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
> new file mode 100644
> index 000000000000..1905ce713592
> --- /dev/null
> +++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
> @@ -0,0 +1,151 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2021 MediaTek Inc.
> + * Author: Yunfei Dong <yunfei.dong@mediatek.com>
> + */
> +
> +#ifndef _VDEC_MSG_QUEUE_H_
> +#define _VDEC_MSG_QUEUE_H_
> +
> +#include <linux/sched.h>
> +#include <linux/semaphore.h>
> +#include <linux/slab.h>
> +#include <media/videobuf2-v4l2.h>
> +
> +#include "mtk_vcodec_util.h"
> +
> +#define NUM_BUFFER_COUNT 3
> +
> +struct vdec_lat_buf;
> +struct mtk_vcodec_ctx;
> +struct mtk_vcodec_dev;
> +typedef int (*core_decode_cb_t)(struct vdec_lat_buf *lat_buf);
> +
> +/**
> + * struct vdec_msg_queue_ctx - represents a queue for buffers ready to be
> + *	                           processed

I would prefer if you don't break this line, 84 columns is fine to have.

> + * @ready_used: ready used queue used to signalize when get a job queue
> + * @ready_queue: list of ready lat buffer queues
> + * @ready_lock: spin lock to protect the lat buffer usage
> + * @ready_num: number of buffers ready to be processed
> + * @hardware_index: hardware id that this queue is used for
> + */
> +struct vdec_msg_queue_ctx {
> +	wait_queue_head_t ready_to_use;
> +	struct list_head ready_queue;
> +	spinlock_t ready_lock;
> +	int ready_num;
> +	int hardware_index;
> +};
> +
> +/**
> + * struct vdec_lat_buf - lat buffer message used to store lat
> + *                       info for core decode
> + * @wdma_err_addr: wdma error address used for lat hardware
> + * @slice_bc_addr: slice bc address used for lat hardware
> + * @ts_info: need to set timestamp from output to capture
> + *
> + * @private_data: shared information used to lat and core hardware
> + * @ctx: mtk vcodec context information
> + * @core_decode: different codec use different decode callback function
> + * @lat_list: add lat buffer to lat head list
> + * @core_list: add lat buffer to core head list
> + */
> +struct vdec_lat_buf {
> +	struct mtk_vcodec_mem wdma_err_addr;
> +	struct mtk_vcodec_mem slice_bc_addr;
> +	struct vb2_v4l2_buffer ts_info;
> +
> +	void *private_data;
> +	struct mtk_vcodec_ctx *ctx;
> +	core_decode_cb_t core_decode;
> +	struct list_head lat_list;
> +	struct list_head core_list;
> +};
> +
> +/**
> + * struct vdec_msg_queue - used to store lat buffer message
> + * @lat_buf: lat buffer used to store lat buffer information
> + * @wdma_addr: wdma address used for ube
> + * @wdma_rptr_addr: ube read point
> + * @wdma_wptr_addr: ube write point
> + * @lat_ctx: used to store lat buffer list
> + */
> +struct vdec_msg_queue {
> +	struct vdec_lat_buf lat_buf[NUM_BUFFER_COUNT];
> +
> +	struct mtk_vcodec_mem wdma_addr;
> +	uint64_t wdma_rptr_addr;
> +	uint64_t wdma_wptr_addr;
> +
> +	struct vdec_msg_queue_ctx lat_ctx;
> +};
> +
> +/**
> + * vdec_msg_queue_init - init lat buffer information.
> + * @msg_queue: used to store the lat buffer information
> + * @ctx: v4l2 ctx
> + * @core_decode: core decode callback for each codec
> + * @private_size: the private data size used to share with core
> + */
> +int vdec_msg_queue_init(
> +	struct vdec_msg_queue *msg_queue,
> +	struct mtk_vcodec_ctx *ctx,
> +	core_decode_cb_t core_decode,
> +	int private_size);
> +
> +/**
> + * vdec_msg_queue_init_ctx - used to init msg queue context information.
> + * @ctx: message queue context
> + * @hardware_index: hardware index
> + */
> +void vdec_msg_queue_init_ctx(struct vdec_msg_queue_ctx *ctx,
> +	int hardware_index);
> +
> +/**
> + * vdec_msg_queue_qbuf - enqueue lat buffer to queue list.
> + * @ctx: message queue context
> + * @buf: current lat buffer
> + */
> +void vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *ctx,
> +	struct vdec_lat_buf *buf);
> +
> +/**
> + * vdec_msg_queue_dqbuf - dequeue lat buffer from queue list.
> + * @ctx: message queue context
> + */
> +struct vdec_lat_buf *vdec_msg_queue_dqbuf(struct vdec_msg_queue_ctx *ctx);
> +
> +/**
> + * vdec_msg_queue_update_ube_rptr - used to updata the ube read point.
> + * @msg_queue: used to store the lat buffer information
> + * @ube_rptr: current ube read point
> + */
> +void vdec_msg_queue_update_ube_rptr(struct vdec_msg_queue *msg_queue,
> +	uint64_t ube_rptr);
> +
> +/**
> + * vdec_msg_queue_update_ube_wptr - used to updata the ube write point.
> + * @msg_queue: used to store the lat buffer information
> + * @ube_wptr: current ube write point
> + */
> +void vdec_msg_queue_update_ube_wptr(struct vdec_msg_queue *msg_queue,
> +	uint64_t ube_wptr);
> +
> +/**
> + * vdec_msg_queue_wait_lat_buf_full - used to check whether all lat buffer
> + *                                    in lat list.
> + * @msg_queue: used to store the lat buffer information
> + */
> +bool vdec_msg_queue_wait_lat_buf_full(struct vdec_msg_queue *msg_queue);
> +
> +/**
> + * vdec_msg_queue_deinit - deinit lat buffer information.
> + * @msg_queue: used to store the lat buffer information
> + * @ctx: v4l2 ctx
> + */
> +void vdec_msg_queue_deinit(
> +	struct vdec_msg_queue *msg_queue,
> +	struct mtk_vcodec_ctx *ctx);
> +

void vdec_msg_queue_deinit(struct vdec_msg_queue *msg_queue,
			   struct mtk_vcodec_ctx *ctx);
> +#endif
> 
Regards,
- Angelo

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v7, 09/15] media: mtk-vcodec: Generalize power and clock on/off interfaces
  2021-10-11  7:02 ` [PATCH v7, 09/15] media: mtk-vcodec: Generalize power and clock on/off interfaces Yunfei Dong
@ 2021-10-14 10:44   ` AngeloGioacchino Del Regno
  2021-10-27  3:55     ` yunfei.dong
  0 siblings, 1 reply; 43+ messages in thread
From: AngeloGioacchino Del Regno @ 2021-10-14 10:44 UTC (permalink / raw)
  To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

> Generalizes power and clock on/off interfaces to support different hardware.
> 
> Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
> ---
>   .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |  6 +-
>   .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   |  2 +-
>   .../platform/mtk-vcodec/mtk_vcodec_dec_hw.h   |  4 +
>   .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 76 ++++++++++++++--
>   .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h   |  8 +-
>   .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  2 +
>   .../platform/mtk-vcodec/mtk_vcodec_util.c     | 87 ++++++++++++++++---
>   .../platform/mtk-vcodec/mtk_vcodec_util.h     |  8 +-
>   .../media/platform/mtk-vcodec/vdec_drv_if.c   | 21 ++---
>   9 files changed, 174 insertions(+), 40 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 ff70fa5b34e3..3ea1e96e0ec0 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
> @@ -96,7 +96,7 @@ static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
>   	void __iomem *vdec_misc_addr = dev->reg_base[VDEC_MISC] +
>   					VDEC_IRQ_CFG_REG;
>   
> -	ctx = mtk_vcodec_get_curr_ctx(dev);
> +	ctx = mtk_vcodec_get_curr_ctx(dev, MTK_VDEC_CORE);
>   
>   	/* check if HW active or not */
>   	cg_status = readl(dev->reg_base[0]);
> @@ -245,7 +245,7 @@ static int fops_vcodec_open(struct file *file)
>   	mtk_vcodec_dec_set_default_params(ctx);
>   
>   	if (v4l2_fh_is_singular(&ctx->fh)) {
> -		ret = mtk_vcodec_dec_pw_on(&dev->pm);
> +		ret = mtk_vcodec_dec_pw_on(dev, MTK_VDEC_LAT0);
>   		if (ret < 0)
>   			goto err_load_fw;
>   		/*
> @@ -306,7 +306,7 @@ static int fops_vcodec_release(struct file *file)
>   	mtk_vcodec_dec_release(ctx);
>   
>   	if (v4l2_fh_is_singular(&ctx->fh))
> -		mtk_vcodec_dec_pw_off(&dev->pm);
> +		mtk_vcodec_dec_pw_off(dev, MTK_VDEC_LAT0);
>   	v4l2_fh_del(&ctx->fh);
>   	v4l2_fh_exit(&ctx->fh);
>   	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
> index 0997a5a08156..78d25916395d 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
> @@ -37,7 +37,7 @@ static irqreturn_t mtk_vdec_comp_irq_handler(int irq, void *priv)
>   	void __iomem *vdec_misc_addr = dev->reg_base[VDEC_COMP_MISC] +
>   					VDEC_IRQ_CFG_REG;
>   
> -	ctx = mtk_vcodec_get_curr_ctx(dev->master_dev);
> +	ctx = mtk_vcodec_get_curr_ctx(dev->master_dev, dev->comp_idx);
>   
>   	/* check if HW active or not */
>   	cg_status = readl(dev->reg_base[VDEC_COMP_SYS]);
> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
> index 8d6e818a3474..0a4c2e6f5df2 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
> @@ -32,6 +32,8 @@ enum mtk_comp_hw_reg_idx {
>    * @master_dev: master device
>    * @reg_base: Mapped address of MTK Vcodec registers.
>    *
> + * @curr_ctx: The context that is waiting for codec hardware
> + *
>    * @dec_irq: decoder irq resource
>    * @pm: power management control
>    * @comp_idx: component index
> @@ -41,6 +43,8 @@ struct mtk_vdec_comp_dev {
>   	struct mtk_vcodec_dev *master_dev;
>   	void __iomem *reg_base[VDEC_COMP_MAX];
>   
> +	struct mtk_vcodec_ctx *curr_ctx;
> +
>   	int dec_irq;
>   	struct mtk_vcodec_pm pm;
>   	int comp_idx;
> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
> index 20bd157a855c..183d4c4e36f0 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
> @@ -5,11 +5,13 @@
>    */
>   
>   #include <linux/clk.h>
> +#include <linux/interrupt.h>
>   #include <linux/of_address.h>
>   #include <linux/of_platform.h>
>   #include <linux/pm_runtime.h>
>   #include <soc/mediatek/smi.h>
>   
> +#include "mtk_vcodec_dec_hw.h"
>   #include "mtk_vcodec_dec_pm.h"
>   #include "mtk_vcodec_util.h"
>   
> @@ -84,10 +86,23 @@ void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm)
>   	put_device(pm->larbvdec);
>   }
>   
> -int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
> +int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int comp_idx)
>   {
> +	struct mtk_vdec_comp_dev *comp_dev;
> +	struct mtk_vcodec_pm *pm;
>   	int ret;
>   
> +	if (vdec_dev->vdec_pdata->is_comp_supported) {

This code is never hit, is_comp_supported is never true.

> +		comp_dev = mtk_vcodec_get_hw_dev(vdec_dev, comp_idx);
> +		if (!comp_dev) {
> +			mtk_v4l2_err("Failed to get hw dev\n");
> +			return -EINVAL;
> +		}
> +		pm = &comp_dev->pm;
> +	} else {
> +		pm = &vdec_dev->pm;
> +	}
> +
>   	ret = pm_runtime_resume_and_get(pm->dev);
>   	if (ret)
>   		mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret);
> @@ -95,20 +110,49 @@ int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
>   	return ret;
>   }
>   
> -void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm)
> +void mtk_vcodec_dec_pw_off(struct mtk_vcodec_dev *vdec_dev, int comp_idx)
>   {
> +	struct mtk_vdec_comp_dev *comp_dev;
> +	struct mtk_vcodec_pm *pm;
>   	int ret;
>   
> +	if (vdec_dev->vdec_pdata->is_comp_supported) {

Ditto.

> +		comp_dev = mtk_vcodec_get_hw_dev(vdec_dev, comp_idx);
> +		if (!comp_dev) {
> +			mtk_v4l2_err("Failed to get hw dev\n");
> +			return;
> +		}
> +		pm = &comp_dev->pm;
> +	} else {
> +		pm = &vdec_dev->pm;
> +	}
> +
>   	ret = pm_runtime_put_sync(pm->dev);
>   	if (ret)
>   		mtk_v4l2_err("pm_runtime_put_sync fail %d", ret);
>   }
>   
> -void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm)
> +void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int comp_idx)
>   {
> -	struct mtk_vcodec_clk *dec_clk = &pm->vdec_clk;
> -	int ret, i = 0;
> +	struct mtk_vdec_comp_dev *comp_dev;
> +	struct mtk_vcodec_pm *pm;
> +	struct mtk_vcodec_clk *dec_clk;
> +	int ret, i;
> +
> +	if (vdec_dev->vdec_pdata->is_comp_supported) {

...and again...

> +		comp_dev = mtk_vcodec_get_hw_dev(vdec_dev, comp_idx);
> +		if (!comp_dev) {
> +			mtk_v4l2_err("Failed to get hw dev\n");
> +			return;
> +		}
> +		pm = &comp_dev->pm;
> +		enable_irq(comp_dev->dec_irq);
> +	} else {
> +		pm = &vdec_dev->pm;
> +		enable_irq(vdec_dev->dec_irq);
> +	}
>   
> +	dec_clk = &pm->vdec_clk;
>   	for (i = 0; i < dec_clk->clk_num; i++) {
>   		ret = clk_prepare_enable(dec_clk->clk_info[i].vcodec_clk);
>   		if (ret) {
> @@ -130,11 +174,27 @@ void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm)
>   		clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
>   }
>   
> -void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm)
> +void mtk_vcodec_dec_clock_off(struct mtk_vcodec_dev *vdec_dev, int comp_idx)
>   {
> -	struct mtk_vcodec_clk *dec_clk = &pm->vdec_clk;
> -	int i = 0;
> +	struct mtk_vdec_comp_dev *comp_dev;
> +	struct mtk_vcodec_pm *pm;
> +	struct mtk_vcodec_clk *dec_clk;
> +	int i;
>   
> +	if (vdec_dev->vdec_pdata->is_comp_supported) {

...

> +		comp_dev = mtk_vcodec_get_hw_dev(vdec_dev, comp_idx);
> +		if (!comp_dev) {
> +			mtk_v4l2_err("Failed to get hw dev\n");
> +			return;
> +		}
> +		pm = &comp_dev->pm;
> +		disable_irq(comp_dev->dec_irq);
> +	} else {
> +		pm = &vdec_dev->pm;
> +		disable_irq(vdec_dev->dec_irq);
> +	}
> +
> +	dec_clk = &pm->vdec_clk;
>   	mtk_smi_larb_put(pm->larbvdec);
>   	for (i = dec_clk->clk_num - 1; i >= 0; i--)
>   		clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
> index a3df6aef6cb9..698750572b57 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
> @@ -13,9 +13,9 @@ int mtk_vcodec_init_dec_pm(struct platform_device *pdev,
>   	struct mtk_vcodec_pm *pm);
>   void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm);
>   
> -int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm);
> -void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm);
> -void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm);
> -void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm);
> +int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int comp_idx);
> +void mtk_vcodec_dec_pw_off(struct mtk_vcodec_dev *vdec_dev, int comp_idx);
> +void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int comp_idx);
> +void mtk_vcodec_dec_clock_off(struct mtk_vcodec_dev *vdec_dev, int comp_idx);
>   
>   #endif /* _MTK_VCODEC_DEC_PM_H_ */
> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> index ab401b2db30e..95c82cb4e568 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> @@ -284,6 +284,7 @@ struct vdec_pic_info {
>    * @decoded_frame_cnt: number of decoded frames
>    * @lock: protect variables accessed by V4L2 threads and worker thread such as
>    *	  mtk_video_dec_buf.
> + * @hw_id: hardware index used to identify different hardware.
>    *
>    * @msg_queue: msg queue used to store lat buffer information.
>    */
> @@ -328,6 +329,7 @@ struct mtk_vcodec_ctx {
>   
>   	int decoded_frame_cnt;
>   	struct mutex lock;
> +	int hw_id;
>   
>   	struct vdec_msg_queue msg_queue;
>   };
> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
> index ac5973b6735f..511b75e49fe7 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
> @@ -6,7 +6,10 @@
>   */
>   
>   #include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
>   
> +#include "mtk_vcodec_dec_hw.h"
>   #include "mtk_vcodec_drv.h"
>   #include "mtk_vcodec_util.h"
>   
> @@ -81,25 +84,87 @@ void mtk_vcodec_mem_free(struct mtk_vcodec_ctx *data,
>   }
>   EXPORT_SYMBOL(mtk_vcodec_mem_free);
>   
> -void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *dev,
> -	struct mtk_vcodec_ctx *ctx)
> +void *mtk_vcodec_get_hw_dev(struct mtk_vcodec_dev *dev, int comp_idx)
>   {
> -	unsigned long flags;
> +	struct platform_device *hw_pdev;
> +	struct device_node *node;
> +	struct mtk_vdec_comp_dev *master_dev;
> +
> +	if (comp_idx >= MTK_VDEC_HW_MAX || comp_idx < 0) {
> +		mtk_v4l2_err("Comp idx is out of range:%d", comp_idx);
> +		return NULL;
> +	}
> +
> +	if (dev->comp_dev[comp_idx])
> +		return dev->comp_dev[comp_idx];
> +
> +	node = dev->component_node[comp_idx];
> +	if (!node) {
> +		mtk_v4l2_err("Get lat node fail:%d", comp_idx);
> +		return NULL;
> +	}
> +
> +	hw_pdev = of_find_device_by_node(node);
> +	of_node_put(node);
> +
> +	if (WARN_ON(!hw_pdev)) {
> +		mtk_v4l2_err("Get hw id(%d) node fail", comp_idx);
> +		return NULL;
> +	}
> +
> +	master_dev = platform_get_drvdata(hw_pdev);
> +	if (!master_dev) {
> +		mtk_v4l2_err("Get hw id(%d) pdev fail", comp_idx);
> +		return NULL;
> +	}
>   
> -	spin_lock_irqsave(&dev->irqlock, flags);
> -	dev->curr_ctx = ctx;
> -	spin_unlock_irqrestore(&dev->irqlock, flags);
> +	dev->comp_dev[master_dev->comp_idx] = master_dev;
> +	return master_dev;
> +}
> +EXPORT_SYMBOL(mtk_vcodec_get_hw_dev);
> +
> +void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *vdec_dev,
> +	struct mtk_vcodec_ctx *ctx, int comp_idx)
> +{
> +	unsigned long flags;
> +	struct mtk_vdec_comp_dev *comp_dev;
> +
> +	spin_lock_irqsave(&vdec_dev->irqlock, flags);
> +	if (vdec_dev->vdec_pdata->is_comp_supported) {

here too...

> +		comp_dev = mtk_vcodec_get_hw_dev(vdec_dev, comp_idx);
> +		if (!comp_dev) {
> +			mtk_v4l2_err("Failed to get hw dev");
> +			spin_unlock_irqrestore(&vdec_dev->irqlock, flags);
> +			return;
> +		}
> +		comp_dev->curr_ctx = ctx;
> +	} else {
> +		vdec_dev->curr_ctx = ctx;
> +	}
> +	spin_unlock_irqrestore(&vdec_dev->irqlock, flags);
>   }
>   EXPORT_SYMBOL(mtk_vcodec_set_curr_ctx);
>   
> -struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *dev)
> +struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *vdec_dev,
> +	unsigned int comp_idx)
>   {
>   	unsigned long flags;
>   	struct mtk_vcodec_ctx *ctx;
> -
> -	spin_lock_irqsave(&dev->irqlock, flags);
> -	ctx = dev->curr_ctx;
> -	spin_unlock_irqrestore(&dev->irqlock, flags);
> +	struct mtk_vdec_comp_dev *comp_dev;
> +
> +	spin_lock_irqsave(&vdec_dev->irqlock, flags);
> +	if (vdec_dev->vdec_pdata->is_comp_supported) {

and here

> +		comp_dev = mtk_vcodec_get_hw_dev(vdec_dev, comp_idx);
> +		if (!comp_dev) {
> +			mtk_v4l2_err("Failed to get hw dev");
> +			spin_unlock_irqrestore(&vdec_dev->irqlock, flags);
> +			return NULL;
> +		}
> +		ctx = comp_dev->curr_ctx;
> +	} else {
> +		ctx = vdec_dev->curr_ctx;
> +	}
> +	spin_unlock_irqrestore(&vdec_dev->irqlock, flags);
>   	return ctx;
>   }
>   EXPORT_SYMBOL(mtk_vcodec_get_curr_ctx);
> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
> index b999d7b84ed1..4cb0fc60c94f 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
> @@ -79,8 +79,10 @@ int mtk_vcodec_mem_alloc(struct mtk_vcodec_ctx *data,
>   				struct mtk_vcodec_mem *mem);
>   void mtk_vcodec_mem_free(struct mtk_vcodec_ctx *data,
>   				struct mtk_vcodec_mem *mem);
> -void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *dev,
> -	struct mtk_vcodec_ctx *ctx);
> -struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *dev);
> +void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *vdec_dev,
> +				struct mtk_vcodec_ctx *ctx, int comp_idx);
> +struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *vdec_dev,
> +	unsigned int comp_idx);

Fix indentation please:

struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *vdec_dev,

					       unsigned int comp_idx);


Regards,
- Angelo

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v7, 10/15] media: mtk-vcodec: Add new interface to lock different hardware
  2021-10-11  7:02 ` [PATCH v7, 10/15] media: mtk-vcodec: Add new interface to lock different hardware Yunfei Dong
@ 2021-10-14 10:47   ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 43+ messages in thread
From: AngeloGioacchino Del Regno @ 2021-10-14 10:47 UTC (permalink / raw)
  To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

> For add new hardware, not only need to lock lat hardware, also
> need to lock core hardware in case of different instance start
> to decoder at the same time.
> 
> Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
> ---

Reviewed-By: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v7, 11/15] media: mtk-vcodec: Add core thread
  2021-10-11  7:02 ` [PATCH v7, 11/15] media: mtk-vcodec: Add core thread Yunfei Dong
@ 2021-10-14 10:56   ` AngeloGioacchino Del Regno
  2021-10-27  3:47     ` yunfei.dong
  2021-10-14 12:29   ` Ezequiel Garcia
  1 sibling, 1 reply; 43+ messages in thread
From: AngeloGioacchino Del Regno @ 2021-10-14 10:56 UTC (permalink / raw)
  To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

> Core thread:
> 1. Gets lat_buf from core msg queue.
> 2. Proceeds core decode.
> 3. Puts the lat_buf back to lat msg queue.
> 
> Both H264 and VP9 rely on the core thread.
> 
> Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>

I would be happier to see a better commit message, for example:
"Introduce a core thread, responsible for... getting lat_buf from ...
which then proceeds core decode by ... and finally, puts the lat_buf
back to the lat message queue"

> ---
>   .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 12 +++++++
>   .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  7 ++++
>   .../platform/mtk-vcodec/vdec_msg_queue.c      | 32 +++++++++++++++++++
>   .../platform/mtk-vcodec/vdec_msg_queue.h      |  6 ++++
>   4 files changed, 57 insertions(+)
> 
> 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 e21e0c4bcd86..de83e3b821b4 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
> @@ -364,6 +364,18 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
>   		goto err_dec_pm;
>   	}
>   
> +	if (VDEC_LAT_ARCH(dev->vdec_pdata->hw_arch)) {
> +		vdec_msg_queue_init_ctx(&dev->msg_queue_core_ctx,
> +			MTK_VDEC_CORE);

No need to break this line.

> +		dev->kthread_core = kthread_run(vdec_msg_queue_core_thead, dev,
> +			"mtk-%s", "core");

Please fix indentation, like so:
		dev->kthread_core = kthread_run(vdec_msg_queue_core_thead, dev,

						"mtk-%s", "core");

> +		if (IS_ERR(dev->kthread_core)) {
> +			dev_err(&pdev->dev, "Failed to create core thread");
> +			ret = PTR_ERR(dev->kthread_core);
> +			goto err_res;
> +		}
> +	}
> +
>   	for (i = 0; i < MTK_VDEC_HW_MAX; i++)
>   		mutex_init(&dev->dec_mutex[i]);
>   	spin_lock_init(&dev->irqlock);
> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> index 9d072c082f73..68a9b1a2d3b3 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> @@ -27,6 +27,7 @@
>   #define MTK_VCODEC_MAX_PLANES	3
>   #define MTK_V4L2_BENCHMARK	0
>   #define WAIT_INTR_TIMEOUT_MS	1000
> +#define VDEC_LAT_ARCH(hw_arch) ((hw_arch) >= MTK_VDEC_LAT_SINGLE_CORE)

I'd propose to change this to IS_VDEC_LAT_ARCH(hw_arch): that would increase human
readability when using this macro.

>   
>   /*
>    * enum mtk_hw_reg_idx - MTK hw register base index
> @@ -466,6 +467,9 @@ struct mtk_vcodec_enc_pdata {
>    * @comp_dev: component hardware device
>    * @component_node: component node
>    *
> + * @kthread_core: thread used for core hardware decode
> + * @msg_queue_core_ctx: msg queue context used for core thread
> + *
>    * @hardware_bitmap: used to record hardware is ready or not
>    */
>   struct mtk_vcodec_dev {
> @@ -508,6 +512,9 @@ struct mtk_vcodec_dev {
>   	void *comp_dev[MTK_VDEC_HW_MAX];
>   	struct device_node *component_node[MTK_VDEC_HW_MAX];
>   
> +	struct task_struct *kthread_core;
> +	struct vdec_msg_queue_ctx msg_queue_core_ctx;
> +
>   	DECLARE_BITMAP(hardware_bitmap, MTK_VDEC_HW_MAX);
>   };
>   
> diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
> index d66ed98c79a9..665f571eab4b 100644
> --- a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
> +++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
> @@ -256,3 +256,35 @@ void vdec_msg_queue_deinit(
>   			kfree(lat_buf->private_data);
>   	}
>   }
> +
> +int vdec_msg_queue_core_thead(void *data)
> +{
> +	struct mtk_vcodec_dev *dev = data;
> +	struct vdec_lat_buf *lat_buf;
> +	struct mtk_vcodec_ctx *ctx;
> +
> +	set_freezable();
> +	for (;;) {
> +		try_to_freeze();
> +		if (kthread_should_stop())
> +			break;
> +
> +		lat_buf = vdec_msg_queue_dqbuf(&dev->msg_queue_core_ctx);
> +		if (!lat_buf)
> +			continue;
> +
> +		ctx = lat_buf->ctx;
> +		mtk_vcodec_set_curr_ctx(dev, ctx, MTK_VDEC_CORE);
> +
> +		if (!lat_buf->core_decode)
> +			mtk_v4l2_err("Core decode callback func is NULL");

Is this supposed to really happen?
I see that this is always initialized in function vdec_msg_queue_init().

Regards,
- Angelo



^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v7, 12/15] media: mtk-vcodec: Support 34bits dma address for vdec
  2021-10-11  7:02 ` [PATCH v7, 12/15] media: mtk-vcodec: Support 34bits dma address for vdec Yunfei Dong
@ 2021-10-14 11:02   ` AngeloGioacchino Del Regno
  2021-10-27  3:44     ` yunfei.dong
  0 siblings, 1 reply; 43+ messages in thread
From: AngeloGioacchino Del Regno @ 2021-10-14 11:02 UTC (permalink / raw)
  To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

> Use the dma_set_mask_and_coherent helper to set vdec
> DMA bit mask to support 34bits iova space(16GB) that
> the mt8192 iommu HW support.
> 
> Whole the iova range separate to 0~4G/4G~8G/8G~12G/12G~16G,
> regarding which iova range VDEC actually locate, it
> depends on the dma-ranges property of vdec dtsi node.
> 
> Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
> ---
>   drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 3 +++
>   1 file changed, 3 insertions(+)
> 
> 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 de83e3b821b4..da963cdac96b 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
> @@ -376,6 +376,9 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
>   		}
>   	}
>   
> +	if (of_get_property(pdev->dev.of_node, "dma-ranges", NULL))
> +		dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(34));
> +

This function returns 0 for success, or negative number for failure: please check
the return value, or this driver may not work correctly in some corner cases.

Regards,
- Angelo

>   	for (i = 0; i < MTK_VDEC_HW_MAX; i++)
>   		mutex_init(&dev->dec_mutex[i]);
>   	spin_lock_init(&dev->irqlock);
> 

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v7, 14/15] media: mtk-vcodec: Add core dec and dec end ipi msg
  2021-10-11  7:02 ` [PATCH v7, 14/15] media: mtk-vcodec: Add core dec and dec end ipi msg Yunfei Dong
@ 2021-10-14 11:04   ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 43+ messages in thread
From: AngeloGioacchino Del Regno @ 2021-10-14 11:04 UTC (permalink / raw)
  To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

> Add core dec and dec end ipi msg: AP_IPIMSG_DEC_CORE/AP_IPIMSG_DEC_CORE_END.
> 
> Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
> ---
>   .../media/platform/mtk-vcodec/vdec_ipi_msg.h   |  4 ++++
>   .../media/platform/mtk-vcodec/vdec_vpu_if.c    | 12 ++++++++++++
>   .../media/platform/mtk-vcodec/vdec_vpu_if.h    | 18 ++++++++++++++++++
>   3 files changed, 34 insertions(+)
> 

Reviewed-By: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v7, 15/15] media: mtk-vcodec: Use codec type to separate different hardware
  2021-10-11  7:02 ` [PATCH v7, 15/15] media: mtk-vcodec: Use codec type to separate different hardware Yunfei Dong
@ 2021-10-14 11:08   ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 43+ messages in thread
From: AngeloGioacchino Del Regno @ 2021-10-14 11:08 UTC (permalink / raw)
  To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

> There are just one core thread, in order to separeate different
> hardware, using codec type to separeate it in scp driver.
> 
> Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
> ---
>   .../media/platform/mtk-vcodec/vdec_ipi_msg.h  | 12 ++++---
>   .../media/platform/mtk-vcodec/vdec_vpu_if.c   | 34 ++++++++++++++++---
>   .../media/platform/mtk-vcodec/vdec_vpu_if.h   |  4 +++
>   3 files changed, 41 insertions(+), 9 deletions(-)
> 

Reviewed-By: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v7, 03/15] media: mtk-vcodec: Refactor vcodec pm interface
  2021-10-11  7:02 ` [PATCH v7, 03/15] media: mtk-vcodec: Refactor vcodec pm interface Yunfei Dong
@ 2021-10-14 11:12   ` AngeloGioacchino Del Regno
  2021-10-14 13:44   ` Dafna Hirschfeld
  1 sibling, 0 replies; 43+ messages in thread
From: AngeloGioacchino Del Regno @ 2021-10-14 11:12 UTC (permalink / raw)
  To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Tzung-Bi Shih

> Using the needed param for pm init/release function and remove unused
> param mtkdev in 'struct mtk_vcodec_pm'.
> 
> Reviewed-by: Tzung-Bi Shih <tzungbi@google.com>
> Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
> ---
>   .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |  6 ++---
>   .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 22 ++++++++-----------
>   .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h   |  5 +++--
>   .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  1 -
>   .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c   |  1 -
>   5 files changed, 15 insertions(+), 20 deletions(-)
> 

Acked-By: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v7, 02/15] media: mtk-vcodec: Align vcodec wake up interrupt interface
  2021-10-11  7:02 ` [PATCH v7, 02/15] media: mtk-vcodec: Align vcodec wake up interrupt interface Yunfei Dong
@ 2021-10-14 11:12   ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 43+ messages in thread
From: AngeloGioacchino Del Regno @ 2021-10-14 11:12 UTC (permalink / raw)
  To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Tzung-Bi Shih

Il 11/10/21 09:02, Yunfei Dong ha scritto:
> Vdec and venc can use the same function to wake up interrupt event.
> 
> Reviewed-by: Tzung-Bi Shih <tzungbi@google.com>
> Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>

Reviewed-By: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v7, 06/15] media: mtk-vcodec: Use pure single core for MT8183
  2021-10-11  7:02 ` [PATCH v7, 06/15] media: mtk-vcodec: Use pure single core for MT8183 Yunfei Dong
@ 2021-10-14 11:13   ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 43+ messages in thread
From: AngeloGioacchino Del Regno @ 2021-10-14 11:13 UTC (permalink / raw)
  To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

> Separates different architecture for hardware: pure_sin_core
> and lat_sin_core. MT8183 is pure single core. Uses .hw_arch to
> distinguish.
> 
> Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>

Acked-By: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>



^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v7, 11/15] media: mtk-vcodec: Add core thread
  2021-10-11  7:02 ` [PATCH v7, 11/15] media: mtk-vcodec: Add core thread Yunfei Dong
  2021-10-14 10:56   ` AngeloGioacchino Del Regno
@ 2021-10-14 12:29   ` Ezequiel Garcia
  2021-10-29  3:25     ` yunfei.dong
  1 sibling, 1 reply; 43+ messages in thread
From: Ezequiel Garcia @ 2021-10-14 12:29 UTC (permalink / raw)
  To: Yunfei Dong
  Cc: Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih, Tiffany Lin,
	Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa, Hsin-Yi Wang, Fritz Koenig,
	Dafna Hirschfeld, Benjamin Gaignard, Daniel Vetter, dri-devel,
	Irui Wang, linux-media, devicetree, linux-kernel,
	linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

Hi Yunfei,

On Mon, Oct 11, 2021 at 03:02:43PM +0800, Yunfei Dong wrote:
> Core thread:
> 1. Gets lat_buf from core msg queue.
> 2. Proceeds core decode.
> 3. Puts the lat_buf back to lat msg queue.
> 
> Both H264 and VP9 rely on the core thread.
> 

Avoid the kthread API and instead go with the workqueue API.

See Documentation/core-api/workqueue.rst and include/linux/workqueue.h.

Thanks!
Ezequiel

> Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
> ---
>  .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 12 +++++++
>  .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  7 ++++
>  .../platform/mtk-vcodec/vdec_msg_queue.c      | 32 +++++++++++++++++++
>  .../platform/mtk-vcodec/vdec_msg_queue.h      |  6 ++++
>  4 files changed, 57 insertions(+)
> 
> 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 e21e0c4bcd86..de83e3b821b4 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
> @@ -364,6 +364,18 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
>  		goto err_dec_pm;
>  	}
>  
> +	if (VDEC_LAT_ARCH(dev->vdec_pdata->hw_arch)) {
> +		vdec_msg_queue_init_ctx(&dev->msg_queue_core_ctx,
> +			MTK_VDEC_CORE);
> +		dev->kthread_core = kthread_run(vdec_msg_queue_core_thead, dev,
> +			"mtk-%s", "core");
> +		if (IS_ERR(dev->kthread_core)) {
> +			dev_err(&pdev->dev, "Failed to create core thread");
> +			ret = PTR_ERR(dev->kthread_core);
> +			goto err_res;
> +		}
> +	}
> +
>  	for (i = 0; i < MTK_VDEC_HW_MAX; i++)
>  		mutex_init(&dev->dec_mutex[i]);
>  	spin_lock_init(&dev->irqlock);
> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> index 9d072c082f73..68a9b1a2d3b3 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> @@ -27,6 +27,7 @@
>  #define MTK_VCODEC_MAX_PLANES	3
>  #define MTK_V4L2_BENCHMARK	0
>  #define WAIT_INTR_TIMEOUT_MS	1000
> +#define VDEC_LAT_ARCH(hw_arch) ((hw_arch) >= MTK_VDEC_LAT_SINGLE_CORE)
>  
>  /*
>   * enum mtk_hw_reg_idx - MTK hw register base index
> @@ -466,6 +467,9 @@ struct mtk_vcodec_enc_pdata {
>   * @comp_dev: component hardware device
>   * @component_node: component node
>   *
> + * @kthread_core: thread used for core hardware decode
> + * @msg_queue_core_ctx: msg queue context used for core thread
> + *
>   * @hardware_bitmap: used to record hardware is ready or not
>   */
>  struct mtk_vcodec_dev {
> @@ -508,6 +512,9 @@ struct mtk_vcodec_dev {
>  	void *comp_dev[MTK_VDEC_HW_MAX];
>  	struct device_node *component_node[MTK_VDEC_HW_MAX];
>  
> +	struct task_struct *kthread_core;
> +	struct vdec_msg_queue_ctx msg_queue_core_ctx;
> +
>  	DECLARE_BITMAP(hardware_bitmap, MTK_VDEC_HW_MAX);
>  };
>  
> diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
> index d66ed98c79a9..665f571eab4b 100644
> --- a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
> +++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
> @@ -256,3 +256,35 @@ void vdec_msg_queue_deinit(
>  			kfree(lat_buf->private_data);
>  	}
>  }
> +
> +int vdec_msg_queue_core_thead(void *data)
> +{
> +	struct mtk_vcodec_dev *dev = data;
> +	struct vdec_lat_buf *lat_buf;
> +	struct mtk_vcodec_ctx *ctx;
> +
> +	set_freezable();
> +	for (;;) {
> +		try_to_freeze();
> +		if (kthread_should_stop())
> +			break;
> +
> +		lat_buf = vdec_msg_queue_dqbuf(&dev->msg_queue_core_ctx);
> +		if (!lat_buf)
> +			continue;
> +
> +		ctx = lat_buf->ctx;
> +		mtk_vcodec_set_curr_ctx(dev, ctx, MTK_VDEC_CORE);
> +
> +		if (!lat_buf->core_decode)
> +			mtk_v4l2_err("Core decode callback func is NULL");
> +		else
> +			lat_buf->core_decode(lat_buf);
> +
> +		mtk_vcodec_set_curr_ctx(dev, NULL, MTK_VDEC_CORE);
> +		vdec_msg_queue_qbuf(&ctx->msg_queue.lat_ctx, lat_buf);
> +	}
> +
> +	mtk_v4l2_debug(3, "Video Capture Thread End");
> +	return 0;
> +}
> diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
> index 1905ce713592..b5745b144140 100644
> --- a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
> +++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
> @@ -148,4 +148,10 @@ void vdec_msg_queue_deinit(
>  	struct vdec_msg_queue *msg_queue,
>  	struct mtk_vcodec_ctx *ctx);
>  
> +/**
> + * vdec_msg_queue_core_thead - used for core decoder.
> + * @data: private data used for each codec
> + */
> +int vdec_msg_queue_core_thead(void *data);
> +
>  #endif
> -- 
> 2.25.1
> 

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v7, 03/15] media: mtk-vcodec: Refactor vcodec pm interface
  2021-10-11  7:02 ` [PATCH v7, 03/15] media: mtk-vcodec: Refactor vcodec pm interface Yunfei Dong
  2021-10-14 11:12   ` AngeloGioacchino Del Regno
@ 2021-10-14 13:44   ` Dafna Hirschfeld
  2021-10-29  3:29     ` yunfei.dong
  1 sibling, 1 reply; 43+ messages in thread
From: Dafna Hirschfeld @ 2021-10-14 13:44 UTC (permalink / raw)
  To: Yunfei Dong, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Benjamin Gaignard, Daniel Vetter,
	dri-devel, Irui Wang, linux-media, devicetree, linux-kernel,
	linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Tzung-Bi Shih



On 11.10.21 09:02, Yunfei Dong wrote:
> Using the needed param for pm init/release function and remove unused
> param mtkdev in 'struct mtk_vcodec_pm'.
> 

I see that there is a lot of code duplication between mtk_vcodec_release_dec_pm.c and mtk_vcodec_release_enc_pm.c
I think if you bother to factor the decoder you should do the same factor to the encoder, but actually the much better thing to do
is to unify all code duplication between these two files, just for example of identical functions:

mtk_vcodec_enc/dec_clock_on/off
mtk_vcodec_release_enc_pm
mtk_vcodec_init_dec_pm

In addition, the function mtk_vcodec_dec_pw_on can be remove since it only calls pm_runtime_resume_and_get.
It would be much better to call pm_runtime_resume_and_get directly and not hide it in a different function

Thanks,
Dafna

> Reviewed-by: Tzung-Bi Shih <tzungbi@google.com>
> Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
> ---
>   .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |  6 ++---
>   .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 22 ++++++++-----------
>   .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h   |  5 +++--
>   .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  1 -
>   .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c   |  1 -
>   5 files changed, 15 insertions(+), 20 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 8db9cdc66043..dd749d41c75a 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
> @@ -249,7 +249,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
>   	if (IS_ERR(dev->fw_handler))
>   		return PTR_ERR(dev->fw_handler);
>   
> -	ret = mtk_vcodec_init_dec_pm(dev);
> +	ret = mtk_vcodec_init_dec_pm(dev->plat_dev, &dev->pm);
>   	if (ret < 0) {
>   		dev_err(&pdev->dev, "Failed to get mt vcodec clock source");
>   		goto err_dec_pm;
> @@ -379,7 +379,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
>   err_dec_alloc:
>   	v4l2_device_unregister(&dev->v4l2_dev);
>   err_res:
> -	mtk_vcodec_release_dec_pm(dev);
> +	mtk_vcodec_release_dec_pm(&dev->pm);
>   err_dec_pm:
>   	mtk_vcodec_fw_release(dev->fw_handler);
>   	return ret;
> @@ -422,7 +422,7 @@ static int mtk_vcodec_dec_remove(struct platform_device *pdev)
>   		video_unregister_device(dev->vfd_dec);
>   
>   	v4l2_device_unregister(&dev->v4l2_dev);
> -	mtk_vcodec_release_dec_pm(dev);
> +	mtk_vcodec_release_dec_pm(&dev->pm);
>   	mtk_vcodec_fw_release(dev->fw_handler);
>   	return 0;
>   }
> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
> index 6038db96f71c..20bd157a855c 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
> @@ -13,18 +13,15 @@
>   #include "mtk_vcodec_dec_pm.h"
>   #include "mtk_vcodec_util.h"
>   
> -int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
> +int mtk_vcodec_init_dec_pm(struct platform_device *pdev,
> +	struct mtk_vcodec_pm *pm)
>   {
>   	struct device_node *node;
> -	struct platform_device *pdev;
> -	struct mtk_vcodec_pm *pm;
> +	struct platform_device *larb_pdev;
>   	struct mtk_vcodec_clk *dec_clk;
>   	struct mtk_vcodec_clk_info *clk_info;
>   	int i = 0, ret = 0;
>   
> -	pdev = mtkdev->plat_dev;
> -	pm = &mtkdev->pm;
> -	pm->mtkdev = mtkdev;
>   	dec_clk = &pm->vdec_clk;
>   	node = of_parse_phandle(pdev->dev.of_node, "mediatek,larb", 0);
>   	if (!node) {
> @@ -32,13 +29,12 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
>   		return -1;
>   	}
>   
> -	pdev = of_find_device_by_node(node);
> +	larb_pdev = of_find_device_by_node(node);
>   	of_node_put(node);
> -	if (WARN_ON(!pdev)) {
> +	if (WARN_ON(!larb_pdev)) {
>   		return -1;
>   	}
> -	pm->larbvdec = &pdev->dev;
> -	pdev = mtkdev->plat_dev;
> +	pm->larbvdec = &larb_pdev->dev;
>   	pm->dev = &pdev->dev;
>   
>   	dec_clk->clk_num =
> @@ -82,10 +78,10 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
>   	return ret;
>   }
>   
> -void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev)
> +void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm)
>   {
> -	pm_runtime_disable(dev->pm.dev);
> -	put_device(dev->pm.larbvdec);
> +	pm_runtime_disable(pm->dev);
> +	put_device(pm->larbvdec);
>   }
>   
>   int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
> index 280aeaefdb65..a3df6aef6cb9 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
> @@ -9,8 +9,9 @@
>   
>   #include "mtk_vcodec_drv.h"
>   
> -int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *dev);
> -void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev);
> +int mtk_vcodec_init_dec_pm(struct platform_device *pdev,
> +	struct mtk_vcodec_pm *pm);
> +void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm);
>   
>   int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm);
>   void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm);
> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> index 3b1e5e3a450e..973b0b3649c6 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> @@ -195,7 +195,6 @@ struct mtk_vcodec_pm {
>   	struct mtk_vcodec_clk	venc_clk;
>   	struct device	*larbvenc;
>   	struct device	*dev;
> -	struct mtk_vcodec_dev	*mtkdev;
>   };
>   
>   /**
> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
> index 1b2e4930ed27..0c8c8f86788c 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
> @@ -26,7 +26,6 @@ int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *mtkdev)
>   	pdev = mtkdev->plat_dev;
>   	pm = &mtkdev->pm;
>   	memset(pm, 0, sizeof(struct mtk_vcodec_pm));
> -	pm->mtkdev = mtkdev;
>   	pm->dev = &pdev->dev;
>   	dev = &pdev->dev;
>   	enc_clk = &pm->venc_clk;
> 

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v7, 12/15] media: mtk-vcodec: Support 34bits dma address for vdec
  2021-10-14 11:02   ` AngeloGioacchino Del Regno
@ 2021-10-27  3:44     ` yunfei.dong
  0 siblings, 0 replies; 43+ messages in thread
From: yunfei.dong @ 2021-10-27  3:44 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Alexandre Courbot, Hans Verkuil,
	Tzung-Bi Shih, Tiffany Lin, Andrew-CT Chen,
	Mauro Carvalho Chehab, Rob Herring, Matthias Brugger,
	Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

Hi AngeloGioacchino,

Thanks for your suggestion.
On Thu, 2021-10-14 at 13:02 +0200, AngeloGioacchino Del Regno wrote:
> > Use the dma_set_mask_and_coherent helper to set vdec
> > DMA bit mask to support 34bits iova space(16GB) that
> > the mt8192 iommu HW support.
> > 
> > Whole the iova range separate to 0~4G/4G~8G/8G~12G/12G~16G,
> > regarding which iova range VDEC actually locate, it
> > depends on the dma-ranges property of vdec dtsi node.
> > 
> > Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
> > ---
> >   drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 3 +++
> >   1 file changed, 3 insertions(+)
> > 
> > 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 de83e3b821b4..da963cdac96b 100644
> > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
> > @@ -376,6 +376,9 @@ static int mtk_vcodec_probe(struct
> > platform_device *pdev)
> >   		}
> >   	}
> >   
> > +	if (of_get_property(pdev->dev.of_node, "dma-ranges", NULL))
> > +		dma_set_mask_and_coherent(&pdev->dev,
> > DMA_BIT_MASK(34));
> > +
> 
Will fix in patch v8.
> This function returns 0 for success, or negative number for failure:
> please check
> the return value, or this driver may not work correctly in some
> corner cases.
> 
> Regards,
> - Angelo
> 
> >   	for (i = 0; i < MTK_VDEC_HW_MAX; i++)
> >   		mutex_init(&dev->dec_mutex[i]);
> >   	spin_lock_init(&dev->irqlock);
> > 

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v7, 11/15] media: mtk-vcodec: Add core thread
  2021-10-14 10:56   ` AngeloGioacchino Del Regno
@ 2021-10-27  3:47     ` yunfei.dong
  0 siblings, 0 replies; 43+ messages in thread
From: yunfei.dong @ 2021-10-27  3:47 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Alexandre Courbot, Hans Verkuil,
	Tzung-Bi Shih, Tiffany Lin, Andrew-CT Chen,
	Mauro Carvalho Chehab, Rob Herring, Matthias Brugger,
	Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

Hi AngeloGioacchino,

Thanks for your suggestion.
On Thu, 2021-10-14 at 12:56 +0200, AngeloGioacchino Del Regno wrote:
> > Core thread:
> > 1. Gets lat_buf from core msg queue.
> > 2. Proceeds core decode.
> > 3. Puts the lat_buf back to lat msg queue.
> > 
> > Both H264 and VP9 rely on the core thread.
> > 
> > Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
> 
> I would be happier to see a better commit message, for example:
> "Introduce a core thread, responsible for... getting lat_buf from ...
> which then proceeds core decode by ... and finally, puts the lat_buf
> back to the lat message queue"
> 
> > ---
> >   .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 12 +++++++
> >   .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  7 ++++
> >   .../platform/mtk-vcodec/vdec_msg_queue.c      | 32
> > +++++++++++++++++++
> >   .../platform/mtk-vcodec/vdec_msg_queue.h      |  6 ++++
> >   4 files changed, 57 insertions(+)
> > 
> > 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 e21e0c4bcd86..de83e3b821b4 100644
> > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
> > @@ -364,6 +364,18 @@ static int mtk_vcodec_probe(struct
> > platform_device *pdev)
> >   		goto err_dec_pm;
> >   	}
> >   
> > +	if (VDEC_LAT_ARCH(dev->vdec_pdata->hw_arch)) {
> > +		vdec_msg_queue_init_ctx(&dev->msg_queue_core_ctx,
> > +			MTK_VDEC_CORE);
> 
> No need to break this line.
> 
Fix in v8.
> > +		dev->kthread_core =
> > kthread_run(vdec_msg_queue_core_thead, dev,
> > +			"mtk-%s", "core");
> 
> Please fix indentation, like so:
> 		dev->kthread_core =
> kthread_run(vdec_msg_queue_core_thead, dev,
> 
> 						"mtk-%s", "core");
> 
> > +		if (IS_ERR(dev->kthread_core)) {
> > +			dev_err(&pdev->dev, "Failed to create core
> > thread");
> > +			ret = PTR_ERR(dev->kthread_core);
> > +			goto err_res;
> > +		}
> > +	}
> > +
> >   	for (i = 0; i < MTK_VDEC_HW_MAX; i++)
> >   		mutex_init(&dev->dec_mutex[i]);
> >   	spin_lock_init(&dev->irqlock);
> > diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> > b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> > index 9d072c082f73..68a9b1a2d3b3 100644
> > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> > @@ -27,6 +27,7 @@
> >   #define MTK_VCODEC_MAX_PLANES	3
> >   #define MTK_V4L2_BENCHMARK	0
> >   #define WAIT_INTR_TIMEOUT_MS	1000
> > +#define VDEC_LAT_ARCH(hw_arch) ((hw_arch) >=
> > MTK_VDEC_LAT_SINGLE_CORE)
> 
> I'd propose to change this to IS_VDEC_LAT_ARCH(hw_arch): that would
> increase human
> readability when using this macro.
> 
Fix in v8.
> >   
> >   /*
> >    * enum mtk_hw_reg_idx - MTK hw register base index
> > @@ -466,6 +467,9 @@ struct mtk_vcodec_enc_pdata {
> >    * @comp_dev: component hardware device
> >    * @component_node: component node
> >    *
> > + * @kthread_core: thread used for core hardware decode
> > + * @msg_queue_core_ctx: msg queue context used for core thread
> > + *
> >    * @hardware_bitmap: used to record hardware is ready or not
> >    */
> >   struct mtk_vcodec_dev {
> > @@ -508,6 +512,9 @@ struct mtk_vcodec_dev {
> >   	void *comp_dev[MTK_VDEC_HW_MAX];
> >   	struct device_node *component_node[MTK_VDEC_HW_MAX];
> >   
> > +	struct task_struct *kthread_core;
> > +	struct vdec_msg_queue_ctx msg_queue_core_ctx;
> > +
> >   	DECLARE_BITMAP(hardware_bitmap, MTK_VDEC_HW_MAX);
> >   };
> >   
> > diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
> > b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
> > index d66ed98c79a9..665f571eab4b 100644
> > --- a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
> > +++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
> > @@ -256,3 +256,35 @@ void vdec_msg_queue_deinit(
> >   			kfree(lat_buf->private_data);
> >   	}
> >   }
> > +
> > +int vdec_msg_queue_core_thead(void *data)
> > +{
> > +	struct mtk_vcodec_dev *dev = data;
> > +	struct vdec_lat_buf *lat_buf;
> > +	struct mtk_vcodec_ctx *ctx;
> > +
> > +	set_freezable();
> > +	for (;;) {
> > +		try_to_freeze();
> > +		if (kthread_should_stop())
> > +			break;
> > +
> > +		lat_buf = vdec_msg_queue_dqbuf(&dev-
> > >msg_queue_core_ctx);
> > +		if (!lat_buf)
> > +			continue;
> > +
> > +		ctx = lat_buf->ctx;
> > +		mtk_vcodec_set_curr_ctx(dev, ctx, MTK_VDEC_CORE);
> > +
> > +		if (!lat_buf->core_decode)
> > +			mtk_v4l2_err("Core decode callback func is
> > NULL");
> 
> Is this supposed to really happen?
> I see that this is always initialized in function
> vdec_msg_queue_init().
Fix in v8, using work queue instead of create thread.

Thanks
Yunfei Dong
> 
> Regards,
> - Angelo
> 
> 

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v7, 09/15] media: mtk-vcodec: Generalize power and clock on/off interfaces
  2021-10-14 10:44   ` AngeloGioacchino Del Regno
@ 2021-10-27  3:55     ` yunfei.dong
  0 siblings, 0 replies; 43+ messages in thread
From: yunfei.dong @ 2021-10-27  3:55 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Alexandre Courbot, Hans Verkuil,
	Tzung-Bi Shih, Tiffany Lin, Andrew-CT Chen,
	Mauro Carvalho Chehab, Rob Herring, Matthias Brugger,
	Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

Hi AngeloGioacchino,

Thanks for your suggestion.
On Thu, 2021-10-14 at 12:44 +0200, AngeloGioacchino Del Regno wrote:
> > Generalizes power and clock on/off interfaces to support different
> > hardware.
> > 
> > Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
> > ---
> >   .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |  6 +-
> >   .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   |  2 +-
> >   .../platform/mtk-vcodec/mtk_vcodec_dec_hw.h   |  4 +
> >   .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 76
> > ++++++++++++++--
> >   .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h   |  8 +-
> >   .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  2 +
> >   .../platform/mtk-vcodec/mtk_vcodec_util.c     | 87
> > ++++++++++++++++---
> >   .../platform/mtk-vcodec/mtk_vcodec_util.h     |  8 +-
> >   .../media/platform/mtk-vcodec/vdec_drv_if.c   | 21 ++---
> >   9 files changed, 174 insertions(+), 40 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 ff70fa5b34e3..3ea1e96e0ec0 100644
> > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
> > @@ -96,7 +96,7 @@ static irqreturn_t mtk_vcodec_dec_irq_handler(int
> > irq, void *priv)
> >   	void __iomem *vdec_misc_addr = dev->reg_base[VDEC_MISC] +
> >   					VDEC_IRQ_CFG_REG;
> >   
> > -	ctx = mtk_vcodec_get_curr_ctx(dev);
> > +	ctx = mtk_vcodec_get_curr_ctx(dev, MTK_VDEC_CORE);
> >   
> >   	/* check if HW active or not */
> >   	cg_status = readl(dev->reg_base[0]);
> > @@ -245,7 +245,7 @@ static int fops_vcodec_open(struct file *file)
> >   	mtk_vcodec_dec_set_default_params(ctx);
> >   
> >   	if (v4l2_fh_is_singular(&ctx->fh)) {
> > -		ret = mtk_vcodec_dec_pw_on(&dev->pm);
> > +		ret = mtk_vcodec_dec_pw_on(dev, MTK_VDEC_LAT0);
> >   		if (ret < 0)
> >   			goto err_load_fw;
> >   		/*
> > @@ -306,7 +306,7 @@ static int fops_vcodec_release(struct file
> > *file)
> >   	mtk_vcodec_dec_release(ctx);
> >   
> >   	if (v4l2_fh_is_singular(&ctx->fh))
> > -		mtk_vcodec_dec_pw_off(&dev->pm);
> > +		mtk_vcodec_dec_pw_off(dev, MTK_VDEC_LAT0);
> >   	v4l2_fh_del(&ctx->fh);
> >   	v4l2_fh_exit(&ctx->fh);
> >   	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
> > diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
> > b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
> > index 0997a5a08156..78d25916395d 100644
> > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
> > @@ -37,7 +37,7 @@ static irqreturn_t mtk_vdec_comp_irq_handler(int
> > irq, void *priv)
> >   	void __iomem *vdec_misc_addr = dev->reg_base[VDEC_COMP_MISC] +
> >   					VDEC_IRQ_CFG_REG;
> >   
> > -	ctx = mtk_vcodec_get_curr_ctx(dev->master_dev);
> > +	ctx = mtk_vcodec_get_curr_ctx(dev->master_dev, dev->comp_idx);
> >   
> >   	/* check if HW active or not */
> >   	cg_status = readl(dev->reg_base[VDEC_COMP_SYS]);
> > diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
> > b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
> > index 8d6e818a3474..0a4c2e6f5df2 100644
> > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
> > @@ -32,6 +32,8 @@ enum mtk_comp_hw_reg_idx {
> >    * @master_dev: master device
> >    * @reg_base: Mapped address of MTK Vcodec registers.
> >    *
> > + * @curr_ctx: The context that is waiting for codec hardware
> > + *
> >    * @dec_irq: decoder irq resource
> >    * @pm: power management control
> >    * @comp_idx: component index
> > @@ -41,6 +43,8 @@ struct mtk_vdec_comp_dev {
> >   	struct mtk_vcodec_dev *master_dev;
> >   	void __iomem *reg_base[VDEC_COMP_MAX];
> >   
> > +	struct mtk_vcodec_ctx *curr_ctx;
> > +
> >   	int dec_irq;
> >   	struct mtk_vcodec_pm pm;
> >   	int comp_idx;
> > diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
> > b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
> > index 20bd157a855c..183d4c4e36f0 100644
> > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
> > @@ -5,11 +5,13 @@
> >    */
> >   
> >   #include <linux/clk.h>
> > +#include <linux/interrupt.h>
> >   #include <linux/of_address.h>
> >   #include <linux/of_platform.h>
> >   #include <linux/pm_runtime.h>
> >   #include <soc/mediatek/smi.h>
> >   
> > +#include "mtk_vcodec_dec_hw.h"
> >   #include "mtk_vcodec_dec_pm.h"
> >   #include "mtk_vcodec_util.h"
> >   
> > @@ -84,10 +86,23 @@ void mtk_vcodec_release_dec_pm(struct
> > mtk_vcodec_pm *pm)
> >   	put_device(pm->larbvdec);
> >   }
> >   
> > -int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
> > +int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int
> > comp_idx)
> >   {
> > +	struct mtk_vdec_comp_dev *comp_dev;
> > +	struct mtk_vcodec_pm *pm;
> >   	int ret;
> >   
> > +	if (vdec_dev->vdec_pdata->is_comp_supported) {
> 
> This code is never hit, is_comp_supported is never true.
> 
This parameter is used to separate component(8192) and non-
component(8183) architecture. Add patch 5 to use it.
> > +		comp_dev = mtk_vcodec_get_hw_dev(vdec_dev, comp_idx);
> > +		if (!comp_dev) {
> > +			mtk_v4l2_err("Failed to get hw dev\n");
> > +			return -EINVAL;
> > +		}
> > +		pm = &comp_dev->pm;
> > +	} else {
> > +		pm = &vdec_dev->pm;
> > +	}
> > +
> >   	ret = pm_runtime_resume_and_get(pm->dev);
> >   	if (ret)
> >   		mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret);
> > @@ -95,20 +110,49 @@ int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm
> > *pm)
> >   	return ret;
> >   }
> >   
> > -void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm)
> > +void mtk_vcodec_dec_pw_off(struct mtk_vcodec_dev *vdec_dev, int
> > comp_idx)
> >   {
> > +	struct mtk_vdec_comp_dev *comp_dev;
> > +	struct mtk_vcodec_pm *pm;
> >   	int ret;
> >   
> > +	if (vdec_dev->vdec_pdata->is_comp_supported) {
> 
> Ditto.
> 
> > +		comp_dev = mtk_vcodec_get_hw_dev(vdec_dev, comp_idx);
> > +		if (!comp_dev) {
> > +			mtk_v4l2_err("Failed to get hw dev\n");
> > +			return;
> > +		}
> > +		pm = &comp_dev->pm;
> > +	} else {
> > +		pm = &vdec_dev->pm;
> > +	}
> > +
> >   	ret = pm_runtime_put_sync(pm->dev);
> >   	if (ret)
> >   		mtk_v4l2_err("pm_runtime_put_sync fail %d", ret);
> >   }
> >   
> > -void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm)
> > +void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int
> > comp_idx)
> >   {
> > -	struct mtk_vcodec_clk *dec_clk = &pm->vdec_clk;
> > -	int ret, i = 0;
> > +	struct mtk_vdec_comp_dev *comp_dev;
> > +	struct mtk_vcodec_pm *pm;
> > +	struct mtk_vcodec_clk *dec_clk;
> > +	int ret, i;
> > +
> > +	if (vdec_dev->vdec_pdata->is_comp_supported) {
> 
> ...and again...
> 
> > +		comp_dev = mtk_vcodec_get_hw_dev(vdec_dev, comp_idx);
> > +		if (!comp_dev) {
> > +			mtk_v4l2_err("Failed to get hw dev\n");
> > +			return;
> > +		}
> > +		pm = &comp_dev->pm;
> > +		enable_irq(comp_dev->dec_irq);
> > +	} else {
> > +		pm = &vdec_dev->pm;
> > +		enable_irq(vdec_dev->dec_irq);
> > +	}
> >   
> > +	dec_clk = &pm->vdec_clk;
> >   	for (i = 0; i < dec_clk->clk_num; i++) {
> >   		ret = clk_prepare_enable(dec_clk-
> > >clk_info[i].vcodec_clk);
> >   		if (ret) {
> > @@ -130,11 +174,27 @@ void mtk_vcodec_dec_clock_on(struct
> > mtk_vcodec_pm *pm)
> >   		clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
> >   }
> >   
> > -void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm)
> > +void mtk_vcodec_dec_clock_off(struct mtk_vcodec_dev *vdec_dev, int
> > comp_idx)
> >   {
> > -	struct mtk_vcodec_clk *dec_clk = &pm->vdec_clk;
> > -	int i = 0;
> > +	struct mtk_vdec_comp_dev *comp_dev;
> > +	struct mtk_vcodec_pm *pm;
> > +	struct mtk_vcodec_clk *dec_clk;
> > +	int i;
> >   
> > +	if (vdec_dev->vdec_pdata->is_comp_supported) {
> 
> ...
> 
> > +		comp_dev = mtk_vcodec_get_hw_dev(vdec_dev, comp_idx);
> > +		if (!comp_dev) {
> > +			mtk_v4l2_err("Failed to get hw dev\n");
> > +			return;
> > +		}
> > +		pm = &comp_dev->pm;
> > +		disable_irq(comp_dev->dec_irq);
> > +	} else {
> > +		pm = &vdec_dev->pm;
> > +		disable_irq(vdec_dev->dec_irq);
> > +	}
> > +
> > +	dec_clk = &pm->vdec_clk;
> >   	mtk_smi_larb_put(pm->larbvdec);
> >   	for (i = dec_clk->clk_num - 1; i >= 0; i--)
> >   		clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
> > diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
> > b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
> > index a3df6aef6cb9..698750572b57 100644
> > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
> > @@ -13,9 +13,9 @@ int mtk_vcodec_init_dec_pm(struct platform_device
> > *pdev,
> >   	struct mtk_vcodec_pm *pm);
> >   void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm);
> >   
> > -int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm);
> > -void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm);
> > -void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm);
> > -void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm);
> > +int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int
> > comp_idx);
> > +void mtk_vcodec_dec_pw_off(struct mtk_vcodec_dev *vdec_dev, int
> > comp_idx);
> > +void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int
> > comp_idx);
> > +void mtk_vcodec_dec_clock_off(struct mtk_vcodec_dev *vdec_dev, int
> > comp_idx);
> >   
> >   #endif /* _MTK_VCODEC_DEC_PM_H_ */
> > diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> > b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> > index ab401b2db30e..95c82cb4e568 100644
> > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> > @@ -284,6 +284,7 @@ struct vdec_pic_info {
> >    * @decoded_frame_cnt: number of decoded frames
> >    * @lock: protect variables accessed by V4L2 threads and worker
> > thread such as
> >    *	  mtk_video_dec_buf.
> > + * @hw_id: hardware index used to identify different hardware.
> >    *
> >    * @msg_queue: msg queue used to store lat buffer information.
> >    */
> > @@ -328,6 +329,7 @@ struct mtk_vcodec_ctx {
> >   
> >   	int decoded_frame_cnt;
> >   	struct mutex lock;
> > +	int hw_id;
> >   
> >   	struct vdec_msg_queue msg_queue;
> >   };
> > diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
> > b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
> > index ac5973b6735f..511b75e49fe7 100644
> > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
> > @@ -6,7 +6,10 @@
> >   */
> >   
> >   #include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/of_device.h>
> >   
> > +#include "mtk_vcodec_dec_hw.h"
> >   #include "mtk_vcodec_drv.h"
> >   #include "mtk_vcodec_util.h"
> >   
> > @@ -81,25 +84,87 @@ void mtk_vcodec_mem_free(struct mtk_vcodec_ctx
> > *data,
> >   }
> >   EXPORT_SYMBOL(mtk_vcodec_mem_free);
> >   
> > -void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *dev,
> > -	struct mtk_vcodec_ctx *ctx)
> > +void *mtk_vcodec_get_hw_dev(struct mtk_vcodec_dev *dev, int
> > comp_idx)
> >   {
> > -	unsigned long flags;
> > +	struct platform_device *hw_pdev;
> > +	struct device_node *node;
> > +	struct mtk_vdec_comp_dev *master_dev;
> > +
> > +	if (comp_idx >= MTK_VDEC_HW_MAX || comp_idx < 0) {
> > +		mtk_v4l2_err("Comp idx is out of range:%d", comp_idx);
> > +		return NULL;
> > +	}
> > +
> > +	if (dev->comp_dev[comp_idx])
> > +		return dev->comp_dev[comp_idx];
> > +
> > +	node = dev->component_node[comp_idx];
> > +	if (!node) {
> > +		mtk_v4l2_err("Get lat node fail:%d", comp_idx);
> > +		return NULL;
> > +	}
> > +
> > +	hw_pdev = of_find_device_by_node(node);
> > +	of_node_put(node);
> > +
> > +	if (WARN_ON(!hw_pdev)) {
> > +		mtk_v4l2_err("Get hw id(%d) node fail", comp_idx);
> > +		return NULL;
> > +	}
> > +
> > +	master_dev = platform_get_drvdata(hw_pdev);
> > +	if (!master_dev) {
> > +		mtk_v4l2_err("Get hw id(%d) pdev fail", comp_idx);
> > +		return NULL;
> > +	}
> >   
> > -	spin_lock_irqsave(&dev->irqlock, flags);
> > -	dev->curr_ctx = ctx;
> > -	spin_unlock_irqrestore(&dev->irqlock, flags);
> > +	dev->comp_dev[master_dev->comp_idx] = master_dev;
> > +	return master_dev;
> > +}
> > +EXPORT_SYMBOL(mtk_vcodec_get_hw_dev);
> > +
> > +void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *vdec_dev,
> > +	struct mtk_vcodec_ctx *ctx, int comp_idx)
> > +{
> > +	unsigned long flags;
> > +	struct mtk_vdec_comp_dev *comp_dev;
> > +
> > +	spin_lock_irqsave(&vdec_dev->irqlock, flags);
> > +	if (vdec_dev->vdec_pdata->is_comp_supported) {
> 
> here too...
> 
> > +		comp_dev = mtk_vcodec_get_hw_dev(vdec_dev, comp_idx);
> > +		if (!comp_dev) {
> > +			mtk_v4l2_err("Failed to get hw dev");
> > +			spin_unlock_irqrestore(&vdec_dev->irqlock,
> > flags);
> > +			return;
> > +		}
> > +		comp_dev->curr_ctx = ctx;
> > +	} else {
> > +		vdec_dev->curr_ctx = ctx;
> > +	}
> > +	spin_unlock_irqrestore(&vdec_dev->irqlock, flags);
> >   }
> >   EXPORT_SYMBOL(mtk_vcodec_set_curr_ctx);
> >   
> > -struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct
> > mtk_vcodec_dev *dev)
> > +struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct
> > mtk_vcodec_dev *vdec_dev,
> > +	unsigned int comp_idx)
> >   {
> >   	unsigned long flags;
> >   	struct mtk_vcodec_ctx *ctx;
> > -
> > -	spin_lock_irqsave(&dev->irqlock, flags);
> > -	ctx = dev->curr_ctx;
> > -	spin_unlock_irqrestore(&dev->irqlock, flags);
> > +	struct mtk_vdec_comp_dev *comp_dev;
> > +
> > +	spin_lock_irqsave(&vdec_dev->irqlock, flags);
> > +	if (vdec_dev->vdec_pdata->is_comp_supported) {
> 
> and here
> 
> > +		comp_dev = mtk_vcodec_get_hw_dev(vdec_dev, comp_idx);
> > +		if (!comp_dev) {
> > +			mtk_v4l2_err("Failed to get hw dev");
> > +			spin_unlock_irqrestore(&vdec_dev->irqlock,
> > flags);
> > +			return NULL;
> > +		}
> > +		ctx = comp_dev->curr_ctx;
> > +	} else {
> > +		ctx = vdec_dev->curr_ctx;
> > +	}
> > +	spin_unlock_irqrestore(&vdec_dev->irqlock, flags);
> >   	return ctx;
> >   }
> >   EXPORT_SYMBOL(mtk_vcodec_get_curr_ctx);
> > diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
> > b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
> > index b999d7b84ed1..4cb0fc60c94f 100644
> > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
> > @@ -79,8 +79,10 @@ int mtk_vcodec_mem_alloc(struct mtk_vcodec_ctx
> > *data,
> >   				struct mtk_vcodec_mem *mem);
> >   void mtk_vcodec_mem_free(struct mtk_vcodec_ctx *data,
> >   				struct mtk_vcodec_mem *mem);
> > -void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *dev,
> > -	struct mtk_vcodec_ctx *ctx);
> > -struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct
> > mtk_vcodec_dev *dev);
> > +void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *vdec_dev,
> > +				struct mtk_vcodec_ctx *ctx, int
> > comp_idx);
> > +struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct
> > mtk_vcodec_dev *vdec_dev,
> > +	unsigned int comp_idx);
> 
> Fix indentation please:
> 
> struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev
> *vdec_dev,
> 
> 					       unsigned int comp_idx);
> 
> Wil fix in patch v8.

Best Regards,
Yunfei Dong
> Regards,
> - Angelo

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v7, 08/15] media: mtk-vcodec: Add msg queue feature for lat and core architecture
  2021-10-14 10:35   ` AngeloGioacchino Del Regno
@ 2021-10-27  4:01     ` yunfei.dong
  0 siblings, 0 replies; 43+ messages in thread
From: yunfei.dong @ 2021-10-27  4:01 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Alexandre Courbot, Hans Verkuil,
	Tzung-Bi Shih, Tiffany Lin, Andrew-CT Chen,
	Mauro Carvalho Chehab, Rob Herring, Matthias Brugger,
	Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

Hi AngeloGioacchino,

Thanks for your suggestion.

On Thu, 2021-10-14 at 12:35 +0200, AngeloGioacchino Del Regno wrote:
> > For lat and core architecture, lat thread will send message to core
> > thread when lat decode done. Core hardware will use the message
> > from lat to decode, then free message to lat thread when decode
> > done.
> > 
> > Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
> > ---
> >   drivers/media/platform/mtk-vcodec/Makefile    |   1 +
> >   .../platform/mtk-vcodec/mtk_vcodec_drv.h      |   5 +
> >   .../platform/mtk-vcodec/vdec_msg_queue.c      | 258
> > ++++++++++++++++++
> >   .../platform/mtk-vcodec/vdec_msg_queue.h      | 151 ++++++++++
> >   4 files changed, 415 insertions(+)
> >   create mode 100644 drivers/media/platform/mtk-
> > vcodec/vdec_msg_queue.c
> >   create mode 100644 drivers/media/platform/mtk-
> > vcodec/vdec_msg_queue.h
> > 
> > diff --git a/drivers/media/platform/mtk-vcodec/Makefile
> > b/drivers/media/platform/mtk-vcodec/Makefile
> > index edeb3b66e9e9..5000e59da576 100644
> > --- a/drivers/media/platform/mtk-vcodec/Makefile
> > +++ b/drivers/media/platform/mtk-vcodec/Makefile
> > @@ -11,6 +11,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
> >   		mtk_vcodec_dec_drv.o \
> >   		vdec_drv_if.o \
> >   		vdec_vpu_if.o \
> > +		vdec_msg_queue.o \
> >   		mtk_vcodec_dec.o \
> >   		mtk_vcodec_dec_stateful.o \
> >   		mtk_vcodec_dec_stateless.o \
> > diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> > b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> > index f8e8b5ba408b..ab401b2db30e 100644
> > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> > @@ -15,7 +15,9 @@
> >   #include <media/v4l2-ioctl.h>
> >   #include <media/v4l2-mem2mem.h>
> >   #include <media/videobuf2-core.h>
> > +
> >   #include "mtk_vcodec_util.h"
> > +#include "vdec_msg_queue.h"
> >   
> >   #define MTK_VCODEC_DRV_NAME	"mtk_vcodec_drv"
> >   #define MTK_VCODEC_DEC_NAME	"mtk-vcodec-dec"
> > @@ -282,6 +284,8 @@ struct vdec_pic_info {
> >    * @decoded_frame_cnt: number of decoded frames
> >    * @lock: protect variables accessed by V4L2 threads and worker
> > thread such as
> >    *	  mtk_video_dec_buf.
> > + *
> > + * @msg_queue: msg queue used to store lat buffer information.
> >    */
> >   struct mtk_vcodec_ctx {
> >   	enum mtk_instance_type type;
> > @@ -325,6 +329,7 @@ struct mtk_vcodec_ctx {
> >   	int decoded_frame_cnt;
> >   	struct mutex lock;
> >   
> > +	struct vdec_msg_queue msg_queue;
> >   };
> >   
> >   enum mtk_chip {
> > diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
> > b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
> > new file mode 100644
> > index 000000000000..d66ed98c79a9
> > --- /dev/null
> > +++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
> > @@ -0,0 +1,258 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2021 MediaTek Inc.
> > + * Author: Yunfei Dong <yunfei.dong@mediatek.com>
> > + */
> > +
> > +#include <linux/freezer.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/kthread.h>
> > +
> > +#include "mtk_vcodec_dec_pm.h"
> > +#include "mtk_vcodec_drv.h"
> > +#include "vdec_msg_queue.h"
> > +
> > +#define VDEC_LAT_SLICE_HEADER_SZ    (640 * 1024)
> 
> This can be 640 * SZ_1K, or 5 * SZ_128K....
> ...if applicable, please multiply as value * alignment, such that,
> for example,
> if the data needs to be 1K aligned, you should prefer writing it as
> 640 * SZ_1K.
> 
> > +#define VDEC_ERR_MAP_SZ_AVC         ((8192 / 16) * (4352 / 16) /
> > 8)
> 
Fix in v8.
> ...and you could do the same here... except, I see some sizes here
> being divided
> and multiplied and I take that as a hint.
> In that case, when you convert it to use sizes definitions, it would
> be very nice
> if you keep that hint / better describe it in a comment.
> 
Fix in v8.
> > +
> > +/* lat write decoded hardware information to trans buffer,
> > + * and core will read the trans buffer to decode again. The
> > + * trans buffer size of FHD and 4K bitstreams are different.
> > + */
> > +static int vde_msg_queue_get_trans_size(int width, int height)
> > +{
> > +	if (width > 1920 || height > 1088)
> > +		return (30 * 1024 * 1024);
> 
> So here we're referring to buffer sizes. 1024 * 1024 is SZ_1M, as
> defined in
> linux/sizes.h.
> 
> Means that this can be simply
> 
> 		return 30 * SZ_1M;
> 
> > +	else
> > +		return 6 * 1024 * 1024;
> 
> 		return 6 * SZ_1M;
> 
Fix in v8.
> > +}
> > +
> > +void vdec_msg_queue_init_ctx(struct vdec_msg_queue_ctx *ctx,
> > +	int hardware_index)
> > +{
> > +	init_waitqueue_head(&ctx->ready_to_use);
> > +	INIT_LIST_HEAD(&ctx->ready_queue);
> > +	spin_lock_init(&ctx->ready_lock);
> > +	ctx->ready_num = 0;
> > +	ctx->hardware_index = hardware_index;
> > +}
> > +
> > +int vdec_msg_queue_init(
> > +	struct vdec_msg_queue *msg_queue,
> > +	struct mtk_vcodec_ctx *ctx,
> > +	core_decode_cb_t core_decode,
> > +	int private_size)
> > +{
> > +	struct vdec_lat_buf *lat_buf;
> > +	int i, err;
> > +
> > +	/* already init msg queue */
> > +	if (msg_queue->wdma_addr.size)
> > +		return 0;
> > +
> > +	vdec_msg_queue_init_ctx(&msg_queue->lat_ctx, MTK_VDEC_LAT0);
> > +	msg_queue->wdma_addr.size = vde_msg_queue_get_trans_size(
> > +		ctx->picinfo.buf_w, ctx->picinfo.buf_h);
> > +
> > +	err = mtk_vcodec_mem_alloc(ctx, &msg_queue->wdma_addr);
> > +	if (err) {
> > +		mtk_v4l2_err("failed to allocate wdma_addr buf");
> > +		return -ENOMEM;
> > +	}
> > +	msg_queue->wdma_rptr_addr = msg_queue->wdma_addr.dma_addr;
> > +	msg_queue->wdma_wptr_addr = msg_queue->wdma_addr.dma_addr;
> > +
> > +	for (i = 0; i < NUM_BUFFER_COUNT; i++) {
> > +		lat_buf = &msg_queue->lat_buf[i];
> > +
> > +		lat_buf->wdma_err_addr.size = VDEC_ERR_MAP_SZ_AVC;
> > +		err = mtk_vcodec_mem_alloc(ctx, &lat_buf-
> > >wdma_err_addr);
> > +		if (err) {
> > +			mtk_v4l2_err("failed to allocate wdma_err_addr
> > buf[%d]", i);
> > +			goto mem_alloc_err;
> > +		}
> > +
> > +		lat_buf->slice_bc_addr.size = VDEC_LAT_SLICE_HEADER_SZ;
> > +		err = mtk_vcodec_mem_alloc(ctx, &lat_buf-
> > >slice_bc_addr);
> > +		if (err) {
> > +			mtk_v4l2_err("failed to allocate wdma_addr
> > buf[%d]", i);
> > +			goto mem_alloc_err;
> > +		}
> > +
> > +		lat_buf->private_data = kzalloc(private_size,
> > GFP_KERNEL);
> > +		if (!lat_buf->private_data) {
> > +			mtk_v4l2_err("failed to allocate
> > private_data[%d]", i);
> > +			goto mem_alloc_err;
> > +		}
> > +
> > +		lat_buf->ctx = ctx;
> > +		lat_buf->core_decode = core_decode;
> > +		vdec_msg_queue_qbuf(&msg_queue->lat_ctx, lat_buf);
> > +	}
> > +	return 0;
> > +
> > +mem_alloc_err:
> > +	vdec_msg_queue_deinit(msg_queue, ctx);
> > +	return -ENOMEM;
> > +}
> > +
> > +static struct list_head *vdec_get_buf_list(int hardware_index,
> > +	struct vdec_lat_buf *buf)
> > +{
> > +	switch (hardware_index) {
> > +	case MTK_VDEC_CORE:
> > +		return &buf->core_list;
> > +	case MTK_VDEC_LAT0:
> > +		return &buf->lat_list;
> > +	default:
> > +		return NULL;
> > +	}
> > +}
> > +
> > +void vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *ctx,
> > +	struct vdec_lat_buf *buf)
> > +{
> > +	struct list_head *head;
> > +
> > +	head = vdec_get_buf_list(ctx->hardware_index, buf);
> > +	if (!head) {
> > +		mtk_v4l2_err("fail to qbuf: %d",ctx->hardware_index);
> > +		return;
> > +	}
> > +
> > +	spin_lock(&ctx->ready_lock);
> > +	list_add_tail(head, &ctx->ready_queue);
> > +	ctx->ready_num++;
> > +
> > +	wake_up_all(&ctx->ready_to_use);
> > +
> > +	mtk_v4l2_debug(3, "enqueue buf type: %d addr: 0x%p num: %d",
> > +		ctx->hardware_index, buf, ctx->ready_num);
> > +	spin_unlock(&ctx->ready_lock);
> > +}
> > +
> > +static bool vdec_msg_queue_wait_event(struct vdec_msg_queue_ctx
> > *ctx)
> > +{
> > +	long timeout_jiff;
> > +	int ret;
> > +
> > +	if (ctx->hardware_index == MTK_VDEC_CORE) {
> > +		ret = wait_event_freezable(ctx->ready_to_use,
> > +			!list_empty(&ctx->ready_queue));
> > +		if (ret)
> > +			return false;
> > +	} else {
> > +		timeout_jiff = msecs_to_jiffies(1500);
> > +		ret = wait_event_timeout(ctx->ready_to_use,
> > +			!list_empty(&ctx->ready_queue), timeout_jiff);
> 
> Suggestion (feel free to not follow this one): since you're using
> that
> msecs_to_jiffies(1500) return value only for this wait_event_timeout
> call,
> you may as well remove the timeout_jiff variable and simply do
> 
> 		ret = wait_event_timeout(ctx->ready_to_use,
> 
> 					 !list_empty(&ctx-
> >ready_queue),
> 	
Fix in v8.
> 				 msecs_to_jiffies(1500));
> 
> > +		if (!ret)
> > +			return false;
> > +	}
> > +
> > +	return true;
> > +}
> > +
> > +struct vdec_lat_buf *vdec_msg_queue_dqbuf(struct
> > vdec_msg_queue_ctx *ctx)
> > +{
> > +	struct vdec_lat_buf *buf;
> > +	struct list_head *head;
> > +	int ret;
> > +
> > +	spin_lock(&ctx->ready_lock);
> > +	if (list_empty(&ctx->ready_queue)) {
> > +		mtk_v4l2_debug(3, "queue is NULL, type:%d num: %d",
> > +			ctx->hardware_index, ctx->ready_num);
> > +		spin_unlock(&ctx->ready_lock);
> > +		ret = vdec_msg_queue_wait_event(ctx);
> > +		if (!ret)
> > +			return NULL;
> > +		spin_lock(&ctx->ready_lock);
> > +	}
> > +
> > +	if (ctx->hardware_index == MTK_VDEC_CORE)
> > +		buf = list_first_entry(&ctx->ready_queue,
> > +			struct vdec_lat_buf, core_list);
> > +	else
> > +		buf = list_first_entry(&ctx->ready_queue,
> > +			struct vdec_lat_buf, lat_list);
> > +
> > +	head = vdec_get_buf_list(ctx->hardware_index, buf);
> > +	if (!head) {
> > +		mtk_v4l2_err("fail to dqbuf: %d",ctx->hardware_index);
> > +		return NULL;
> > +	}
> > +	list_del(head);
> > +
> > +	ctx->ready_num--;
> > +	mtk_v4l2_debug(3, "dqueue buf type:%d addr: 0x%p num: %d",
> > +		ctx->hardware_index, buf, ctx->ready_num);
> > +	spin_unlock(&ctx->ready_lock);
> > +
> > +	return buf;
> > +}
> > +
> > +void vdec_msg_queue_update_ube_rptr(struct vdec_msg_queue
> > *msg_queue,
> > +	uint64_t ube_rptr)
> > +{
> > +	spin_lock(&msg_queue->lat_ctx.ready_lock);
> > +	msg_queue->wdma_rptr_addr = ube_rptr;
> > +	mtk_v4l2_debug(3, "update ube rprt (0x%llx)", ube_rptr);
> > +	spin_unlock(&msg_queue->lat_ctx.ready_lock);
> > +}
> > +
> > +void vdec_msg_queue_update_ube_wptr(struct vdec_msg_queue
> > *msg_queue,
> > +	uint64_t ube_wptr)
> > +{
> > +	spin_lock(&msg_queue->lat_ctx.ready_lock);
> > +	msg_queue->wdma_wptr_addr = ube_wptr;
> > +	mtk_v4l2_debug(3, "update ube wprt: (0x%llx 0x%llx) offset:
> > 0x%llx",
> > +		msg_queue->wdma_rptr_addr, msg_queue->wdma_wptr_addr,
> > ube_wptr);
> > +	spin_unlock(&msg_queue->lat_ctx.ready_lock);
> > +}
> > +
> > +bool vdec_msg_queue_wait_lat_buf_full(struct vdec_msg_queue
> > *msg_queue)
> > +{
> > +	long timeout_jiff;
> > +	int ret;
> > +
> > +	timeout_jiff = msecs_to_jiffies(1000 * (NUM_BUFFER_COUNT + 2));
> > +
> > +	ret = wait_event_timeout(msg_queue->lat_ctx.ready_to_use,
> > +		msg_queue->lat_ctx.ready_num == NUM_BUFFER_COUNT,
> > +		timeout_jiff);
> > +	if (ret) {
> > +		mtk_v4l2_debug(3, "success to get lat buf: %d",
> > +			msg_queue->lat_ctx.ready_num);
> > +		return true;
> > +	}
> > +	mtk_v4l2_err("failed with lat buf isn't full: %d",
> > +		msg_queue->lat_ctx.ready_num);
> > +	return false;
> > +}
> > +
> > +void vdec_msg_queue_deinit(
> > +	struct vdec_msg_queue *msg_queue,
> > +	struct mtk_vcodec_ctx *ctx)
> > +{
> > +	struct vdec_lat_buf *lat_buf;
> > +	struct mtk_vcodec_mem *mem;
> > +	int i;
> > +
> > +	mem = &msg_queue->wdma_addr;
> > +	if (mem->va)
> > +		mtk_vcodec_mem_free(ctx, mem);
> > +	for (i = 0; i < NUM_BUFFER_COUNT; i++) {
> > +		lat_buf = &msg_queue->lat_buf[i];
> > +
> > +		mem = &lat_buf->wdma_err_addr;
> > +		if (mem->va)
> > +			mtk_vcodec_mem_free(ctx, mem);
> > +
> > +		mem = &lat_buf->slice_bc_addr;
> > +		if (mem->va)
> > +			mtk_vcodec_mem_free(ctx, mem);
> > +
> > +		if (lat_buf->private_data)
> > +			kfree(lat_buf->private_data);
> > +	}
> > +}
> > diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
> > b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
> > new file mode 100644
> > index 000000000000..1905ce713592
> > --- /dev/null
> > +++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
> > @@ -0,0 +1,151 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2021 MediaTek Inc.
> > + * Author: Yunfei Dong <yunfei.dong@mediatek.com>
> > + */
> > +
> > +#ifndef _VDEC_MSG_QUEUE_H_
> > +#define _VDEC_MSG_QUEUE_H_
> > +
> > +#include <linux/sched.h>
> > +#include <linux/semaphore.h>
> > +#include <linux/slab.h>
> > +#include <media/videobuf2-v4l2.h>
> > +
> > +#include "mtk_vcodec_util.h"
> > +
> > +#define NUM_BUFFER_COUNT 3
> > +
> > +struct vdec_lat_buf;
> > +struct mtk_vcodec_ctx;
> > +struct mtk_vcodec_dev;
> > +typedef int (*core_decode_cb_t)(struct vdec_lat_buf *lat_buf);
> > +
> > +/**
> > + * struct vdec_msg_queue_ctx - represents a queue for buffers
> > ready to be
> > + *	                           processed
> 
> I would prefer if you don't break this line, 84 columns is fine to
> have.
> 
Fix in v8.> > + * @ready_used: ready used queue used to signalize when get a job
> > queue
> > + * @ready_queue: list of ready lat buffer queues
> > + * @ready_lock: spin lock to protect the lat buffer usage
> > + * @ready_num: number of buffers ready to be processed
> > + * @hardware_index: hardware id that this queue is used for
> > + */
> > +struct vdec_msg_queue_ctx {
> > +	wait_queue_head_t ready_to_use;
> > +	struct list_head ready_queue;
> > +	spinlock_t ready_lock;
> > +	int ready_num;
> > +	int hardware_index;
> > +};
> > +
> > +/**
> > + * struct vdec_lat_buf - lat buffer message used to store lat
> > + *                       info for core decode
> > + * @wdma_err_addr: wdma error address used for lat hardware
> > + * @slice_bc_addr: slice bc address used for lat hardware
> > + * @ts_info: need to set timestamp from output to capture
> > + *
> > + * @private_data: shared information used to lat and core hardware
> > + * @ctx: mtk vcodec context information
> > + * @core_decode: different codec use different decode callback
> > function
> > + * @lat_list: add lat buffer to lat head list
> > + * @core_list: add lat buffer to core head list
> > + */
> > +struct vdec_lat_buf {
> > +	struct mtk_vcodec_mem wdma_err_addr;
> > +	struct mtk_vcodec_mem slice_bc_addr;
> > +	struct vb2_v4l2_buffer ts_info;
> > +
> > +	void *private_data;
> > +	struct mtk_vcodec_ctx *ctx;
> > +	core_decode_cb_t core_decode;
> > +	struct list_head lat_list;
> > +	struct list_head core_list;
> > +};
> > +
> > +/**
> > + * struct vdec_msg_queue - used to store lat buffer message
> > + * @lat_buf: lat buffer used to store lat buffer information
> > + * @wdma_addr: wdma address used for ube
> > + * @wdma_rptr_addr: ube read point
> > + * @wdma_wptr_addr: ube write point
> > + * @lat_ctx: used to store lat buffer list
> > + */
> > +struct vdec_msg_queue {
> > +	struct vdec_lat_buf lat_buf[NUM_BUFFER_COUNT];
> > +
> > +	struct mtk_vcodec_mem wdma_addr;
> > +	uint64_t wdma_rptr_addr;
> > +	uint64_t wdma_wptr_addr;
> > +
> > +	struct vdec_msg_queue_ctx lat_ctx;
> > +};
> > +
> > +/**
> > + * vdec_msg_queue_init - init lat buffer information.
> > + * @msg_queue: used to store the lat buffer information
> > + * @ctx: v4l2 ctx
> > + * @core_decode: core decode callback for each codec
> > + * @private_size: the private data size used to share with core
> > + */
> > +int vdec_msg_queue_init(
> > +	struct vdec_msg_queue *msg_queue,
> > +	struct mtk_vcodec_ctx *ctx,
> > +	core_decode_cb_t core_decode,
> > +	int private_size);
> > +
> > +/**
> > + * vdec_msg_queue_init_ctx - used to init msg queue context
> > information.
> > + * @ctx: message queue context
> > + * @hardware_index: hardware index
> > + */
> > +void vdec_msg_queue_init_ctx(struct vdec_msg_queue_ctx *ctx,
> > +	int hardware_index);
> > +
> > +/**
> > + * vdec_msg_queue_qbuf - enqueue lat buffer to queue list.
> > + * @ctx: message queue context
> > + * @buf: current lat buffer
> > + */
> > +void vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *ctx,
> > +	struct vdec_lat_buf *buf);
> > +
> > +/**
> > + * vdec_msg_queue_dqbuf - dequeue lat buffer from queue list.
> > + * @ctx: message queue context
> > + */
> > +struct vdec_lat_buf *vdec_msg_queue_dqbuf(struct
> > vdec_msg_queue_ctx *ctx);
> > +
> > +/**
> > + * vdec_msg_queue_update_ube_rptr - used to updata the ube read
> > point.
> > + * @msg_queue: used to store the lat buffer information
> > + * @ube_rptr: current ube read point
> > + */
> > +void vdec_msg_queue_update_ube_rptr(struct vdec_msg_queue
> > *msg_queue,
> > +	uint64_t ube_rptr);
> > +
> > +/**
> > + * vdec_msg_queue_update_ube_wptr - used to updata the ube write
> > point.
> > + * @msg_queue: used to store the lat buffer information
> > + * @ube_wptr: current ube write point
> > + */
> > +void vdec_msg_queue_update_ube_wptr(struct vdec_msg_queue
> > *msg_queue,
> > +	uint64_t ube_wptr);
> > +
> > +/**
> > + * vdec_msg_queue_wait_lat_buf_full - used to check whether all
> > lat buffer
> > + *                                    in lat list.
> > + * @msg_queue: used to store the lat buffer information
> > + */
> > +bool vdec_msg_queue_wait_lat_buf_full(struct vdec_msg_queue
> > *msg_queue);
> > +
> > +/**
> > + * vdec_msg_queue_deinit - deinit lat buffer information.
> > + * @msg_queue: used to store the lat buffer information
> > + * @ctx: v4l2 ctx
> > + */
> > +void vdec_msg_queue_deinit(
> > +	struct vdec_msg_queue *msg_queue,
> > +	struct mtk_vcodec_ctx *ctx);
> > +
> 
> void vdec_msg_queue_deinit(struct vdec_msg_queue *msg_queue,
> 			   struct mtk_vcodec_ctx *ctx);
> > +#endif
> > 
> 
> Regards,
> - Angelo
Best Regards,
Yunfei Dong

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v7, 07/15] media: mtk-vcodec: Add irq interface for multi hardware
  2021-10-14 10:04   ` AngeloGioacchino Del Regno
@ 2021-10-27 11:36     ` yunfei.dong
  0 siblings, 0 replies; 43+ messages in thread
From: yunfei.dong @ 2021-10-27 11:36 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Alexandre Courbot, Hans Verkuil,
	Tzung-Bi Shih, Tiffany Lin, Andrew-CT Chen,
	Mauro Carvalho Chehab, Rob Herring, Matthias Brugger,
	Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

Hi AngeloGioacchino,

Thanks for your suggestion.

On Thu, 2021-10-14 at 12:04 +0200, AngeloGioacchino Del Regno wrote:
> > Adds irq interface for multi hardware.
> > 
> > Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
> > ---
> >   .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 33
> > +++++++++++++++++--
> >   .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   |  2 +-
> >   .../platform/mtk-vcodec/mtk_vcodec_drv.h      | 25 ++++++++++----
> >   .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |  4 +--
> >   .../platform/mtk-vcodec/mtk_vcodec_intr.c     | 27 +++++++-------
> > -
> >   .../platform/mtk-vcodec/mtk_vcodec_intr.h     |  4 +--
> >   .../platform/mtk-vcodec/vdec/vdec_h264_if.c   |  2 +-
> >   .../mtk-vcodec/vdec/vdec_h264_req_if.c        |  2 +-
> >   .../platform/mtk-vcodec/vdec/vdec_vp8_if.c    |  2 +-
> >   .../platform/mtk-vcodec/vdec/vdec_vp9_if.c    |  2 +-
> >   .../platform/mtk-vcodec/venc/venc_h264_if.c   |  2 +-
> >   .../platform/mtk-vcodec/venc/venc_vp8_if.c    |  2 +-
> >   12 files changed, 71 insertions(+), 36 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 17cb3e3519eb..ff70fa5b34e3 100644
> > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
> > @@ -73,6 +73,20 @@ static int mtk_vcodec_comp_device_check(struct
> > mtk_vcodec_ctx *ctx)
> >   	return 0;
> >   }
> >   
> > +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("not support hw arch:%d",
> > +			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;
> > @@ -104,7 +118,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",
> > @@ -176,7 +190,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);
> > @@ -190,7 +204,19 @@ 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);
> > +
> > +	if (ctx->dev->vdec_pdata->is_comp_supported) {
> 
> As pointed out in the review for patch 04/15 of this series,
> is_comp_supported
> is always false since you moved away from the component framework.
> 
> That means that this code can be removed, as nothing ever hits that.
> 
> Please note that other patches in this series are following
> similar/same patterns,
> so this comment applies to the entire series.
> 
> > +		hw_count = mtk_vcodec_get_hw_count(dev);
> > +		if (!hw_count) {
> > +			ret = -EINVAL;
> > +			goto err_init_queue;
> > +		}
> > +		for (i = 0; i < hw_count; i++)
> > +			init_waitqueue_head(&ctx->queue[i]);
> > +	} else {
> > +			init_waitqueue_head(&ctx->queue[0]);
> > +	}
> > +
> >   	mutex_init(&ctx->lock);
> >   
> >   	ret = mtk_vcodec_comp_device_check(ctx);
> > @@ -253,6 +279,7 @@ static int fops_vcodec_open(struct file *file)
> >   err_m2m_ctx_init:
> >   	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
> >   err_ctrls_setup:
> > +err_init_queue:
> 
> ...and if that unused component code gets removed, this label can
> also be removed.
> 
For add 8192 to support component, these code need to keep.
> >   	v4l2_fh_del(&ctx->fh);
> >   	v4l2_fh_exit(&ctx->fh);
> >   	kfree(ctx);
> > diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
> > b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
> > index 3752ccaea284..0997a5a08156 100644
> > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
> > @@ -56,7 +56,7 @@ static irqreturn_t mtk_vdec_comp_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->comp_idx);
> >   
> >   	mtk_v4l2_debug(3, "wake up ctx %d, dec_done_status=%x",
> >   		ctx->id, dec_done_status);
> > diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> > b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> > index 140f1a761942..f8e8b5ba408b 100644
> > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> > @@ -104,6 +104,16 @@ enum mtk_vdec_hw_id {
> >   	MTK_VDEC_HW_MAX,
> >   };
> >   
> > +/**
> > + * struct 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;
> > @@ -505,11 +515,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_ */
> > diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c 
> > b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
> > index 2828df77020c..c7540c0cdcea 100644
> > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
> > @@ -114,7 +114,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;
> >   }
> >   
> > @@ -140,7 +140,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);
> > diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c
> > b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c
> > index 70580c2525ba..8147533da98b 100644
> > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c
> > @@ -11,34 +11,31 @@
> >   #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 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,
> > +	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;
> >   }
> > diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h
> > b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h
> > index 638cd1f3526a..2bf4cabfaa43 100644
> > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h
> > @@ -12,7 +12,7 @@
> >   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_ */
> > diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c
> > b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c
> > index 40d6e6c5ac7a..481655bb6016 100644
> > --- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c
> > +++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c
> > @@ -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_RECEIVE
> > D,
> > -						   WAIT_INTR_TIMEOUT_MS
> > );
> > +						   WAIT_INTR_TIMEOUT_MS
> > , 0);
> >   		if (err)
> >   			goto err_free_fb_out;
> >   
> > diff --git a/drivers/media/platform/mtk-
> > vcodec/vdec/vdec_h264_req_if.c b/drivers/media/platform/mtk-
> > vcodec/vdec/vdec_h264_req_if.c
> > index 4dde9ee786b4..d23baa364246 100644
> > --- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
> > +++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
> > @@ -724,7 +724,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);
> > diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c
> > b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c
> > index e5393f841080..88c046731754 100644
> > --- a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c
> > +++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c
> > @@ -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);
> > diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c
> > b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c
> > index 71cdc3ddafcb..70b8383f7c8e 100644
> > --- a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c
> > +++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c
> > @@ -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;
> > diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
> > b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
> > index b6a4f2074fa5..9ae1bd8dbc32 100644
> > --- a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
> > +++ b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
> > @@ -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);
> >   	}
> > diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
> > b/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
> > index 8267a9c4fd25..f96564277577 100644
> > --- a/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
> > +++ b/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
> > @@ -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);
> >   	}
> > 
Thanks,
Yunfei Dong

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v7, 04/15] media: mtk-vcodec: Manage multi hardware information
  2021-10-14  9:20   ` AngeloGioacchino Del Regno
@ 2021-10-29  3:05     ` yunfei.dong
  0 siblings, 0 replies; 43+ messages in thread
From: yunfei.dong @ 2021-10-29  3:05 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Alexandre Courbot, Hans Verkuil,
	Tzung-Bi Shih, Tiffany Lin, Andrew-CT Chen,
	Mauro Carvalho Chehab, Rob Herring, Matthias Brugger,
	Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Dafna Hirschfeld, Benjamin Gaignard,
	Daniel Vetter, dri-devel, Irui Wang, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

Hi AngeloGioacchino,

Thanks for your suggestion.

On Thu, 2021-10-14 at 11:20 +0200, AngeloGioacchino Del Regno wrote:
> > Manage each hardware information which includes irq/power/clk.
> > The hardware includes LAT0, LAT1 and CORE.
> > 
> > Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
> > ---
> > v7: Using of_platform_populate not component framework to manage
> > multi hardware.
> > ---
> >   drivers/media/platform/mtk-vcodec/Makefile    |   1 +
> >   .../platform/mtk-vcodec/mtk_vcodec_dec.h      |   1 +
> >   .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 151 ++++++++++++-
> > ---
> >   .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   | 165
> > ++++++++++++++++++
> >   .../platform/mtk-vcodec/mtk_vcodec_dec_hw.h   |  49 ++++++
> >   .../mtk-vcodec/mtk_vcodec_dec_stateful.c      |   1 +
> >   .../mtk-vcodec/mtk_vcodec_dec_stateless.c     |   1 +
> >   .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  23 +++
> >   8 files changed, 359 insertions(+), 33 deletions(-)
> >   create mode 100644 drivers/media/platform/mtk-
> > vcodec/mtk_vcodec_dec_hw.c
> >   create mode 100644 drivers/media/platform/mtk-
> > vcodec/mtk_vcodec_dec_hw.h
> > 
> 
> 
> 
> Hello Yunfei,
> 
> thanks for this great series! However, there are a few things to
> improve...
> 
> > diff --git a/drivers/media/platform/mtk-vcodec/Makefile
> > b/drivers/media/platform/mtk-vcodec/Makefile
> > index ca8e9e7a9c4e..edeb3b66e9e9 100644
> > --- a/drivers/media/platform/mtk-vcodec/Makefile
> > +++ b/drivers/media/platform/mtk-vcodec/Makefile
> > @@ -15,6 +15,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
> >   		mtk_vcodec_dec_stateful.o \
> >   		mtk_vcodec_dec_stateless.o \
> >   		mtk_vcodec_dec_pm.o \
> > +		mtk_vcodec_dec_hw.o \
> >   
> >   mtk-vcodec-enc-y := venc/venc_vp8_if.o \
> >   		venc/venc_h264_if.o \
> > diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
> > b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
> > index 9fbd24186c1a..c509224cbff4 100644
> > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
> > @@ -66,6 +66,7 @@ extern const struct v4l2_ioctl_ops
> > mtk_vdec_ioctl_ops;
> >   extern const struct v4l2_m2m_ops mtk_vdec_m2m_ops;
> >   extern const struct media_device_ops mtk_vcodec_media_ops;
> >   
> > +extern struct platform_driver mtk_vdec_comp_driver;
> 
> This may be useless... more on that later in this review.
> 
Remove in patch v8.
> >   
> >   /*
> >    * mtk_vdec_lock/mtk_vdec_unlock are for ctx instance to
> > 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 dd749d41c75a..17cb3e3519eb 100644
> > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
> > @@ -18,19 +18,61 @@
> >   
> >   #include "mtk_vcodec_drv.h"
> >   #include "mtk_vcodec_dec.h"
> > +#include "mtk_vcodec_dec_hw.h"
> >   #include "mtk_vcodec_dec_pm.h"
> >   #include "mtk_vcodec_intr.h"
> > -#include "mtk_vcodec_util.h"
> >   #include "mtk_vcodec_fw.h"
> >   
> > -#define VDEC_HW_ACTIVE	0x10
> > -#define VDEC_IRQ_CFG	0x11
> > -#define VDEC_IRQ_CLR	0x10
> > -#define VDEC_IRQ_CFG_REG	0xa4
> > -
> >   module_param(mtk_v4l2_dbg_level, int, 0644);
> >   module_param(mtk_vcodec_dbg, bool, 0644);
> >   
> > +static struct of_device_id mtk_vdec_drv_ids[] = {
> > +	{
> > +		.compatible = "mediatek,mtk-vcodec-lat",
> > +		.data = (void *)MTK_VDEC_LAT0,
> > +	},
> > +	{
> > +		.compatible = "mediatek,mtk-vcodec-core",
> > +		.data = (void *)MTK_VDEC_CORE,
> > +	},
> > +	{},
> > +};
> 
> Is this a duplicate of "mtk_vdec_comp_ids", found in
> mtk_vcodec_dec_hw.c?!
> 
Will change it.
> > +
> > +static int mtk_vcodec_comp_device_check(struct mtk_vcodec_ctx
> > *ctx)
> > + {
> > +	struct mtk_vcodec_dev *vdec_dev = ctx->dev;
> > +	struct platform_device *pdev = vdec_dev->plat_dev;
> > +	struct device_node *comp_node;
> > +	enum mtk_vdec_hw_id comp_idx;
> > +	const struct of_device_id *of_id;
> > +	int i;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(mtk_vdec_drv_ids); i++) {
> > +		of_id = &mtk_vdec_drv_ids[i];
> > +		comp_node = of_find_compatible_node(NULL, NULL,
> > +			of_id->compatible);
> > +		if (!comp_node)
> > +			continue;
> > +
> > +		if (!of_device_is_available(comp_node)) {
> > +			of_node_put(comp_node);
> > +			dev_err(&pdev->dev, "Fail to get MMSYS
> > node\n");
> > +			continue;
> > +		}
> > +
> > +		comp_idx = (enum mtk_vdec_hw_id)of_id->data;
> > +		vdec_dev->component_node[comp_idx] = comp_node;
> > +
> > +		if (!test_bit(comp_idx, vdec_dev->hardware_bitmap)) {
> > +			dev_err(&pdev->dev, "Vdec comp_idx is not ready
> > %d.",
> > +				comp_idx);
> > +			return -EINVAL;
> > +		}
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> >   static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void
> > *priv)
> >   {
> >   	struct mtk_vcodec_dev *dev = priv;
> > @@ -95,6 +137,41 @@ static int mtk_vcodec_get_reg_bases(struct
> > mtk_vcodec_dev *dev)
> >   	return 0;
> >   }
> >   
> > +static int mtk_vcodec_init_dec_params(struct mtk_vcodec_dev *dev)
> > +{
> > +	struct platform_device *pdev = dev->plat_dev;
> > +	int ret;
> > +
> > +	ret = mtk_vcodec_get_reg_bases(dev);
> > +	if (ret)
> > +		return ret;
> > +
> > +	if (!dev->vdec_pdata->is_comp_supported) {
> 
> component is never supported (is_comp_supported is always false), so
> this check
> is useless.
8192 need to support new architecture, but 8183 still use the older
one.
> 
> > +		dev->dec_irq = platform_get_irq(pdev, 0);
> > +		if (dev->dec_irq < 0) {
> > +			dev_err(&pdev->dev, "failed to get irq
> > number");
> > +			return dev->dec_irq;
> > +		}
> > +
> > +		irq_set_status_flags(dev->dec_irq, IRQ_NOAUTOEN);
> > +		ret = devm_request_irq(&pdev->dev, dev->dec_irq,
> > +			mtk_vcodec_dec_irq_handler, 0, pdev->name,
> > dev);
> > +		if (ret) {
> > +			dev_err(&pdev->dev, "failed to install dev-
> > >dec_irq %d (%d)",
> > +				dev->dec_irq, ret);
> > +			return ret;
> > +		}
> > +
> > +		ret = mtk_vcodec_init_dec_pm(pdev, &dev->pm);
> > +		if (ret < 0) {
> > +			dev_err(&pdev->dev, "failed to get mt vcodec
> > clock source");
> > +			return ret;
> > +		}
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> >   static int fops_vcodec_open(struct file *file)
> >   {
> >   	struct mtk_vcodec_dev *dev = video_drvdata(file);
> > @@ -116,6 +193,12 @@ static int fops_vcodec_open(struct file *file)
> >   	init_waitqueue_head(&ctx->queue);
> >   	mutex_init(&ctx->lock);
> >   
> > +	ret = mtk_vcodec_comp_device_check(ctx);
> 
> Are you checking available devices outside of a probe function?
>  From what I can see, you require that the MMSYS device is available
> at this
> time, but that's something that should be granted if we reach this
> point.
> 
> I would say that this driver probe should be deferred until the MMSYS
> device
> becomes available, since it's required for this to work and since,
> once that
> device gets registered and probed successfully, it'll never go away
> (unless
> module unloaded, but you can't unload module A if module B is using
> it, or
> depends on it, unless you also unload module B): like this, you will
> avoid
> performing N useless checks, everytime the userspace opens the vdec
> device.
> 
The master device(parent node) is available, but the component(child
node) device is also ready? Need to register irq, open/close power and
clock using component device. This function just used to check whether
the component device is ready to use.
> > +	if (ret) {
> > +		mtk_v4l2_err("Failed to check vdec comp device.");
> > +		goto err_ctrls_setup;
> > +	}
> > +
> >   	ctx->type = MTK_INST_DECODER;
> >   	ret = dev->vdec_pdata->ctrls_setup(ctx);
> >   	if (ret) {
> > @@ -220,7 +303,6 @@ 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 ret;
> > @@ -249,32 +331,10 @@ static int mtk_vcodec_probe(struct
> > platform_device *pdev)
> >   	if (IS_ERR(dev->fw_handler))
> >   		return PTR_ERR(dev->fw_handler);
> >   
> > -	ret = mtk_vcodec_init_dec_pm(dev->plat_dev, &dev->pm);
> > -	if (ret < 0) {
> > -		dev_err(&pdev->dev, "Failed to get mt vcodec clock
> > source");
> > -		goto err_dec_pm;
> > -	}
> > -
> > -	ret = mtk_vcodec_get_reg_bases(dev);
> > -	if (ret)
> > -		goto err_res;
> > -
> > -	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
> > -	if (res == NULL) {
> > -		dev_err(&pdev->dev, "failed to get irq resource");
> > -		ret = -ENOENT;
> > -		goto err_res;
> > -	}
> > -
> > -	dev->dec_irq = platform_get_irq(pdev, 0);
> > -	irq_set_status_flags(dev->dec_irq, IRQ_NOAUTOEN);
> > -	ret = devm_request_irq(&pdev->dev, dev->dec_irq,
> > -			mtk_vcodec_dec_irq_handler, 0, pdev->name,
> > dev);
> > +	ret = mtk_vcodec_init_dec_params(dev);
> >   	if (ret) {
> > -		dev_err(&pdev->dev, "Failed to install dev->dec_irq %d
> > (%d)",
> > -			dev->dec_irq,
> > -			ret);
> > -		goto err_res;
> > +		dev_err(&pdev->dev, "Failed to init pm and registers");
> > +		goto err_dec_pm;
> >   	}
> >   
> >   	mutex_init(&dev->dec_mutex);
> > @@ -329,6 +389,13 @@ static int mtk_vcodec_probe(struct
> > platform_device *pdev)
> >   		goto err_event_workq;
> >   	}
> >   
> > +	ret = of_platform_populate(pdev->dev.of_node, NULL, NULL,
> > +		&pdev->dev);
> > +	if (ret) {
> > +		mtk_v4l2_err("Master device of_platform_populate
> > failed.");
> > +		goto err_event_workq;
> > +	}
> > +
> >   	if (dev->vdec_pdata->uses_stateless_api) {
> >   		dev->mdev_dec.dev = &pdev->dev;
> >   		strscpy(dev->mdev_dec.model, MTK_VCODEC_DEC_NAME,
> > @@ -436,7 +503,25 @@ static struct platform_driver
> > mtk_vcodec_dec_driver = {
> >   	},
> >   };
> >   
> > -module_platform_driver(mtk_vcodec_dec_driver);
> > +static struct platform_driver * const mtk_vdec_drivers[] = {
> > +	&mtk_vdec_comp_driver,
> > +	&mtk_vcodec_dec_driver,
> > +};
> 
> I would say that this is not a good idea, since you can simply
> register
> your mtk_vdec_comp_driver in mtk_vcodec_dec_hw.c.
> 
Change it.
> > +
> > +static int __init mtk_vdec_init(void)
> > +{
> > +	return platform_register_drivers(mtk_vdec_drivers,
> > +					 ARRAY_SIZE(mtk_vdec_drivers));
> > +}
> > +
> > +static void __exit mtk_vdec_exit(void)
> > +{
> > +	platform_unregister_drivers(mtk_vdec_drivers,
> > +				    ARRAY_SIZE(mtk_vdec_drivers));
> > +}
> > +
> > +module_init(mtk_vdec_init);
> > +module_exit(mtk_vdec_exit);
> >   
> >   MODULE_LICENSE("GPL v2");
> >   MODULE_DESCRIPTION("Mediatek video codec V4L2 decoder driver");
> > diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
> > b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
> > new file mode 100644
> > index 000000000000..3752ccaea284
> > --- /dev/null
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
> > @@ -0,0 +1,165 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2021 MediaTek Inc.
> > + * Author: Yunfei Dong <yunfei.dong@mediatek.com>
> > + */
> > +
> > +#include <linux/interrupt.h>
> > +#include <linux/irq.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/of_device.h>
> > +#include <linux/slab.h>
> > +
> > +#include "mtk_vcodec_drv.h"
> > +#include "mtk_vcodec_dec.h"
> > +#include "mtk_vcodec_dec_hw.h"
> > +#include "mtk_vcodec_dec_pm.h"
> > +#include "mtk_vcodec_intr.h"
> > +#include "mtk_vcodec_util.h"
> > +
> > +static const struct of_device_id mtk_vdec_comp_ids[] = {
> > +	{
> > +		.compatible = "mediatek,mtk-vcodec-lat",
> > +	},
> > +	{
> > +		.compatible = "mediatek,mtk-vcodec-core",
> > +	},
> > +	{},
> > +};
> 
> I think that you forgot some ".data = " here...
> 
Yes, forget to add, thanks.
> > +
> > +static irqreturn_t mtk_vdec_comp_irq_handler(int irq, void *priv)
> > +{
> > +	struct mtk_vdec_comp_dev *dev = priv;
> > +	struct mtk_vcodec_ctx *ctx;
> > +	u32 cg_status;
> > +	unsigned int dec_done_status;
> > +	void __iomem *vdec_misc_addr = dev->reg_base[VDEC_COMP_MISC] +
> > +					VDEC_IRQ_CFG_REG;
> > +
> > +	ctx = mtk_vcodec_get_curr_ctx(dev->master_dev);
> > +
> > +	/* check if HW active or not */
> > +	cg_status = readl(dev->reg_base[VDEC_COMP_SYS]);
> > +	if ((cg_status & VDEC_HW_ACTIVE) != 0) {
> 
> The "!= 0" can be dropped here, since cg_status is unsigned.
> 
Fix
> > +		mtk_v4l2_err("vdec active is not 0x0 (0x%08x)",
> > +			cg_status);
> > +		return IRQ_HANDLED;
> > +	}
> > +
> > +	dec_done_status = readl(vdec_misc_addr);
> > +	if ((dec_done_status & MTK_VDEC_IRQ_STATUS_DEC_SUCCESS) !=
> > +		MTK_VDEC_IRQ_STATUS_DEC_SUCCESS)
> 
> I suggest to fix the indentation here to increase human readability,
> like so:
> 
Will Fix.
> 	if ((dec_done_status & MTK_VDEC_IRQ_STATUS_DEC_SUCCESS) !=
> 
> 	    MTK_VDEC_IRQ_STATUS_DEC_SUCCESS)
> 
> 
> > +		return IRQ_HANDLED;
> > +
> > +	/* clear interrupt */
> > +	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);
> > +
> > +	mtk_v4l2_debug(3, "wake up ctx %d, dec_done_status=%x",
> > +		ctx->id, dec_done_status);
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> > +static int mtk_vdec_comp_init_irq(struct mtk_vdec_comp_dev *dev)
> > +{
> > +	struct platform_device *pdev = dev->plat_dev;
> > +	int ret;
> > +
> > +	dev->dec_irq = platform_get_irq(pdev, 0);
> > +	if (dev->dec_irq < 0) {
> > +		dev_err(&pdev->dev, "Failed to get irq resource");
> > +		return dev->dec_irq;
> > +	}
> > +
> > +	irq_set_status_flags(dev->dec_irq, IRQ_NOAUTOEN);
> > +	ret = devm_request_irq(&pdev->dev, dev->dec_irq,
> > +				mtk_vdec_comp_irq_handler, 0, pdev-
> > >name, dev);
> > +	if (ret) {
> > +		dev_err(&pdev->dev, "Failed to install dev->dec_irq %d
> > (%d)",
> > +			dev->dec_irq, ret);
> > +		return ret;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int mtk_vdec_comp_probe(struct platform_device *pdev)
> > +{
> > +	struct device *dev = &pdev->dev;
> > +	struct mtk_vdec_comp_dev *comp_dev;
> > +	struct mtk_vcodec_dev *master_dev;
> > +	const struct of_device_id *of_id;
> > +	int comp_idx;
> > +	int ret;
> > +
> > +	if (!dev->parent) {
> > +		dev_err(dev, "Vdec parent prob is not ready.");
> 
> This is not an error, since it's not a "critical" error, until it
> becomes one (so,
> after max deferral count has been reached).
> I would remove this message entirely, however, if you really want
> this message to
> be here, you should use dev_dbg.
> 
Remove error log.
> > +		return -EPROBE_DEFER;
> > +	}
> > +
> > +	master_dev = dev_get_drvdata(dev->parent);
> > +	if (!master_dev) {
> > +		dev_err(dev, "Failed to get master device.");
> 
> Same here.
> 
Will remove error log
> > +		return -EPROBE_DEFER;
> > +	}
> > +
> > +	comp_dev = devm_kzalloc(dev, sizeof(*comp_dev), GFP_KERNEL);
> > +	if (!comp_dev)
> > +		return -ENOMEM;
> > +
> > +	comp_dev->plat_dev = pdev;
> > +	ret = mtk_vcodec_init_dec_pm(pdev, &comp_dev->pm);
> > +	if (ret) {
> > +		dev_err(dev, "Failed to get mt vcodec clock source.");
> 
> As far as I can see, you have failure prints all over in function 
> mtk_vcodec_init_dec_pm, so there's no need to add another print here:
> you can simply return the error value here.
> 
Will fix.
> > +		return ret;
> > +	}
> > +
> > +	comp_dev->reg_base[VDEC_COMP_MISC] =
> > +		devm_platform_ioremap_resource_byname(pdev, "reg-
> > misc");
> > +	if (IS_ERR((__force void *)comp_dev->reg_base[VDEC_COMP_MISC])) 
> > {
> > +		ret = PTR_ERR((__force void *)comp_dev-
> > >reg_base[VDEC_COMP_MISC]);
> > +		goto err;
> > +	}
> > +
> > +	ret = mtk_vdec_comp_init_irq(comp_dev);
> > +	if (ret) {
> > +		dev_err(dev, "Failed to register irq handler.\n");
> > +		goto err;
> > +	}
> 
> ...and the same applies here: mtk_vdec_comp_init_irq already prints
> on its own.
> 
Will fix
> > +
> > +	of_id = of_match_device(mtk_vdec_comp_ids, dev);
> > +	if (!of_id) {
> > +		dev_err(dev, "Can't get vdec comp device id.\n");
> > +		ret = -EINVAL;
> > +		goto err;
> > +	}
> > +
> > +	comp_idx = (enum mtk_vdec_hw_id)of_id->data;
> 
> Are you sure that this one is working as expected?
> The only driver that registers compatibles mediatek,mtk-vcodec-lat
> and
> mediatek,mtk-vcodec-core is exactly this one, but there's no .data
> assigned
> to any of the of_device_id entries... and this means that your of_id-
> >data
> will not contain the expected value of type enum mtk_vdec_hw_id.
> 
Will fix
> > +	if (comp_idx < MTK_VDEC_HW_MAX) {
> > +		master_dev->comp_dev[comp_idx] = comp_dev;
> > +		comp_dev->comp_idx = comp_idx;
> > +		comp_dev->master_dev = master_dev;
> > +		comp_dev->reg_base[VDEC_COMP_SYS] =
> > +			master_dev->reg_base[VDEC_COMP_SYS];
> > +		set_bit(comp_dev->comp_idx, master_dev-
> > >hardware_bitmap);
> > +	}
> > +
> > +	platform_set_drvdata(pdev, comp_dev);
> > +	return 0;
> > +err:
> > +	mtk_vcodec_release_dec_pm(&comp_dev->pm);
> > +	return ret;
> > +}
> > +
> > +MODULE_DEVICE_TABLE(of, mtk_vdec_comp_ids);
> > +struct platform_driver mtk_vdec_comp_driver = {
> 
> The `_comp` here is a name that's making a logical reference to that:
> in this case,
> 
> that may confuse developers around. Can you please drop that `_comp`?
> 
> That would become `mtk_vdec_driver` instead.
> 
Rename the parameters.
> 
> Logically, the same applies for the rest - always assuming that it's
> referencing to
> the Linux component API.
> 
> > +	.probe	= mtk_vdec_comp_probe,
> > +	.driver	= {
> > +		.name	= "mtk-vdec-comp",
> > +		.of_match_table = mtk_vdec_comp_ids,
> > +	},
> > +};
> 
> Since you're using of_platform_populate, there is no need to register
> this driver
> externally: you can simply register it here (module_platform_driver)
> and it will
> be probed at of_platform_populate time in your parent.
> 
Fix to use module_platform_driver.
> > diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
> > b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
> > new file mode 100644
> > index 000000000000..8d6e818a3474
> > --- /dev/null
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
> > @@ -0,0 +1,49 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2021 MediaTek Inc.
> > + * Author: Yunfei Dong <yunfei.dong@mediatek.com>
> > + */
> > +
> > +#ifndef _MTK_VCODEC_DEC_HW_H_
> > +#define _MTK_VCODEC_DEC_HW_H_
> > +
> > +#include <linux/io.h>
> > +#include <linux/platform_device.h>
> > +
> > +#include "mtk_vcodec_drv.h"
> > +
> > +#define VDEC_HW_ACTIVE	0x10
> > +#define VDEC_IRQ_CFG	0x11
> > +#define VDEC_IRQ_CLR	0x10
> > +#define VDEC_IRQ_CFG_REG	0xa4
> 
> Cosmetic nitpick: either all values in the same column, or simply use
> a space
> instead of tabulations.
> 
Will fix using a space.
> > +
> > +/**
> > + * enum mtk_comp_hw_reg_idx - component register base index
> > + */
> > +enum mtk_comp_hw_reg_idx {
> > +	VDEC_COMP_SYS,
> > +	VDEC_COMP_MISC,
> > +	VDEC_COMP_MAX
> > +};
> > +
> > +/**
> > + * struct mtk_vdec_comp_dev - component framwork driver data
> 
> You've switched away from the component framework... so this
> structure's
> description seems to be a bit misleading now...
> 
Will fix.
> > + * @plat_dev: platform device
> > + * @master_dev: master device
> > + * @reg_base: Mapped address of MTK Vcodec registers.
> > + *
> > + * @dec_irq: decoder irq resource
> > + * @pm: power management control
> > + * @comp_idx: component index
> > + */
> > +struct mtk_vdec_comp_dev {
> > +	struct platform_device *plat_dev;
> > +	struct mtk_vcodec_dev *master_dev;
> > +	void __iomem *reg_base[VDEC_COMP_MAX];
> > +
> > +	int dec_irq;
> > +	struct mtk_vcodec_pm pm;
> > +	int comp_idx;
> > +};
> > +
> > +#endif /* _MTK_VCODEC_DEC_HW_H_ */
> > diff --git a/drivers/media/platform/mtk-
> > vcodec/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mtk-
> > vcodec/mtk_vcodec_dec_stateful.c
> > index 59c24b22ab6d..4f9a80ce15d8 100644
> > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
> > @@ -623,4 +623,5 @@ const struct mtk_vcodec_dec_pdata
> > mtk_vdec_8173_pdata = {
> >   	.num_framesizes = NUM_SUPPORTED_FRAMESIZE,
> >   	.worker = mtk_vdec_worker,
> >   	.flush_decoder = mtk_vdec_flush_decoder,
> > +	.is_comp_supported = false,
> >   };
> > diff --git a/drivers/media/platform/mtk-
> > vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-
> > vcodec/mtk_vcodec_dec_stateless.c
> > index 8f4a1f0a0769..762633572b49 100644
> > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
> > @@ -357,4 +357,5 @@ const struct mtk_vcodec_dec_pdata
> > mtk_vdec_8183_pdata = {
> >   	.uses_stateless_api = true,
> >   	.worker = mtk_vdec_worker,
> >   	.flush_decoder = mtk_vdec_flush_decoder,
> > +	.is_comp_supported = false,
> 
> component is not supported anywhere, since you've switched away from
> it?!
> 
Still need to use, add patch 5 to use it.
> >   };
> > diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> > b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> > index 973b0b3649c6..ec3850b4c638 100644
> > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> > @@ -93,6 +93,17 @@ enum mtk_fmt_type {
> >   	MTK_FMT_FRAME = 2,
> >   };
> >   
> > +/**
> > + * struct mtk_vdec_hw_id - Hardware index used to separate
> > + *                         different hardware
> > + */
> > +enum mtk_vdec_hw_id {
> > +	MTK_VDEC_CORE,
> > +	MTK_VDEC_LAT0,
> > +	MTK_VDEC_LAT1,
> > +	MTK_VDEC_HW_MAX,
> > +};
> > +
> >   /*
> >    * struct mtk_video_fmt - Structure used to store information
> > about pixelformats
> >    */
> > @@ -331,6 +342,7 @@ enum mtk_chip {
> >    *
> >    * @chip: chip this decoder is compatible with
> >    *
> > + * @is_comp_supported: true: using compoent framework, false: not
> > support
> >    * @uses_stateless_api: whether the decoder uses the stateless
> > API with requests
> >    */
> >   
> > @@ -352,6 +364,7 @@ struct mtk_vcodec_dec_pdata {
> >   
> >   	enum mtk_chip chip;
> >   
> > +	bool is_comp_supported;
> 
> Adding this member looks useless: there's nothing declaring
> is_comp_supported as
> true... not here, not in any other patch of this entire series!
> 
Rename is_comp_supported to is_subdev_supported and add patch 5 to use
it.
> 
> Regards,
> - Angelo
> 
Thanks,
Yunfei Dong

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v7, 11/15] media: mtk-vcodec: Add core thread
  2021-10-14 12:29   ` Ezequiel Garcia
@ 2021-10-29  3:25     ` yunfei.dong
  0 siblings, 0 replies; 43+ messages in thread
From: yunfei.dong @ 2021-10-29  3:25 UTC (permalink / raw)
  To: Ezequiel Garcia
  Cc: Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih, Tiffany Lin,
	Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa, Hsin-Yi Wang, Fritz Koenig,
	Dafna Hirschfeld, Benjamin Gaignard, Daniel Vetter, dri-devel,
	Irui Wang, linux-media, devicetree, linux-kernel,
	linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

Hi Ezequiel,

   1. Thanks for your suggestion.
On Thu, 2021-10-14 at 09:29 -0300, Ezequiel Garcia wrote:
> Hi Yunfei,
> 
> On Mon, Oct 11, 2021 at 03:02:43PM +0800, Yunfei Dong wrote:
> > Core thread:
> > 1. Gets lat_buf from core msg queue.
> > 2. Proceeds core decode.
> > 3. Puts the lat_buf back to lat msg queue.
> > 
> > Both H264 and VP9 rely on the core thread.
> > 
> 
> Avoid the kthread API and instead go with the workqueue API.
> 
> See Documentation/core-api/workqueue.rst and
> include/linux/workqueue.h.
> 
Fix it in patch v8.
> Thanks!
> Ezequiel
> 
Thanks
Yunfei Dong
> > Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
> > ---
> >  .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 12 +++++++
> >  .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  7 ++++
> >  .../platform/mtk-vcodec/vdec_msg_queue.c      | 32
> > +++++++++++++++++++
> >  .../platform/mtk-vcodec/vdec_msg_queue.h      |  6 ++++
> >  4 files changed, 57 insertions(+)
> > 
> > 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 e21e0c4bcd86..de83e3b821b4 100644
> > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
> > @@ -364,6 +364,18 @@ static int mtk_vcodec_probe(struct
> > platform_device *pdev)
> >  		goto err_dec_pm;
> >  	}
> >  
> > +	if (VDEC_LAT_ARCH(dev->vdec_pdata->hw_arch)) {
> > +		vdec_msg_queue_init_ctx(&dev->msg_queue_core_ctx,
> > +			MTK_VDEC_CORE);
> > +		dev->kthread_core =
> > kthread_run(vdec_msg_queue_core_thead, dev,
> > +			"mtk-%s", "core");
> > +		if (IS_ERR(dev->kthread_core)) {
> > +			dev_err(&pdev->dev, "Failed to create core
> > thread");
> > +			ret = PTR_ERR(dev->kthread_core);
> > +			goto err_res;
> > +		}
> > +	}
> > +
> >  	for (i = 0; i < MTK_VDEC_HW_MAX; i++)
> >  		mutex_init(&dev->dec_mutex[i]);
> >  	spin_lock_init(&dev->irqlock);
> > diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> > b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> > index 9d072c082f73..68a9b1a2d3b3 100644
> > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> > @@ -27,6 +27,7 @@
> >  #define MTK_VCODEC_MAX_PLANES	3
> >  #define MTK_V4L2_BENCHMARK	0
> >  #define WAIT_INTR_TIMEOUT_MS	1000
> > +#define VDEC_LAT_ARCH(hw_arch) ((hw_arch) >=
> > MTK_VDEC_LAT_SINGLE_CORE)
> >  
> >  /*
> >   * enum mtk_hw_reg_idx - MTK hw register base index
> > @@ -466,6 +467,9 @@ struct mtk_vcodec_enc_pdata {
> >   * @comp_dev: component hardware device
> >   * @component_node: component node
> >   *
> > + * @kthread_core: thread used for core hardware decode
> > + * @msg_queue_core_ctx: msg queue context used for core thread
> > + *
> >   * @hardware_bitmap: used to record hardware is ready or not
> >   */
> >  struct mtk_vcodec_dev {
> > @@ -508,6 +512,9 @@ struct mtk_vcodec_dev {
> >  	void *comp_dev[MTK_VDEC_HW_MAX];
> >  	struct device_node *component_node[MTK_VDEC_HW_MAX];
> >  
> > +	struct task_struct *kthread_core;
> > +	struct vdec_msg_queue_ctx msg_queue_core_ctx;
> > +
> >  	DECLARE_BITMAP(hardware_bitmap, MTK_VDEC_HW_MAX);
> >  };
> >  
> > diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
> > b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
> > index d66ed98c79a9..665f571eab4b 100644
> > --- a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
> > +++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
> > @@ -256,3 +256,35 @@ void vdec_msg_queue_deinit(
> >  			kfree(lat_buf->private_data);
> >  	}
> >  }
> > +
> > +int vdec_msg_queue_core_thead(void *data)
> > +{
> > +	struct mtk_vcodec_dev *dev = data;
> > +	struct vdec_lat_buf *lat_buf;
> > +	struct mtk_vcodec_ctx *ctx;
> > +
> > +	set_freezable();
> > +	for (;;) {
> > +		try_to_freeze();
> > +		if (kthread_should_stop())
> > +			break;
> > +
> > +		lat_buf = vdec_msg_queue_dqbuf(&dev-
> > >msg_queue_core_ctx);
> > +		if (!lat_buf)
> > +			continue;
> > +
> > +		ctx = lat_buf->ctx;
> > +		mtk_vcodec_set_curr_ctx(dev, ctx, MTK_VDEC_CORE);
> > +
> > +		if (!lat_buf->core_decode)
> > +			mtk_v4l2_err("Core decode callback func is
> > NULL");
> > +		else
> > +			lat_buf->core_decode(lat_buf);
> > +
> > +		mtk_vcodec_set_curr_ctx(dev, NULL, MTK_VDEC_CORE);
> > +		vdec_msg_queue_qbuf(&ctx->msg_queue.lat_ctx, lat_buf);
> > +	}
> > +
> > +	mtk_v4l2_debug(3, "Video Capture Thread End");
> > +	return 0;
> > +}
> > diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
> > b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
> > index 1905ce713592..b5745b144140 100644
> > --- a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
> > +++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
> > @@ -148,4 +148,10 @@ void vdec_msg_queue_deinit(
> >  	struct vdec_msg_queue *msg_queue,
> >  	struct mtk_vcodec_ctx *ctx);
> >  
> > +/**
> > + * vdec_msg_queue_core_thead - used for core decoder.
> > + * @data: private data used for each codec
> > + */
> > +int vdec_msg_queue_core_thead(void *data);
> > +
> >  #endif
> > -- 
> > 2.25.1
> > 

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v7, 03/15] media: mtk-vcodec: Refactor vcodec pm interface
  2021-10-14 13:44   ` Dafna Hirschfeld
@ 2021-10-29  3:29     ` yunfei.dong
  0 siblings, 0 replies; 43+ messages in thread
From: yunfei.dong @ 2021-10-29  3:29 UTC (permalink / raw)
  To: Dafna Hirschfeld, Alexandre Courbot, Hans Verkuil, Tzung-Bi Shih,
	Tiffany Lin, Andrew-CT Chen, Mauro Carvalho Chehab, Rob Herring,
	Matthias Brugger, Tomasz Figa
  Cc: Hsin-Yi Wang, Fritz Koenig, Benjamin Gaignard, Daniel Vetter,
	dri-devel, Irui Wang, linux-media, devicetree, linux-kernel,
	linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Tzung-Bi Shih

Hi Dafna,

Thanks for your suggestion.

On Thu, 2021-10-14 at 15:44 +0200, Dafna Hirschfeld wrote:
> 
> On 11.10.21 09:02, Yunfei Dong wrote:
> > Using the needed param for pm init/release function and remove
> > unused
> > param mtkdev in 'struct mtk_vcodec_pm'.
> > 
> 
> I see that there is a lot of code duplication between
> mtk_vcodec_release_dec_pm.c and mtk_vcodec_release_enc_pm.c
> I think if you bother to factor the decoder you should do the same
> factor to the encoder, but actually the much better thing to do
> is to unify all code duplication between these two files, just for
> example of identical functions:
> 
> mtk_vcodec_enc/dec_clock_on/off
> mtk_vcodec_release_enc_pm
> mtk_vcodec_init_dec_pm
> 
> In addition, the function mtk_vcodec_dec_pw_on can be remove since it
> only calls pm_runtime_resume_and_get.
> It would be much better to call pm_runtime_resume_and_get directly
> and not hide it in a different function
> 
I will fix it in next patch series. It's not very reasonable in this
patch  series.

> Thanks,
> Dafna
> 
Thanks,
Yunfei Dong
> > Reviewed-by: Tzung-Bi Shih <tzungbi@google.com>
> > Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
> > ---
> >   .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |  6 ++---
> >   .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 22 ++++++++----
> > -------
> >   .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h   |  5 +++--
> >   .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  1 -
> >   .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c   |  1 -
> >   5 files changed, 15 insertions(+), 20 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 8db9cdc66043..dd749d41c75a 100644
> > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
> > @@ -249,7 +249,7 @@ static int mtk_vcodec_probe(struct
> > platform_device *pdev)
> >   	if (IS_ERR(dev->fw_handler))
> >   		return PTR_ERR(dev->fw_handler);
> >   
> > -	ret = mtk_vcodec_init_dec_pm(dev);
> > +	ret = mtk_vcodec_init_dec_pm(dev->plat_dev, &dev->pm);
> >   	if (ret < 0) {
> >   		dev_err(&pdev->dev, "Failed to get mt vcodec clock
> > source");
> >   		goto err_dec_pm;
> > @@ -379,7 +379,7 @@ static int mtk_vcodec_probe(struct
> > platform_device *pdev)
> >   err_dec_alloc:
> >   	v4l2_device_unregister(&dev->v4l2_dev);
> >   err_res:
> > -	mtk_vcodec_release_dec_pm(dev);
> > +	mtk_vcodec_release_dec_pm(&dev->pm);
> >   err_dec_pm:
> >   	mtk_vcodec_fw_release(dev->fw_handler);
> >   	return ret;
> > @@ -422,7 +422,7 @@ static int mtk_vcodec_dec_remove(struct
> > platform_device *pdev)
> >   		video_unregister_device(dev->vfd_dec);
> >   
> >   	v4l2_device_unregister(&dev->v4l2_dev);
> > -	mtk_vcodec_release_dec_pm(dev);
> > +	mtk_vcodec_release_dec_pm(&dev->pm);
> >   	mtk_vcodec_fw_release(dev->fw_handler);
> >   	return 0;
> >   }
> > diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
> > b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
> > index 6038db96f71c..20bd157a855c 100644
> > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
> > @@ -13,18 +13,15 @@
> >   #include "mtk_vcodec_dec_pm.h"
> >   #include "mtk_vcodec_util.h"
> >   
> > -int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
> > +int mtk_vcodec_init_dec_pm(struct platform_device *pdev,
> > +	struct mtk_vcodec_pm *pm)
> >   {
> >   	struct device_node *node;
> > -	struct platform_device *pdev;
> > -	struct mtk_vcodec_pm *pm;
> > +	struct platform_device *larb_pdev;
> >   	struct mtk_vcodec_clk *dec_clk;
> >   	struct mtk_vcodec_clk_info *clk_info;
> >   	int i = 0, ret = 0;
> >   
> > -	pdev = mtkdev->plat_dev;
> > -	pm = &mtkdev->pm;
> > -	pm->mtkdev = mtkdev;
> >   	dec_clk = &pm->vdec_clk;
> >   	node = of_parse_phandle(pdev->dev.of_node, "mediatek,larb", 0);
> >   	if (!node) {
> > @@ -32,13 +29,12 @@ int mtk_vcodec_init_dec_pm(struct
> > mtk_vcodec_dev *mtkdev)
> >   		return -1;
> >   	}
> >   
> > -	pdev = of_find_device_by_node(node);
> > +	larb_pdev = of_find_device_by_node(node);
> >   	of_node_put(node);
> > -	if (WARN_ON(!pdev)) {
> > +	if (WARN_ON(!larb_pdev)) {
> >   		return -1;
> >   	}
> > -	pm->larbvdec = &pdev->dev;
> > -	pdev = mtkdev->plat_dev;
> > +	pm->larbvdec = &larb_pdev->dev;
> >   	pm->dev = &pdev->dev;
> >   
> >   	dec_clk->clk_num =
> > @@ -82,10 +78,10 @@ int mtk_vcodec_init_dec_pm(struct
> > mtk_vcodec_dev *mtkdev)
> >   	return ret;
> >   }
> >   
> > -void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev)
> > +void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm)
> >   {
> > -	pm_runtime_disable(dev->pm.dev);
> > -	put_device(dev->pm.larbvdec);
> > +	pm_runtime_disable(pm->dev);
> > +	put_device(pm->larbvdec);
> >   }
> >   
> >   int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
> > diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
> > b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
> > index 280aeaefdb65..a3df6aef6cb9 100644
> > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
> > @@ -9,8 +9,9 @@
> >   
> >   #include "mtk_vcodec_drv.h"
> >   
> > -int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *dev);
> > -void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev);
> > +int mtk_vcodec_init_dec_pm(struct platform_device *pdev,
> > +	struct mtk_vcodec_pm *pm);
> > +void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm);
> >   
> >   int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm);
> >   void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm);
> > diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> > b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> > index 3b1e5e3a450e..973b0b3649c6 100644
> > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> > @@ -195,7 +195,6 @@ struct mtk_vcodec_pm {
> >   	struct mtk_vcodec_clk	venc_clk;
> >   	struct device	*larbvenc;
> >   	struct device	*dev;
> > -	struct mtk_vcodec_dev	*mtkdev;
> >   };
> >   
> >   /**
> > diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
> > b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
> > index 1b2e4930ed27..0c8c8f86788c 100644
> > --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
> > +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
> > @@ -26,7 +26,6 @@ int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev
> > *mtkdev)
> >   	pdev = mtkdev->plat_dev;
> >   	pm = &mtkdev->pm;
> >   	memset(pm, 0, sizeof(struct mtk_vcodec_pm));
> > -	pm->mtkdev = mtkdev;
> >   	pm->dev = &pdev->dev;
> >   	dev = &pdev->dev;
> >   	enc_clk = &pm->venc_clk;
> > 

^ permalink raw reply	[flat|nested] 43+ messages in thread

end of thread, other threads:[~2021-10-29  3:29 UTC | newest]

Thread overview: 43+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-11  7:02 [PATCH v7, 00/15] Support multi hardware decode using of_platform_populate Yunfei Dong
2021-10-11  7:02 ` [PATCH v7, 01/15] media: mtk-vcodec: Get numbers of register bases from DT Yunfei Dong
2021-10-11  7:02 ` [PATCH v7, 02/15] media: mtk-vcodec: Align vcodec wake up interrupt interface Yunfei Dong
2021-10-14 11:12   ` AngeloGioacchino Del Regno
2021-10-11  7:02 ` [PATCH v7, 03/15] media: mtk-vcodec: Refactor vcodec pm interface Yunfei Dong
2021-10-14 11:12   ` AngeloGioacchino Del Regno
2021-10-14 13:44   ` Dafna Hirschfeld
2021-10-29  3:29     ` yunfei.dong
2021-10-11  7:02 ` [PATCH v7, 04/15] media: mtk-vcodec: Manage multi hardware information Yunfei Dong
2021-10-14  9:20   ` AngeloGioacchino Del Regno
2021-10-29  3:05     ` yunfei.dong
2021-10-14  9:30   ` AngeloGioacchino Del Regno
2021-10-11  7:02 ` [PATCH v7, 05/15] dt-bindings: media: mtk-vcodec: Separate video encoder and decoder dt-bindings Yunfei Dong
2021-10-11  7:02 ` [PATCH v7, 06/15] media: mtk-vcodec: Use pure single core for MT8183 Yunfei Dong
2021-10-14 11:13   ` AngeloGioacchino Del Regno
2021-10-11  7:02 ` [PATCH v7, 07/15] media: mtk-vcodec: Add irq interface for multi hardware Yunfei Dong
2021-10-14 10:04   ` AngeloGioacchino Del Regno
2021-10-27 11:36     ` yunfei.dong
2021-10-11  7:02 ` [PATCH v7, 08/15] media: mtk-vcodec: Add msg queue feature for lat and core architecture Yunfei Dong
2021-10-14 10:35   ` AngeloGioacchino Del Regno
2021-10-27  4:01     ` yunfei.dong
2021-10-11  7:02 ` [PATCH v7, 09/15] media: mtk-vcodec: Generalize power and clock on/off interfaces Yunfei Dong
2021-10-14 10:44   ` AngeloGioacchino Del Regno
2021-10-27  3:55     ` yunfei.dong
2021-10-11  7:02 ` [PATCH v7, 10/15] media: mtk-vcodec: Add new interface to lock different hardware Yunfei Dong
2021-10-14 10:47   ` AngeloGioacchino Del Regno
2021-10-11  7:02 ` [PATCH v7, 11/15] media: mtk-vcodec: Add core thread Yunfei Dong
2021-10-14 10:56   ` AngeloGioacchino Del Regno
2021-10-27  3:47     ` yunfei.dong
2021-10-14 12:29   ` Ezequiel Garcia
2021-10-29  3:25     ` yunfei.dong
2021-10-11  7:02 ` [PATCH v7, 12/15] media: mtk-vcodec: Support 34bits dma address for vdec Yunfei Dong
2021-10-14 11:02   ` AngeloGioacchino Del Regno
2021-10-27  3:44     ` yunfei.dong
2021-10-11  7:02 ` [PATCH v7, 13/15] dt-bindings: media: mtk-vcodec: Adds decoder dt-bindings for mt8192 Yunfei Dong
2021-10-11 13:36   ` Rob Herring
2021-10-11  7:02 ` [PATCH v7, 14/15] media: mtk-vcodec: Add core dec and dec end ipi msg Yunfei Dong
2021-10-14 11:04   ` AngeloGioacchino Del Regno
2021-10-11  7:02 ` [PATCH v7, 15/15] media: mtk-vcodec: Use codec type to separate different hardware Yunfei Dong
2021-10-14 11:08   ` AngeloGioacchino Del Regno
2021-10-12 14:27 ` [PATCH v7, 00/15] Support multi hardware decode using of_platform_populate Andrzej Pietrasiewicz
2021-10-13  1:08   ` yunfei.dong
2021-10-13 10:55     ` Andrzej Pietrasiewicz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).