linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3, 00/10] Enable two H264 encoder core on MT8195
@ 2022-03-17  8:22 Irui Wang
  2022-03-17  8:22 ` [PATCH v3, 01/10] media: mtk-vcodec: Use core type to indicate h264 and vp8 enc Irui Wang
                   ` (10 more replies)
  0 siblings, 11 replies; 21+ messages in thread
From: Irui Wang @ 2022-03-17  8:22 UTC (permalink / raw)
  To: Hans Verkuil, Tzung-Bi Shih, Rob Herring, Alexandre Courbot,
	Mauro Carvalho Chehab, Matthias Brugger, Tomasz Figa,
	angelogioacchino.delregno, Yong Wu, Tiffany Lin, Andrew-CT Chen
  Cc: Hsin-Yi Wang, Maoguang Meng, Longfei Wang, Yunfei Dong,
	Fritz Koenig, Irui Wang, linux-media, devicetree, linux-kernel,
	linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

MT8195 has two H264 encoder cores, they have their own power-domains,
clocks, interrupts, register base. The two H264 encoder cores can work
together to achieve higher performance, it's a core mode called
frame-racing, one core has 4K@30fps performance, two cores can achieve
4K@60fps.
The two encoder core encoding process looks like this:

    VENC Core0: frm#0....frm#2....frm#4....
    VENC Core1: ..frm#1....frm#3....frm#5....

This series of patches are used to enable the two H264 encoder cores,
encoding process will be changed:
As-Is: Synchronous
V4L2_VIDIOC_QBUF#0 --> device_run(triger encoder) --> wait encoder IRQ -->
encoding done with result --> job_finish
V4l2_VIDIOC_QBUF#1 --> device_run(triger encoder) --> wait encoder IRQ -->
encoding done with result --> job_finish
...

To-Be: Asynchronous
V4L2_VIDIOC_QBUF#0 --> device_run(triger encoder) --> job_finish
..V4l2_VIDIOC_QBUF#1 --> device_run(triger encoder) --> job_finish
(venc core0 may encode done here, done the encoding result to client)
V4L2_VIDIOC_QBUF#2 --> device_run(triger encoder) --> job_finish.

There is no "wait encoder IRQ" synchronous call during frame-racing mode
encoding process, it can full use the two encoder cores to achieve higher
performance.

---
This series patches dependent on:
media_stage tree:
[1]
https://git.linuxtv.org/media_stage.git/commit/?id=b3627647f9ea7473d10fb08a95fd7c4133a17ca4

mt8192 decoder:
[2] https://patchwork.kernel.org/project/linux-mediatek/list/?series=616991

patch3 new venc dt-bindings included files
[3] MM IOMMU binding:
https://patchwork.kernel.org/project/linux-mediatek/patch/20220217113453.13658-2-yong.wu@mediatek.com/

[4] MT8195 power domain:
https://patchwork.kernel.org/project/linux-mediatek/list/?series=580579

changes compared with v2:
- update venc core dt-bindings, add two new properties for current usage.
- parse venc multi_core mode from device tree.
- rebase to the newer linux media stage.

changes compared with v1:
- of_platform_populate was used in place of the component framework.
- new yaml file for venc cores.
- some modifications for patch v1's review comments.
---

Irui Wang (10):
  media: mtk-vcodec: Use core type to indicate h264 and vp8 enc
  media: mtk-vcodec: export encoder functions
  dt-bindings: media: mtk-vcodec: Adds encoder cores dt-bindings for
    mt8195
  media: mtk-vcodec: Enable venc dual core usage
  media: mtk-vcodec: mtk-vcodec: Rewrite venc power manage interface
  media: mtk-vcodec: Add venc power on/off interface
  media: mtk-vcodec: Rewrite venc clock interface
  media: mtk-vcodec: Add more extra processing for venc_multi_core mode
  media: mtk-vcodec: Add venc_multi_core mode encode process
  media: mtk-vcodec: Done encode result to client

 .../media/mediatek,vcodec-encoder-core.yaml   | 181 +++++++++++++++
 .../media/mediatek,vcodec-encoder.yaml        |   1 -
 drivers/media/platform/mtk-vcodec/Makefile    |   4 +-
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  36 ++-
 .../platform/mtk-vcodec/mtk_vcodec_enc.c      | 113 +++++++---
 .../platform/mtk-vcodec/mtk_vcodec_enc.h      |   7 +-
 .../platform/mtk-vcodec/mtk_vcodec_enc_core.c | 169 ++++++++++++++
 .../platform/mtk-vcodec/mtk_vcodec_enc_core.h |  36 +++
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  | 107 +++++----
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c   | 183 +++++++++++++--
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.h   |  11 +-
 .../platform/mtk-vcodec/mtk_vcodec_util.c     |  19 ++
 .../platform/mtk-vcodec/mtk_vcodec_util.h     |   5 +
 .../platform/mtk-vcodec/venc/venc_h264_if.c   | 212 +++++++++++++++---
 .../platform/mtk-vcodec/venc/venc_vp8_if.c    |   3 +-
 .../media/platform/mtk-vcodec/venc_drv_if.c   |  79 +++++--
 .../media/platform/mtk-vcodec/venc_drv_if.h   |   7 +
 .../media/platform/mtk-vcodec/venc_vpu_if.c   |  11 +-
 .../media/platform/mtk-vcodec/venc_vpu_if.h   |   3 +-
 19 files changed, 1026 insertions(+), 161 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-encoder-core.yaml
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.c
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.h

-- 
2.18.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3, 01/10] media: mtk-vcodec: Use core type to indicate h264 and vp8 enc
  2022-03-17  8:22 [PATCH v3, 00/10] Enable two H264 encoder core on MT8195 Irui Wang
@ 2022-03-17  8:22 ` Irui Wang
  2022-03-17  8:22 ` [PATCH v3, 02/10] media: mtk-vcodec: export encoder functions Irui Wang
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Irui Wang @ 2022-03-17  8:22 UTC (permalink / raw)
  To: Hans Verkuil, Tzung-Bi Shih, Rob Herring, Alexandre Courbot,
	Mauro Carvalho Chehab, Matthias Brugger, Tomasz Figa,
	angelogioacchino.delregno, Yong Wu, Tiffany Lin, Andrew-CT Chen
  Cc: Hsin-Yi Wang, Maoguang Meng, Longfei Wang, Yunfei Dong,
	Fritz Koenig, Irui Wang, linux-media, devicetree, linux-kernel,
	linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

use core type variables to indicate h264 and vp8 encoder

Signed-off-by: Irui Wang <irui.wang@mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  4 +--
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  | 30 ++++++++++---------
 2 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index ea58f11e7659..3affb2d4a4ec 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -416,7 +416,7 @@ struct mtk_vcodec_dec_pdata {
  * @num_capture_formats: number of entries in capture_formats
  * @output_formats: array of supported output formats
  * @num_output_formats: number of entries in output_formats
- * @core_id: stand for h264 or vp8 encode index
+ * @core_type: stand for h264 or vp8 encode
  */
 struct mtk_vcodec_enc_pdata {
 	bool uses_ext;
@@ -426,7 +426,7 @@ struct mtk_vcodec_enc_pdata {
 	size_t num_capture_formats;
 	const struct mtk_video_fmt *output_formats;
 	size_t num_output_formats;
-	int core_id;
+	int core_type;
 };
 
 #define MTK_ENC_CTX_IS_EXT(ctx) ((ctx)->dev->venc_pdata->uses_ext)
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 95e8c29ccc65..f12f887e4bdc 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -94,11 +94,13 @@ static irqreturn_t mtk_vcodec_enc_irq_handler(int irq, void *priv)
 	ctx = dev->curr_ctx;
 	spin_unlock_irqrestore(&dev->irqlock, flags);
 
-	mtk_v4l2_debug(1, "id=%d coreid:%d", ctx->id, dev->venc_pdata->core_id);
-	addr = dev->reg_base[dev->venc_pdata->core_id] +
+	mtk_v4l2_debug(1, "id: %d core type: %d",
+		       ctx->id, dev->venc_pdata->core_type);
+
+	addr = dev->reg_base[dev->venc_pdata->core_type] +
 				MTK_VENC_IRQ_ACK_OFFSET;
 
-	ctx->irq_status = readl(dev->reg_base[dev->venc_pdata->core_id] +
+	ctx->irq_status = readl(dev->reg_base[dev->venc_pdata->core_type] +
 				(MTK_VENC_IRQ_STATUS_OFFSET));
 
 	clean_irq_status(ctx->irq_status, addr);
@@ -265,10 +267,10 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 
 	pm_runtime_enable(&pdev->dev);
 
-	dev->reg_base[dev->venc_pdata->core_id] =
+	dev->reg_base[dev->venc_pdata->core_type] =
 		devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(dev->reg_base[dev->venc_pdata->core_id])) {
-		ret = PTR_ERR(dev->reg_base[dev->venc_pdata->core_id]);
+	if (IS_ERR(dev->reg_base[dev->venc_pdata->core_type])) {
+		ret = PTR_ERR(dev->reg_base[dev->venc_pdata->core_type]);
 		goto err_res;
 	}
 
@@ -286,8 +288,8 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 			       0, pdev->name, dev);
 	if (ret) {
 		dev_err(&pdev->dev,
-			"Failed to install dev->enc_irq %d (%d) core_id (%d)",
-			dev->enc_irq, ret, dev->venc_pdata->core_id);
+			"Failed to install dev->enc_irq %d (%d) core_type (%d)",
+			dev->enc_irq, ret, dev->venc_pdata->core_type);
 		ret = -EINVAL;
 		goto err_res;
 	}
@@ -356,7 +358,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	}
 
 	mtk_v4l2_debug(0, "encoder %d registered as /dev/video%d",
-		       dev->venc_pdata->core_id, vfd_enc->num);
+		       dev->venc_pdata->core_type, vfd_enc->num);
 
 	return 0;
 
@@ -382,7 +384,7 @@ static const struct mtk_vcodec_enc_pdata mt8173_avc_pdata = {
 	.num_output_formats = ARRAY_SIZE(mtk_video_formats_output),
 	.min_bitrate = 64,
 	.max_bitrate = 60000000,
-	.core_id = VENC_SYS,
+	.core_type = VENC_SYS,
 };
 
 static const struct mtk_vcodec_enc_pdata mt8173_vp8_pdata = {
@@ -392,7 +394,7 @@ static const struct mtk_vcodec_enc_pdata mt8173_vp8_pdata = {
 	.num_output_formats = ARRAY_SIZE(mtk_video_formats_output),
 	.min_bitrate = 64,
 	.max_bitrate = 9000000,
-	.core_id = VENC_LT_SYS,
+	.core_type = VENC_LT_SYS,
 };
 
 static const struct mtk_vcodec_enc_pdata mt8183_pdata = {
@@ -403,7 +405,7 @@ static const struct mtk_vcodec_enc_pdata mt8183_pdata = {
 	.num_output_formats = ARRAY_SIZE(mtk_video_formats_output),
 	.min_bitrate = 64,
 	.max_bitrate = 40000000,
-	.core_id = VENC_SYS,
+	.core_type = VENC_SYS,
 };
 
 static const struct mtk_vcodec_enc_pdata mt8192_pdata = {
@@ -414,7 +416,7 @@ static const struct mtk_vcodec_enc_pdata mt8192_pdata = {
 	.num_output_formats = ARRAY_SIZE(mtk_video_formats_output),
 	.min_bitrate = 64,
 	.max_bitrate = 100000000,
-	.core_id = VENC_SYS,
+	.core_type = VENC_SYS,
 };
 
 static const struct mtk_vcodec_enc_pdata mt8195_pdata = {
@@ -425,7 +427,7 @@ static const struct mtk_vcodec_enc_pdata mt8195_pdata = {
 	.num_output_formats = ARRAY_SIZE(mtk_video_formats_output),
 	.min_bitrate = 64,
 	.max_bitrate = 100000000,
-	.core_id = VENC_SYS,
+	.core_type = VENC_SYS,
 };
 
 static const struct of_device_id mtk_vcodec_enc_match[] = {
-- 
2.18.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3, 02/10] media: mtk-vcodec: export encoder functions
  2022-03-17  8:22 [PATCH v3, 00/10] Enable two H264 encoder core on MT8195 Irui Wang
  2022-03-17  8:22 ` [PATCH v3, 01/10] media: mtk-vcodec: Use core type to indicate h264 and vp8 enc Irui Wang
@ 2022-03-17  8:22 ` Irui Wang
  2022-03-17  8:22 ` [PATCH v3, 03/10] dt-bindings: media: mtk-vcodec: Adds encoder cores dt-bindings for mt8195 Irui Wang
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Irui Wang @ 2022-03-17  8:22 UTC (permalink / raw)
  To: Hans Verkuil, Tzung-Bi Shih, Rob Herring, Alexandre Courbot,
	Mauro Carvalho Chehab, Matthias Brugger, Tomasz Figa,
	angelogioacchino.delregno, Yong Wu, Tiffany Lin, Andrew-CT Chen
  Cc: Hsin-Yi Wang, Maoguang Meng, Longfei Wang, Yunfei Dong,
	Fritz Koenig, Irui Wang, linux-media, devicetree, linux-kernel,
	linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

mtk vcodec is built as a module, export some functions to make them
visible by other modules.

Signed-off-by: Irui Wang <irui.wang@mediatek.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c    | 2 ++
 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c | 3 +++
 2 files changed, 5 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
index c21367038c34..0d1b065048a9 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
@@ -1431,6 +1431,7 @@ int mtk_venc_unlock(struct mtk_vcodec_ctx *ctx)
 	mutex_unlock(&dev->enc_mutex);
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mtk_venc_unlock);
 
 int mtk_venc_lock(struct mtk_vcodec_ctx *ctx)
 {
@@ -1439,6 +1440,7 @@ int mtk_venc_lock(struct mtk_vcodec_ctx *ctx)
 	mutex_lock(&dev->enc_mutex);
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mtk_venc_lock);
 
 void mtk_vcodec_enc_release(struct mtk_vcodec_ctx *ctx)
 {
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 7055954eb2af..74495edab558 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
@@ -58,6 +58,7 @@ int mtk_vcodec_init_enc_clk(struct mtk_vcodec_dev *mtkdev)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mtk_vcodec_init_enc_clk);
 
 void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm)
 {
@@ -79,6 +80,7 @@ void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm)
 	for (i -= 1; i >= 0; i--)
 		clk_disable_unprepare(enc_clk->clk_info[i].vcodec_clk);
 }
+EXPORT_SYMBOL_GPL(mtk_vcodec_enc_clock_on);
 
 void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm)
 {
@@ -88,3 +90,4 @@ void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm)
 	for (i = enc_clk->clk_num - 1; i >= 0; i--)
 		clk_disable_unprepare(enc_clk->clk_info[i].vcodec_clk);
 }
+EXPORT_SYMBOL_GPL(mtk_vcodec_enc_clock_off);
-- 
2.18.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3, 03/10] dt-bindings: media: mtk-vcodec: Adds encoder cores dt-bindings for mt8195
  2022-03-17  8:22 [PATCH v3, 00/10] Enable two H264 encoder core on MT8195 Irui Wang
  2022-03-17  8:22 ` [PATCH v3, 01/10] media: mtk-vcodec: Use core type to indicate h264 and vp8 enc Irui Wang
  2022-03-17  8:22 ` [PATCH v3, 02/10] media: mtk-vcodec: export encoder functions Irui Wang
@ 2022-03-17  8:22 ` Irui Wang
  2022-03-17 23:32   ` Miles Chen
  2022-03-25 20:57   ` Rob Herring
  2022-03-17  8:22 ` [PATCH v3, 04/10] media: mtk-vcodec: Enable venc dual core usage Irui Wang
                   ` (7 subsequent siblings)
  10 siblings, 2 replies; 21+ messages in thread
From: Irui Wang @ 2022-03-17  8:22 UTC (permalink / raw)
  To: Hans Verkuil, Tzung-Bi Shih, Rob Herring, Alexandre Courbot,
	Mauro Carvalho Chehab, Matthias Brugger, Tomasz Figa,
	angelogioacchino.delregno, Yong Wu, Tiffany Lin, Andrew-CT Chen
  Cc: Hsin-Yi Wang, Maoguang Meng, Longfei Wang, Yunfei Dong,
	Fritz Koenig, Irui Wang, linux-media, devicetree, linux-kernel,
	linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

Adds encoder cores dt-bindings for mt8195.

Signed-off-by: Irui Wang <irui.wang@mediatek.com>
---
 .../media/mediatek,vcodec-encoder-core.yaml   | 181 ++++++++++++++++++
 .../media/mediatek,vcodec-encoder.yaml        |   1 -
 2 files changed, 181 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-encoder-core.yaml

diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder-core.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder-core.yaml
new file mode 100644
index 000000000000..fcfb48900c76
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder-core.yaml
@@ -0,0 +1,181 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/media/mediatek,vcodec-encoder-core.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Mediatek Video Encoder Accelerator With Multi Core
+
+maintainers:
+  - Irui Wang <irui.wang@mediatek.com>
+
+description: |
+  Mediatek Video Encode is the video encode hardware present in Mediatek
+  SoCs which supports high resolution encoding functionalities. Required
+  parent and child device node.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - mediatek,mt8195-vcodec-enc
+
+  mediatek,scp:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: |
+      The node of system control processor (SCP), using
+      the remoteproc & rpmsg framework.
+
+  mediatek,venc-multi-core:
+    type: boolean
+    description: |
+      Indicates whether the encoder has multiple cores or not.
+
+  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.
+
+  "#address-cells":
+    const: 2
+
+  "#size-cells":
+    const: 2
+
+  ranges: true
+
+# Required child node:
+patternProperties:
+  "^venc-core@[0-9a-f]+$":
+    type: object
+    description: |
+      The video encoder core device node which should be added as subnodes to
+      the main venc node.
+
+    properties:
+      compatible:
+        items:
+         - const: mediatek,mtk-venc-core
+
+      reg:
+        maxItems: 1
+
+      mediatek,core-id:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: |
+          Current encoder core id.
+
+      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.
+
+      interrupts:
+        maxItems: 1
+
+      clocks:
+        maxItems: 1
+
+      clock-names:
+        maxItems: 1
+
+      power-domains:
+        maxItems: 1
+
+    required:
+      - compatible
+      - reg
+      - mediatek,core-id
+      - iommus
+      - interrupts
+      - clocks
+      - clock-names
+      - assigned-clocks
+      - assigned-clock-parents
+      - power-domains
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - mediatek,scp
+  - iommus
+  - dma-ranges
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/memory/mt8195-memory-port.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/clock/mt8195-clk.h>
+    #include <dt-bindings/power/mt8195-power.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        venc {
+            compatible = "mediatek,mt8195-vcodec-enc";
+            mediatek,scp = <&scp>;
+            mediatek,venc-multi-core;
+            iommus = <&iommu_vdo M4U_PORT_L19_VENC_RCPU>;
+            #address-cells = <2>;
+            #size-cells = <2>;
+            ranges;
+            dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
+
+            venc-core@1a020000 {
+                compatible = "mediatek,mtk-venc-core";
+                reg = <0 0x1a020000 0 0x10000>;
+                mediatek,core-id = <0>;
+                iommus = <&iommu_vdo M4U_PORT_L19_VENC_RCPU>,
+                         <&iommu_vdo M4U_PORT_L19_VENC_REC>,
+                         <&iommu_vdo M4U_PORT_L19_VENC_BSDMA>,
+                         <&iommu_vdo M4U_PORT_L19_VENC_SV_COMV>,
+                         <&iommu_vdo M4U_PORT_L19_VENC_RD_COMV>,
+                         <&iommu_vdo M4U_PORT_L19_VENC_CUR_LUMA>,
+                         <&iommu_vdo M4U_PORT_L19_VENC_CUR_CHROMA>,
+                         <&iommu_vdo M4U_PORT_L19_VENC_REF_LUMA>,
+                         <&iommu_vdo M4U_PORT_L19_VENC_REF_CHROMA>;
+                interrupts = <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH 0>;
+                clocks = <&vencsys CLK_VENC_VENC>;
+                clock-names = "clk_venc";
+                assigned-clocks = <&topckgen CLK_TOP_VENC>;
+                assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D4>;
+                power-domains = <&spm MT8195_POWER_DOMAIN_VENC>;
+            };
+
+            venc-core@1b020000 {
+                compatible = "mediatek,mtk-venc-core";
+                reg = <0 0x1b020000 0 0x10000>;
+                mediatek,core-id = <1>;
+                iommus = <&iommu_vpp M4U_PORT_L20_VENC_RCPU>,
+                         <&iommu_vpp M4U_PORT_L20_VENC_REC>,
+                         <&iommu_vpp M4U_PORT_L20_VENC_BSDMA>,
+                         <&iommu_vpp M4U_PORT_L20_VENC_SV_COMV>,
+                         <&iommu_vpp M4U_PORT_L20_VENC_RD_COMV>,
+                         <&iommu_vpp M4U_PORT_L20_VENC_CUR_LUMA>,
+                         <&iommu_vpp M4U_PORT_L20_VENC_CUR_CHROMA>,
+                         <&iommu_vpp M4U_PORT_L20_VENC_REF_LUMA>,
+                         <&iommu_vpp M4U_PORT_L20_VENC_REF_CHROMA>;
+                interrupts = <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH 0>;
+                clocks = <&vencsys_core1 CLK_VENC_CORE1_VENC>;
+                clock-names = "clk_venc_core1";
+                assigned-clocks = <&topckgen CLK_TOP_VENC>;
+                assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D4>;
+                power-domains = <&spm MT8195_POWER_DOMAIN_VENC_CORE1>;
+            };
+        };
+    };
diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
index e7b65a91c92c..0530a694bcbe 100644
--- a/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
@@ -21,7 +21,6 @@ properties:
       - mediatek,mt8173-vcodec-enc
       - mediatek,mt8183-vcodec-enc
       - mediatek,mt8192-vcodec-enc
-      - mediatek,mt8195-vcodec-enc
 
   reg:
     maxItems: 1
-- 
2.18.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3, 04/10] media: mtk-vcodec: Enable venc dual core usage
  2022-03-17  8:22 [PATCH v3, 00/10] Enable two H264 encoder core on MT8195 Irui Wang
                   ` (2 preceding siblings ...)
  2022-03-17  8:22 ` [PATCH v3, 03/10] dt-bindings: media: mtk-vcodec: Adds encoder cores dt-bindings for mt8195 Irui Wang
@ 2022-03-17  8:22 ` Irui Wang
  2022-03-17  8:22 ` [PATCH v3, 05/10] media: mtk-vcodec: mtk-vcodec: Rewrite venc power manage interface Irui Wang
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Irui Wang @ 2022-03-17  8:22 UTC (permalink / raw)
  To: Hans Verkuil, Tzung-Bi Shih, Rob Herring, Alexandre Courbot,
	Mauro Carvalho Chehab, Matthias Brugger, Tomasz Figa,
	angelogioacchino.delregno, Yong Wu, Tiffany Lin, Andrew-CT Chen
  Cc: Hsin-Yi Wang, Maoguang Meng, Longfei Wang, Yunfei Dong,
	Fritz Koenig, Irui Wang, linux-media, devicetree, linux-kernel,
	linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

Adds new property to indicate whether the encoder has multiple cores.

Use of_platform_populate to probe each venc cores, the core device can use
the init_clk/request_irq helper to initialize their own power/clk/irq, and
the main device doesn't need use these helper anymore.

Signed-off-by: Irui Wang <irui.wang@mediatek.com>
---
 drivers/media/platform/mtk-vcodec/Makefile    |   4 +-
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  14 ++
 .../platform/mtk-vcodec/mtk_vcodec_enc_core.c | 138 ++++++++++++++++++
 .../platform/mtk-vcodec/mtk_vcodec_enc_core.h |  36 +++++
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |  77 +++++-----
 5 files changed, 235 insertions(+), 34 deletions(-)
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.c
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.h

diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index 93e7a343b5b0..c472b221bd6b 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -3,7 +3,8 @@
 obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec-dec.o \
 				       mtk-vcodec-enc.o \
 				       mtk-vcodec-common.o \
-				       mtk-vcodec-dec-hw.o
+				       mtk-vcodec-dec-hw.o \
+				       mtk-vcodec-enc-core.o
 
 mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 		vdec/vdec_vp8_if.o \
@@ -32,6 +33,7 @@ mtk-vcodec-enc-y := venc/venc_vp8_if.o \
 		venc_drv_if.o \
 		venc_vpu_if.o \
 
+mtk-vcodec-enc-core-y := mtk_vcodec_enc_core.o
 
 mtk-vcodec-common-y := mtk_vcodec_intr.o \
 		mtk_vcodec_util.o \
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 3affb2d4a4ec..43e1349d6a54 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -117,6 +117,15 @@ enum mtk_vdec_hw_count {
 	MTK_VDEC_MAX_HW_COUNT,
 };
 
+/*
+ * enum mtk_venc_core_id -- encoder core id
+ */
+enum mtk_venc_core_id {
+	MTK_VENC_CORE0 = 0,
+	MTK_VENC_CORE1,
+	MTK_VENC_CORE_MAX,
+};
+
 /*
  * struct mtk_video_fmt - Structure used to store information about pixelformats
  */
@@ -476,6 +485,8 @@ struct mtk_vcodec_enc_pdata {
  * @subdev_dev: subdev hardware device
  * @subdev_prob_done: check whether all used hw device is prob done
  * @subdev_bitmap: used to record hardware is ready or not
+ * @venc_multi_core: indicates whether the encoder has multiple cores or not
+ * @enc_core_dev: used to store venc core device
  */
 struct mtk_vcodec_dev {
 	struct v4l2_device v4l2_dev;
@@ -521,6 +532,9 @@ struct mtk_vcodec_dev {
 	void *subdev_dev[MTK_VDEC_HW_MAX];
 	int (*subdev_prob_done)(struct mtk_vcodec_dev *vdec_dev);
 	DECLARE_BITMAP(subdev_bitmap, MTK_VDEC_HW_MAX);
+
+	bool venc_multi_core;
+	void *enc_core_dev[MTK_VENC_CORE_MAX];
 };
 
 static inline struct mtk_vcodec_ctx *fh_to_ctx(struct v4l2_fh *fh)
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.c
new file mode 100644
index 000000000000..9d3ea5a8afe4
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.c
@@ -0,0 +1,138 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+
+#include "mtk_vcodec_drv.h"
+#include "mtk_vcodec_enc.h"
+#include "mtk_vcodec_enc_core.h"
+#include "mtk_vcodec_intr.h"
+
+static const struct of_device_id mtk_venc_core_ids[] = {
+	{
+		.compatible = "mediatek,mtk-venc-core",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, mtk_venc_core_ids);
+
+static void clean_irq_status(unsigned int irq_status, void __iomem *addr)
+{
+	if (irq_status & MTK_VENC_IRQ_STATUS_PAUSE)
+		writel(MTK_VENC_IRQ_STATUS_PAUSE, addr);
+
+	if (irq_status & MTK_VENC_IRQ_STATUS_SWITCH)
+		writel(MTK_VENC_IRQ_STATUS_SWITCH, addr);
+
+	if (irq_status & MTK_VENC_IRQ_STATUS_DRAM)
+		writel(MTK_VENC_IRQ_STATUS_DRAM, addr);
+
+	if (irq_status & MTK_VENC_IRQ_STATUS_SPS)
+		writel(MTK_VENC_IRQ_STATUS_SPS, addr);
+
+	if (irq_status & MTK_VENC_IRQ_STATUS_PPS)
+		writel(MTK_VENC_IRQ_STATUS_PPS, addr);
+
+	if (irq_status & MTK_VENC_IRQ_STATUS_FRM)
+		writel(MTK_VENC_IRQ_STATUS_FRM, addr);
+}
+
+static irqreturn_t mtk_enc_core_irq_handler(int irq, void *priv)
+{
+	struct mtk_venc_core_dev *core = priv;
+	struct mtk_vcodec_ctx *ctx;
+	unsigned long flags;
+	void __iomem *addr;
+
+	spin_lock_irqsave(&core->main_dev->irqlock, flags);
+	ctx = core->curr_ctx;
+	spin_unlock_irqrestore(&core->main_dev->irqlock, flags);
+	if (!ctx)
+		return IRQ_HANDLED;
+
+	mtk_v4l2_debug(1, "id=%d core :%d", ctx->id, core->core_id);
+
+	addr = core->reg_base + MTK_VENC_IRQ_ACK_OFFSET;
+	ctx->irq_status = readl(core->reg_base + MTK_VENC_IRQ_STATUS_OFFSET);
+	clean_irq_status(ctx->irq_status, addr);
+
+	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, 0);
+	return IRQ_HANDLED;
+}
+
+static int mtk_venc_core_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_venc_core_dev *core;
+	struct mtk_vcodec_dev *main_dev;
+	int ret;
+
+	if (!dev->parent)
+		return dev_err_probe(dev, -ENODEV,
+				     "No parent for venc core device\n");
+
+	main_dev = dev_get_drvdata(dev->parent);
+	if (!main_dev)
+		return dev_err_probe(dev, -EINVAL,
+				     "Failed to get parent driver data\n");
+
+	core = devm_kzalloc(&pdev->dev, sizeof(*core), GFP_KERNEL);
+	if (!core)
+		return dev_err_probe(dev, -ENOMEM,
+				     "Failed to get alloc core data\n");
+
+	core->plat_dev = pdev;
+
+	platform_set_drvdata(pdev, core);
+
+	core->reg_base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(core->reg_base))
+		return dev_err_probe(dev, PTR_ERR(core->reg_base),
+				     "Failed to get reg base\n");
+
+	core->enc_irq = platform_get_irq(pdev, 0);
+	if (core->enc_irq < 0)
+		return dev_err_probe(dev, -EINVAL,
+				     "Failed to get irq resource\n");
+
+	ret = devm_request_irq(dev, core->enc_irq,
+			       mtk_enc_core_irq_handler, 0,
+			       pdev->name, core);
+	if (ret)
+		return dev_err_probe(dev, -EINVAL,
+				     "Failed to install core->enc_irq %d\n",
+				     core->enc_irq);
+
+	of_property_read_u32(dev->of_node, "mediatek,core-id",
+			     &core->core_id);
+
+	if (core->core_id < 0 || core->core_id >= MTK_VENC_CORE_MAX)
+		return dev_err_probe(dev, -EINVAL,
+				     "Invalid core id %d\n", core->core_id);
+
+	main_dev->enc_core_dev[core->core_id] = core;
+	core->main_dev = main_dev;
+
+	dev_dbg(dev, "Venc core :%d probe done\n", core->core_id);
+
+	return 0;
+}
+
+static struct platform_driver mtk_venc_core_driver = {
+	.probe  = mtk_venc_core_probe,
+	.driver = {
+		.name	 = "mtk-venc-core",
+		.of_match_table = mtk_venc_core_ids,
+	},
+};
+module_platform_driver(mtk_venc_core_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Mediatek video encoder core driver");
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.h
new file mode 100644
index 000000000000..9c0f661509df
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#ifndef _MTK_VCODEC_ENC_CORE_H_
+#define _MTK_VCODEC_ENC_CORE_H_
+
+#include <linux/platform_device.h>
+#include "mtk_vcodec_drv.h"
+
+/**
+ * struct mtk_venc_core_dev - driver data
+ * @plat_dev: platform_device
+ * @main_dev: main device
+ * @pm: power management data
+ * @curr_ctx: the context that is waiting for venc hardware
+ * @reg_base: mapped address of venc registers
+ * @irq_status: venc core irq status
+ * @enc_irq: venc device irq
+ * @core id: for venc core id: core#0, core#1...
+ */
+struct mtk_venc_core_dev {
+	struct platform_device *plat_dev;
+	struct mtk_vcodec_dev *main_dev;
+
+	struct mtk_vcodec_pm pm;
+	struct mtk_vcodec_ctx *curr_ctx;
+
+	void __iomem *reg_base;
+	unsigned int irq_status;
+	int enc_irq;
+	int core_id;
+};
+
+#endif /* _MTK_VCODEC_ENC_CORE_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 f12f887e4bdc..d540d52191d9 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -230,10 +230,9 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 {
 	struct mtk_vcodec_dev *dev;
 	struct video_device *vfd_enc;
-	struct resource *res;
 	phandle rproc_phandle;
 	enum mtk_vcodec_fw_type fw_type;
-	int ret;
+	int ret, core_type;
 
 	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
 	if (!dev)
@@ -259,39 +258,48 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		return PTR_ERR(dev->fw_handler);
 
 	dev->venc_pdata = of_device_get_match_data(&pdev->dev);
-	ret = mtk_vcodec_init_enc_clk(dev);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "Failed to get mtk vcodec clock source!");
-		goto err_enc_pm;
+	core_type = dev->venc_pdata->core_type;
+
+	if (of_property_read_bool(pdev->dev.of_node,
+				  "mediatek,venc-multi-core")) {
+		dev->venc_multi_core = true;
+		ret = of_platform_populate(pdev->dev.of_node,
+					   NULL, NULL, &pdev->dev);
+		if (ret) {
+			mtk_v4l2_err("Venc main device populate failed");
+			goto err_enc_pm;
+		}
 	}
 
-	pm_runtime_enable(&pdev->dev);
+	if (!dev->venc_multi_core) {
+		ret = mtk_vcodec_init_enc_clk(dev);
+		if (ret < 0) {
+			dev_err(&pdev->dev,
+				"Failed to get mtk vcodec clock source!");
+			goto err_enc_pm;
+		}
 
-	dev->reg_base[dev->venc_pdata->core_type] =
-		devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(dev->reg_base[dev->venc_pdata->core_type])) {
-		ret = PTR_ERR(dev->reg_base[dev->venc_pdata->core_type]);
-		goto err_res;
-	}
+		pm_runtime_enable(&pdev->dev);
 
-	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->reg_base[core_type] =
+			devm_platform_ioremap_resource(pdev, 0);
+		if (IS_ERR(dev->reg_base[core_type])) {
+			ret = PTR_ERR(dev->reg_base[core_type]);
+			goto err_res;
+		}
 
-	dev->enc_irq = platform_get_irq(pdev, 0);
-	irq_set_status_flags(dev->enc_irq, IRQ_NOAUTOEN);
-	ret = devm_request_irq(&pdev->dev, dev->enc_irq,
-			       mtk_vcodec_enc_irq_handler,
-			       0, pdev->name, dev);
-	if (ret) {
-		dev_err(&pdev->dev,
-			"Failed to install dev->enc_irq %d (%d) core_type (%d)",
-			dev->enc_irq, ret, dev->venc_pdata->core_type);
-		ret = -EINVAL;
-		goto err_res;
+		dev->enc_irq = platform_get_irq(pdev, 0);
+		irq_set_status_flags(dev->enc_irq, IRQ_NOAUTOEN);
+		ret = devm_request_irq(&pdev->dev, dev->enc_irq,
+				       mtk_vcodec_enc_irq_handler,
+				       0, pdev->name, dev);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"Failed to install irq %d (%d) core_type (%d)",
+				dev->enc_irq, ret, core_type);
+			ret = -EINVAL;
+			goto err_res;
+		}
 	}
 
 	mutex_init(&dev->enc_mutex);
@@ -358,7 +366,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	}
 
 	mtk_v4l2_debug(0, "encoder %d registered as /dev/video%d",
-		       dev->venc_pdata->core_type, vfd_enc->num);
+		       core_type, vfd_enc->num);
 
 	return 0;
 
@@ -371,7 +379,8 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 err_enc_alloc:
 	v4l2_device_unregister(&dev->v4l2_dev);
 err_res:
-	pm_runtime_disable(dev->pm.dev);
+	if (!dev->venc_multi_core)
+		pm_runtime_disable(dev->pm.dev);
 err_enc_pm:
 	mtk_vcodec_fw_release(dev->fw_handler);
 	return ret;
@@ -455,7 +464,9 @@ static int mtk_vcodec_enc_remove(struct platform_device *pdev)
 		video_unregister_device(dev->vfd_enc);
 
 	v4l2_device_unregister(&dev->v4l2_dev);
-	pm_runtime_disable(dev->pm.dev);
+	if (!dev->venc_multi_core)
+		pm_runtime_disable(dev->pm.dev);
+
 	mtk_vcodec_fw_release(dev->fw_handler);
 	return 0;
 }
-- 
2.18.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3, 05/10] media: mtk-vcodec: mtk-vcodec: Rewrite venc power manage interface
  2022-03-17  8:22 [PATCH v3, 00/10] Enable two H264 encoder core on MT8195 Irui Wang
                   ` (3 preceding siblings ...)
  2022-03-17  8:22 ` [PATCH v3, 04/10] media: mtk-vcodec: Enable venc dual core usage Irui Wang
@ 2022-03-17  8:22 ` Irui Wang
  2022-03-17  8:22 ` [PATCH v3, 06/10] media: mtk-vcodec: Add venc power on/off interface Irui Wang
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Irui Wang @ 2022-03-17  8:22 UTC (permalink / raw)
  To: Hans Verkuil, Tzung-Bi Shih, Rob Herring, Alexandre Courbot,
	Mauro Carvalho Chehab, Matthias Brugger, Tomasz Figa,
	angelogioacchino.delregno, Yong Wu, Tiffany Lin, Andrew-CT Chen
  Cc: Hsin-Yi Wang, Maoguang Meng, Longfei Wang, Yunfei Dong,
	Fritz Koenig, Irui Wang, linux-media, devicetree, linux-kernel,
	linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

The args "struct mtk_vcodec_dev *" doesn't appropriate for init_clk
functions because of sub-devices. For main device, it has no "pm/clk"
properties in dtsi, sub-devices will init their own "pm/clk" instead.
So rewrite the pm interface with args "platform_device *" and
"mtk_vcodec_pm*".

Signed-off-by: Irui Wang <irui.wang@mediatek.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.c | 8 ++++++++
 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c  | 2 +-
 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c   | 8 ++------
 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h   | 4 ++--
 4 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.c
index 9d3ea5a8afe4..7e376413beaa 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.c
@@ -13,6 +13,7 @@
 #include "mtk_vcodec_drv.h"
 #include "mtk_vcodec_enc.h"
 #include "mtk_vcodec_enc_core.h"
+#include "mtk_vcodec_enc_pm.h"
 #include "mtk_vcodec_intr.h"
 
 static const struct of_device_id mtk_venc_core_ids[] = {
@@ -117,6 +118,13 @@ static int mtk_venc_core_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, -EINVAL,
 				     "Invalid core id %d\n", core->core_id);
 
+	ret = mtk_vcodec_init_enc_clk(core->plat_dev, &core->pm);
+	if (ret < 0)
+		return dev_err_probe(dev, ret,
+				     "Failed to get venc core clock source!");
+
+	pm_runtime_enable(&pdev->dev);
+
 	main_dev->enc_core_dev[core->core_id] = core;
 	core->main_dev = main_dev;
 
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 d540d52191d9..1b1c17b03ef5 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -272,7 +272,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	}
 
 	if (!dev->venc_multi_core) {
-		ret = mtk_vcodec_init_enc_clk(dev);
+		ret = mtk_vcodec_init_enc_clk(dev->plat_dev, &dev->pm);
 		if (ret < 0) {
 			dev_err(&pdev->dev,
 				"Failed to get mtk vcodec clock source!");
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 74495edab558..1e814fc3172f 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
@@ -12,17 +12,13 @@
 #include "mtk_vcodec_enc_pm.h"
 #include "mtk_vcodec_util.h"
 
-int mtk_vcodec_init_enc_clk(struct mtk_vcodec_dev *mtkdev)
+int mtk_vcodec_init_enc_clk(struct platform_device *pdev,
+			    struct mtk_vcodec_pm *pm)
 {
-	struct platform_device *pdev;
-	struct mtk_vcodec_pm *pm;
 	struct mtk_vcodec_clk *enc_clk;
 	struct mtk_vcodec_clk_info *clk_info;
 	int ret, i;
 
-	pdev = mtkdev->plat_dev;
-	pm = &mtkdev->pm;
-	memset(pm, 0, sizeof(struct mtk_vcodec_pm));
 	pm->dev = &pdev->dev;
 	enc_clk = &pm->venc_clk;
 
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
index bc455cefc0cd..97a394c68f4e 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
@@ -9,8 +9,8 @@
 
 #include "mtk_vcodec_drv.h"
 
-int mtk_vcodec_init_enc_clk(struct mtk_vcodec_dev *dev);
-
+int mtk_vcodec_init_enc_clk(struct platform_device *pdev,
+			    struct mtk_vcodec_pm *pm);
 void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm);
 void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm);
 
-- 
2.18.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3, 06/10] media: mtk-vcodec: Add venc power on/off interface
  2022-03-17  8:22 [PATCH v3, 00/10] Enable two H264 encoder core on MT8195 Irui Wang
                   ` (4 preceding siblings ...)
  2022-03-17  8:22 ` [PATCH v3, 05/10] media: mtk-vcodec: mtk-vcodec: Rewrite venc power manage interface Irui Wang
@ 2022-03-17  8:22 ` Irui Wang
  2022-03-17  8:22 ` [PATCH v3, 07/10] media: mtk-vcodec: Rewrite venc clock interface Irui Wang
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Irui Wang @ 2022-03-17  8:22 UTC (permalink / raw)
  To: Hans Verkuil, Tzung-Bi Shih, Rob Herring, Alexandre Courbot,
	Mauro Carvalho Chehab, Matthias Brugger, Tomasz Figa,
	angelogioacchino.delregno, Yong Wu, Tiffany Lin, Andrew-CT Chen
  Cc: Hsin-Yi Wang, Maoguang Meng, Longfei Wang, Yunfei Dong,
	Fritz Koenig, Irui Wang, linux-media, devicetree, linux-kernel,
	linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

venc_multi_core mode power on/off all venc available power, pm_runtime_xx
helper is not appropriate called directly, add new power on/off
interface for it.

Signed-off-by: Irui Wang <irui.wang@mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_enc.c      | 20 +----
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |  7 ++
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c   | 83 +++++++++++++++++++
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.h   |  5 ++
 4 files changed, 98 insertions(+), 17 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
index 0d1b065048a9..b0bc71f00930 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
@@ -12,6 +12,7 @@
 
 #include "mtk_vcodec_drv.h"
 #include "mtk_vcodec_enc.h"
+#include "mtk_vcodec_enc_pm.h"
 #include "mtk_vcodec_intr.h"
 #include "mtk_vcodec_util.h"
 #include "venc_drv_if.h"
@@ -849,7 +850,7 @@ static int vb2ops_venc_start_streaming(struct vb2_queue *q, unsigned int count)
 {
 	struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q);
 	struct venc_enc_param param;
-	int ret, pm_ret;
+	int ret;
 	int i;
 
 	/* Once state turn into MTK_STATE_ABORT, we need stop_streaming
@@ -857,7 +858,7 @@ static int vb2ops_venc_start_streaming(struct vb2_queue *q, unsigned int count)
 	  */
 	if ((ctx->state == MTK_STATE_ABORT) || (ctx->state == MTK_STATE_FREE)) {
 		ret = -EIO;
-		goto err_start_stream;
+		goto err_set_param;
 	}
 
 	/* Do the initialization when both start_streaming have been called */
@@ -869,12 +870,6 @@ static int vb2ops_venc_start_streaming(struct vb2_queue *q, unsigned int count)
 			return 0;
 	}
 
-	ret = pm_runtime_resume_and_get(&ctx->dev->plat_dev->dev);
-	if (ret < 0) {
-		mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret);
-		goto err_start_stream;
-	}
-
 	mtk_venc_set_param(ctx, &param);
 	ret = venc_if_set_param(ctx, VENC_SET_PARAM_ENC, &param);
 	if (ret) {
@@ -901,11 +896,6 @@ static int vb2ops_venc_start_streaming(struct vb2_queue *q, unsigned int count)
 	return 0;
 
 err_set_param:
-	pm_ret = pm_runtime_put(&ctx->dev->plat_dev->dev);
-	if (pm_ret < 0)
-		mtk_v4l2_err("pm_runtime_put fail %d", pm_ret);
-
-err_start_stream:
 	for (i = 0; i < q->num_buffers; ++i) {
 		struct vb2_buffer *buf = vb2_get_buffer(q, i);
 
@@ -988,10 +978,6 @@ static void vb2ops_venc_stop_streaming(struct vb2_queue *q)
 	if (ret)
 		mtk_v4l2_err("venc_if_deinit failed=%d", ret);
 
-	ret = pm_runtime_put(&ctx->dev->plat_dev->dev);
-	if (ret < 0)
-		mtk_v4l2_err("pm_runtime_put fail %d", ret);
-
 	ctx->state = MTK_STATE_FREE;
 }
 
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 1b1c17b03ef5..d2937e62df29 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -173,6 +173,12 @@ static int fops_vcodec_open(struct file *file)
 		mtk_v4l2_debug(0, "encoder capability %x", dev->enc_capability);
 	}
 
+	ret = mtk_vcodec_enc_pw_on(dev);
+	if (ret < 0) {
+		mtk_v4l2_err("encoder power on failed %d", ret);
+		goto err_load_fw;
+	}
+
 	mtk_v4l2_debug(2, "Create instance [%d]@%p m2m_ctx=%p ",
 			ctx->id, ctx, ctx->m2m_ctx);
 
@@ -207,6 +213,7 @@ static int fops_vcodec_release(struct file *file)
 
 	v4l2_m2m_ctx_release(ctx->m2m_ctx);
 	mtk_vcodec_enc_release(ctx);
+	mtk_vcodec_enc_pw_off(dev);
 	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_enc_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
index 1e814fc3172f..22b2eb867998 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
@@ -9,6 +9,7 @@
 #include <linux/of_platform.h>
 #include <linux/pm_runtime.h>
 
+#include "mtk_vcodec_enc_core.h"
 #include "mtk_vcodec_enc_pm.h"
 #include "mtk_vcodec_util.h"
 
@@ -87,3 +88,85 @@ void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm)
 		clk_disable_unprepare(enc_clk->clk_info[i].vcodec_clk);
 }
 EXPORT_SYMBOL_GPL(mtk_vcodec_enc_clock_off);
+
+int mtk_venc_core_pw_on(struct mtk_vcodec_dev *dev)
+{
+	int i, ret;
+	struct mtk_venc_core_dev *core;
+
+	/* power on all available venc cores */
+	for (i = 0; i < MTK_VENC_CORE_MAX; i++) {
+		core = (struct mtk_venc_core_dev *)dev->enc_core_dev[i];
+		if (!core)
+			return 0;
+
+		ret = pm_runtime_resume_and_get(&core->plat_dev->dev);
+		if (ret < 0) {
+			mtk_v4l2_err("power on core[%d] fail %d", i, ret);
+			goto pw_on_fail;
+		}
+	}
+	return 0;
+
+pw_on_fail:
+	for (i -= 1; i >= 0; i--) {
+		core = (struct mtk_venc_core_dev *)dev->enc_core_dev[i];
+		pm_runtime_put_sync(&core->plat_dev->dev);
+	}
+	return ret;
+}
+
+int mtk_venc_core_pw_off(struct mtk_vcodec_dev *dev)
+{
+	int i, ret;
+	struct mtk_venc_core_dev *core;
+
+	/* power off all available venc cores */
+	for (i = 0; i < MTK_VENC_CORE_MAX; i++) {
+		core = (struct mtk_venc_core_dev *)dev->enc_core_dev[i];
+		if (!core)
+			return 0;
+
+		ret = pm_runtime_put_sync(&core->plat_dev->dev);
+		if (ret < 0)
+			mtk_v4l2_err("power off core[%d] fail %d", i, ret);
+	}
+	return ret;
+}
+
+int mtk_vcodec_enc_pw_on(struct mtk_vcodec_dev *dev)
+{
+	int ret;
+
+	if (dev->venc_multi_core) {
+		ret = mtk_venc_core_pw_on(dev);
+		if (ret < 0) {
+			mtk_v4l2_err("venc core power on fail: %d", ret);
+			return ret;
+		}
+	} else {
+		ret = pm_runtime_resume_and_get(&dev->plat_dev->dev);
+		if (ret < 0) {
+			mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret);
+			return ret;
+		}
+	}
+	return 0;
+}
+
+int mtk_vcodec_enc_pw_off(struct mtk_vcodec_dev *dev)
+{
+	int ret;
+
+	if (dev->venc_multi_core) {
+		ret = mtk_venc_core_pw_off(dev);
+		if (ret < 0)
+			mtk_v4l2_err("venc core power off fail: %d", ret);
+
+	} else {
+		ret = pm_runtime_put_sync(&dev->plat_dev->dev);
+		if (ret < 0)
+			mtk_v4l2_err("pm_runtime_put_sync fail %d", ret);
+	}
+	return ret;
+}
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
index 97a394c68f4e..99b6b6e29e35 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
@@ -14,4 +14,9 @@ int mtk_vcodec_init_enc_clk(struct platform_device *pdev,
 void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm);
 void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm);
 
+int mtk_venc_core_pw_on(struct mtk_vcodec_dev *dev);
+int mtk_venc_core_pw_off(struct mtk_vcodec_dev *dev);
+int mtk_vcodec_enc_pw_on(struct mtk_vcodec_dev *dev);
+int mtk_vcodec_enc_pw_off(struct mtk_vcodec_dev *dev);
+
 #endif /* _MTK_VCODEC_ENC_PM_H_ */
-- 
2.18.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3, 07/10] media: mtk-vcodec: Rewrite venc clock interface
  2022-03-17  8:22 [PATCH v3, 00/10] Enable two H264 encoder core on MT8195 Irui Wang
                   ` (5 preceding siblings ...)
  2022-03-17  8:22 ` [PATCH v3, 06/10] media: mtk-vcodec: Add venc power on/off interface Irui Wang
@ 2022-03-17  8:22 ` Irui Wang
  2022-03-17  8:22 ` [PATCH v3, 08/10] media: mtk-vcodec: Add more extra processing for venc_multi_core mode Irui Wang
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Irui Wang @ 2022-03-17  8:22 UTC (permalink / raw)
  To: Hans Verkuil, Tzung-Bi Shih, Rob Herring, Alexandre Courbot,
	Mauro Carvalho Chehab, Matthias Brugger, Tomasz Figa,
	angelogioacchino.delregno, Yong Wu, Tiffany Lin, Andrew-CT Chen
  Cc: Hsin-Yi Wang, Maoguang Meng, Longfei Wang, Yunfei Dong,
	Fritz Koenig, Irui Wang, linux-media, devicetree, linux-kernel,
	linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

venc_multi_core mode need enable the specific core's clk, add an
another param for clock_on/clock_off interface.

Signed-off-by: Irui Wang <irui.wang@mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c   | 95 ++++++++++++++++---
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.h   |  4 +-
 .../media/platform/mtk-vcodec/venc_drv_if.c   | 10 +-
 3 files changed, 84 insertions(+), 25 deletions(-)

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 22b2eb867998..cdf7083c9335 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
@@ -57,42 +57,86 @@ int mtk_vcodec_init_enc_clk(struct platform_device *pdev,
 }
 EXPORT_SYMBOL_GPL(mtk_vcodec_init_enc_clk);
 
-void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm)
+void mtk_vcodec_enc_clock_on(struct mtk_vcodec_dev *dev, int core_id)
 {
-	struct mtk_vcodec_clk *enc_clk = &pm->venc_clk;
+	struct mtk_venc_core_dev *core;
+	struct mtk_vcodec_pm *enc_pm;
+	struct mtk_vcodec_clk *enc_clk;
+	struct clk              *clk;
 	int ret, i = 0;
 
-	for (i = 0; i < enc_clk->clk_num; i++) {
-		ret = clk_prepare_enable(enc_clk->clk_info[i].vcodec_clk);
-		if (ret) {
-			mtk_v4l2_err("venc clk_prepare_enable %d %s fail %d", i,
-				enc_clk->clk_info[i].clk_name, ret);
-			goto clkerr;
+	if (dev->venc_multi_core) {
+		core = (struct mtk_venc_core_dev *)dev->enc_core_dev[core_id];
+		enc_pm = &core->pm;
+		enc_clk = &enc_pm->venc_clk;
+
+		for (i = 0; i < enc_clk->clk_num; i++) {
+			clk = enc_clk->clk_info[i].vcodec_clk;
+			ret = clk_enable(clk);
+			if (ret) {
+				mtk_v4l2_err("clk_enable %d %s fail %d", i,
+					     enc_clk->clk_info[i].clk_name,
+					     ret);
+				goto core_clk_err;
+			}
+		}
+	} else {
+		enc_pm = &dev->pm;
+		enc_clk = &enc_pm->venc_clk;
+
+		for (i = 0; i < enc_clk->clk_num; i++) {
+			clk = enc_clk->clk_info[i].vcodec_clk;
+			ret = clk_prepare_enable(clk);
+			if (ret) {
+				mtk_v4l2_err("clk_prepare %d %s fail %d",
+					     i, enc_clk->clk_info[i].clk_name,
+					     ret);
+				goto clkerr;
+			}
 		}
 	}
 
 	return;
 
+core_clk_err:
+	for (i -= 1; i >= 0; i--)
+		clk_disable(enc_clk->clk_info[i].vcodec_clk);
 clkerr:
 	for (i -= 1; i >= 0; i--)
 		clk_disable_unprepare(enc_clk->clk_info[i].vcodec_clk);
 }
 EXPORT_SYMBOL_GPL(mtk_vcodec_enc_clock_on);
 
-void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm)
+void mtk_vcodec_enc_clock_off(struct mtk_vcodec_dev *dev, int core_id)
 {
-	struct mtk_vcodec_clk *enc_clk = &pm->venc_clk;
+	struct mtk_venc_core_dev *core;
+	struct mtk_vcodec_pm *enc_pm;
+	struct mtk_vcodec_clk *enc_clk;
 	int i = 0;
 
-	for (i = enc_clk->clk_num - 1; i >= 0; i--)
-		clk_disable_unprepare(enc_clk->clk_info[i].vcodec_clk);
+	if (dev->venc_multi_core) {
+		core = (struct mtk_venc_core_dev *)dev->enc_core_dev[core_id];
+		enc_pm = &core->pm;
+		enc_clk = &enc_pm->venc_clk;
+
+		for (i = enc_clk->clk_num - 1; i >= 0; i--)
+			clk_disable(enc_clk->clk_info[i].vcodec_clk);
+	} else {
+		enc_pm = &dev->pm;
+		enc_clk = &enc_pm->venc_clk;
+
+		for (i = enc_clk->clk_num - 1; i >= 0; i--)
+			clk_disable_unprepare(enc_clk->clk_info[i].vcodec_clk);
+	}
+
 }
 EXPORT_SYMBOL_GPL(mtk_vcodec_enc_clock_off);
 
 int mtk_venc_core_pw_on(struct mtk_vcodec_dev *dev)
 {
-	int i, ret;
+	int i, ret, j;
 	struct mtk_venc_core_dev *core;
+	struct mtk_vcodec_clk *clk;
 
 	/* power on all available venc cores */
 	for (i = 0; i < MTK_VENC_CORE_MAX; i++) {
@@ -102,15 +146,31 @@ int mtk_venc_core_pw_on(struct mtk_vcodec_dev *dev)
 
 		ret = pm_runtime_resume_and_get(&core->plat_dev->dev);
 		if (ret < 0) {
-			mtk_v4l2_err("power on core[%d] fail %d", i, ret);
+			mtk_v4l2_err("power on core[%d] fail", i);
 			goto pw_on_fail;
 		}
+
+		clk = &core->pm.venc_clk;
+		for (j = 0; j < clk->clk_num; j++) {
+			ret = clk_prepare(clk->clk_info[j].vcodec_clk);
+			if (ret) {
+				mtk_v4l2_err("prepare clk [%s] fail %d",
+					     clk->clk_info[j].clk_name,
+					     ret);
+				goto pw_on_fail;
+			}
+		}
 	}
 	return 0;
 
 pw_on_fail:
 	for (i -= 1; i >= 0; i--) {
 		core = (struct mtk_venc_core_dev *)dev->enc_core_dev[i];
+
+		clk = &core->pm.venc_clk;
+		for (j -= 1; j >= 0; j--)
+			clk_unprepare(clk->clk_info[j].vcodec_clk);
+
 		pm_runtime_put_sync(&core->plat_dev->dev);
 	}
 	return ret;
@@ -118,8 +178,9 @@ int mtk_venc_core_pw_on(struct mtk_vcodec_dev *dev)
 
 int mtk_venc_core_pw_off(struct mtk_vcodec_dev *dev)
 {
-	int i, ret;
+	int i, ret, j;
 	struct mtk_venc_core_dev *core;
+	struct mtk_vcodec_clk *clk;
 
 	/* power off all available venc cores */
 	for (i = 0; i < MTK_VENC_CORE_MAX; i++) {
@@ -127,6 +188,10 @@ int mtk_venc_core_pw_off(struct mtk_vcodec_dev *dev)
 		if (!core)
 			return 0;
 
+		clk = &core->pm.venc_clk;
+		for (j = clk->clk_num - 1; j >= 0; j--)
+			clk_unprepare(clk->clk_info[j].vcodec_clk);
+
 		ret = pm_runtime_put_sync(&core->plat_dev->dev);
 		if (ret < 0)
 			mtk_v4l2_err("power off core[%d] fail %d", i, ret);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
index 99b6b6e29e35..5113ed8a869e 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
@@ -11,8 +11,8 @@
 
 int mtk_vcodec_init_enc_clk(struct platform_device *pdev,
 			    struct mtk_vcodec_pm *pm);
-void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm);
-void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm);
+void mtk_vcodec_enc_clock_on(struct mtk_vcodec_dev *dev, int core_id);
+void mtk_vcodec_enc_clock_off(struct mtk_vcodec_dev *dev, int core_id);
 
 int mtk_venc_core_pw_on(struct mtk_vcodec_dev *dev);
 int mtk_venc_core_pw_off(struct mtk_vcodec_dev *dev);
diff --git a/drivers/media/platform/mtk-vcodec/venc_drv_if.c b/drivers/media/platform/mtk-vcodec/venc_drv_if.c
index ce0bce811615..6cbdb7e30bb3 100644
--- a/drivers/media/platform/mtk-vcodec/venc_drv_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc_drv_if.c
@@ -32,9 +32,7 @@ int venc_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
 	}
 
 	mtk_venc_lock(ctx);
-	mtk_vcodec_enc_clock_on(&ctx->dev->pm);
 	ret = ctx->enc_if->init(ctx);
-	mtk_vcodec_enc_clock_off(&ctx->dev->pm);
 	mtk_venc_unlock(ctx);
 
 	return ret;
@@ -46,9 +44,7 @@ int venc_if_set_param(struct mtk_vcodec_ctx *ctx,
 	int ret = 0;
 
 	mtk_venc_lock(ctx);
-	mtk_vcodec_enc_clock_on(&ctx->dev->pm);
 	ret = ctx->enc_if->set_param(ctx->drv_handle, type, in);
-	mtk_vcodec_enc_clock_off(&ctx->dev->pm);
 	mtk_venc_unlock(ctx);
 
 	return ret;
@@ -68,10 +64,10 @@ int venc_if_encode(struct mtk_vcodec_ctx *ctx,
 	ctx->dev->curr_ctx = ctx;
 	spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
 
-	mtk_vcodec_enc_clock_on(&ctx->dev->pm);
+	mtk_vcodec_enc_clock_on(ctx->dev, 0);
 	ret = ctx->enc_if->encode(ctx->drv_handle, opt, frm_buf,
 				  bs_buf, result);
-	mtk_vcodec_enc_clock_off(&ctx->dev->pm);
+	mtk_vcodec_enc_clock_off(ctx->dev, 0);
 
 	spin_lock_irqsave(&ctx->dev->irqlock, flags);
 	ctx->dev->curr_ctx = NULL;
@@ -89,9 +85,7 @@ int venc_if_deinit(struct mtk_vcodec_ctx *ctx)
 		return 0;
 
 	mtk_venc_lock(ctx);
-	mtk_vcodec_enc_clock_on(&ctx->dev->pm);
 	ret = ctx->enc_if->deinit(ctx->drv_handle);
-	mtk_vcodec_enc_clock_off(&ctx->dev->pm);
 	mtk_venc_unlock(ctx);
 
 	ctx->drv_handle = NULL;
-- 
2.18.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3, 08/10] media: mtk-vcodec: Add more extra processing for venc_multi_core mode
  2022-03-17  8:22 [PATCH v3, 00/10] Enable two H264 encoder core on MT8195 Irui Wang
                   ` (6 preceding siblings ...)
  2022-03-17  8:22 ` [PATCH v3, 07/10] media: mtk-vcodec: Rewrite venc clock interface Irui Wang
@ 2022-03-17  8:22 ` Irui Wang
  2022-03-17  8:22 ` [PATCH v3, 09/10] media: mtk-vcodec: Add venc_multi_core mode encode process Irui Wang
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Irui Wang @ 2022-03-17  8:22 UTC (permalink / raw)
  To: Hans Verkuil, Tzung-Bi Shih, Rob Herring, Alexandre Courbot,
	Mauro Carvalho Chehab, Matthias Brugger, Tomasz Figa,
	angelogioacchino.delregno, Yong Wu, Tiffany Lin, Andrew-CT Chen
  Cc: Hsin-Yi Wang, Maoguang Meng, Longfei Wang, Yunfei Dong,
	Fritz Koenig, Irui Wang, linux-media, devicetree, linux-kernel,
	linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

venc_multi_core mode encoding need more venc working buffers, it
will break the compatibility if we just add venc_vsi in AP-Kernel
but not in firmware, so add more struct definition for it.

Signed-off-by: Irui Wang <irui.wang@mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_util.c     |  19 ++
 .../platform/mtk-vcodec/mtk_vcodec_util.h     |   4 +
 .../platform/mtk-vcodec/venc/venc_h264_if.c   | 174 +++++++++++++++---
 3 files changed, 172 insertions(+), 25 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
index ace78c4b5b9e..059f665afa96 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
@@ -11,6 +11,7 @@
 
 #include "mtk_vcodec_dec_hw.h"
 #include "mtk_vcodec_drv.h"
+#include "mtk_vcodec_enc_core.h"
 #include "mtk_vcodec_util.h"
 
 void __iomem *mtk_vcodec_get_reg_addr(struct mtk_vcodec_ctx *data,
@@ -26,6 +27,24 @@ void __iomem *mtk_vcodec_get_reg_addr(struct mtk_vcodec_ctx *data,
 }
 EXPORT_SYMBOL(mtk_vcodec_get_reg_addr);
 
+void __iomem *mtk_venc_get_core_reg_addr(struct mtk_vcodec_ctx *ctx,
+					 unsigned int core_id)
+{
+	struct mtk_venc_core_dev *core;
+
+	if (core_id >= MTK_VENC_CORE_MAX) {
+		mtk_v4l2_err("Invalid core_id = %d", core_id);
+		return NULL;
+	}
+
+	core = (struct mtk_venc_core_dev *)ctx->dev->enc_core_dev[core_id];
+	if (!core)
+		return NULL;
+
+	return core->reg_base;
+}
+EXPORT_SYMBOL(mtk_venc_get_core_reg_addr);
+
 int mtk_vcodec_mem_alloc(struct mtk_vcodec_ctx *data,
 			struct mtk_vcodec_mem *mem)
 {
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
index 71956627a0e2..de9e18688842 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
@@ -50,6 +50,10 @@ struct mtk_vcodec_dev;
 
 void __iomem *mtk_vcodec_get_reg_addr(struct mtk_vcodec_ctx *data,
 				unsigned int reg_idx);
+
+void __iomem *mtk_venc_get_core_reg_addr(struct mtk_vcodec_ctx *data,
+					 unsigned int core_id);
+
 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,
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 4d9b8798dffe..aee31cb836c6 100644
--- a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
@@ -50,6 +50,24 @@ enum venc_h264_vpu_work_buf {
 	VENC_H264_VPU_WORK_BUF_MAX,
 };
 
+/*
+ * enum venc_multi_core_work_buf - h264 multi core encoder buffer index
+ */
+enum venc_multi_core_work_buf {
+	VENC_MULTI_CORE_WORK_BUF_RC_INFO_CORE0,
+	VENC_MULTI_CORE_WORK_BUF_RC_CODE,
+	VENC_MULTI_CORE_WORK_BUF_REC_LUMA,
+	VENC_MULTI_CORE_WORK_BUF_REC_CHROMA,
+	VENC_MULTI_CORE_WORK_BUF_REF_LUMA,
+	VENC_MULTI_CORE_WORK_BUF_REF_CHROMA,
+	VENC_MULTI_CORE_WORK_BUF_MV_INFO_1,
+	VENC_MULTI_CORE_WORK_BUF_MV_INFO_2,
+	VENC_MULTI_CORE_WORK_BUF_SKIP_FRAME,
+	VENC_MULTI_CORE_WORK_BUF_RC_INFO_CORE1,
+	VENC_MULTI_CORE_WORK_BUF_FR_RC_INFO,
+	VENC_MULTI_CORE_WORK_BUF_MAX,
+};
+
 /*
  * enum venc_h264_bs_mode - for bs_mode argument in h264_enc_vpu_encode
  */
@@ -94,6 +112,24 @@ struct venc_h264_vpu_config {
 	u32 wfd;
 };
 
+struct venc_multi_core_config {
+	u32 input_fourcc;
+	u32 bitrate;
+	u32 pic_w;
+	u32 pic_h;
+	u32 buf_w;
+	u32 buf_h;
+	u32 gop_size;
+	u32 intra_period;
+	u32 framerate;
+	u32 profile;
+	u32 level;
+	u32 wfd;
+	u32 max_qp;
+	u32 min_qp;
+	u32 reserved[8];
+};
+
 /*
  * struct venc_h264_vpu_buf - Structure for buffer information
  *                            AP-W/R : AP is writer/reader on this item
@@ -127,6 +163,11 @@ struct venc_h264_vsi {
 	struct venc_h264_vpu_buf work_bufs[VENC_H264_VPU_WORK_BUF_MAX];
 };
 
+struct venc_multi_core_vsi {
+	struct venc_multi_core_config config;
+	struct venc_h264_vpu_buf work_bufs[VENC_MULTI_CORE_WORK_BUF_MAX];
+};
+
 /*
  * struct venc_h264_inst - h264 encoder AP driver instance
  * @hw_base: h264 encoder hardware register base
@@ -143,8 +184,8 @@ struct venc_h264_vsi {
  * @ctx: context for v4l2 layer integration
  */
 struct venc_h264_inst {
-	void __iomem *hw_base;
-	struct mtk_vcodec_mem work_bufs[VENC_H264_VPU_WORK_BUF_MAX];
+	void __iomem *hw_base[MTK_VENC_CORE_MAX];
+	struct mtk_vcodec_mem work_bufs[VENC_MULTI_CORE_WORK_BUF_MAX];
 	struct mtk_vcodec_mem pps_buf;
 	bool work_buf_allocated;
 	unsigned int frm_cnt;
@@ -152,12 +193,13 @@ struct venc_h264_inst {
 	unsigned int prepend_hdr;
 	struct venc_vpu_inst vpu_inst;
 	struct venc_h264_vsi *vsi;
+	struct venc_multi_core_vsi *core_vsi;
 	struct mtk_vcodec_ctx *ctx;
 };
 
 static inline u32 h264_read_reg(struct venc_h264_inst *inst, u32 addr)
 {
-	return readl(inst->hw_base + addr);
+	return readl(inst->hw_base[MTK_VENC_CORE0] + addr);
 }
 
 static unsigned int h264_get_profile(struct venc_h264_inst *inst,
@@ -228,13 +270,20 @@ static unsigned int h264_get_level(struct venc_h264_inst *inst,
 static void h264_enc_free_work_buf(struct venc_h264_inst *inst)
 {
 	int i;
+	struct mtk_vcodec_ctx *ctx = inst->ctx;
+	int max_work_buf;
 
 	mtk_vcodec_debug_enter(inst);
 
+	if (ctx->dev->venc_multi_core)
+		max_work_buf = VENC_MULTI_CORE_WORK_BUF_MAX;
+	else
+		max_work_buf = VENC_H264_VPU_WORK_BUF_MAX;
+
 	/* Except the SKIP_FRAME buffers,
 	 * other buffers need to be freed by AP.
 	 */
-	for (i = 0; i < VENC_H264_VPU_WORK_BUF_MAX; i++) {
+	for (i = 0; i < max_work_buf; i++) {
 		if (i != VENC_H264_VPU_WORK_BUF_SKIP_FRAME)
 			mtk_vcodec_mem_free(inst->ctx, &inst->work_bufs[i]);
 	}
@@ -248,11 +297,21 @@ static int h264_enc_alloc_work_buf(struct venc_h264_inst *inst)
 {
 	int i;
 	int ret = 0;
-	struct venc_h264_vpu_buf *wb = inst->vsi->work_bufs;
+	struct mtk_vcodec_ctx *ctx = inst->ctx;
+	struct venc_h264_vpu_buf *wb;
+	int max_work_buf;
 
 	mtk_vcodec_debug_enter(inst);
 
-	for (i = 0; i < VENC_H264_VPU_WORK_BUF_MAX; i++) {
+	if (ctx->dev->venc_multi_core) {
+		wb = inst->core_vsi->work_bufs;
+		max_work_buf = VENC_MULTI_CORE_WORK_BUF_MAX;
+	} else {
+		wb = inst->vsi->work_bufs;
+		max_work_buf = VENC_H264_VPU_WORK_BUF_MAX;
+	}
+
+	for (i = 0; i < max_work_buf; i++) {
 		/*
 		 * This 'wb' structure is set by VPU side and shared to AP for
 		 * buffer allocation and IO virtual addr mapping. For most of
@@ -358,6 +417,26 @@ static int h264_frame_type(struct venc_h264_inst *inst)
 		return VENC_H264_P_FRM;  /* Note: B frames are not supported */
 	}
 }
+
+static int h264_core_frame_type(struct venc_h264_inst *inst)
+{
+	struct venc_multi_core_vsi *vsi = inst->core_vsi;
+
+	if ((vsi->config.gop_size != 0 &&
+	     (inst->frm_cnt % vsi->config.gop_size) == 0) ||
+	    (inst->frm_cnt == 0 && vsi->config.gop_size == 0)) {
+		/* IDR frame */
+		return VENC_H264_IDR_FRM;
+	} else if ((vsi->config.intra_period != 0 &&
+		    (inst->frm_cnt % vsi->config.intra_period) == 0) ||
+		   (inst->frm_cnt == 0 && vsi->config.intra_period == 0)) {
+		/* I frame */
+		return VENC_H264_I_FRM;
+	} else {
+		return VENC_H264_P_FRM;  /* Note: B frames are not supported */
+	}
+}
+
 static int h264_encode_sps(struct venc_h264_inst *inst,
 			   struct mtk_vcodec_mem *bs_buf,
 			   unsigned int *bs_size)
@@ -440,12 +519,17 @@ static int h264_encode_frame(struct venc_h264_inst *inst,
 	int ret = 0;
 	unsigned int irq_status;
 	struct venc_frame_info frame_info;
+	struct mtk_vcodec_ctx *ctx = inst->ctx;
 
 	mtk_vcodec_debug_enter(inst);
 	mtk_vcodec_debug(inst, "frm_cnt = %d\n ", inst->frm_cnt);
 	frame_info.frm_count = inst->frm_cnt;
 	frame_info.skip_frm_count = inst->skip_frm_cnt;
-	frame_info.frm_type = h264_frame_type(inst);
+	if (ctx->dev->venc_multi_core)
+		frame_info.frm_type = h264_core_frame_type(inst);
+	else
+		frame_info.frm_type = h264_frame_type(inst);
+
 	mtk_vcodec_debug(inst, "frm_count = %d,skip_frm_count =%d,frm_type=%d.\n",
 			 frame_info.frm_count, frame_info.skip_frm_count,
 			 frame_info.frm_type);
@@ -501,7 +585,7 @@ static void h264_encode_filler(struct venc_h264_inst *inst, void *buf,
 static int h264_enc_init(struct mtk_vcodec_ctx *ctx)
 {
 	const bool is_ext = MTK_ENC_CTX_IS_EXT(ctx);
-	int ret = 0;
+	int ret, i = 0;
 	struct venc_h264_inst *inst;
 
 	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
@@ -511,13 +595,22 @@ static int h264_enc_init(struct mtk_vcodec_ctx *ctx)
 	inst->ctx = ctx;
 	inst->vpu_inst.ctx = ctx;
 	inst->vpu_inst.id = is_ext ? SCP_IPI_VENC_H264 : IPI_VENC_H264;
-	inst->hw_base = mtk_vcodec_get_reg_addr(inst->ctx, VENC_SYS);
 
 	mtk_vcodec_debug_enter(inst);
 
 	ret = vpu_enc_init(&inst->vpu_inst);
 
-	inst->vsi = (struct venc_h264_vsi *)inst->vpu_inst.vsi;
+	if (ctx->dev->venc_multi_core) {
+		inst->core_vsi =
+			(struct venc_multi_core_vsi *)inst->vpu_inst.vsi;
+		for (i = 0; i < MTK_VENC_CORE_MAX; i++)
+			inst->hw_base[i] =
+				mtk_venc_get_core_reg_addr(inst->ctx, i);
+
+	} else {
+		inst->vsi = (struct venc_h264_vsi *)inst->vpu_inst.vsi;
+		inst->hw_base[0] = mtk_vcodec_get_reg_addr(inst->ctx, VENC_SYS);
+	}
 
 	mtk_vcodec_debug_leave(inst);
 
@@ -624,31 +717,62 @@ static int h264_enc_encode(void *handle,
 	return ret;
 }
 
+static void h264_enc_set_configs(struct venc_h264_inst *inst,
+				 struct venc_enc_param *enc_prm)
+{
+	inst->vsi->config.input_fourcc = enc_prm->input_yuv_fmt;
+	inst->vsi->config.bitrate = enc_prm->bitrate;
+	inst->vsi->config.pic_w = enc_prm->width;
+	inst->vsi->config.pic_h = enc_prm->height;
+	inst->vsi->config.buf_w = enc_prm->buf_width;
+	inst->vsi->config.buf_h = enc_prm->buf_height;
+	inst->vsi->config.gop_size = enc_prm->gop_size;
+	inst->vsi->config.framerate = enc_prm->frm_rate;
+	inst->vsi->config.intra_period = enc_prm->intra_period;
+	inst->vsi->config.profile =
+		h264_get_profile(inst, enc_prm->h264_profile);
+	inst->vsi->config.level =
+		h264_get_level(inst, enc_prm->h264_level);
+	inst->vsi->config.wfd = 0;
+}
+
+static void h264_enc_set_core_configs(struct venc_h264_inst *inst,
+				      struct venc_enc_param *enc_prm)
+{
+	inst->core_vsi->config.input_fourcc = enc_prm->input_yuv_fmt;
+	inst->core_vsi->config.bitrate = enc_prm->bitrate;
+	inst->core_vsi->config.pic_w = enc_prm->width;
+	inst->core_vsi->config.pic_h = enc_prm->height;
+	inst->core_vsi->config.buf_w = enc_prm->buf_width;
+	inst->core_vsi->config.buf_h = enc_prm->buf_height;
+	inst->core_vsi->config.gop_size = enc_prm->gop_size;
+	inst->core_vsi->config.framerate = enc_prm->frm_rate;
+	inst->core_vsi->config.intra_period = enc_prm->intra_period;
+	inst->core_vsi->config.profile =
+		h264_get_profile(inst, enc_prm->h264_profile);
+	inst->core_vsi->config.level =
+		h264_get_level(inst, enc_prm->h264_level);
+	inst->core_vsi->config.wfd = 0;
+}
+
 static int h264_enc_set_param(void *handle,
 			      enum venc_set_param_type type,
 			      struct venc_enc_param *enc_prm)
 {
 	int ret = 0;
 	struct venc_h264_inst *inst = (struct venc_h264_inst *)handle;
+	struct mtk_vcodec_ctx *ctx = inst->ctx;
 
-	mtk_vcodec_debug(inst, "->type=%d", type);
+	mtk_vcodec_debug(inst, "->type=%d, multi_core=%d",
+			 type, ctx->dev->venc_multi_core);
 
 	switch (type) {
 	case VENC_SET_PARAM_ENC:
-		inst->vsi->config.input_fourcc = enc_prm->input_yuv_fmt;
-		inst->vsi->config.bitrate = enc_prm->bitrate;
-		inst->vsi->config.pic_w = enc_prm->width;
-		inst->vsi->config.pic_h = enc_prm->height;
-		inst->vsi->config.buf_w = enc_prm->buf_width;
-		inst->vsi->config.buf_h = enc_prm->buf_height;
-		inst->vsi->config.gop_size = enc_prm->gop_size;
-		inst->vsi->config.framerate = enc_prm->frm_rate;
-		inst->vsi->config.intra_period = enc_prm->intra_period;
-		inst->vsi->config.profile =
-			h264_get_profile(inst, enc_prm->h264_profile);
-		inst->vsi->config.level =
-			h264_get_level(inst, enc_prm->h264_level);
-		inst->vsi->config.wfd = 0;
+		if (ctx->dev->venc_multi_core)
+			h264_enc_set_core_configs(inst, enc_prm);
+		else
+			h264_enc_set_configs(inst, enc_prm);
+
 		ret = vpu_enc_set_param(&inst->vpu_inst, type, enc_prm);
 		if (ret)
 			break;
-- 
2.18.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3, 09/10] media: mtk-vcodec: Add venc_multi_core mode encode process
  2022-03-17  8:22 [PATCH v3, 00/10] Enable two H264 encoder core on MT8195 Irui Wang
                   ` (7 preceding siblings ...)
  2022-03-17  8:22 ` [PATCH v3, 08/10] media: mtk-vcodec: Add more extra processing for venc_multi_core mode Irui Wang
@ 2022-03-17  8:22 ` Irui Wang
  2022-03-17  8:22 ` [PATCH v3, 10/10] media: mtk-vcodec: Done encode result to client Irui Wang
  2022-03-18 14:04 ` [PATCH v3, 00/10] Enable two H264 encoder core on MT8195 AngeloGioacchino Del Regno
  10 siblings, 0 replies; 21+ messages in thread
From: Irui Wang @ 2022-03-17  8:22 UTC (permalink / raw)
  To: Hans Verkuil, Tzung-Bi Shih, Rob Herring, Alexandre Courbot,
	Mauro Carvalho Chehab, Matthias Brugger, Tomasz Figa,
	angelogioacchino.delregno, Yong Wu, Tiffany Lin, Andrew-CT Chen
  Cc: Hsin-Yi Wang, Maoguang Meng, Longfei Wang, Yunfei Dong,
	Fritz Koenig, Irui Wang, linux-media, devicetree, linux-kernel,
	linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

The venc_multi_core mode encoding is tries to uses all available cores.
MT8195 has two venc cores:
frame#0 uses core#0, frame#1 uses core#1, frame#2 uses core#0...,

Lock the device and enable the clock by used core, for sequence
header encoding, it always uses core#0.

Signed-off-by: Irui Wang <irui.wang@mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      | 12 ++-
 .../platform/mtk-vcodec/mtk_vcodec_enc.c      | 23 +++---
 .../platform/mtk-vcodec/mtk_vcodec_enc.h      |  4 +-
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |  7 +-
 .../platform/mtk-vcodec/venc/venc_h264_if.c   | 16 ++--
 .../platform/mtk-vcodec/venc/venc_vp8_if.c    |  3 +-
 .../media/platform/mtk-vcodec/venc_drv_if.c   | 73 ++++++++++++++-----
 .../media/platform/mtk-vcodec/venc_drv_if.h   |  5 ++
 .../media/platform/mtk-vcodec/venc_vpu_if.c   | 11 ++-
 .../media/platform/mtk-vcodec/venc_vpu_if.h   |  3 +-
 10 files changed, 115 insertions(+), 42 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 43e1349d6a54..889ce61f0fc8 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -297,6 +297,9 @@ struct vdec_pic_info {
  * @max_width: hardware supported max width
  * @max_height: hardware supported max height
  * @msg_queue: msg queue used to store lat buffer information.
+ * @q_mutex: src & dst vb2_queue mutex
+ * @enc_idx: used to record encoded frame count
+ * @core_id: used to record used core
  */
 struct mtk_vcodec_ctx {
 	enum mtk_instance_type type;
@@ -345,6 +348,11 @@ struct mtk_vcodec_ctx {
 	unsigned int max_width;
 	unsigned int max_height;
 	struct vdec_msg_queue msg_queue;
+
+	/* src & dst vb2_queue mutex */
+	struct mutex q_mutex;
+	int enc_idx;
+	int core_id;
 };
 
 /*
@@ -520,7 +528,9 @@ struct mtk_vcodec_dev {
 
 	/* decoder hardware mutex lock */
 	struct mutex dec_mutex[MTK_VDEC_HW_MAX];
-	struct mutex enc_mutex;
+
+	/* encoder core mutex lock */
+	struct mutex enc_mutex[MTK_VENC_CORE_MAX];
 
 	struct mtk_vcodec_pm pm;
 	unsigned int dec_capability;
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
index b0bc71f00930..2753f004f123 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
@@ -1197,14 +1197,17 @@ static void mtk_venc_worker(struct work_struct *work)
 		vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0);
 		v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
 		mtk_v4l2_err("venc_if_encode failed=%d", ret);
-	} else {
+	} else if (!ctx->dev->venc_multi_core) {
 		v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
-		vb2_set_plane_payload(&dst_buf->vb2_buf, 0, enc_result.bs_size);
+		vb2_set_plane_payload(&dst_buf->vb2_buf, 0,
+				      enc_result.bs_size);
 		v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
 		mtk_v4l2_debug(2, "venc_if_encode bs size=%d",
-				 enc_result.bs_size);
+			       enc_result.bs_size);
 	}
 
+	ctx->enc_idx++;
+
 	v4l2_m2m_job_finish(ctx->dev->m2m_dev_enc, ctx->m2m_ctx);
 
 	mtk_v4l2_debug(1, "<=== src_buf[%d] dst_buf[%d] venc_if_encode ret=%d Size=%u===>",
@@ -1258,7 +1261,7 @@ void mtk_vcodec_enc_set_default_params(struct mtk_vcodec_ctx *ctx)
 {
 	struct mtk_q_data *q_data;
 
-	ctx->m2m_ctx->q_lock = &ctx->dev->dev_mutex;
+	ctx->m2m_ctx->q_lock = &ctx->q_mutex;
 	ctx->fh.m2m_ctx = ctx->m2m_ctx;
 	ctx->fh.ctrl_handler = &ctx->ctrl_hdl;
 	INIT_WORK(&ctx->encode_work, mtk_venc_worker);
@@ -1390,7 +1393,7 @@ int mtk_vcodec_enc_queue_init(void *priv, struct vb2_queue *src_vq,
 	src_vq->ops		= &mtk_venc_vb2_ops;
 	src_vq->mem_ops		= &vb2_dma_contig_memops;
 	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
-	src_vq->lock		= &ctx->dev->dev_mutex;
+	src_vq->lock		= &ctx->q_mutex;
 	src_vq->dev		= &ctx->dev->plat_dev->dev;
 
 	ret = vb2_queue_init(src_vq);
@@ -1404,26 +1407,26 @@ int mtk_vcodec_enc_queue_init(void *priv, struct vb2_queue *src_vq,
 	dst_vq->ops		= &mtk_venc_vb2_ops;
 	dst_vq->mem_ops		= &vb2_dma_contig_memops;
 	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
-	dst_vq->lock		= &ctx->dev->dev_mutex;
+	dst_vq->lock		= &ctx->q_mutex;
 	dst_vq->dev		= &ctx->dev->plat_dev->dev;
 
 	return vb2_queue_init(dst_vq);
 }
 
-int mtk_venc_unlock(struct mtk_vcodec_ctx *ctx)
+int mtk_venc_unlock(struct mtk_vcodec_ctx *ctx, int core_id)
 {
 	struct mtk_vcodec_dev *dev = ctx->dev;
 
-	mutex_unlock(&dev->enc_mutex);
+	mutex_unlock(&dev->enc_mutex[core_id]);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(mtk_venc_unlock);
 
-int mtk_venc_lock(struct mtk_vcodec_ctx *ctx)
+int mtk_venc_lock(struct mtk_vcodec_ctx *ctx, int core_id)
 {
 	struct mtk_vcodec_dev *dev = ctx->dev;
 
-	mutex_lock(&dev->enc_mutex);
+	mutex_lock(&dev->enc_mutex[core_id]);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(mtk_venc_lock);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h
index 513ee7993e34..434d91d36158 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h
@@ -39,8 +39,8 @@ struct mtk_video_enc_buf {
 extern const struct v4l2_ioctl_ops mtk_venc_ioctl_ops;
 extern const struct v4l2_m2m_ops mtk_venc_m2m_ops;
 
-int mtk_venc_unlock(struct mtk_vcodec_ctx *ctx);
-int mtk_venc_lock(struct mtk_vcodec_ctx *ctx);
+int mtk_venc_unlock(struct mtk_vcodec_ctx *ctx, int core_id);
+int mtk_venc_lock(struct mtk_vcodec_ctx *ctx, int core_id);
 int mtk_vcodec_enc_queue_init(void *priv, struct vb2_queue *src_vq,
 			      struct vb2_queue *dst_vq);
 void mtk_vcodec_enc_release(struct mtk_vcodec_ctx *ctx);
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 d2937e62df29..c89d3a20eb42 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -132,6 +132,7 @@ static int fops_vcodec_open(struct file *file)
 	INIT_LIST_HEAD(&ctx->list);
 	ctx->dev = dev;
 	init_waitqueue_head(&ctx->queue[0]);
+	mutex_init(&ctx->q_mutex);
 
 	ctx->type = MTK_INST_ENCODER;
 	ret = mtk_vcodec_enc_ctrls_setup(ctx);
@@ -239,7 +240,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	struct video_device *vfd_enc;
 	phandle rproc_phandle;
 	enum mtk_vcodec_fw_type fw_type;
-	int ret, core_type;
+	int ret, core_type, i;
 
 	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
 	if (!dev)
@@ -309,7 +310,9 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		}
 	}
 
-	mutex_init(&dev->enc_mutex);
+	for (i = 0; i < MTK_VENC_CORE_MAX; i++)
+		mutex_init(&dev->enc_mutex[i]);
+
 	mutex_init(&dev->dev_mutex);
 	spin_lock_init(&dev->irqlock);
 
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 aee31cb836c6..4bfaaf2ec91c 100644
--- a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
@@ -446,7 +446,8 @@ static int h264_encode_sps(struct venc_h264_inst *inst,
 
 	mtk_vcodec_debug_enter(inst);
 
-	ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_SPS, NULL, bs_buf, NULL);
+	ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_SPS,
+			     NULL, bs_buf, NULL, MTK_VENC_CORE0);
 	if (ret)
 		return ret;
 
@@ -472,7 +473,8 @@ static int h264_encode_pps(struct venc_h264_inst *inst,
 
 	mtk_vcodec_debug_enter(inst);
 
-	ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_PPS, NULL, bs_buf, NULL);
+	ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_PPS,
+			     NULL, bs_buf, NULL, MTK_VENC_CORE0);
 	if (ret)
 		return ret;
 
@@ -514,7 +516,8 @@ static int h264_encode_header(struct venc_h264_inst *inst,
 static int h264_encode_frame(struct venc_h264_inst *inst,
 			     struct venc_frm_buf *frm_buf,
 			     struct mtk_vcodec_mem *bs_buf,
-			     unsigned int *bs_size)
+			     unsigned int *bs_size,
+			     int core_id)
 {
 	int ret = 0;
 	unsigned int irq_status;
@@ -533,7 +536,8 @@ static int h264_encode_frame(struct venc_h264_inst *inst,
 	mtk_vcodec_debug(inst, "frm_count = %d,skip_frm_count =%d,frm_type=%d.\n",
 			 frame_info.frm_count, frame_info.skip_frm_count,
 			 frame_info.frm_type);
-	ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_FRAME, frm_buf, bs_buf, &frame_info);
+	ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_FRAME,
+			     frm_buf, bs_buf, &frame_info, core_id);
 	if (ret)
 		return ret;
 
@@ -660,7 +664,7 @@ static int h264_enc_encode(void *handle,
 
 		if (!inst->prepend_hdr) {
 			ret = h264_encode_frame(inst, frm_buf, bs_buf,
-						&result->bs_size);
+						&result->bs_size, ctx->core_id);
 			if (ret)
 				goto encode_err;
 			result->is_key_frm = inst->vpu_inst.is_key_frm;
@@ -688,7 +692,7 @@ static int h264_enc_encode(void *handle,
 		tmp_bs_buf.size = bs_buf->size - (hdr_sz + filler_sz);
 
 		ret = h264_encode_frame(inst, frm_buf, &tmp_bs_buf,
-					&bs_size_frm);
+					&bs_size_frm, ctx->core_id);
 		if (ret)
 			goto encode_err;
 
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 56ce58f761f1..3b3471d90e21 100644
--- a/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
@@ -302,7 +302,8 @@ static int vp8_enc_encode_frame(struct venc_vp8_inst *inst,
 
 	mtk_vcodec_debug(inst, "->frm_cnt=%d", inst->frm_cnt);
 
-	ret = vpu_enc_encode(&inst->vpu_inst, 0, frm_buf, bs_buf, NULL);
+	ret = vpu_enc_encode(&inst->vpu_inst, 0, frm_buf, bs_buf,
+			     NULL, MTK_VENC_CORE0);
 	if (ret)
 		return ret;
 
diff --git a/drivers/media/platform/mtk-vcodec/venc_drv_if.c b/drivers/media/platform/mtk-vcodec/venc_drv_if.c
index 6cbdb7e30bb3..a8a17dca96e7 100644
--- a/drivers/media/platform/mtk-vcodec/venc_drv_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc_drv_if.c
@@ -14,6 +14,7 @@
 #include "venc_drv_if.h"
 
 #include "mtk_vcodec_enc.h"
+#include "mtk_vcodec_enc_core.h"
 #include "mtk_vcodec_enc_pm.h"
 
 int venc_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
@@ -31,9 +32,9 @@ int venc_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
 		return -EINVAL;
 	}
 
-	mtk_venc_lock(ctx);
+	mtk_venc_lock(ctx, ctx->core_id);
 	ret = ctx->enc_if->init(ctx);
-	mtk_venc_unlock(ctx);
+	mtk_venc_unlock(ctx, ctx->core_id);
 
 	return ret;
 }
@@ -43,9 +44,9 @@ int venc_if_set_param(struct mtk_vcodec_ctx *ctx,
 {
 	int ret = 0;
 
-	mtk_venc_lock(ctx);
+	mtk_venc_lock(ctx, ctx->core_id);
 	ret = ctx->enc_if->set_param(ctx->drv_handle, type, in);
-	mtk_venc_unlock(ctx);
+	mtk_venc_unlock(ctx, ctx->core_id);
 
 	return ret;
 }
@@ -56,24 +57,14 @@ int venc_if_encode(struct mtk_vcodec_ctx *ctx,
 		   struct venc_done_result *result)
 {
 	int ret = 0;
-	unsigned long flags;
-
-	mtk_venc_lock(ctx);
 
-	spin_lock_irqsave(&ctx->dev->irqlock, flags);
-	ctx->dev->curr_ctx = ctx;
-	spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
+	venc_encode_prepare(ctx, opt);
 
-	mtk_vcodec_enc_clock_on(ctx->dev, 0);
 	ret = ctx->enc_if->encode(ctx->drv_handle, opt, frm_buf,
 				  bs_buf, result);
-	mtk_vcodec_enc_clock_off(ctx->dev, 0);
 
-	spin_lock_irqsave(&ctx->dev->irqlock, flags);
-	ctx->dev->curr_ctx = NULL;
-	spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
+	venc_encode_unprepare(ctx, opt);
 
-	mtk_venc_unlock(ctx);
 	return ret;
 }
 
@@ -84,11 +75,57 @@ int venc_if_deinit(struct mtk_vcodec_ctx *ctx)
 	if (!ctx->drv_handle)
 		return 0;
 
-	mtk_venc_lock(ctx);
+	mtk_venc_lock(ctx, ctx->core_id);
 	ret = ctx->enc_if->deinit(ctx->drv_handle);
-	mtk_venc_unlock(ctx);
+	mtk_venc_unlock(ctx, ctx->core_id);
 
 	ctx->drv_handle = NULL;
 
 	return ret;
 }
+
+void venc_encode_prepare(struct mtk_vcodec_ctx *ctx,
+			 enum venc_start_opt opt)
+{
+	unsigned long flags;
+	struct mtk_venc_core_dev *core;
+
+	if (ctx->dev->venc_multi_core) {
+		if (ctx->enc_idx & 0x01)
+			ctx->core_id = MTK_VENC_CORE1;
+		else
+			ctx->core_id = MTK_VENC_CORE0;
+	} else {
+		ctx->core_id = MTK_VENC_CORE0;
+	}
+	mtk_venc_lock(ctx, ctx->core_id);
+
+	spin_lock_irqsave(&ctx->dev->irqlock, flags);
+
+	if (ctx->dev->venc_multi_core) {
+		core = ctx->dev->enc_core_dev[ctx->core_id];
+
+		core->curr_ctx = ctx;
+	} else {
+		ctx->dev->curr_ctx = ctx;
+	}
+
+	spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
+
+	mtk_vcodec_enc_clock_on(ctx->dev, ctx->core_id);
+}
+
+void venc_encode_unprepare(struct mtk_vcodec_ctx *ctx,
+			   enum venc_start_opt opt)
+{
+	unsigned long flags;
+
+	if (!ctx->dev->venc_multi_core ||
+	    opt == VENC_START_OPT_ENCODE_SEQUENCE_HEADER) {
+		mtk_vcodec_enc_clock_off(ctx->dev, ctx->core_id);
+		spin_lock_irqsave(&ctx->dev->irqlock, flags);
+		ctx->dev->curr_ctx = NULL;
+		spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
+		mtk_venc_unlock(ctx, ctx->core_id);
+	}
+}
diff --git a/drivers/media/platform/mtk-vcodec/venc_drv_if.h b/drivers/media/platform/mtk-vcodec/venc_drv_if.h
index 0b04a1020873..15e9a2ab9cda 100644
--- a/drivers/media/platform/mtk-vcodec/venc_drv_if.h
+++ b/drivers/media/platform/mtk-vcodec/venc_drv_if.h
@@ -167,4 +167,9 @@ int venc_if_encode(struct mtk_vcodec_ctx *ctx,
 		   struct mtk_vcodec_mem *bs_buf,
 		   struct venc_done_result *result);
 
+void venc_encode_prepare(struct mtk_vcodec_ctx *ctx,
+			 enum venc_start_opt opt);
+void venc_encode_unprepare(struct mtk_vcodec_ctx *ctx,
+			   enum venc_start_opt opt);
+
 #endif /* _VENC_DRV_IF_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/venc_vpu_if.c b/drivers/media/platform/mtk-vcodec/venc_vpu_if.c
index d3570c4c177d..0a672ada8928 100644
--- a/drivers/media/platform/mtk-vcodec/venc_vpu_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc_vpu_if.c
@@ -225,9 +225,12 @@ int vpu_enc_set_param(struct venc_vpu_inst *vpu,
 int vpu_enc_encode(struct venc_vpu_inst *vpu, unsigned int bs_mode,
 		   struct venc_frm_buf *frm_buf,
 		   struct mtk_vcodec_mem *bs_buf,
-		   struct venc_frame_info *frame_info)
+		   struct venc_frame_info *frame_info,
+		   int core_id)
 {
 	const bool is_ext = MTK_ENC_CTX_IS_EXT(vpu->ctx);
+	const bool is_multi_core = vpu->ctx->dev->venc_multi_core;
+
 	size_t msg_size = is_ext ?
 		sizeof(struct venc_ap_ipi_msg_enc_ext) :
 		sizeof(struct venc_ap_ipi_msg_enc);
@@ -261,6 +264,12 @@ int vpu_enc_encode(struct venc_vpu_inst *vpu, unsigned int bs_mode,
 		out.data[1] = frame_info->skip_frm_count;
 		out.data[2] = frame_info->frm_type;
 	}
+
+	if (is_multi_core) {
+		out.data_item = 4;
+		out.data[3] = core_id;
+	}
+
 	if (vpu_enc_send_msg(vpu, &out, msg_size)) {
 		mtk_vcodec_err(vpu, "AP_IPIMSG_ENC_ENCODE %d fail",
 			       bs_mode);
diff --git a/drivers/media/platform/mtk-vcodec/venc_vpu_if.h b/drivers/media/platform/mtk-vcodec/venc_vpu_if.h
index f83bc1b3f2bf..a8055eb62f7c 100644
--- a/drivers/media/platform/mtk-vcodec/venc_vpu_if.h
+++ b/drivers/media/platform/mtk-vcodec/venc_vpu_if.h
@@ -45,7 +45,8 @@ int vpu_enc_set_param(struct venc_vpu_inst *vpu,
 int vpu_enc_encode(struct venc_vpu_inst *vpu, unsigned int bs_mode,
 		   struct venc_frm_buf *frm_buf,
 		   struct mtk_vcodec_mem *bs_buf,
-		   struct venc_frame_info *frame_info);
+		   struct venc_frame_info *frame_info,
+		   int core_id);
 int vpu_enc_deinit(struct venc_vpu_inst *vpu);
 
 #endif
-- 
2.18.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3, 10/10] media: mtk-vcodec: Done encode result to client
  2022-03-17  8:22 [PATCH v3, 00/10] Enable two H264 encoder core on MT8195 Irui Wang
                   ` (8 preceding siblings ...)
  2022-03-17  8:22 ` [PATCH v3, 09/10] media: mtk-vcodec: Add venc_multi_core mode encode process Irui Wang
@ 2022-03-17  8:22 ` Irui Wang
  2022-03-18 14:04 ` [PATCH v3, 00/10] Enable two H264 encoder core on MT8195 AngeloGioacchino Del Regno
  10 siblings, 0 replies; 21+ messages in thread
From: Irui Wang @ 2022-03-17  8:22 UTC (permalink / raw)
  To: Hans Verkuil, Tzung-Bi Shih, Rob Herring, Alexandre Courbot,
	Mauro Carvalho Chehab, Matthias Brugger, Tomasz Figa,
	angelogioacchino.delregno, Yong Wu, Tiffany Lin, Andrew-CT Chen
  Cc: Hsin-Yi Wang, Maoguang Meng, Longfei Wang, Yunfei Dong,
	Fritz Koenig, Irui Wang, linux-media, devicetree, linux-kernel,
	linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

When enable venc_multi_core mode encoding, the wait IRQ done synchronous
function should not be called, so the encode result can't return
to client in device_run. device_run called to trigger encoding
process, finish it, so another scheduled job can be ran. When
encoding done, done the encode result to client in IRQ handler.

Signed-off-by: Irui Wang <irui.wang@mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  6 ++
 .../platform/mtk-vcodec/mtk_vcodec_enc.c      | 68 +++++++++++++++++--
 .../platform/mtk-vcodec/mtk_vcodec_enc.h      |  3 +
 .../platform/mtk-vcodec/mtk_vcodec_enc_core.c | 25 ++++++-
 .../platform/mtk-vcodec/mtk_vcodec_util.h     |  1 +
 .../platform/mtk-vcodec/venc/venc_h264_if.c   | 22 +++++-
 .../media/platform/mtk-vcodec/venc_drv_if.h   |  2 +
 7 files changed, 120 insertions(+), 7 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 889ce61f0fc8..0317707b2ed3 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -300,6 +300,9 @@ struct vdec_pic_info {
  * @q_mutex: src & dst vb2_queue mutex
  * @enc_idx: used to record encoded frame count
  * @core_id: used to record used core
+ * @pfrm_buf: used to store current ctx's frame buffer
+ * @pbs_buf: used to store current ctx's bitstream buffer
+ * @hdr_size: used to store prepend header size
  */
 struct mtk_vcodec_ctx {
 	enum mtk_instance_type type;
@@ -353,6 +356,9 @@ struct mtk_vcodec_ctx {
 	struct mutex q_mutex;
 	int enc_idx;
 	int core_id;
+	struct vb2_v4l2_buffer *pfrm_buf[MTK_VENC_CORE_MAX];
+	struct vb2_v4l2_buffer *pbs_buf[MTK_VENC_CORE_MAX];
+	unsigned int hdr_size;
 };
 
 /*
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
index 2753f004f123..49186b6ab943 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
@@ -476,13 +476,13 @@ static int vidioc_venc_s_fmt_out(struct file *file, void *priv,
 		f->fmt.pix.pixelformat = fmt->fourcc;
 	}
 
+	q_data->visible_width = f->fmt.pix_mp.width;
+	q_data->visible_height = f->fmt.pix_mp.height;
 	ret = vidioc_try_fmt_out(ctx, f, fmt);
 	if (ret)
 		return ret;
 
 	q_data->fmt = fmt;
-	q_data->visible_width = f->fmt.pix_mp.width;
-	q_data->visible_height = f->fmt.pix_mp.height;
 	q_data->coded_width = f->fmt.pix_mp.width;
 	q_data->coded_height = f->fmt.pix_mp.height;
 
@@ -923,6 +923,8 @@ static void vb2ops_venc_stop_streaming(struct vb2_queue *q)
 
 	mtk_v4l2_debug(2, "[%d]-> type=%d", ctx->id, q->type);
 
+	mtk_venc_lock_all(ctx);
+
 	if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
 		while ((dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx))) {
 			vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0);
@@ -1102,10 +1104,13 @@ static int mtk_venc_param_change(struct mtk_vcodec_ctx *ctx)
 				ctx->id,
 				vb2_v4l2->vb2_buf.index,
 				mtk_buf->enc_params.force_intra);
-		if (mtk_buf->enc_params.force_intra)
+		if (mtk_buf->enc_params.force_intra) {
 			ret |= venc_if_set_param(ctx,
 						 VENC_SET_PARAM_FORCE_INTRA,
 						 NULL);
+
+			ctx->enc_idx = 0;
+		}
 	}
 
 	mtk_buf->param_change = MTK_ENCODE_PARAM_NONE;
@@ -1156,6 +1161,7 @@ static void mtk_venc_worker(struct work_struct *work)
 	 * is dequeued.
 	 */
 	if (src_buf == &ctx->empty_flush_buf.vb) {
+		mtk_venc_lock_all(ctx);
 		vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0);
 		dst_buf->flags |= V4L2_BUF_FLAG_LAST;
 		v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
@@ -1170,9 +1176,12 @@ static void mtk_venc_worker(struct work_struct *work)
 		frm_buf.fb_addr[i].size =
 				(size_t)src_buf->vb2_buf.planes[i].length;
 	}
+	frm_buf.src_addr = src_buf;
+
 	bs_buf.va = vb2_plane_vaddr(&dst_buf->vb2_buf, 0);
 	bs_buf.dma_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
 	bs_buf.size = (size_t)dst_buf->vb2_buf.planes[0].length;
+	bs_buf.buf = dst_buf;
 
 	mtk_v4l2_debug(2,
 			"Framebuf PA=%llx Size=0x%zx;PA=0x%llx Size=0x%zx;PA=0x%llx Size=%zu",
@@ -1219,6 +1228,8 @@ static void m2mops_venc_device_run(void *priv)
 {
 	struct mtk_vcodec_ctx *ctx = priv;
 
+	mtk_venc_param_change(ctx);
+
 	if ((ctx->q_data[MTK_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_H264) &&
 	    (ctx->state != MTK_STATE_HEADER)) {
 		/* encode h264 sps/pps header */
@@ -1227,7 +1238,6 @@ static void m2mops_venc_device_run(void *priv)
 		return;
 	}
 
-	mtk_venc_param_change(ctx);
 	queue_work(ctx->dev->encode_workqueue, &ctx->encode_work);
 }
 
@@ -1413,6 +1423,34 @@ int mtk_vcodec_enc_queue_init(void *priv, struct vb2_queue *src_vq,
 	return vb2_queue_init(dst_vq);
 }
 
+void mtk_venc_buf_done(struct mtk_vcodec_ctx *ctx, int core_id,
+		       unsigned int bs_size, bool time_out, bool key_frame)
+{
+	struct vb2_v4l2_buffer *src_vb2_v4l2 = NULL;
+	struct vb2_v4l2_buffer *dst_vb2_v4l2 = NULL;
+
+	/*
+	 * the frm_buf(src_buf) and bs_buf(dst_buf) can be obtained from ctx,
+	 * then put them to done list, user can get them by dqbuf call
+	 */
+	src_vb2_v4l2 = ctx->pfrm_buf[core_id];
+	dst_vb2_v4l2 = ctx->pbs_buf[core_id];
+
+	if (src_vb2_v4l2 && dst_vb2_v4l2) {
+		dst_vb2_v4l2->vb2_buf.timestamp =
+			src_vb2_v4l2->vb2_buf.timestamp;
+		dst_vb2_v4l2->timecode = src_vb2_v4l2->timecode;
+
+		if (key_frame)
+			dst_vb2_v4l2->flags |= V4L2_BUF_FLAG_KEYFRAME;
+
+		v4l2_m2m_buf_done(src_vb2_v4l2, VB2_BUF_STATE_DONE);
+		vb2_set_plane_payload(&dst_vb2_v4l2->vb2_buf, 0, bs_size);
+		v4l2_m2m_buf_done(dst_vb2_v4l2, VB2_BUF_STATE_DONE);
+	}
+}
+EXPORT_SYMBOL_GPL(mtk_venc_buf_done);
+
 int mtk_venc_unlock(struct mtk_vcodec_ctx *ctx, int core_id)
 {
 	struct mtk_vcodec_dev *dev = ctx->dev;
@@ -1440,3 +1478,25 @@ void mtk_vcodec_enc_release(struct mtk_vcodec_ctx *ctx)
 
 	ctx->state = MTK_STATE_FREE;
 }
+
+void mtk_venc_lock_all(struct mtk_vcodec_ctx *ctx)
+{
+	unsigned int i;
+	struct mtk_vcodec_dev *dev = ctx->dev;
+
+	/*
+	 * For frame-racing mode encoding, there are may be bufs being encoded
+	 * when get the empty flush buffer or stop streaming, for example, the
+	 * buffer with LAST flag will return to client before the encoding
+	 * buffers, which will cause frame lost.
+	 * The encoder device mutex will be locked during encoding process,
+	 * when encode done, the mutex unlocked. So if all encoder device mutex
+	 * can be locked, which means there are no bufs being encoded at this
+	 * time, then the buffer with LAST flag can return to client properly.
+	 */
+	for (i = 0; i < MTK_VENC_CORE_MAX; i++) {
+		mutex_lock(&dev->enc_mutex[i]);
+		mutex_unlock(&dev->enc_mutex[i]);
+	}
+}
+EXPORT_SYMBOL_GPL(mtk_venc_lock_all);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h
index 434d91d36158..1e22c77a2760 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h
@@ -46,5 +46,8 @@ int mtk_vcodec_enc_queue_init(void *priv, struct vb2_queue *src_vq,
 void mtk_vcodec_enc_release(struct mtk_vcodec_ctx *ctx);
 int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_ctx *ctx);
 void mtk_vcodec_enc_set_default_params(struct mtk_vcodec_ctx *ctx);
+void mtk_venc_buf_done(struct mtk_vcodec_ctx *ctx, int core_id,
+		       unsigned int bs_size, bool time_out, bool key_frame);
+void mtk_venc_lock_all(struct mtk_vcodec_ctx *ctx);
 
 #endif /* _MTK_VCODEC_ENC_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.c
index 7e376413beaa..c295b5d0b877 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.c
@@ -16,6 +16,10 @@
 #include "mtk_vcodec_enc_pm.h"
 #include "mtk_vcodec_intr.h"
 
+#define VENC_PIC_BITSTREAM_BYTE_CNT 0x0098
+#define VENC_PIC_FRM_TYPE      0x0010
+#define VENC_PIC_KEY_FRM       0x2
+
 static const struct of_device_id mtk_venc_core_ids[] = {
 	{
 		.compatible = "mediatek,mtk-venc-core",
@@ -51,6 +55,9 @@ static irqreturn_t mtk_enc_core_irq_handler(int irq, void *priv)
 	struct mtk_vcodec_ctx *ctx;
 	unsigned long flags;
 	void __iomem *addr;
+	unsigned int bs_size;
+	unsigned int frm_type;
+	bool is_key_frame = 0;
 
 	spin_lock_irqsave(&core->main_dev->irqlock, flags);
 	ctx = core->curr_ctx;
@@ -62,9 +69,25 @@ static irqreturn_t mtk_enc_core_irq_handler(int irq, void *priv)
 
 	addr = core->reg_base + MTK_VENC_IRQ_ACK_OFFSET;
 	ctx->irq_status = readl(core->reg_base + MTK_VENC_IRQ_STATUS_OFFSET);
+	bs_size = readl(core->reg_base + VENC_PIC_BITSTREAM_BYTE_CNT);
+	frm_type = readl(core->reg_base + VENC_PIC_FRM_TYPE);
 	clean_irq_status(ctx->irq_status, addr);
 
-	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, 0);
+	if (ctx->irq_status & MTK_VENC_IRQ_STATUS_FRM) {
+		if (ctx->hdr_size != 0) {
+			bs_size += ctx->hdr_size;
+			ctx->hdr_size = 0;
+		}
+		if (frm_type & VENC_PIC_KEY_FRM)
+			is_key_frame = 1;
+
+		mtk_venc_buf_done(ctx, core->core_id, bs_size, 0, is_key_frame);
+		mtk_vcodec_enc_clock_off(core->main_dev, core->core_id);
+		mtk_venc_unlock(ctx, core->core_id);
+	} else {
+		wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, 0);
+	}
+
 	return IRQ_HANDLED;
 }
 
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
index de9e18688842..4436d8bc60a0 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
@@ -15,6 +15,7 @@ struct mtk_vcodec_mem {
 	size_t size;
 	void *va;
 	dma_addr_t dma_addr;
+	void *buf;
 };
 
 struct mtk_vcodec_fb {
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 4bfaaf2ec91c..b54c3c7ccab8 100644
--- a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
@@ -555,6 +555,12 @@ static int h264_encode_frame(struct venc_h264_inst *inst,
 		return ret;
 	}
 
+	if (ctx->dev->venc_multi_core) {
+		++inst->frm_cnt;
+		mtk_vcodec_debug(inst, "multi core : frm %d <-", inst->frm_cnt);
+		return ret;
+	}
+
 	irq_status = h264_enc_wait_venc_done(inst);
 	if (irq_status != MTK_VENC_IRQ_STATUS_FRM) {
 		mtk_vcodec_err(inst, "irq_status=%d failed", irq_status);
@@ -635,10 +641,12 @@ static int h264_enc_encode(void *handle,
 	int ret = 0;
 	struct venc_h264_inst *inst = (struct venc_h264_inst *)handle;
 	struct mtk_vcodec_ctx *ctx = inst->ctx;
+	bool is_single_core = !ctx->dev->venc_multi_core;
 
 	mtk_vcodec_debug(inst, "opt %d ->", opt);
 
-	enable_irq(ctx->dev->enc_irq);
+	if (is_single_core)
+		enable_irq(ctx->dev->enc_irq);
 
 	switch (opt) {
 	case VENC_START_OPT_ENCODE_SEQUENCE_HEADER: {
@@ -662,6 +670,13 @@ static int h264_enc_encode(void *handle,
 		unsigned int bs_size_hdr;
 		unsigned int bs_size_frm;
 
+		/*
+		 * the frm_buf and bs_buf need to be recorded into ctx,
+		 * when encoding done, the target buffer can be obtained
+		 */
+		ctx->pfrm_buf[ctx->core_id] = frm_buf->src_addr;
+		ctx->pbs_buf[ctx->core_id] = bs_buf->buf;
+
 		if (!inst->prepend_hdr) {
 			ret = h264_encode_frame(inst, frm_buf, bs_buf,
 						&result->bs_size, ctx->core_id);
@@ -698,6 +713,8 @@ static int h264_enc_encode(void *handle,
 
 		result->bs_size = hdr_sz + filler_sz + bs_size_frm;
 
+		ctx->hdr_size = hdr_sz + filler_sz;
+
 		mtk_vcodec_debug(inst, "hdr %d filler %d frame %d bs %d",
 				 hdr_sz, filler_sz, bs_size_frm,
 				 result->bs_size);
@@ -714,8 +731,9 @@ static int h264_enc_encode(void *handle,
 	}
 
 encode_err:
+	if (is_single_core)
+		disable_irq(ctx->dev->enc_irq);
 
-	disable_irq(ctx->dev->enc_irq);
 	mtk_vcodec_debug(inst, "opt %d <-", opt);
 
 	return ret;
diff --git a/drivers/media/platform/mtk-vcodec/venc_drv_if.h b/drivers/media/platform/mtk-vcodec/venc_drv_if.h
index 15e9a2ab9cda..3ad31abb7290 100644
--- a/drivers/media/platform/mtk-vcodec/venc_drv_if.h
+++ b/drivers/media/platform/mtk-vcodec/venc_drv_if.h
@@ -108,9 +108,11 @@ struct venc_frame_info {
 /*
  * struct venc_frm_buf - frame buffer information used in venc_if_encode()
  * @fb_addr: plane frame buffer addresses
+ * @src_addr: vb2_v4l2_buffer src buffer address
  */
 struct venc_frm_buf {
 	struct mtk_vcodec_fb fb_addr[MTK_VCODEC_MAX_PLANES];
+	void *src_addr;
 };
 
 /*
-- 
2.18.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3, 03/10] dt-bindings: media: mtk-vcodec: Adds encoder cores dt-bindings for mt8195
  2022-03-17  8:22 ` [PATCH v3, 03/10] dt-bindings: media: mtk-vcodec: Adds encoder cores dt-bindings for mt8195 Irui Wang
@ 2022-03-17 23:32   ` Miles Chen
  2022-03-25 20:57   ` Rob Herring
  1 sibling, 0 replies; 21+ messages in thread
From: Miles Chen @ 2022-03-17 23:32 UTC (permalink / raw)
  To: irui.wang
  Cc: Project_Global_Chrome_Upstream_Group, acourbot, andrew-ct.chen,
	angelogioacchino.delregno, devicetree, frkoenig, hsinyi,
	hverkuil-cisco, linux-arm-kernel, linux-kernel, linux-media,
	linux-mediatek, longfei.wang, maoguang.meng, matthias.bgg,
	mchehab, robh+dt, srv_heupstream, tfiga, tiffany.lin, tzungbi,
	yong.wu, yunfei.dong

Hi Irui,

> +
> +%YAML 1.2
> +---
> +$id: "http://devicetree.org/schemas/media/mediatek,vcodec-encoder-core.yaml#"
> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
> +
> +title: Mediatek Video Encoder Accelerator With Multi Core

s/Mediatek/MediaTek/
> +
> +maintainers:
> +  - Irui Wang <irui.wang@mediatek.com>
> +
> +description: |
> +  Mediatek Video Encode is the video encode hardware present in Mediatek

s/Mediatek/MediaTek/

> +  SoCs which supports high resolution encoding functionalities. Required
> +  parent and child device node.
> +

Thanks,
Miles

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3, 00/10] Enable two H264 encoder core on MT8195
  2022-03-17  8:22 [PATCH v3, 00/10] Enable two H264 encoder core on MT8195 Irui Wang
                   ` (9 preceding siblings ...)
  2022-03-17  8:22 ` [PATCH v3, 10/10] media: mtk-vcodec: Done encode result to client Irui Wang
@ 2022-03-18 14:04 ` AngeloGioacchino Del Regno
  2022-03-21  1:38   ` Irui Wang
  10 siblings, 1 reply; 21+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-03-18 14:04 UTC (permalink / raw)
  To: Irui Wang, Hans Verkuil, Tzung-Bi Shih, Rob Herring,
	Alexandre Courbot, Mauro Carvalho Chehab, Matthias Brugger,
	Tomasz Figa, Yong Wu, Tiffany Lin, Andrew-CT Chen
  Cc: Hsin-Yi Wang, Maoguang Meng, Longfei Wang, Yunfei Dong,
	Fritz Koenig, linux-media, devicetree, linux-kernel,
	linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

Il 17/03/22 09:22, Irui Wang ha scritto:
> MT8195 has two H264 encoder cores, they have their own power-domains,
> clocks, interrupts, register base. The two H264 encoder cores can work
> together to achieve higher performance, it's a core mode called
> frame-racing, one core has 4K@30fps performance, two cores can achieve
> 4K@60fps.
> The two encoder core encoding process looks like this:
> 
>      VENC Core0: frm#0....frm#2....frm#4....
>      VENC Core1: ..frm#1....frm#3....frm#5....
> 
> This series of patches are used to enable the two H264 encoder cores,
> encoding process will be changed:
> As-Is: Synchronous
> V4L2_VIDIOC_QBUF#0 --> device_run(triger encoder) --> wait encoder IRQ -->
> encoding done with result --> job_finish
> V4l2_VIDIOC_QBUF#1 --> device_run(triger encoder) --> wait encoder IRQ -->
> encoding done with result --> job_finish
> ...
> 
> To-Be: Asynchronous
> V4L2_VIDIOC_QBUF#0 --> device_run(triger encoder) --> job_finish
> ..V4l2_VIDIOC_QBUF#1 --> device_run(triger encoder) --> job_finish
> (venc core0 may encode done here, done the encoding result to client)
> V4L2_VIDIOC_QBUF#2 --> device_run(triger encoder) --> job_finish.
> 
> There is no "wait encoder IRQ" synchronous call during frame-racing mode
> encoding process, it can full use the two encoder cores to achieve higher
> performance.
> 

Hello Irui,
like v1 and v2, also this version of the series will crash the kernel when
trying to encode.

Before pushing the next series, you shall ensure that it is not crashing
the entire kernel, hence, please test your code with gstreamer.


Please use the following pipeline to test:

gst-launch-1.0 videotestsrc num-buffers=100 ! v4l2h264enc ! queue ! h264parse ! 
qtmux ! filesink location=test.mov


Regards,
Angelo

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3, 00/10] Enable two H264 encoder core on MT8195
  2022-03-18 14:04 ` [PATCH v3, 00/10] Enable two H264 encoder core on MT8195 AngeloGioacchino Del Regno
@ 2022-03-21  1:38   ` Irui Wang
  0 siblings, 0 replies; 21+ messages in thread
From: Irui Wang @ 2022-03-21  1:38 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Hans Verkuil, Tzung-Bi Shih,
	Rob Herring, Alexandre Courbot, Mauro Carvalho Chehab,
	Matthias Brugger, Tomasz Figa, Yong Wu, Tiffany Lin,
	Andrew-CT Chen
  Cc: Hsin-Yi Wang, Maoguang Meng, Longfei Wang, Yunfei Dong,
	Fritz Koenig, linux-media, devicetree, linux-kernel,
	linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

Dear Angelo,

Thanks for your comments.
On Fri, 2022-03-18 at 15:04 +0100, AngeloGioacchino Del Regno wrote:
> Il 17/03/22 09:22, Irui Wang ha scritto:
> > MT8195 has two H264 encoder cores, they have their own power-
> > domains,
> > clocks, interrupts, register base. The two H264 encoder cores can
> > work
> > together to achieve higher performance, it's a core mode called
> > frame-racing, one core has 4K@30fps performance, two cores can
> > achieve
> > 4K@60fps.
> > The two encoder core encoding process looks like this:
> > 
> >      VENC Core0: frm#0....frm#2....frm#4....
> >      VENC Core1: ..frm#1....frm#3....frm#5....
> > 
> > This series of patches are used to enable the two H264 encoder
> > cores,
> > encoding process will be changed:
> > As-Is: Synchronous
> > V4L2_VIDIOC_QBUF#0 --> device_run(triger encoder) --> wait encoder
> > IRQ -->
> > encoding done with result --> job_finish
> > V4l2_VIDIOC_QBUF#1 --> device_run(triger encoder) --> wait encoder
> > IRQ -->
> > encoding done with result --> job_finish
> > ...
> > 
> > To-Be: Asynchronous
> > V4L2_VIDIOC_QBUF#0 --> device_run(triger encoder) --> job_finish
> > ..V4l2_VIDIOC_QBUF#1 --> device_run(triger encoder) --> job_finish
> > (venc core0 may encode done here, done the encoding result to
> > client)
> > V4L2_VIDIOC_QBUF#2 --> device_run(triger encoder) --> job_finish.
> > 
> > There is no "wait encoder IRQ" synchronous call during frame-racing 
> > mode
> > encoding process, it can full use the two encoder cores to achieve
> > higher
> > performance.
> > 
> 
> Hello Irui,
> like v1 and v2, also this version of the series will crash the kernel
> when
> trying to encode.

As mentioned before, dual core encoding need more encoding working
buffers in patch-8:
media: mtk-vcodec: Add more extra processing for venc_multi_core mode
a new structure, struct venc_multi_core_vsi defined for it,

encoding processing like this: 
kernel --> ipi message --> scp firmware(userspace), vsi is a share
memory to transfer data between kernel and user, so, the definition of
vsi must be the same in kernel and userspace. otherwise, errors will be
occurred, for example, kernel crash.

When we enable dual core encoding in this patch, the
venc_multi_core_vsi used in kernel, but scp(userspace) still use the
older one vsi(struct venc_h264_vsi), the crash happened.

Maybe we would find out how to resolve the limitations, many thanks for
your review.
> 
> Before pushing the next series, you shall ensure that it is not
> crashing
> the entire kernel, hence, please test your code with gstreamer.
> 
> 
> Please use the following pipeline to test:
> 
> gst-launch-1.0 videotestsrc num-buffers=100 ! v4l2h264enc ! queue !
> h264parse ! 
> qtmux ! filesink location=test.mov
> 
> 
> Regards,
> Angelo

Thanks
Best Regards
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3, 03/10] dt-bindings: media: mtk-vcodec: Adds encoder cores dt-bindings for mt8195
  2022-03-17  8:22 ` [PATCH v3, 03/10] dt-bindings: media: mtk-vcodec: Adds encoder cores dt-bindings for mt8195 Irui Wang
  2022-03-17 23:32   ` Miles Chen
@ 2022-03-25 20:57   ` Rob Herring
  2022-03-26  2:00     ` Irui Wang
  1 sibling, 1 reply; 21+ messages in thread
From: Rob Herring @ 2022-03-25 20:57 UTC (permalink / raw)
  To: Irui Wang
  Cc: Hans Verkuil, Tzung-Bi Shih, Alexandre Courbot,
	Mauro Carvalho Chehab, Matthias Brugger, Tomasz Figa,
	angelogioacchino.delregno, Yong Wu, Tiffany Lin, Andrew-CT Chen,
	Hsin-Yi Wang, Maoguang Meng, Longfei Wang, Yunfei Dong,
	Fritz Koenig, linux-media, devicetree, linux-kernel,
	linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

On Thu, Mar 17, 2022 at 04:22:23PM +0800, Irui Wang wrote:
> Adds encoder cores dt-bindings for mt8195.

Why?

> 
> Signed-off-by: Irui Wang <irui.wang@mediatek.com>
> ---
>  .../media/mediatek,vcodec-encoder-core.yaml   | 181 ++++++++++++++++++
>  .../media/mediatek,vcodec-encoder.yaml        |   1 -
>  2 files changed, 181 insertions(+), 1 deletion(-)
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-encoder-core.yaml
> 
> diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder-core.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder-core.yaml
> new file mode 100644
> index 000000000000..fcfb48900c76
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder-core.yaml
> @@ -0,0 +1,181 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +
> +%YAML 1.2
> +---
> +$id: "http://devicetree.org/schemas/media/mediatek,vcodec-encoder-core.yaml#"
> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
> +
> +title: Mediatek Video Encoder Accelerator With Multi Core
> +
> +maintainers:
> +  - Irui Wang <irui.wang@mediatek.com>
> +
> +description: |
> +  Mediatek Video Encode is the video encode hardware present in Mediatek
> +  SoCs which supports high resolution encoding functionalities. Required
> +  parent and child device node.
> +
> +properties:
> +  compatible:
> +    items:
> +      - enum:
> +          - mediatek,mt8195-vcodec-enc
> +
> +  mediatek,scp:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description: |
> +      The node of system control processor (SCP), using
> +      the remoteproc & rpmsg framework.
> +
> +  mediatek,venc-multi-core:
> +    type: boolean
> +    description: |
> +      Indicates whether the encoder has multiple cores or not.

Isn't this implied by how many child nodes you have?

> +
> +  iommus:
> +    minItems: 1
> +    maxItems: 32

You really have up to 32 IOMMUs?

> +    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.
> +
> +  "#address-cells":
> +    const: 2
> +
> +  "#size-cells":
> +    const: 2
> +
> +  ranges: true
> +
> +# Required child node:
> +patternProperties:
> +  "^venc-core@[0-9a-f]+$":
> +    type: object
> +    description: |
> +      The video encoder core device node which should be added as subnodes to
> +      the main venc node.
> +
> +    properties:
> +      compatible:
> +        items:
> +         - const: mediatek,mtk-venc-core
> +
> +      reg:
> +        maxItems: 1
> +
> +      mediatek,core-id:
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        description: |
> +          Current encoder core id.

What is this for and what does its value correspond to in the h/w. We 
generally don't do made up indices in DT.

> +
> +      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.
> +
> +      interrupts:
> +        maxItems: 1
> +
> +      clocks:
> +        maxItems: 1
> +
> +      clock-names:
> +        maxItems: 1
> +
> +      power-domains:
> +        maxItems: 1
> +
> +    required:
> +      - compatible
> +      - reg
> +      - mediatek,core-id
> +      - iommus
> +      - interrupts
> +      - clocks
> +      - clock-names
> +      - assigned-clocks
> +      - assigned-clock-parents
> +      - power-domains
> +
> +    additionalProperties: false
> +
> +required:
> +  - compatible
> +  - mediatek,scp
> +  - iommus
> +  - dma-ranges
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/memory/mt8195-memory-port.h>
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/clock/mt8195-clk.h>
> +    #include <dt-bindings/power/mt8195-power.h>
> +
> +    soc {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +
> +        venc {
> +            compatible = "mediatek,mt8195-vcodec-enc";
> +            mediatek,scp = <&scp>;
> +            mediatek,venc-multi-core;
> +            iommus = <&iommu_vdo M4U_PORT_L19_VENC_RCPU>;
> +            #address-cells = <2>;
> +            #size-cells = <2>;
> +            ranges;
> +            dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
> +
> +            venc-core@1a020000 {
> +                compatible = "mediatek,mtk-venc-core";
> +                reg = <0 0x1a020000 0 0x10000>;
> +                mediatek,core-id = <0>;
> +                iommus = <&iommu_vdo M4U_PORT_L19_VENC_RCPU>,
> +                         <&iommu_vdo M4U_PORT_L19_VENC_REC>,
> +                         <&iommu_vdo M4U_PORT_L19_VENC_BSDMA>,
> +                         <&iommu_vdo M4U_PORT_L19_VENC_SV_COMV>,
> +                         <&iommu_vdo M4U_PORT_L19_VENC_RD_COMV>,
> +                         <&iommu_vdo M4U_PORT_L19_VENC_CUR_LUMA>,
> +                         <&iommu_vdo M4U_PORT_L19_VENC_CUR_CHROMA>,
> +                         <&iommu_vdo M4U_PORT_L19_VENC_REF_LUMA>,
> +                         <&iommu_vdo M4U_PORT_L19_VENC_REF_CHROMA>;
> +                interrupts = <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH 0>;
> +                clocks = <&vencsys CLK_VENC_VENC>;
> +                clock-names = "clk_venc";
> +                assigned-clocks = <&topckgen CLK_TOP_VENC>;
> +                assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D4>;
> +                power-domains = <&spm MT8195_POWER_DOMAIN_VENC>;
> +            };
> +
> +            venc-core@1b020000 {
> +                compatible = "mediatek,mtk-venc-core";
> +                reg = <0 0x1b020000 0 0x10000>;
> +                mediatek,core-id = <1>;
> +                iommus = <&iommu_vpp M4U_PORT_L20_VENC_RCPU>,
> +                         <&iommu_vpp M4U_PORT_L20_VENC_REC>,
> +                         <&iommu_vpp M4U_PORT_L20_VENC_BSDMA>,
> +                         <&iommu_vpp M4U_PORT_L20_VENC_SV_COMV>,
> +                         <&iommu_vpp M4U_PORT_L20_VENC_RD_COMV>,
> +                         <&iommu_vpp M4U_PORT_L20_VENC_CUR_LUMA>,
> +                         <&iommu_vpp M4U_PORT_L20_VENC_CUR_CHROMA>,
> +                         <&iommu_vpp M4U_PORT_L20_VENC_REF_LUMA>,
> +                         <&iommu_vpp M4U_PORT_L20_VENC_REF_CHROMA>;
> +                interrupts = <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH 0>;
> +                clocks = <&vencsys_core1 CLK_VENC_CORE1_VENC>;
> +                clock-names = "clk_venc_core1";
> +                assigned-clocks = <&topckgen CLK_TOP_VENC>;
> +                assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D4>;
> +                power-domains = <&spm MT8195_POWER_DOMAIN_VENC_CORE1>;
> +            };
> +        };
> +    };
> diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
> index e7b65a91c92c..0530a694bcbe 100644
> --- a/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
> +++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
> @@ -21,7 +21,6 @@ properties:
>        - mediatek,mt8173-vcodec-enc
>        - mediatek,mt8183-vcodec-enc
>        - mediatek,mt8192-vcodec-enc
> -      - mediatek,mt8195-vcodec-enc
>  
>    reg:
>      maxItems: 1
> -- 
> 2.18.0
> 
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3, 03/10] dt-bindings: media: mtk-vcodec: Adds encoder cores dt-bindings for mt8195
  2022-03-25 20:57   ` Rob Herring
@ 2022-03-26  2:00     ` Irui Wang
  2022-03-28 13:48       ` Rob Herring
  0 siblings, 1 reply; 21+ messages in thread
From: Irui Wang @ 2022-03-26  2:00 UTC (permalink / raw)
  To: Rob Herring
  Cc: Hans Verkuil, Tzung-Bi Shih, Alexandre Courbot,
	Mauro Carvalho Chehab, Matthias Brugger, Tomasz Figa,
	angelogioacchino.delregno, Yong Wu, Tiffany Lin, Andrew-CT Chen,
	Hsin-Yi Wang, Maoguang Meng, Longfei Wang, Yunfei Dong,
	Fritz Koenig, linux-media, devicetree, linux-kernel,
	linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

Dear Rob,

Thanks for your review and comments.

On Fri, 2022-03-25 at 15:57 -0500, Rob Herring wrote:
> On Thu, Mar 17, 2022 at 04:22:23PM +0800, Irui Wang wrote:
> > Adds encoder cores dt-bindings for mt8195.
> 
> Why?
mt8195 has two h264 encoder cores and we want to enable both of them.
the original encoder bindings file is for single core which may can not
handle it, so we new a core dt-bindings. We will think about it again
about this dt-bindings.
> 
> > 
> > Signed-off-by: Irui Wang <irui.wang@mediatek.com>
> > ---
> >  .../media/mediatek,vcodec-encoder-core.yaml   | 181
> > ++++++++++++++++++
> >  .../media/mediatek,vcodec-encoder.yaml        |   1 -
> >  2 files changed, 181 insertions(+), 1 deletion(-)
> >  create mode 100644
> > Documentation/devicetree/bindings/media/mediatek,vcodec-encoder-
> > core.yaml
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder-
> > core.yaml
> > b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder-
> > core.yaml
> > new file mode 100644
> > index 000000000000..fcfb48900c76
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-
> > encoder-core.yaml
> > @@ -0,0 +1,181 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +
> > +%YAML 1.2
> > +---
> > +$id: "
> > http://devicetree.org/schemas/media/mediatek,vcodec-encoder-core.yaml#
> > "
> > +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
> > +
> > +title: Mediatek Video Encoder Accelerator With Multi Core
> > +
> > +maintainers:
> > +  - Irui Wang <irui.wang@mediatek.com>
> > +
> > +description: |
> > +  Mediatek Video Encode is the video encode hardware present in
> > Mediatek
> > +  SoCs which supports high resolution encoding functionalities.
> > Required
> > +  parent and child device node.
> > +
> > +properties:
> > +  compatible:
> > +    items:
> > +      - enum:
> > +          - mediatek,mt8195-vcodec-enc
> > +
> > +  mediatek,scp:
> > +    $ref: /schemas/types.yaml#/definitions/phandle
> > +    description: |
> > +      The node of system control processor (SCP), using
> > +      the remoteproc & rpmsg framework.
> > +
> > +  mediatek,venc-multi-core:
> > +    type: boolean
> > +    description: |
> > +      Indicates whether the encoder has multiple cores or not.
> 
> Isn't this implied by how many child nodes you have?
It implies that we have child nodes, distinguish with single core,  
> 
> > +
> > +  iommus:
> > +    minItems: 1
> > +    maxItems: 32
> 
> You really have up to 32 IOMMUs?
Currently, totally 27 IOMMUs and used 9 of them.
> 
> > +    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.
> > +
> > +  "#address-cells":
> > +    const: 2
> > +
> > +  "#size-cells":
> > +    const: 2
> > +
> > +  ranges: true
> > +
> > +# Required child node:
> > +patternProperties:
> > +  "^venc-core@[0-9a-f]+$":
> > +    type: object
> > +    description: |
> > +      The video encoder core device node which should be added as
> > subnodes to
> > +      the main venc node.
> > +
> > +    properties:
> > +      compatible:
> > +        items:
> > +         - const: mediatek,mtk-venc-core
> > +
> > +      reg:
> > +        maxItems: 1
> > +
> > +      mediatek,core-id:
> > +        $ref: /schemas/types.yaml#/definitions/uint32
> > +        description: |
> > +          Current encoder core id.
> 
> What is this for and what does its value correspond to in the h/w.
> We 
> generally don't do made up indices in DT.
It's for encoder core id, core@1a020000 must be core-0, core@1b020000
must be core-1, we add this property in each child node, so we can get core-id in drivers. If it can't ref "uint32" types yaml, would you mind giving some more suggestions ?
> 
> > +
> > +      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.
> > +
> > +      interrupts:
> > +        maxItems: 1
> > +
> > +      clocks:
> > +        maxItems: 1
> > +
> > +      clock-names:
> > +        maxItems: 1
> > +
> > +      power-domains:
> > +        maxItems: 1
> > +
> > +    required:
> > +      - compatible
> > +      - reg
> > +      - mediatek,core-id
> > +      - iommus
> > +      - interrupts
> > +      - clocks
> > +      - clock-names
> > +      - assigned-clocks
> > +      - assigned-clock-parents
> > +      - power-domains
> > +
> > +    additionalProperties: false
> > +
> > +required:
> > +  - compatible
> > +  - mediatek,scp
> > +  - iommus
> > +  - dma-ranges
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > +    #include <dt-bindings/memory/mt8195-memory-port.h>
> > +    #include <dt-bindings/interrupt-controller/irq.h>
> > +    #include <dt-bindings/clock/mt8195-clk.h>
> > +    #include <dt-bindings/power/mt8195-power.h>
> > +
> > +    soc {
> > +        #address-cells = <2>;
> > +        #size-cells = <2>;
> > +
> > +        venc {
> > +            compatible = "mediatek,mt8195-vcodec-enc";
> > +            mediatek,scp = <&scp>;
> > +            mediatek,venc-multi-core;
> > +            iommus = <&iommu_vdo M4U_PORT_L19_VENC_RCPU>;
> > +            #address-cells = <2>;
> > +            #size-cells = <2>;
> > +            ranges;
> > +            dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
> > +
> > +            venc-core@1a020000 {
> > +                compatible = "mediatek,mtk-venc-core";
> > +                reg = <0 0x1a020000 0 0x10000>;
> > +                mediatek,core-id = <0>;
> > +                iommus = <&iommu_vdo M4U_PORT_L19_VENC_RCPU>,
> > +                         <&iommu_vdo M4U_PORT_L19_VENC_REC>,
> > +                         <&iommu_vdo M4U_PORT_L19_VENC_BSDMA>,
> > +                         <&iommu_vdo M4U_PORT_L19_VENC_SV_COMV>,
> > +                         <&iommu_vdo M4U_PORT_L19_VENC_RD_COMV>,
> > +                         <&iommu_vdo M4U_PORT_L19_VENC_CUR_LUMA>,
> > +                         <&iommu_vdo
> > M4U_PORT_L19_VENC_CUR_CHROMA>,
> > +                         <&iommu_vdo M4U_PORT_L19_VENC_REF_LUMA>,
> > +                         <&iommu_vdo
> > M4U_PORT_L19_VENC_REF_CHROMA>;
> > +                interrupts = <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH 0>;
> > +                clocks = <&vencsys CLK_VENC_VENC>;
> > +                clock-names = "clk_venc";
> > +                assigned-clocks = <&topckgen CLK_TOP_VENC>;
> > +                assigned-clock-parents = <&topckgen
> > CLK_TOP_UNIVPLL_D4>;
> > +                power-domains = <&spm MT8195_POWER_DOMAIN_VENC>;
> > +            };
> > +
> > +            venc-core@1b020000 {
> > +                compatible = "mediatek,mtk-venc-core";
> > +                reg = <0 0x1b020000 0 0x10000>;
> > +                mediatek,core-id = <1>;
> > +                iommus = <&iommu_vpp M4U_PORT_L20_VENC_RCPU>,
> > +                         <&iommu_vpp M4U_PORT_L20_VENC_REC>,
> > +                         <&iommu_vpp M4U_PORT_L20_VENC_BSDMA>,
> > +                         <&iommu_vpp M4U_PORT_L20_VENC_SV_COMV>,
> > +                         <&iommu_vpp M4U_PORT_L20_VENC_RD_COMV>,
> > +                         <&iommu_vpp M4U_PORT_L20_VENC_CUR_LUMA>,
> > +                         <&iommu_vpp
> > M4U_PORT_L20_VENC_CUR_CHROMA>,
> > +                         <&iommu_vpp M4U_PORT_L20_VENC_REF_LUMA>,
> > +                         <&iommu_vpp
> > M4U_PORT_L20_VENC_REF_CHROMA>;
> > +                interrupts = <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH 0>;
> > +                clocks = <&vencsys_core1 CLK_VENC_CORE1_VENC>;
> > +                clock-names = "clk_venc_core1";
> > +                assigned-clocks = <&topckgen CLK_TOP_VENC>;
> > +                assigned-clock-parents = <&topckgen
> > CLK_TOP_UNIVPLL_D4>;
> > +                power-domains = <&spm
> > MT8195_POWER_DOMAIN_VENC_CORE1>;
> > +            };
> > +        };
> > +    };
> > diff --git
> > a/Documentation/devicetree/bindings/media/mediatek,vcodec-
> > encoder.yaml
> > b/Documentation/devicetree/bindings/media/mediatek,vcodec-
> > encoder.yaml
> > index e7b65a91c92c..0530a694bcbe 100644
> > --- a/Documentation/devicetree/bindings/media/mediatek,vcodec-
> > encoder.yaml
> > +++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-
> > encoder.yaml
> > @@ -21,7 +21,6 @@ properties:
> >        - mediatek,mt8173-vcodec-enc
> >        - mediatek,mt8183-vcodec-enc
> >        - mediatek,mt8192-vcodec-enc
> > -      - mediatek,mt8195-vcodec-enc
> >  
> >    reg:
> >      maxItems: 1
> > -- 
> > 2.18.0
> > 
> > 
Thanks
Best Regards

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3, 03/10] dt-bindings: media: mtk-vcodec: Adds encoder cores dt-bindings for mt8195
  2022-03-26  2:00     ` Irui Wang
@ 2022-03-28 13:48       ` Rob Herring
  2022-03-29  1:26         ` Irui Wang
  0 siblings, 1 reply; 21+ messages in thread
From: Rob Herring @ 2022-03-28 13:48 UTC (permalink / raw)
  To: Irui Wang
  Cc: Hans Verkuil, Tzung-Bi Shih, Alexandre Courbot,
	Mauro Carvalho Chehab, Matthias Brugger, Tomasz Figa,
	angelogioacchino.delregno, Yong Wu, Tiffany Lin, Andrew-CT Chen,
	Hsin-Yi Wang, Maoguang Meng, Longfei Wang, Yunfei Dong,
	Fritz Koenig, linux-media, devicetree, linux-kernel,
	linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

On Sat, Mar 26, 2022 at 10:00:55AM +0800, Irui Wang wrote:
> Dear Rob,
> 
> Thanks for your review and comments.
> 
> On Fri, 2022-03-25 at 15:57 -0500, Rob Herring wrote:
> > On Thu, Mar 17, 2022 at 04:22:23PM +0800, Irui Wang wrote:
> > > Adds encoder cores dt-bindings for mt8195.
> > 
> > Why?
> mt8195 has two h264 encoder cores and we want to enable both of them.
> the original encoder bindings file is for single core which may can not
> handle it, so we new a core dt-bindings. We will think about it again
> about this dt-bindings.
> > 
> > > 
> > > Signed-off-by: Irui Wang <irui.wang@mediatek.com>
> > > ---
> > >  .../media/mediatek,vcodec-encoder-core.yaml   | 181
> > > ++++++++++++++++++
> > >  .../media/mediatek,vcodec-encoder.yaml        |   1 -
> > >  2 files changed, 181 insertions(+), 1 deletion(-)
> > >  create mode 100644
> > > Documentation/devicetree/bindings/media/mediatek,vcodec-encoder-
> > > core.yaml
> > > 
> > > diff --git
> > > a/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder-
> > > core.yaml
> > > b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder-
> > > core.yaml
> > > new file mode 100644
> > > index 000000000000..fcfb48900c76
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-
> > > encoder-core.yaml
> > > @@ -0,0 +1,181 @@
> > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > +
> > > +%YAML 1.2
> > > +---
> > > +$id: "
> > > http://devicetree.org/schemas/media/mediatek,vcodec-encoder-core.yaml#
> > > "
> > > +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
> > > +
> > > +title: Mediatek Video Encoder Accelerator With Multi Core
> > > +
> > > +maintainers:
> > > +  - Irui Wang <irui.wang@mediatek.com>
> > > +
> > > +description: |
> > > +  Mediatek Video Encode is the video encode hardware present in
> > > Mediatek
> > > +  SoCs which supports high resolution encoding functionalities.
> > > Required
> > > +  parent and child device node.
> > > +
> > > +properties:
> > > +  compatible:
> > > +    items:
> > > +      - enum:
> > > +          - mediatek,mt8195-vcodec-enc
> > > +
> > > +  mediatek,scp:
> > > +    $ref: /schemas/types.yaml#/definitions/phandle
> > > +    description: |
> > > +      The node of system control processor (SCP), using
> > > +      the remoteproc & rpmsg framework.
> > > +
> > > +  mediatek,venc-multi-core:
> > > +    type: boolean
> > > +    description: |
> > > +      Indicates whether the encoder has multiple cores or not.
> > 
> > Isn't this implied by how many child nodes you have?
> It implies that we have child nodes, distinguish with single core,  

Just check if you have a child node or not.


> > > +  iommus:
> > > +    minItems: 1
> > > +    maxItems: 32
> > 
> > You really have up to 32 IOMMUs?
> Currently, totally 27 IOMMUs and used 9 of them.
> > 
> > > +    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.
> > > +
> > > +  "#address-cells":
> > > +    const: 2
> > > +
> > > +  "#size-cells":
> > > +    const: 2
> > > +
> > > +  ranges: true
> > > +
> > > +# Required child node:
> > > +patternProperties:
> > > +  "^venc-core@[0-9a-f]+$":
> > > +    type: object
> > > +    description: |
> > > +      The video encoder core device node which should be added as
> > > subnodes to
> > > +      the main venc node.
> > > +
> > > +    properties:
> > > +      compatible:
> > > +        items:
> > > +         - const: mediatek,mtk-venc-core
> > > +
> > > +      reg:
> > > +        maxItems: 1
> > > +
> > > +      mediatek,core-id:
> > > +        $ref: /schemas/types.yaml#/definitions/uint32
> > > +        description: |
> > > +          Current encoder core id.
> > 
> > What is this for and what does its value correspond to in the h/w.
> > We 
> > generally don't do made up indices in DT.
> It's for encoder core id, core@1a020000 must be core-0, core@1b020000
> must be core-1, we add this property in each child node, so we can 
> get core-id in drivers. If it can't ref "uint32" types yaml, would 
> you mind giving some more suggestions ?

I still don't understand why it is needed. What is 'core-0'?

Is there some functional difference between the cores? If so, describe 
that difference.

Rob

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3, 03/10] dt-bindings: media: mtk-vcodec: Adds encoder cores dt-bindings for mt8195
  2022-03-28 13:48       ` Rob Herring
@ 2022-03-29  1:26         ` Irui Wang
  2022-03-29 13:09           ` Rob Herring
  0 siblings, 1 reply; 21+ messages in thread
From: Irui Wang @ 2022-03-29  1:26 UTC (permalink / raw)
  To: Rob Herring
  Cc: Hans Verkuil, Tzung-Bi Shih, Alexandre Courbot,
	Mauro Carvalho Chehab, Matthias Brugger, Tomasz Figa,
	angelogioacchino.delregno, Yong Wu, Tiffany Lin, Andrew-CT Chen,
	Hsin-Yi Wang, Maoguang Meng, Longfei Wang, Yunfei Dong,
	Fritz Koenig, linux-media, devicetree, linux-kernel,
	linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

Dear Rob,

Many thanks for your attention.

On Mon, 2022-03-28 at 08:48 -0500, Rob Herring wrote:
> On Sat, Mar 26, 2022 at 10:00:55AM +0800, Irui Wang wrote:
> > Dear Rob,
> > 
> > Thanks for your review and comments.
> > 
> > On Fri, 2022-03-25 at 15:57 -0500, Rob Herring wrote:
> > > On Thu, Mar 17, 2022 at 04:22:23PM +0800, Irui Wang wrote:
> > > > Adds encoder cores dt-bindings for mt8195.
> > > 
> > > Why?
> > 
> > mt8195 has two h264 encoder cores and we want to enable both of
> > them.
> > the original encoder bindings file is for single core which may can
> > not
> > handle it, so we new a core dt-bindings. We will think about it
> > again
> > about this dt-bindings.
> > > 
> > > > 
> > > > Signed-off-by: Irui Wang <irui.wang@mediatek.com>
> > > > ---
> > > >  .../media/mediatek,vcodec-encoder-core.yaml   | 181
> > > > ++++++++++++++++++
> > > >  .../media/mediatek,vcodec-encoder.yaml        |   1 -
> > > >  2 files changed, 181 insertions(+), 1 deletion(-)
> > > >  create mode 100644
> > > > Documentation/devicetree/bindings/media/mediatek,vcodec-
> > > > encoder-
> > > > core.yaml
> > > > 
> > > > diff --git
> > > > a/Documentation/devicetree/bindings/media/mediatek,vcodec-
> > > > encoder-
> > > > core.yaml
> > > > b/Documentation/devicetree/bindings/media/mediatek,vcodec-
> > > > encoder-
> > > > core.yaml
> > > > new file mode 100644
> > > > index 000000000000..fcfb48900c76
> > > > --- /dev/null
> > > > +++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-
> > > > encoder-core.yaml
> > > > @@ -0,0 +1,181 @@
> > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > > +
> > > > +%YAML 1.2
> > > > +---
> > > > +$id: "
> > > > 
http://devicetree.org/schemas/media/mediatek,vcodec-encoder-core.yaml#
> > > > "
> > > > +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
> > > > +
> > > > +title: Mediatek Video Encoder Accelerator With Multi Core
> > > > +
> > > > +maintainers:
> > > > +  - Irui Wang <irui.wang@mediatek.com>
> > > > +
> > > > +description: |
> > > > +  Mediatek Video Encode is the video encode hardware present
> > > > in
> > > > Mediatek
> > > > +  SoCs which supports high resolution encoding
> > > > functionalities.
> > > > Required
> > > > +  parent and child device node.
> > > > +
> > > > +properties:
> > > > +  compatible:
> > > > +    items:
> > > > +      - enum:
> > > > +          - mediatek,mt8195-vcodec-enc
> > > > +
> > > > +  mediatek,scp:
> > > > +    $ref: /schemas/types.yaml#/definitions/phandle
> > > > +    description: |
> > > > +      The node of system control processor (SCP), using
> > > > +      the remoteproc & rpmsg framework.
> > > > +
> > > > +  mediatek,venc-multi-core:
> > > > +    type: boolean
> > > > +    description: |
> > > > +      Indicates whether the encoder has multiple cores or not.
> > > 
> > > Isn't this implied by how many child nodes you have?
> > 
> > It implies that we have child nodes, distinguish with single
> > core,  
> 
> Just check if you have a child node or not.
Yes.
> 
> 
> > > > +  iommus:
> > > > +    minItems: 1
> > > > +    maxItems: 32
> > > 
> > > You really have up to 32 IOMMUs?
> > 
> > Currently, totally 27 IOMMUs and used 9 of them.
> > > 
> > > > +    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.
> > > > +
> > > > +  "#address-cells":
> > > > +    const: 2
> > > > +
> > > > +  "#size-cells":
> > > > +    const: 2
> > > > +
> > > > +  ranges: true
> > > > +
> > > > +# Required child node:
> > > > +patternProperties:
> > > > +  "^venc-core@[0-9a-f]+$":
> > > > +    type: object
> > > > +    description: |
> > > > +      The video encoder core device node which should be added
> > > > as
> > > > subnodes to
> > > > +      the main venc node.
> > > > +
> > > > +    properties:
> > > > +      compatible:
> > > > +        items:
> > > > +         - const: mediatek,mtk-venc-core
> > > > +
> > > > +      reg:
> > > > +        maxItems: 1
> > > > +
> > > > +      mediatek,core-id:
> > > > +        $ref: /schemas/types.yaml#/definitions/uint32
> > > > +        description: |
> > > > +          Current encoder core id.
> > > 
> > > What is this for and what does its value correspond to in the
> > > h/w.
> > > We 
> > > generally don't do made up indices in DT.
> > 
> > It's for encoder core id, core@1a020000 must be core-0, 
> > core@1b020000
> > must be core-1, we add this property in each child node, so we can 
> > get core-id in drivers. If it can't ref "uint32" types yaml, would 
> > you mind giving some more suggestions ?
> 
> I still don't understand why it is needed. What is 'core-0'?
> 
> Is there some functional difference between the cores? If so,
> describe 
> that difference.
> 
> Rob

They are two different pieces of hardware, it's our encoder hardware
design. There are two encoder hardware cores inside MT8195, named core0
and core1(we can rename it, but core id should be declared),
for core0, its module base address is 0x1A02_0000, uses IOMMU
"vdo0_iommu" and power domain "POWER_DOMAIN_VENC",
for core1, its module base address is 0x1B02_0000, uses IOMMU
"vpp_iommu" and power domain "POWER_DOMAIN_VENC_CORE1".
So the two encoder cores have their own base, IRQ, clock, power, etc.
Each core can encode independently, moreover, they can work together
for higher performance. 
We will describe more details in YAML about it if it's OK for you.

Thanks
Best Regards.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3, 03/10] dt-bindings: media: mtk-vcodec: Adds encoder cores dt-bindings for mt8195
  2022-03-29  1:26         ` Irui Wang
@ 2022-03-29 13:09           ` Rob Herring
  2022-03-30  8:48             ` Irui Wang
  0 siblings, 1 reply; 21+ messages in thread
From: Rob Herring @ 2022-03-29 13:09 UTC (permalink / raw)
  To: Irui Wang
  Cc: Hans Verkuil, Tzung-Bi Shih, Alexandre Courbot,
	Mauro Carvalho Chehab, Matthias Brugger, Tomasz Figa,
	angelogioacchino.delregno, Yong Wu, Tiffany Lin, Andrew-CT Chen,
	Hsin-Yi Wang, Maoguang Meng, Longfei Wang, Yunfei Dong,
	Fritz Koenig, linux-media, devicetree, linux-kernel,
	linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

On Tue, Mar 29, 2022 at 09:26:37AM +0800, Irui Wang wrote:
> Dear Rob,
> 
> Many thanks for your attention.
> 
> On Mon, 2022-03-28 at 08:48 -0500, Rob Herring wrote:
> > On Sat, Mar 26, 2022 at 10:00:55AM +0800, Irui Wang wrote:
> > > Dear Rob,
> > > 
> > > Thanks for your review and comments.
> > > 
> > > On Fri, 2022-03-25 at 15:57 -0500, Rob Herring wrote:
> > > > On Thu, Mar 17, 2022 at 04:22:23PM +0800, Irui Wang wrote:
> > > > > Adds encoder cores dt-bindings for mt8195.

[...]

> > > > > +      mediatek,core-id:
> > > > > +        $ref: /schemas/types.yaml#/definitions/uint32
> > > > > +        description: |
> > > > > +          Current encoder core id.
> > > > 
> > > > What is this for and what does its value correspond to in the
> > > > h/w.
> > > > We 
> > > > generally don't do made up indices in DT.
> > > 
> > > It's for encoder core id, core@1a020000 must be core-0, 
> > > core@1b020000
> > > must be core-1, we add this property in each child node, so we can 
> > > get core-id in drivers. If it can't ref "uint32" types yaml, would 
> > > you mind giving some more suggestions ?
> > 
> > I still don't understand why it is needed. What is 'core-0'?
> > 
> > Is there some functional difference between the cores? If so,
> > describe 
> > that difference.
> > 
> > Rob
> 
> They are two different pieces of hardware, it's our encoder hardware
> design. There are two encoder hardware cores inside MT8195, named core0
> and core1(we can rename it, but core id should be declared),
> for core0, its module base address is 0x1A02_0000, uses IOMMU
> "vdo0_iommu" and power domain "POWER_DOMAIN_VENC",
> for core1, its module base address is 0x1B02_0000, uses IOMMU
> "vpp_iommu" and power domain "POWER_DOMAIN_VENC_CORE1".
> So the two encoder cores have their own base, IRQ, clock, power, etc.
> Each core can encode independently, moreover, they can work together
> for higher performance. 
> We will describe more details in YAML about it if it's OK for you.

All the resources you list are in the child nodes, so you don't need 0 
and 1 numbering for those. 

Looking at the driver patches, the only thing I see distinguishing 
core numbers is this:

"frame#0 uses core#0, frame#1 uses core#1, frame#2 uses core#0...,

Lock the device and enable the clock by used core, for sequence
header encoding, it always uses core#0."

Is this a requirement in the h/w or just what the driver picked? IOW, 
could frame#0 use core#1?

Rob

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3, 03/10] dt-bindings: media: mtk-vcodec: Adds encoder cores dt-bindings for mt8195
  2022-03-29 13:09           ` Rob Herring
@ 2022-03-30  8:48             ` Irui Wang
  2022-03-31 18:00               ` Rob Herring
  0 siblings, 1 reply; 21+ messages in thread
From: Irui Wang @ 2022-03-30  8:48 UTC (permalink / raw)
  To: Rob Herring
  Cc: Hans Verkuil, Tzung-Bi Shih, Alexandre Courbot,
	Mauro Carvalho Chehab, Matthias Brugger, Tomasz Figa,
	angelogioacchino.delregno, Yong Wu, Tiffany Lin, Andrew-CT Chen,
	Hsin-Yi Wang, Maoguang Meng, Longfei Wang, Yunfei Dong,
	Fritz Koenig, linux-media, devicetree, linux-kernel,
	linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

Dear Rob,

A sample encoder hardware block diagram attached.
On Tue, 2022-03-29 at 08:09 -0500, Rob Herring wrote:
> On Tue, Mar 29, 2022 at 09:26:37AM +0800, Irui Wang wrote:
> > Dear Rob,
> > 
> > Many thanks for your attention.
> > 
> > On Mon, 2022-03-28 at 08:48 -0500, Rob Herring wrote:
> > > On Sat, Mar 26, 2022 at 10:00:55AM +0800, Irui Wang wrote:
> > > > Dear Rob,
> > > > 
> > > > Thanks for your review and comments.
> > > > 
> > > > On Fri, 2022-03-25 at 15:57 -0500, Rob Herring wrote:
> > > > > On Thu, Mar 17, 2022 at 04:22:23PM +0800, Irui Wang wrote:
> > > > > > Adds encoder cores dt-bindings for mt8195.
> 
> [...]
> 
> > > > > > +      mediatek,core-id:
> > > > > > +        $ref: /schemas/types.yaml#/definitions/uint32
> > > > > > +        description: |
> > > > > > +          Current encoder core id.
> > > > > 
> > > > > What is this for and what does its value correspond to in the
> > > > > h/w.
> > > > > We 
> > > > > generally don't do made up indices in DT.
> > > > 
> > > > It's for encoder core id, core@1a020000 must be core-0, 
> > > > core@1b020000
> > > > must be core-1, we add this property in each child node, so we
> > > > can 
> > > > get core-id in drivers. If it can't ref "uint32" types yaml,
> > > > would 
> > > > you mind giving some more suggestions ?
> > > 
> > > I still don't understand why it is needed. What is 'core-0'?
> > > 
> > > Is there some functional difference between the cores? If so,
> > > describe 
> > > that difference.
> > > 
> > > Rob
> > 
> > They are two different pieces of hardware, it's our encoder
> > hardware
> > design. There are two encoder hardware cores inside MT8195, named
> > core0
> > and core1(we can rename it, but core id should be declared),
> > for core0, its module base address is 0x1A02_0000, uses IOMMU
> > "vdo0_iommu" and power domain "POWER_DOMAIN_VENC",
> > for core1, its module base address is 0x1B02_0000, uses IOMMU
> > "vpp_iommu" and power domain "POWER_DOMAIN_VENC_CORE1".
> > So the two encoder cores have their own base, IRQ, clock, power,
> > etc.
> > Each core can encode independently, moreover, they can work
> > together
> > for higher performance. 
> > We will describe more details in YAML about it if it's OK for you.
> 
> All the resources you list are in the child nodes, so you don't need
> 0 
> and 1 numbering for those. 
> 
> Looking at the driver patches, the only thing I see distinguishing 
> core numbers is this:
> 
> "frame#0 uses core#0, frame#1 uses core#1, frame#2 uses core#0...,
> 
> Lock the device and enable the clock by used core, for sequence
> header encoding, it always uses core#0."
> 
> Is this a requirement in the h/w or just what the driver picked?
> IOW, 
> could frame#0 use core#1?
No, it's a requirement in the h/w, driver trigger core start encoding
is in order.
About the encoder hardware block diagram, please check below:
--------------------------------------------------------------
Input Buffer: 0     1     2     3     4     5     6
              |     |     |     |     |     |     |
              v     |     v     |     v     |     v
          +-------+ | +-------+ | +-------+ | +-------+
          | core0 | | | core0 | | | core0 | | | core0 |
          +-------+ | +-------+ | +-------+ | +-------+
              |     |     |     |     |     |     |
              |     v     |     v     |     v     |
              | +-------+ | +-------+ | +-------+ |
              | | core1 | | | core1 | | | core1 | |
              | +-------+ | +-------+ | +-------+ |
              |     |     |     |     |     |     |
              v     v     v     v     v     v     v    <parent>
--------------------------------------------------------------
                        core || index                  <child>
                             \/
       +-----------------------------------------------+
       |                  core0/core1                  |
       |          enable/disable power/clk/irq         |
       +-----------------------------------------------+
--------------------------------------------------------------
As above , there are parent and child devices, child mean each venc
core, the child device controls the information of each core
independent which inlcude power/clk/irq.
When start encoding, input buffer 0 will be encoded by core0, and input
buffer 1 can be encoded by core1 even if buffer 0 has not been encoded
done yet, after buffer 0 encoded done, buffer 2 will be encoded by
core0, and buffer 1 encoded done by core1. These two encoder cores will
encode each input in this overlapping manner.

We need manage each child device in parent device by core-id property.
And we also need record current encoding input buffer, encode done
output buffers and which one core is in used through core-id, because
the two cores are encoding at the same time under one parent driver.
> 
> Rob

Thanks
Best Regards
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3, 03/10] dt-bindings: media: mtk-vcodec: Adds encoder cores dt-bindings for mt8195
  2022-03-30  8:48             ` Irui Wang
@ 2022-03-31 18:00               ` Rob Herring
  0 siblings, 0 replies; 21+ messages in thread
From: Rob Herring @ 2022-03-31 18:00 UTC (permalink / raw)
  To: Irui Wang
  Cc: Hans Verkuil, Tzung-Bi Shih, Alexandre Courbot,
	Mauro Carvalho Chehab, Matthias Brugger, Tomasz Figa,
	angelogioacchino.delregno, Yong Wu, Tiffany Lin, Andrew-CT Chen,
	Hsin-Yi Wang, Maoguang Meng, Longfei Wang, Yunfei Dong,
	Fritz Koenig, linux-media, devicetree, linux-kernel,
	linux-arm-kernel, srv_heupstream, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

On Wed, Mar 30, 2022 at 04:48:47PM +0800, Irui Wang wrote:
> Dear Rob,
> 
> A sample encoder hardware block diagram attached.
> On Tue, 2022-03-29 at 08:09 -0500, Rob Herring wrote:
> > On Tue, Mar 29, 2022 at 09:26:37AM +0800, Irui Wang wrote:
> > > Dear Rob,
> > > 
> > > Many thanks for your attention.
> > > 
> > > On Mon, 2022-03-28 at 08:48 -0500, Rob Herring wrote:
> > > > On Sat, Mar 26, 2022 at 10:00:55AM +0800, Irui Wang wrote:
> > > > > Dear Rob,
> > > > > 
> > > > > Thanks for your review and comments.
> > > > > 
> > > > > On Fri, 2022-03-25 at 15:57 -0500, Rob Herring wrote:
> > > > > > On Thu, Mar 17, 2022 at 04:22:23PM +0800, Irui Wang wrote:
> > > > > > > Adds encoder cores dt-bindings for mt8195.
> > 
> > [...]
> > 
> > > > > > > +      mediatek,core-id:
> > > > > > > +        $ref: /schemas/types.yaml#/definitions/uint32
> > > > > > > +        description: |
> > > > > > > +          Current encoder core id.
> > > > > > 
> > > > > > What is this for and what does its value correspond to in the
> > > > > > h/w.
> > > > > > We 
> > > > > > generally don't do made up indices in DT.
> > > > > 
> > > > > It's for encoder core id, core@1a020000 must be core-0, 
> > > > > core@1b020000
> > > > > must be core-1, we add this property in each child node, so we
> > > > > can 
> > > > > get core-id in drivers. If it can't ref "uint32" types yaml,
> > > > > would 
> > > > > you mind giving some more suggestions ?
> > > > 
> > > > I still don't understand why it is needed. What is 'core-0'?
> > > > 
> > > > Is there some functional difference between the cores? If so,
> > > > describe 
> > > > that difference.
> > > > 
> > > > Rob
> > > 
> > > They are two different pieces of hardware, it's our encoder
> > > hardware
> > > design. There are two encoder hardware cores inside MT8195, named
> > > core0
> > > and core1(we can rename it, but core id should be declared),
> > > for core0, its module base address is 0x1A02_0000, uses IOMMU
> > > "vdo0_iommu" and power domain "POWER_DOMAIN_VENC",
> > > for core1, its module base address is 0x1B02_0000, uses IOMMU
> > > "vpp_iommu" and power domain "POWER_DOMAIN_VENC_CORE1".
> > > So the two encoder cores have their own base, IRQ, clock, power,
> > > etc.
> > > Each core can encode independently, moreover, they can work
> > > together
> > > for higher performance. 
> > > We will describe more details in YAML about it if it's OK for you.
> > 
> > All the resources you list are in the child nodes, so you don't need
> > 0 
> > and 1 numbering for those. 
> > 
> > Looking at the driver patches, the only thing I see distinguishing 
> > core numbers is this:
> > 
> > "frame#0 uses core#0, frame#1 uses core#1, frame#2 uses core#0...,
> > 
> > Lock the device and enable the clock by used core, for sequence
> > header encoding, it always uses core#0."
> > 
> > Is this a requirement in the h/w or just what the driver picked?
> > IOW, 
> > could frame#0 use core#1?
> No, it's a requirement in the h/w, driver trigger core start encoding
> is in order.
> About the encoder hardware block diagram, please check below:
> --------------------------------------------------------------
> Input Buffer: 0     1     2     3     4     5     6
>               |     |     |     |     |     |     |
>               v     |     v     |     v     |     v
>           +-------+ | +-------+ | +-------+ | +-------+
>           | core0 | | | core0 | | | core0 | | | core0 |
>           +-------+ | +-------+ | +-------+ | +-------+
>               |     |     |     |     |     |     |
>               |     v     |     v     |     v     |
>               | +-------+ | +-------+ | +-------+ |
>               | | core1 | | | core1 | | | core1 | |
>               | +-------+ | +-------+ | +-------+ |
>               |     |     |     |     |     |     |
>               v     v     v     v     v     v     v    <parent>
> --------------------------------------------------------------
>                         core || index                  <child>
>                              \/
>        +-----------------------------------------------+
>        |                  core0/core1                  |
>        |          enable/disable power/clk/irq         |
>        +-----------------------------------------------+
> --------------------------------------------------------------
> As above , there are parent and child devices, child mean each venc
> core, the child device controls the information of each core
> independent which inlcude power/clk/irq.
> When start encoding, input buffer 0 will be encoded by core0, and input
> buffer 1 can be encoded by core1 even if buffer 0 has not been encoded
> done yet, after buffer 0 encoded done, buffer 2 will be encoded by
> core0, and buffer 1 encoded done by core1. These two encoder cores will
> encode each input in this overlapping manner.
> 
> We need manage each child device in parent device by core-id property.
> And we also need record current encoding input buffer, encode done
> output buffers and which one core is in used through core-id, because
> the two cores are encoding at the same time under one parent driver.

Okay, please summarize the h/w requirement in the property description.

You might put the above diagram in the top description too.

Rob

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

end of thread, other threads:[~2022-03-31 18:02 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-17  8:22 [PATCH v3, 00/10] Enable two H264 encoder core on MT8195 Irui Wang
2022-03-17  8:22 ` [PATCH v3, 01/10] media: mtk-vcodec: Use core type to indicate h264 and vp8 enc Irui Wang
2022-03-17  8:22 ` [PATCH v3, 02/10] media: mtk-vcodec: export encoder functions Irui Wang
2022-03-17  8:22 ` [PATCH v3, 03/10] dt-bindings: media: mtk-vcodec: Adds encoder cores dt-bindings for mt8195 Irui Wang
2022-03-17 23:32   ` Miles Chen
2022-03-25 20:57   ` Rob Herring
2022-03-26  2:00     ` Irui Wang
2022-03-28 13:48       ` Rob Herring
2022-03-29  1:26         ` Irui Wang
2022-03-29 13:09           ` Rob Herring
2022-03-30  8:48             ` Irui Wang
2022-03-31 18:00               ` Rob Herring
2022-03-17  8:22 ` [PATCH v3, 04/10] media: mtk-vcodec: Enable venc dual core usage Irui Wang
2022-03-17  8:22 ` [PATCH v3, 05/10] media: mtk-vcodec: mtk-vcodec: Rewrite venc power manage interface Irui Wang
2022-03-17  8:22 ` [PATCH v3, 06/10] media: mtk-vcodec: Add venc power on/off interface Irui Wang
2022-03-17  8:22 ` [PATCH v3, 07/10] media: mtk-vcodec: Rewrite venc clock interface Irui Wang
2022-03-17  8:22 ` [PATCH v3, 08/10] media: mtk-vcodec: Add more extra processing for venc_multi_core mode Irui Wang
2022-03-17  8:22 ` [PATCH v3, 09/10] media: mtk-vcodec: Add venc_multi_core mode encode process Irui Wang
2022-03-17  8:22 ` [PATCH v3, 10/10] media: mtk-vcodec: Done encode result to client Irui Wang
2022-03-18 14:04 ` [PATCH v3, 00/10] Enable two H264 encoder core on MT8195 AngeloGioacchino Del Regno
2022-03-21  1:38   ` Irui Wang

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).