All of lore.kernel.org
 help / color / mirror / Atom feed
* [Patch v4 00/11] Add MFC V12 support
       [not found] <CGME20231025102230epcas5p1558641a18fbf4f841c82b0ef4cf5a91f@epcas5p1.samsung.com>
@ 2023-10-25 10:22   ` Aakarsh Jain
  0 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-10-25 10:22 UTC (permalink / raw)
  To: linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	aakarsh.jain

This patch series adds MFC v12 support. MFC v12 is used in Tesla FSD SoC.

This adds support for following:

-Add support for YV12 and I420 format (3-plane)
-Add support for Rate Control, UHD and DMABUF for encoder
-Add support for DPB buffers allocation based on MFC requirement

Changes since v3:
-Removed vp9 codec support for now and just keeping MFC v12 base
patches with necessary hardware controls, decoder, encoder and
structural changes. Also covers luma dbp, chroma dpb and mv sizes
for each codec as per the UM for MFCv12, along with appropriate
alignment.
v3 link: https://patchwork.kernel.org/project/linux-media/cover/20221011122516.32135-1-aakarsh.jain@samsung.com/

Changes since v2:
-Addressed review comments by Rob Herring.
This was regarding the errors found by Rob bot in yaml file. File
'samsung,s5p-mfc.yaml' is already converted into json schema and is
merged.

-Addressed review comments by Krzysztof Kozlowski.
This was regarding depricated properties mentioned in s5p-mfc.txt file.
Review comment was addressed and 'samsung,s5p-mfc.yaml' is already
merged now.

-Addressed review comments by Andi Shyti.
This was regarding addition of 'MFC_V10PLUS_BITS' macro in
's5p_mfc_common.h file. 
v2 link: https://patchwork.kernel.org/project/linux-media/cover/20220907064715.55778-1-smitha.t@samsung.com/

Changes since v1:
-Addressed review comments by Krzysztof Kozlowski.
Separated bug fixes patches, resent again with fix tag
and those are merged now.
-Added SoC based compatible string.

-Addressed review comments by Andrzej Hajda
Assigned width64 and height32 variable with ALIGN(ctx->img_..) 
used in the code in 's5p_mfc_opr_v6.c' file.
v1 link: https://patchwork.kernel.org/project/linux-media/patch/20220517125548.14746-2-smitha.t@samsung.com/

Aakarsh Jain (11):
  dt-bindings: media: s5p-mfc: Add mfcv12 variant
  media: s5p-mfc: Rename IS_MFCV10 macro
  media: s5p-mfc: Add initial support for MFCv12
  media: s5p-mfc: Add YV12 and I420 multiplanar format support
  media: s5p-mfc: Add support for rate controls in MFCv12
  media: s5p-mfc: Add support for UHD encoding.
  media: s5p-mfc: Add support for DMABUF for encoder
  media: s5p-mfc: Set context for valid case before calling try_run
  media: s5p-mfc: Load firmware for each run in MFCv12.
  media: s5p-mfc: DPB Count Independent of VIDIOC_REQBUF
  arm64: dts: fsd: Add MFC related DT enteries

 .../bindings/media/samsung,s5p-mfc.yaml       |  16 +
 arch/arm64/boot/dts/tesla/fsd.dtsi            |  21 ++
 .../platform/samsung/s5p-mfc/regs-mfc-v12.h   |  52 +++
 .../platform/samsung/s5p-mfc/regs-mfc-v7.h    |   1 +
 .../platform/samsung/s5p-mfc/regs-mfc-v8.h    |   3 +
 .../media/platform/samsung/s5p-mfc/s5p_mfc.c  |  36 +-
 .../platform/samsung/s5p-mfc/s5p_mfc_common.h |  29 +-
 .../platform/samsung/s5p-mfc/s5p_mfc_ctrl.c   |   9 +-
 .../platform/samsung/s5p-mfc/s5p_mfc_dec.c    |  51 ++-
 .../platform/samsung/s5p-mfc/s5p_mfc_enc.c    | 138 +++++---
 .../platform/samsung/s5p-mfc/s5p_mfc_opr.h    |  14 +-
 .../platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c |  12 +-
 .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 312 +++++++++++++++---
 .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h |   7 +-
 14 files changed, 574 insertions(+), 127 deletions(-)
 create mode 100644 drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h

-- 
2.17.1


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

* [Patch v4 00/11] Add MFC V12 support
@ 2023-10-25 10:22   ` Aakarsh Jain
  0 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-10-25 10:22 UTC (permalink / raw)
  To: linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	aakarsh.jain

This patch series adds MFC v12 support. MFC v12 is used in Tesla FSD SoC.

This adds support for following:

-Add support for YV12 and I420 format (3-plane)
-Add support for Rate Control, UHD and DMABUF for encoder
-Add support for DPB buffers allocation based on MFC requirement

Changes since v3:
-Removed vp9 codec support for now and just keeping MFC v12 base
patches with necessary hardware controls, decoder, encoder and
structural changes. Also covers luma dbp, chroma dpb and mv sizes
for each codec as per the UM for MFCv12, along with appropriate
alignment.
v3 link: https://patchwork.kernel.org/project/linux-media/cover/20221011122516.32135-1-aakarsh.jain@samsung.com/

Changes since v2:
-Addressed review comments by Rob Herring.
This was regarding the errors found by Rob bot in yaml file. File
'samsung,s5p-mfc.yaml' is already converted into json schema and is
merged.

-Addressed review comments by Krzysztof Kozlowski.
This was regarding depricated properties mentioned in s5p-mfc.txt file.
Review comment was addressed and 'samsung,s5p-mfc.yaml' is already
merged now.

-Addressed review comments by Andi Shyti.
This was regarding addition of 'MFC_V10PLUS_BITS' macro in
's5p_mfc_common.h file. 
v2 link: https://patchwork.kernel.org/project/linux-media/cover/20220907064715.55778-1-smitha.t@samsung.com/

Changes since v1:
-Addressed review comments by Krzysztof Kozlowski.
Separated bug fixes patches, resent again with fix tag
and those are merged now.
-Added SoC based compatible string.

-Addressed review comments by Andrzej Hajda
Assigned width64 and height32 variable with ALIGN(ctx->img_..) 
used in the code in 's5p_mfc_opr_v6.c' file.
v1 link: https://patchwork.kernel.org/project/linux-media/patch/20220517125548.14746-2-smitha.t@samsung.com/

Aakarsh Jain (11):
  dt-bindings: media: s5p-mfc: Add mfcv12 variant
  media: s5p-mfc: Rename IS_MFCV10 macro
  media: s5p-mfc: Add initial support for MFCv12
  media: s5p-mfc: Add YV12 and I420 multiplanar format support
  media: s5p-mfc: Add support for rate controls in MFCv12
  media: s5p-mfc: Add support for UHD encoding.
  media: s5p-mfc: Add support for DMABUF for encoder
  media: s5p-mfc: Set context for valid case before calling try_run
  media: s5p-mfc: Load firmware for each run in MFCv12.
  media: s5p-mfc: DPB Count Independent of VIDIOC_REQBUF
  arm64: dts: fsd: Add MFC related DT enteries

 .../bindings/media/samsung,s5p-mfc.yaml       |  16 +
 arch/arm64/boot/dts/tesla/fsd.dtsi            |  21 ++
 .../platform/samsung/s5p-mfc/regs-mfc-v12.h   |  52 +++
 .../platform/samsung/s5p-mfc/regs-mfc-v7.h    |   1 +
 .../platform/samsung/s5p-mfc/regs-mfc-v8.h    |   3 +
 .../media/platform/samsung/s5p-mfc/s5p_mfc.c  |  36 +-
 .../platform/samsung/s5p-mfc/s5p_mfc_common.h |  29 +-
 .../platform/samsung/s5p-mfc/s5p_mfc_ctrl.c   |   9 +-
 .../platform/samsung/s5p-mfc/s5p_mfc_dec.c    |  51 ++-
 .../platform/samsung/s5p-mfc/s5p_mfc_enc.c    | 138 +++++---
 .../platform/samsung/s5p-mfc/s5p_mfc_opr.h    |  14 +-
 .../platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c |  12 +-
 .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 312 +++++++++++++++---
 .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h |   7 +-
 14 files changed, 574 insertions(+), 127 deletions(-)
 create mode 100644 drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h

-- 
2.17.1


_______________________________________________
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] 54+ messages in thread

* [Patch v4 01/11] dt-bindings: media: s5p-mfc: Add mfcv12 variant
       [not found]   ` <CGME20231025102233epcas5p16b716d5b650bbc5af0d759ea4f58f44d@epcas5p1.samsung.com>
@ 2023-10-25 10:22       ` Aakarsh Jain
  0 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-10-25 10:22 UTC (permalink / raw)
  To: linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	aakarsh.jain, linux-fsd

Add Tesla FSD MFC(MFC v12) compatible.

Cc: linux-fsd@tesla.com
Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
---
 .../bindings/media/samsung,s5p-mfc.yaml          | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/samsung,s5p-mfc.yaml b/Documentation/devicetree/bindings/media/samsung,s5p-mfc.yaml
index 084b44582a43..c30eb309f670 100644
--- a/Documentation/devicetree/bindings/media/samsung,s5p-mfc.yaml
+++ b/Documentation/devicetree/bindings/media/samsung,s5p-mfc.yaml
@@ -24,6 +24,7 @@ properties:
           - samsung,mfc-v7                # Exynos5420
           - samsung,mfc-v8                # Exynos5800
           - samsung,mfc-v10               # Exynos7880
+          - tesla,fsd-mfc                 # Tesla FSD
       - items:
           - enum:
               - samsung,exynos3250-mfc    # Exynos3250
@@ -165,6 +166,21 @@ allOf:
           minItems: 1
           maxItems: 2
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - tesla,fsd-mfc
+    then:
+      properties:
+        clocks:
+          maxItems: 1
+        clock-names:
+          items:
+            - const: mfc
+        iommus: false
+
 examples:
   - |
     #include <dt-bindings/clock/exynos4.h>
-- 
2.17.1


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

* [Patch v4 01/11] dt-bindings: media: s5p-mfc: Add mfcv12 variant
@ 2023-10-25 10:22       ` Aakarsh Jain
  0 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-10-25 10:22 UTC (permalink / raw)
  To: linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	aakarsh.jain, linux-fsd

Add Tesla FSD MFC(MFC v12) compatible.

Cc: linux-fsd@tesla.com
Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
---
 .../bindings/media/samsung,s5p-mfc.yaml          | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/samsung,s5p-mfc.yaml b/Documentation/devicetree/bindings/media/samsung,s5p-mfc.yaml
index 084b44582a43..c30eb309f670 100644
--- a/Documentation/devicetree/bindings/media/samsung,s5p-mfc.yaml
+++ b/Documentation/devicetree/bindings/media/samsung,s5p-mfc.yaml
@@ -24,6 +24,7 @@ properties:
           - samsung,mfc-v7                # Exynos5420
           - samsung,mfc-v8                # Exynos5800
           - samsung,mfc-v10               # Exynos7880
+          - tesla,fsd-mfc                 # Tesla FSD
       - items:
           - enum:
               - samsung,exynos3250-mfc    # Exynos3250
@@ -165,6 +166,21 @@ allOf:
           minItems: 1
           maxItems: 2
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - tesla,fsd-mfc
+    then:
+      properties:
+        clocks:
+          maxItems: 1
+        clock-names:
+          items:
+            - const: mfc
+        iommus: false
+
 examples:
   - |
     #include <dt-bindings/clock/exynos4.h>
-- 
2.17.1


_______________________________________________
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] 54+ messages in thread

* [Patch v4 02/11] media: s5p-mfc: Rename IS_MFCV10 macro
       [not found]   ` <CGME20231025102237epcas5p28a5ad9db8d7dea072a6986d530810dde@epcas5p2.samsung.com>
@ 2023-10-25 10:22       ` Aakarsh Jain
  0 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-10-25 10:22 UTC (permalink / raw)
  To: linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	aakarsh.jain, linux-fsd, Smitha T Murthy

Renames macro IS_MFCV10 to IS_MFCV10_PLUS so that the MFCv10 code can
be resued for MFCv12 support. Since some part of MFCv10 specific code
holds good for MFCv12 also.

Cc: linux-fsd@tesla.com
Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
---
 .../platform/samsung/s5p-mfc/s5p_mfc_common.h | 10 +++----
 .../platform/samsung/s5p-mfc/s5p_mfc_ctrl.c   |  2 +-
 .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 28 +++++++++----------
 3 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
index 5304f42c8c72..e6ec4a43b290 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
@@ -771,11 +771,11 @@ void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq);
 #define HAS_PORTNUM(dev)	(dev ? (dev->variant ? \
 				(dev->variant->port_num ? 1 : 0) : 0) : 0)
 #define IS_TWOPORT(dev)		(dev->variant->port_num == 2 ? 1 : 0)
-#define IS_MFCV6_PLUS(dev)	(dev->variant->version >= 0x60 ? 1 : 0)
-#define IS_MFCV7_PLUS(dev)	(dev->variant->version >= 0x70 ? 1 : 0)
-#define IS_MFCV8_PLUS(dev)	(dev->variant->version >= 0x80 ? 1 : 0)
-#define IS_MFCV10(dev)		(dev->variant->version >= 0xA0 ? 1 : 0)
-#define FW_HAS_E_MIN_SCRATCH_BUF(dev) (IS_MFCV10(dev))
+#define IS_MFCV6_PLUS(dev)	(dev->variant->version >= 0x60)
+#define IS_MFCV7_PLUS(dev)	(dev->variant->version >= 0x70)
+#define IS_MFCV8_PLUS(dev)	(dev->variant->version >= 0x80)
+#define IS_MFCV10_PLUS(dev)	(dev->variant->version >= 0xA0)
+#define FW_HAS_E_MIN_SCRATCH_BUF(dev) (IS_MFCV10_PLUS(dev))
 
 #define MFC_V5_BIT	BIT(0)
 #define MFC_V6_BIT	BIT(1)
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
index 6d3c92045c05..54b54b2fa9b1 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
@@ -236,7 +236,7 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
 	else
 		mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET);
 
-	if (IS_MFCV10(dev))
+	if (IS_MFCV10_PLUS(dev))
 		mfc_write(dev, 0x0, S5P_FIMV_MFC_CLOCK_OFF_V10);
 
 	mfc_debug(2, "Will now wait for completion of firmware transfer\n");
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
index c0df5ac9fcff..882166e4ac50 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
@@ -72,9 +72,9 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 			  ctx->luma_size, ctx->chroma_size, ctx->mv_size);
 		mfc_debug(2, "Totals bufs: %d\n", ctx->total_dpb_count);
 	} else if (ctx->type == MFCINST_ENCODER) {
-		if (IS_MFCV10(dev)) {
+		if (IS_MFCV10_PLUS(dev))
 			ctx->tmv_buffer_size = 0;
-		} else if (IS_MFCV8_PLUS(dev))
+		else if (IS_MFCV8_PLUS(dev))
 			ctx->tmv_buffer_size = S5P_FIMV_NUM_TMV_BUFFERS_V6 *
 			ALIGN(S5P_FIMV_TMV_BUFFER_SIZE_V8(mb_width, mb_height),
 			S5P_FIMV_TMV_BUFFER_ALIGN_V6);
@@ -82,7 +82,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 			ctx->tmv_buffer_size = S5P_FIMV_NUM_TMV_BUFFERS_V6 *
 			ALIGN(S5P_FIMV_TMV_BUFFER_SIZE_V6(mb_width, mb_height),
 			S5P_FIMV_TMV_BUFFER_ALIGN_V6);
-		if (IS_MFCV10(dev)) {
+		if (IS_MFCV10_PLUS(dev)) {
 			lcu_width = S5P_MFC_LCU_WIDTH(ctx->img_width);
 			lcu_height = S5P_MFC_LCU_HEIGHT(ctx->img_height);
 			if (ctx->codec_mode != S5P_FIMV_CODEC_HEVC_ENC) {
@@ -133,7 +133,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 	switch (ctx->codec_mode) {
 	case S5P_MFC_CODEC_H264_DEC:
 	case S5P_MFC_CODEC_H264_MVC_DEC:
-		if (IS_MFCV10(dev))
+		if (IS_MFCV10_PLUS(dev))
 			mfc_debug(2, "Use min scratch buffer size\n");
 		else if (IS_MFCV8_PLUS(dev))
 			ctx->scratch_buf_size =
@@ -152,7 +152,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 			(ctx->mv_count * ctx->mv_size);
 		break;
 	case S5P_MFC_CODEC_MPEG4_DEC:
-		if (IS_MFCV10(dev))
+		if (IS_MFCV10_PLUS(dev))
 			mfc_debug(2, "Use min scratch buffer size\n");
 		else if (IS_MFCV7_PLUS(dev)) {
 			ctx->scratch_buf_size =
@@ -172,7 +172,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 		break;
 	case S5P_MFC_CODEC_VC1RCV_DEC:
 	case S5P_MFC_CODEC_VC1_DEC:
-		if (IS_MFCV10(dev))
+		if (IS_MFCV10_PLUS(dev))
 			mfc_debug(2, "Use min scratch buffer size\n");
 		else
 			ctx->scratch_buf_size =
@@ -189,7 +189,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 		ctx->bank2.size = 0;
 		break;
 	case S5P_MFC_CODEC_H263_DEC:
-		if (IS_MFCV10(dev))
+		if (IS_MFCV10_PLUS(dev))
 			mfc_debug(2, "Use min scratch buffer size\n");
 		else
 			ctx->scratch_buf_size =
@@ -201,7 +201,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 		ctx->bank1.size = ctx->scratch_buf_size;
 		break;
 	case S5P_MFC_CODEC_VP8_DEC:
-		if (IS_MFCV10(dev))
+		if (IS_MFCV10_PLUS(dev))
 			mfc_debug(2, "Use min scratch buffer size\n");
 		else if (IS_MFCV8_PLUS(dev))
 			ctx->scratch_buf_size =
@@ -230,7 +230,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 			DEC_VP9_STATIC_BUFFER_SIZE;
 		break;
 	case S5P_MFC_CODEC_H264_ENC:
-		if (IS_MFCV10(dev)) {
+		if (IS_MFCV10_PLUS(dev)) {
 			mfc_debug(2, "Use min scratch buffer size\n");
 			ctx->me_buffer_size =
 			ALIGN(ENC_V100_H264_ME_SIZE(mb_width, mb_height), 16);
@@ -254,7 +254,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 		break;
 	case S5P_MFC_CODEC_MPEG4_ENC:
 	case S5P_MFC_CODEC_H263_ENC:
-		if (IS_MFCV10(dev)) {
+		if (IS_MFCV10_PLUS(dev)) {
 			mfc_debug(2, "Use min scratch buffer size\n");
 			ctx->me_buffer_size =
 				ALIGN(ENC_V100_MPEG4_ME_SIZE(mb_width,
@@ -273,7 +273,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 		ctx->bank2.size = 0;
 		break;
 	case S5P_MFC_CODEC_VP8_ENC:
-		if (IS_MFCV10(dev)) {
+		if (IS_MFCV10_PLUS(dev)) {
 			mfc_debug(2, "Use min scratch buffer size\n");
 			ctx->me_buffer_size =
 				ALIGN(ENC_V100_VP8_ME_SIZE(mb_width, mb_height),
@@ -452,7 +452,7 @@ static void s5p_mfc_dec_calc_dpb_size_v6(struct s5p_mfc_ctx *ctx)
 
 	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
 			ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC) {
-		if (IS_MFCV10(dev)) {
+		if (IS_MFCV10_PLUS(dev)) {
 			ctx->mv_size = S5P_MFC_DEC_MV_SIZE_V10(ctx->img_width,
 					ctx->img_height);
 		} else {
@@ -668,7 +668,7 @@ static int s5p_mfc_set_enc_ref_buffer_v6(struct s5p_mfc_ctx *ctx)
 
 	mfc_debug(2, "Buf1: %p (%d)\n", (void *)buf_addr1, buf_size1);
 
-	if (IS_MFCV10(dev)) {
+	if (IS_MFCV10_PLUS(dev)) {
 		/* start address of per buffer is aligned */
 		for (i = 0; i < ctx->pb_count; i++) {
 			writel(buf_addr1, mfc_regs->e_luma_dpb + (4 * i));
@@ -2455,7 +2455,7 @@ const struct s5p_mfc_regs *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev)
 	R(e_h264_options, S5P_FIMV_E_H264_OPTIONS_V8);
 	R(e_min_scratch_buffer_size, S5P_FIMV_E_MIN_SCRATCH_BUFFER_SIZE_V8);
 
-	if (!IS_MFCV10(dev))
+	if (!IS_MFCV10_PLUS(dev))
 		goto done;
 
 	/* Initialize registers used in MFC v10 only.
-- 
2.17.1


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

* [Patch v4 02/11] media: s5p-mfc: Rename IS_MFCV10 macro
@ 2023-10-25 10:22       ` Aakarsh Jain
  0 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-10-25 10:22 UTC (permalink / raw)
  To: linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	aakarsh.jain, linux-fsd, Smitha T Murthy

Renames macro IS_MFCV10 to IS_MFCV10_PLUS so that the MFCv10 code can
be resued for MFCv12 support. Since some part of MFCv10 specific code
holds good for MFCv12 also.

Cc: linux-fsd@tesla.com
Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
---
 .../platform/samsung/s5p-mfc/s5p_mfc_common.h | 10 +++----
 .../platform/samsung/s5p-mfc/s5p_mfc_ctrl.c   |  2 +-
 .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 28 +++++++++----------
 3 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
index 5304f42c8c72..e6ec4a43b290 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
@@ -771,11 +771,11 @@ void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq);
 #define HAS_PORTNUM(dev)	(dev ? (dev->variant ? \
 				(dev->variant->port_num ? 1 : 0) : 0) : 0)
 #define IS_TWOPORT(dev)		(dev->variant->port_num == 2 ? 1 : 0)
-#define IS_MFCV6_PLUS(dev)	(dev->variant->version >= 0x60 ? 1 : 0)
-#define IS_MFCV7_PLUS(dev)	(dev->variant->version >= 0x70 ? 1 : 0)
-#define IS_MFCV8_PLUS(dev)	(dev->variant->version >= 0x80 ? 1 : 0)
-#define IS_MFCV10(dev)		(dev->variant->version >= 0xA0 ? 1 : 0)
-#define FW_HAS_E_MIN_SCRATCH_BUF(dev) (IS_MFCV10(dev))
+#define IS_MFCV6_PLUS(dev)	(dev->variant->version >= 0x60)
+#define IS_MFCV7_PLUS(dev)	(dev->variant->version >= 0x70)
+#define IS_MFCV8_PLUS(dev)	(dev->variant->version >= 0x80)
+#define IS_MFCV10_PLUS(dev)	(dev->variant->version >= 0xA0)
+#define FW_HAS_E_MIN_SCRATCH_BUF(dev) (IS_MFCV10_PLUS(dev))
 
 #define MFC_V5_BIT	BIT(0)
 #define MFC_V6_BIT	BIT(1)
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
index 6d3c92045c05..54b54b2fa9b1 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
@@ -236,7 +236,7 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
 	else
 		mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET);
 
-	if (IS_MFCV10(dev))
+	if (IS_MFCV10_PLUS(dev))
 		mfc_write(dev, 0x0, S5P_FIMV_MFC_CLOCK_OFF_V10);
 
 	mfc_debug(2, "Will now wait for completion of firmware transfer\n");
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
index c0df5ac9fcff..882166e4ac50 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
@@ -72,9 +72,9 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 			  ctx->luma_size, ctx->chroma_size, ctx->mv_size);
 		mfc_debug(2, "Totals bufs: %d\n", ctx->total_dpb_count);
 	} else if (ctx->type == MFCINST_ENCODER) {
-		if (IS_MFCV10(dev)) {
+		if (IS_MFCV10_PLUS(dev))
 			ctx->tmv_buffer_size = 0;
-		} else if (IS_MFCV8_PLUS(dev))
+		else if (IS_MFCV8_PLUS(dev))
 			ctx->tmv_buffer_size = S5P_FIMV_NUM_TMV_BUFFERS_V6 *
 			ALIGN(S5P_FIMV_TMV_BUFFER_SIZE_V8(mb_width, mb_height),
 			S5P_FIMV_TMV_BUFFER_ALIGN_V6);
@@ -82,7 +82,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 			ctx->tmv_buffer_size = S5P_FIMV_NUM_TMV_BUFFERS_V6 *
 			ALIGN(S5P_FIMV_TMV_BUFFER_SIZE_V6(mb_width, mb_height),
 			S5P_FIMV_TMV_BUFFER_ALIGN_V6);
-		if (IS_MFCV10(dev)) {
+		if (IS_MFCV10_PLUS(dev)) {
 			lcu_width = S5P_MFC_LCU_WIDTH(ctx->img_width);
 			lcu_height = S5P_MFC_LCU_HEIGHT(ctx->img_height);
 			if (ctx->codec_mode != S5P_FIMV_CODEC_HEVC_ENC) {
@@ -133,7 +133,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 	switch (ctx->codec_mode) {
 	case S5P_MFC_CODEC_H264_DEC:
 	case S5P_MFC_CODEC_H264_MVC_DEC:
-		if (IS_MFCV10(dev))
+		if (IS_MFCV10_PLUS(dev))
 			mfc_debug(2, "Use min scratch buffer size\n");
 		else if (IS_MFCV8_PLUS(dev))
 			ctx->scratch_buf_size =
@@ -152,7 +152,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 			(ctx->mv_count * ctx->mv_size);
 		break;
 	case S5P_MFC_CODEC_MPEG4_DEC:
-		if (IS_MFCV10(dev))
+		if (IS_MFCV10_PLUS(dev))
 			mfc_debug(2, "Use min scratch buffer size\n");
 		else if (IS_MFCV7_PLUS(dev)) {
 			ctx->scratch_buf_size =
@@ -172,7 +172,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 		break;
 	case S5P_MFC_CODEC_VC1RCV_DEC:
 	case S5P_MFC_CODEC_VC1_DEC:
-		if (IS_MFCV10(dev))
+		if (IS_MFCV10_PLUS(dev))
 			mfc_debug(2, "Use min scratch buffer size\n");
 		else
 			ctx->scratch_buf_size =
@@ -189,7 +189,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 		ctx->bank2.size = 0;
 		break;
 	case S5P_MFC_CODEC_H263_DEC:
-		if (IS_MFCV10(dev))
+		if (IS_MFCV10_PLUS(dev))
 			mfc_debug(2, "Use min scratch buffer size\n");
 		else
 			ctx->scratch_buf_size =
@@ -201,7 +201,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 		ctx->bank1.size = ctx->scratch_buf_size;
 		break;
 	case S5P_MFC_CODEC_VP8_DEC:
-		if (IS_MFCV10(dev))
+		if (IS_MFCV10_PLUS(dev))
 			mfc_debug(2, "Use min scratch buffer size\n");
 		else if (IS_MFCV8_PLUS(dev))
 			ctx->scratch_buf_size =
@@ -230,7 +230,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 			DEC_VP9_STATIC_BUFFER_SIZE;
 		break;
 	case S5P_MFC_CODEC_H264_ENC:
-		if (IS_MFCV10(dev)) {
+		if (IS_MFCV10_PLUS(dev)) {
 			mfc_debug(2, "Use min scratch buffer size\n");
 			ctx->me_buffer_size =
 			ALIGN(ENC_V100_H264_ME_SIZE(mb_width, mb_height), 16);
@@ -254,7 +254,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 		break;
 	case S5P_MFC_CODEC_MPEG4_ENC:
 	case S5P_MFC_CODEC_H263_ENC:
-		if (IS_MFCV10(dev)) {
+		if (IS_MFCV10_PLUS(dev)) {
 			mfc_debug(2, "Use min scratch buffer size\n");
 			ctx->me_buffer_size =
 				ALIGN(ENC_V100_MPEG4_ME_SIZE(mb_width,
@@ -273,7 +273,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 		ctx->bank2.size = 0;
 		break;
 	case S5P_MFC_CODEC_VP8_ENC:
-		if (IS_MFCV10(dev)) {
+		if (IS_MFCV10_PLUS(dev)) {
 			mfc_debug(2, "Use min scratch buffer size\n");
 			ctx->me_buffer_size =
 				ALIGN(ENC_V100_VP8_ME_SIZE(mb_width, mb_height),
@@ -452,7 +452,7 @@ static void s5p_mfc_dec_calc_dpb_size_v6(struct s5p_mfc_ctx *ctx)
 
 	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
 			ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC) {
-		if (IS_MFCV10(dev)) {
+		if (IS_MFCV10_PLUS(dev)) {
 			ctx->mv_size = S5P_MFC_DEC_MV_SIZE_V10(ctx->img_width,
 					ctx->img_height);
 		} else {
@@ -668,7 +668,7 @@ static int s5p_mfc_set_enc_ref_buffer_v6(struct s5p_mfc_ctx *ctx)
 
 	mfc_debug(2, "Buf1: %p (%d)\n", (void *)buf_addr1, buf_size1);
 
-	if (IS_MFCV10(dev)) {
+	if (IS_MFCV10_PLUS(dev)) {
 		/* start address of per buffer is aligned */
 		for (i = 0; i < ctx->pb_count; i++) {
 			writel(buf_addr1, mfc_regs->e_luma_dpb + (4 * i));
@@ -2455,7 +2455,7 @@ const struct s5p_mfc_regs *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev)
 	R(e_h264_options, S5P_FIMV_E_H264_OPTIONS_V8);
 	R(e_min_scratch_buffer_size, S5P_FIMV_E_MIN_SCRATCH_BUFFER_SIZE_V8);
 
-	if (!IS_MFCV10(dev))
+	if (!IS_MFCV10_PLUS(dev))
 		goto done;
 
 	/* Initialize registers used in MFC v10 only.
-- 
2.17.1


_______________________________________________
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] 54+ messages in thread

* [Patch v4 03/11] media: s5p-mfc: Add initial support for MFCv12
       [not found]   ` <CGME20231025102240epcas5p1551ac81bc2cd45f6c84e2eebc11571c4@epcas5p1.samsung.com>
@ 2023-10-25 10:22       ` Aakarsh Jain
  0 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-10-25 10:22 UTC (permalink / raw)
  To: linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	aakarsh.jain, linux-fsd, Smitha T Murthy

Add support for MFCv12, with a new register file and necessary hw
control, decoder, encoder and structural changes. Add luma dbp, chroma
dpb and mv sizes for each codec as per the UM for MFCv12, along with
appropriate alignment.

Cc: linux-fsd@tesla.com
Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
---
 .../platform/samsung/s5p-mfc/regs-mfc-v12.h   | 50 +++++++++++
 .../media/platform/samsung/s5p-mfc/s5p_mfc.c  | 30 +++++++
 .../platform/samsung/s5p-mfc/s5p_mfc_common.h | 15 +++-
 .../platform/samsung/s5p-mfc/s5p_mfc_ctrl.c   |  2 +-
 .../platform/samsung/s5p-mfc/s5p_mfc_dec.c    |  6 +-
 .../platform/samsung/s5p-mfc/s5p_mfc_enc.c    |  5 +-
 .../platform/samsung/s5p-mfc/s5p_mfc_opr.h    |  8 +-
 .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 83 ++++++++++++++++---
 .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h |  6 +-
 9 files changed, 175 insertions(+), 30 deletions(-)
 create mode 100644 drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h

diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
new file mode 100644
index 000000000000..6c68a45082d0
--- /dev/null
+++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Register definition file for Samsung MFC V12.x Interface (FIMV) driver
+ *
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *     http://www.samsung.com/
+ */
+
+#ifndef _REGS_MFC_V12_H
+#define _REGS_MFC_V12_H
+
+#include <linux/sizes.h>
+#include "regs-mfc-v10.h"
+
+/* MFCv12 Context buffer sizes */
+#define MFC_CTX_BUF_SIZE_V12		(30 * SZ_1K)
+#define MFC_H264_DEC_CTX_BUF_SIZE_V12	(2 * SZ_1M)
+#define MFC_OTHER_DEC_CTX_BUF_SIZE_V12	(30 * SZ_1K)
+#define MFC_H264_ENC_CTX_BUF_SIZE_V12	(100 * SZ_1K)
+#define MFC_HEVC_ENC_CTX_BUF_SIZE_V12	(40 * SZ_1K)
+#define MFC_OTHER_ENC_CTX_BUF_SIZE_V12	(25 * SZ_1K)
+
+/* MFCv12 variant defines */
+#define MAX_FW_SIZE_V12			(SZ_1M)
+#define MAX_CPB_SIZE_V12		(7 * SZ_1M)
+#define MFC_VERSION_V12			0xC0
+#define MFC_NUM_PORTS_V12		1
+#define S5P_FIMV_CODEC_VP9_ENC		27
+
+/* Encoder buffer size for MFCv12 */
+#define ENC_V120_BASE_SIZE(x, y) \
+	(((x + 3) * (y + 3) * 8) \
+	+ (((y * 64) + 2304) * (x + 7) / 8))
+
+#define ENC_V120_H264_ME_SIZE(x, y) \
+	ALIGN((ENC_V120_BASE_SIZE(x, y) \
+	+ (DIV_ROUND_UP(x * y, 64) * 32)), 256)
+
+#define ENC_V120_MPEG4_ME_SIZE(x, y) \
+	ALIGN((ENC_V120_BASE_SIZE(x, y) \
+	+ (DIV_ROUND_UP(x * y, 128) * 16)), 256)
+
+#define ENC_V120_VP8_ME_SIZE(x, y) \
+	ALIGN(ENC_V120_BASE_SIZE(x, y), 256)
+
+#define ENC_V120_HEVC_ME_SIZE(x, y)     \
+	ALIGN((((x + 3) * (y + 3) * 32)       \
+	+ (((y * 128) + 2304) * (x + 3) / 4)), 256)
+
+#endif /*_REGS_MFC_V12_H*/
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
index e30e54935d79..dee9ef017997 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
@@ -790,6 +790,8 @@ static int s5p_mfc_open(struct file *file)
 	INIT_LIST_HEAD(&ctx->dst_queue);
 	ctx->src_queue_cnt = 0;
 	ctx->dst_queue_cnt = 0;
+	ctx->is_422 = 0;
+	ctx->is_10bit = 0;
 	/* Get context number */
 	ctx->num = 0;
 	while (dev->ctx[ctx->num]) {
@@ -1660,6 +1662,31 @@ static struct s5p_mfc_variant mfc_drvdata_v10 = {
 	.fw_name[0]     = "s5p-mfc-v10.fw",
 };
 
+static struct s5p_mfc_buf_size_v6 mfc_buf_size_v12 = {
+	.dev_ctx        = MFC_CTX_BUF_SIZE_V12,
+	.h264_dec_ctx   = MFC_H264_DEC_CTX_BUF_SIZE_V12,
+	.other_dec_ctx  = MFC_OTHER_DEC_CTX_BUF_SIZE_V12,
+	.h264_enc_ctx   = MFC_H264_ENC_CTX_BUF_SIZE_V12,
+	.hevc_enc_ctx   = MFC_HEVC_ENC_CTX_BUF_SIZE_V12,
+	.other_enc_ctx  = MFC_OTHER_ENC_CTX_BUF_SIZE_V12,
+};
+
+static struct s5p_mfc_buf_size buf_size_v12 = {
+	.fw     = MAX_FW_SIZE_V12,
+	.cpb    = MAX_CPB_SIZE_V12,
+	.priv   = &mfc_buf_size_v12,
+};
+
+static struct s5p_mfc_variant mfc_drvdata_v12 = {
+	.version        = MFC_VERSION_V12,
+	.version_bit    = MFC_V12_BIT,
+	.port_num       = MFC_NUM_PORTS_V12,
+	.buf_size       = &buf_size_v12,
+	.fw_name[0]     = "s5p-mfc-v12.fw",
+	.clk_names	= {"mfc"},
+	.num_clocks	= 1,
+};
+
 static const struct of_device_id exynos_mfc_match[] = {
 	{
 		.compatible = "samsung,mfc-v5",
@@ -1682,6 +1709,9 @@ static const struct of_device_id exynos_mfc_match[] = {
 	}, {
 		.compatible = "samsung,mfc-v10",
 		.data = &mfc_drvdata_v10,
+	}, {
+		.compatible = "tesla,fsd-mfc",
+		.data = &mfc_drvdata_v12,
 	},
 	{},
 };
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
index e6ec4a43b290..dd2e9f7704ab 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
@@ -19,7 +19,7 @@
 #include <media/v4l2-ioctl.h>
 #include <media/videobuf2-v4l2.h>
 #include "regs-mfc.h"
-#include "regs-mfc-v10.h"
+#include "regs-mfc-v12.h"
 
 #define S5P_MFC_NAME		"s5p-mfc"
 
@@ -720,6 +720,8 @@ struct s5p_mfc_ctx {
 	struct v4l2_ctrl *ctrls[MFC_MAX_CTRLS];
 	struct v4l2_ctrl_handler ctrl_handler;
 	size_t scratch_buf_size;
+	int is_10bit;
+	int is_422;
 };
 
 /*
@@ -775,6 +777,7 @@ void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq);
 #define IS_MFCV7_PLUS(dev)	(dev->variant->version >= 0x70)
 #define IS_MFCV8_PLUS(dev)	(dev->variant->version >= 0x80)
 #define IS_MFCV10_PLUS(dev)	(dev->variant->version >= 0xA0)
+#define IS_MFCV12(dev)		(dev->variant->version >= 0xC0)
 #define FW_HAS_E_MIN_SCRATCH_BUF(dev) (IS_MFCV10_PLUS(dev))
 
 #define MFC_V5_BIT	BIT(0)
@@ -782,11 +785,15 @@ void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq);
 #define MFC_V7_BIT	BIT(2)
 #define MFC_V8_BIT	BIT(3)
 #define MFC_V10_BIT	BIT(5)
+#define MFC_V12_BIT	BIT(7)
 
 #define MFC_V5PLUS_BITS		(MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | \
-					MFC_V8_BIT | MFC_V10_BIT)
+					MFC_V8_BIT | MFC_V10_BIT | MFC_V12_BIT)
 #define MFC_V6PLUS_BITS		(MFC_V6_BIT | MFC_V7_BIT | MFC_V8_BIT | \
-					MFC_V10_BIT)
-#define MFC_V7PLUS_BITS		(MFC_V7_BIT | MFC_V8_BIT | MFC_V10_BIT)
+					MFC_V10_BIT | MFC_V12_BIT)
+#define MFC_V7PLUS_BITS		(MFC_V7_BIT | MFC_V8_BIT | MFC_V10_BIT | \
+					MFC_V12_BIT)
+
+#define MFC_V10PLUS_BITS	(MFC_V10_BIT | MFC_V12_BIT)
 
 #endif /* S5P_MFC_COMMON_H_ */
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
index 54b54b2fa9b1..b49159142c53 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
@@ -130,7 +130,7 @@ int s5p_mfc_reset(struct s5p_mfc_dev *dev)
 			mfc_write(dev, 0, S5P_FIMV_REG_CLEAR_BEGIN_V6 + (i*4));
 
 		/* check bus reset control before reset */
-		if (dev->risc_on)
+		if (dev->risc_on && !IS_MFCV12(dev))
 			if (s5p_mfc_bus_reset(dev))
 				return -EIO;
 		/* Reset
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
index 268ffe4da53c..e219cbcd86d5 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
@@ -146,7 +146,7 @@ static struct s5p_mfc_fmt formats[] = {
 		.codec_mode	= S5P_FIMV_CODEC_HEVC_DEC,
 		.type		= MFC_FMT_DEC,
 		.num_planes	= 1,
-		.versions	= MFC_V10_BIT,
+		.versions	= MFC_V10PLUS_BITS,
 		.flags		= V4L2_FMT_FLAG_DYN_RESOLUTION |
 				  V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM,
 	},
@@ -155,7 +155,7 @@ static struct s5p_mfc_fmt formats[] = {
 		.codec_mode	= S5P_FIMV_CODEC_VP9_DEC,
 		.type		= MFC_FMT_DEC,
 		.num_planes	= 1,
-		.versions	= MFC_V10_BIT,
+		.versions	= MFC_V10PLUS_BITS,
 		.flags		= V4L2_FMT_FLAG_DYN_RESOLUTION,
 	},
 };
@@ -355,7 +355,7 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
 		pix_mp->width = ctx->buf_width;
 		pix_mp->height = ctx->buf_height;
 		pix_mp->field = V4L2_FIELD_NONE;
-		pix_mp->num_planes = 2;
+		pix_mp->num_planes = ctx->dst_fmt->num_planes;
 		/* Set pixelformat to the format in which MFC
 		   outputs the decoded frame */
 		pix_mp->pixelformat = ctx->dst_fmt->fourcc;
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
index f62703cebb77..e4d6e7c117b5 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
@@ -92,7 +92,7 @@ static struct s5p_mfc_fmt formats[] = {
 		.codec_mode	= S5P_FIMV_CODEC_HEVC_ENC,
 		.type		= MFC_FMT_ENC,
 		.num_planes	= 1,
-		.versions	= MFC_V10_BIT,
+		.versions	= MFC_V10PLUS_BITS,
 	},
 };
 
@@ -1179,7 +1179,8 @@ static int enc_post_seq_start(struct s5p_mfc_ctx *ctx)
 		if (FW_HAS_E_MIN_SCRATCH_BUF(dev)) {
 			ctx->scratch_buf_size = s5p_mfc_hw_call(dev->mfc_ops,
 					get_e_min_scratch_buf_size, dev);
-			ctx->bank1.size += ctx->scratch_buf_size;
+			if (!IS_MFCV12(dev))
+				ctx->bank1.size += ctx->scratch_buf_size;
 		}
 		ctx->state = MFCINST_HEAD_PRODUCED;
 	}
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
index b9831275f3ab..87ac56756a16 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
@@ -166,9 +166,9 @@ struct s5p_mfc_regs {
 	void __iomem *d_decoded_third_addr;/* only v7 */
 	void __iomem *d_used_dpb_flag_upper;/* v7 and v8 */
 	void __iomem *d_used_dpb_flag_lower;/* v7 and v8 */
-	void __iomem *d_min_scratch_buffer_size; /* v10 */
-	void __iomem *d_static_buffer_addr; /* v10 */
-	void __iomem *d_static_buffer_size; /* v10 */
+	void __iomem *d_min_scratch_buffer_size; /* v10 and v12 */
+	void __iomem *d_static_buffer_addr; /* v10 and v12 */
+	void __iomem *d_static_buffer_size; /* v10 and v12 */
 
 	/* encoder registers */
 	void __iomem *e_frame_width;
@@ -268,7 +268,7 @@ struct s5p_mfc_regs {
 	void __iomem *e_vp8_hierarchical_qp_layer0;/* v7 and v8 */
 	void __iomem *e_vp8_hierarchical_qp_layer1;/* v7 and v8 */
 	void __iomem *e_vp8_hierarchical_qp_layer2;/* v7 and v8 */
-	void __iomem *e_min_scratch_buffer_size; /* v10 */
+	void __iomem *e_min_scratch_buffer_size; /* v10 and v12 */
 	void __iomem *e_num_t_layer; /* v10 */
 	void __iomem *e_hier_qp_layer0; /* v10 */
 	void __iomem *e_hier_bit_rate_layer0; /* v10 */
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
index 882166e4ac50..fb3f0718821d 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
@@ -60,12 +60,14 @@ static void s5p_mfc_release_dec_desc_buffer_v6(struct s5p_mfc_ctx *ctx)
 static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 {
 	struct s5p_mfc_dev *dev = ctx->dev;
-	unsigned int mb_width, mb_height;
+	unsigned int mb_width, mb_height, width64, height32;
 	unsigned int lcu_width = 0, lcu_height = 0;
 	int ret;
 
 	mb_width = MB_WIDTH(ctx->img_width);
 	mb_height = MB_HEIGHT(ctx->img_height);
+	width64 = ALIGN(ctx->img_width, 64);
+	height32 = ALIGN(ctx->img_height, 32);
 
 	if (ctx->type == MFCINST_DECODER) {
 		mfc_debug(2, "Luma size:%d Chroma size:%d MV size:%d\n",
@@ -82,7 +84,44 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 			ctx->tmv_buffer_size = S5P_FIMV_NUM_TMV_BUFFERS_V6 *
 			ALIGN(S5P_FIMV_TMV_BUFFER_SIZE_V6(mb_width, mb_height),
 			S5P_FIMV_TMV_BUFFER_ALIGN_V6);
-		if (IS_MFCV10_PLUS(dev)) {
+		if (IS_MFCV12(dev)) {
+			lcu_width = S5P_MFC_LCU_WIDTH(ctx->img_width);
+			lcu_height = S5P_MFC_LCU_HEIGHT(ctx->img_height);
+			if (ctx->codec_mode == S5P_FIMV_CODEC_HEVC_ENC &&
+								ctx->is_10bit) {
+				ctx->luma_dpb_size =
+					width64 * height32 +
+					ALIGN(DIV_ROUND_UP(lcu_width * 32, 4),
+							16) * height32 + 128;
+				if (ctx->is_422)
+					ctx->chroma_dpb_size =
+						ctx->luma_dpb_size;
+				else
+					ctx->chroma_dpb_size =
+						width64 * height32 / 2 +
+						ALIGN(DIV_ROUND_UP(lcu_width *
+						32, 4), 16) * height32 / 2 + 128;
+			} else if (ctx->codec_mode == S5P_FIMV_CODEC_VP9_ENC &&
+					ctx->is_10bit) {
+				ctx->luma_dpb_size =
+					ALIGN(ctx->img_width * 2, 128) *
+					height32 + 64;
+				ctx->chroma_dpb_size =
+					ALIGN(ctx->img_width * 2, 128) *
+					height32 / 2 + 64;
+			} else {
+				ctx->luma_dpb_size =
+					width64 * height32 + 64;
+				if (ctx->is_422)
+					ctx->chroma_dpb_size =
+						ctx->luma_dpb_size;
+				else
+					ctx->chroma_dpb_size =
+						width64 * height32 / 2 + 64;
+			}
+			ctx->luma_dpb_size = ALIGN(ctx->luma_dpb_size + 256, SZ_2K);
+			ctx->chroma_dpb_size = ALIGN(ctx->chroma_dpb_size + 256, SZ_2K);
+		} else if (IS_MFCV10_PLUS(dev)) {
 			lcu_width = S5P_MFC_LCU_WIDTH(ctx->img_width);
 			lcu_height = S5P_MFC_LCU_HEIGHT(ctx->img_height);
 			if (ctx->codec_mode != S5P_FIMV_CODEC_HEVC_ENC) {
@@ -230,7 +269,11 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 			DEC_VP9_STATIC_BUFFER_SIZE;
 		break;
 	case S5P_MFC_CODEC_H264_ENC:
-		if (IS_MFCV10_PLUS(dev)) {
+		if (IS_MFCV12(dev)) {
+			mfc_debug(2, "Use min scratch buffer size\n");
+			ctx->me_buffer_size =
+				ENC_V120_H264_ME_SIZE(mb_width, mb_height);
+		} else if (IS_MFCV10_PLUS(dev)) {
 			mfc_debug(2, "Use min scratch buffer size\n");
 			ctx->me_buffer_size =
 			ALIGN(ENC_V100_H264_ME_SIZE(mb_width, mb_height), 16);
@@ -254,7 +297,11 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 		break;
 	case S5P_MFC_CODEC_MPEG4_ENC:
 	case S5P_MFC_CODEC_H263_ENC:
-		if (IS_MFCV10_PLUS(dev)) {
+		if (IS_MFCV12(dev)) {
+			mfc_debug(2, "Use min scratch buffer size\n");
+			ctx->me_buffer_size =
+				ENC_V120_MPEG4_ME_SIZE(mb_width, mb_height);
+		} else if (IS_MFCV10_PLUS(dev)) {
 			mfc_debug(2, "Use min scratch buffer size\n");
 			ctx->me_buffer_size =
 				ALIGN(ENC_V100_MPEG4_ME_SIZE(mb_width,
@@ -273,7 +320,11 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 		ctx->bank2.size = 0;
 		break;
 	case S5P_MFC_CODEC_VP8_ENC:
-		if (IS_MFCV10_PLUS(dev)) {
+		if (IS_MFCV12(dev)) {
+			mfc_debug(2, "Use min scratch buffer size\n");
+			ctx->me_buffer_size =
+				ENC_V120_VP8_ME_SIZE(mb_width, mb_height);
+		} else if (IS_MFCV10_PLUS(dev)) {
 			mfc_debug(2, "Use min scratch buffer size\n");
 			ctx->me_buffer_size =
 				ALIGN(ENC_V100_VP8_ME_SIZE(mb_width, mb_height),
@@ -297,9 +348,14 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 		ctx->bank2.size = 0;
 		break;
 	case S5P_MFC_CODEC_HEVC_ENC:
+		if (IS_MFCV12(dev))
+			ctx->me_buffer_size =
+				ENC_V120_HEVC_ME_SIZE(lcu_width, lcu_height);
+		else
+			ctx->me_buffer_size =
+				ALIGN(ENC_V100_HEVC_ME_SIZE(lcu_width,
+							lcu_height), 16);
 		mfc_debug(2, "Use min scratch buffer size\n");
-		ctx->me_buffer_size =
-			ALIGN(ENC_V100_HEVC_ME_SIZE(lcu_width, lcu_height), 16);
 		ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, 256);
 		ctx->bank1.size =
 			ctx->scratch_buf_size + ctx->tmv_buffer_size +
@@ -452,12 +508,15 @@ static void s5p_mfc_dec_calc_dpb_size_v6(struct s5p_mfc_ctx *ctx)
 
 	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
 			ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC) {
-		if (IS_MFCV10_PLUS(dev)) {
-			ctx->mv_size = S5P_MFC_DEC_MV_SIZE_V10(ctx->img_width,
-					ctx->img_height);
+		if (IS_MFCV12(dev)) {
+			ctx->mv_size = S5P_MFC_DEC_MV_SIZE(ctx->img_width,
+					ctx->img_height, 1024);
+		} else if (IS_MFCV10_PLUS(dev)) {
+			ctx->mv_size = S5P_MFC_DEC_MV_SIZE(ctx->img_width,
+					ctx->img_height, 512);
 		} else {
-			ctx->mv_size = S5P_MFC_DEC_MV_SIZE_V6(ctx->img_width,
-					ctx->img_height);
+			ctx->mv_size = S5P_MFC_DEC_MV_SIZE(ctx->img_width,
+					ctx->img_height, 128);
 		}
 	} else if (ctx->codec_mode == S5P_MFC_CODEC_HEVC_DEC) {
 		ctx->mv_size = s5p_mfc_dec_hevc_mv_size(ctx->img_width,
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
index e4dd03c5454c..30269f3e68e8 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
@@ -19,10 +19,8 @@
 
 #define MB_WIDTH(x_size)		DIV_ROUND_UP(x_size, 16)
 #define MB_HEIGHT(y_size)		DIV_ROUND_UP(y_size, 16)
-#define S5P_MFC_DEC_MV_SIZE_V6(x, y)	(MB_WIDTH(x) * \
-					(((MB_HEIGHT(y)+1)/2)*2) * 64 + 128)
-#define S5P_MFC_DEC_MV_SIZE_V10(x, y)	(MB_WIDTH(x) * \
-					(((MB_HEIGHT(y)+1)/2)*2) * 64 + 512)
+#define S5P_MFC_DEC_MV_SIZE(x, y, offset)	(MB_WIDTH(x) * \
+					(((MB_HEIGHT(y)+1)/2)*2) * 64 + offset)
 #define S5P_MFC_LCU_WIDTH(x_size)	DIV_ROUND_UP(x_size, 32)
 #define S5P_MFC_LCU_HEIGHT(y_size)	DIV_ROUND_UP(y_size, 32)
 
-- 
2.17.1


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

* [Patch v4 03/11] media: s5p-mfc: Add initial support for MFCv12
@ 2023-10-25 10:22       ` Aakarsh Jain
  0 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-10-25 10:22 UTC (permalink / raw)
  To: linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	aakarsh.jain, linux-fsd, Smitha T Murthy

Add support for MFCv12, with a new register file and necessary hw
control, decoder, encoder and structural changes. Add luma dbp, chroma
dpb and mv sizes for each codec as per the UM for MFCv12, along with
appropriate alignment.

Cc: linux-fsd@tesla.com
Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
---
 .../platform/samsung/s5p-mfc/regs-mfc-v12.h   | 50 +++++++++++
 .../media/platform/samsung/s5p-mfc/s5p_mfc.c  | 30 +++++++
 .../platform/samsung/s5p-mfc/s5p_mfc_common.h | 15 +++-
 .../platform/samsung/s5p-mfc/s5p_mfc_ctrl.c   |  2 +-
 .../platform/samsung/s5p-mfc/s5p_mfc_dec.c    |  6 +-
 .../platform/samsung/s5p-mfc/s5p_mfc_enc.c    |  5 +-
 .../platform/samsung/s5p-mfc/s5p_mfc_opr.h    |  8 +-
 .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 83 ++++++++++++++++---
 .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h |  6 +-
 9 files changed, 175 insertions(+), 30 deletions(-)
 create mode 100644 drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h

diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
new file mode 100644
index 000000000000..6c68a45082d0
--- /dev/null
+++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Register definition file for Samsung MFC V12.x Interface (FIMV) driver
+ *
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *     http://www.samsung.com/
+ */
+
+#ifndef _REGS_MFC_V12_H
+#define _REGS_MFC_V12_H
+
+#include <linux/sizes.h>
+#include "regs-mfc-v10.h"
+
+/* MFCv12 Context buffer sizes */
+#define MFC_CTX_BUF_SIZE_V12		(30 * SZ_1K)
+#define MFC_H264_DEC_CTX_BUF_SIZE_V12	(2 * SZ_1M)
+#define MFC_OTHER_DEC_CTX_BUF_SIZE_V12	(30 * SZ_1K)
+#define MFC_H264_ENC_CTX_BUF_SIZE_V12	(100 * SZ_1K)
+#define MFC_HEVC_ENC_CTX_BUF_SIZE_V12	(40 * SZ_1K)
+#define MFC_OTHER_ENC_CTX_BUF_SIZE_V12	(25 * SZ_1K)
+
+/* MFCv12 variant defines */
+#define MAX_FW_SIZE_V12			(SZ_1M)
+#define MAX_CPB_SIZE_V12		(7 * SZ_1M)
+#define MFC_VERSION_V12			0xC0
+#define MFC_NUM_PORTS_V12		1
+#define S5P_FIMV_CODEC_VP9_ENC		27
+
+/* Encoder buffer size for MFCv12 */
+#define ENC_V120_BASE_SIZE(x, y) \
+	(((x + 3) * (y + 3) * 8) \
+	+ (((y * 64) + 2304) * (x + 7) / 8))
+
+#define ENC_V120_H264_ME_SIZE(x, y) \
+	ALIGN((ENC_V120_BASE_SIZE(x, y) \
+	+ (DIV_ROUND_UP(x * y, 64) * 32)), 256)
+
+#define ENC_V120_MPEG4_ME_SIZE(x, y) \
+	ALIGN((ENC_V120_BASE_SIZE(x, y) \
+	+ (DIV_ROUND_UP(x * y, 128) * 16)), 256)
+
+#define ENC_V120_VP8_ME_SIZE(x, y) \
+	ALIGN(ENC_V120_BASE_SIZE(x, y), 256)
+
+#define ENC_V120_HEVC_ME_SIZE(x, y)     \
+	ALIGN((((x + 3) * (y + 3) * 32)       \
+	+ (((y * 128) + 2304) * (x + 3) / 4)), 256)
+
+#endif /*_REGS_MFC_V12_H*/
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
index e30e54935d79..dee9ef017997 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
@@ -790,6 +790,8 @@ static int s5p_mfc_open(struct file *file)
 	INIT_LIST_HEAD(&ctx->dst_queue);
 	ctx->src_queue_cnt = 0;
 	ctx->dst_queue_cnt = 0;
+	ctx->is_422 = 0;
+	ctx->is_10bit = 0;
 	/* Get context number */
 	ctx->num = 0;
 	while (dev->ctx[ctx->num]) {
@@ -1660,6 +1662,31 @@ static struct s5p_mfc_variant mfc_drvdata_v10 = {
 	.fw_name[0]     = "s5p-mfc-v10.fw",
 };
 
+static struct s5p_mfc_buf_size_v6 mfc_buf_size_v12 = {
+	.dev_ctx        = MFC_CTX_BUF_SIZE_V12,
+	.h264_dec_ctx   = MFC_H264_DEC_CTX_BUF_SIZE_V12,
+	.other_dec_ctx  = MFC_OTHER_DEC_CTX_BUF_SIZE_V12,
+	.h264_enc_ctx   = MFC_H264_ENC_CTX_BUF_SIZE_V12,
+	.hevc_enc_ctx   = MFC_HEVC_ENC_CTX_BUF_SIZE_V12,
+	.other_enc_ctx  = MFC_OTHER_ENC_CTX_BUF_SIZE_V12,
+};
+
+static struct s5p_mfc_buf_size buf_size_v12 = {
+	.fw     = MAX_FW_SIZE_V12,
+	.cpb    = MAX_CPB_SIZE_V12,
+	.priv   = &mfc_buf_size_v12,
+};
+
+static struct s5p_mfc_variant mfc_drvdata_v12 = {
+	.version        = MFC_VERSION_V12,
+	.version_bit    = MFC_V12_BIT,
+	.port_num       = MFC_NUM_PORTS_V12,
+	.buf_size       = &buf_size_v12,
+	.fw_name[0]     = "s5p-mfc-v12.fw",
+	.clk_names	= {"mfc"},
+	.num_clocks	= 1,
+};
+
 static const struct of_device_id exynos_mfc_match[] = {
 	{
 		.compatible = "samsung,mfc-v5",
@@ -1682,6 +1709,9 @@ static const struct of_device_id exynos_mfc_match[] = {
 	}, {
 		.compatible = "samsung,mfc-v10",
 		.data = &mfc_drvdata_v10,
+	}, {
+		.compatible = "tesla,fsd-mfc",
+		.data = &mfc_drvdata_v12,
 	},
 	{},
 };
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
index e6ec4a43b290..dd2e9f7704ab 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
@@ -19,7 +19,7 @@
 #include <media/v4l2-ioctl.h>
 #include <media/videobuf2-v4l2.h>
 #include "regs-mfc.h"
-#include "regs-mfc-v10.h"
+#include "regs-mfc-v12.h"
 
 #define S5P_MFC_NAME		"s5p-mfc"
 
@@ -720,6 +720,8 @@ struct s5p_mfc_ctx {
 	struct v4l2_ctrl *ctrls[MFC_MAX_CTRLS];
 	struct v4l2_ctrl_handler ctrl_handler;
 	size_t scratch_buf_size;
+	int is_10bit;
+	int is_422;
 };
 
 /*
@@ -775,6 +777,7 @@ void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq);
 #define IS_MFCV7_PLUS(dev)	(dev->variant->version >= 0x70)
 #define IS_MFCV8_PLUS(dev)	(dev->variant->version >= 0x80)
 #define IS_MFCV10_PLUS(dev)	(dev->variant->version >= 0xA0)
+#define IS_MFCV12(dev)		(dev->variant->version >= 0xC0)
 #define FW_HAS_E_MIN_SCRATCH_BUF(dev) (IS_MFCV10_PLUS(dev))
 
 #define MFC_V5_BIT	BIT(0)
@@ -782,11 +785,15 @@ void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq);
 #define MFC_V7_BIT	BIT(2)
 #define MFC_V8_BIT	BIT(3)
 #define MFC_V10_BIT	BIT(5)
+#define MFC_V12_BIT	BIT(7)
 
 #define MFC_V5PLUS_BITS		(MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | \
-					MFC_V8_BIT | MFC_V10_BIT)
+					MFC_V8_BIT | MFC_V10_BIT | MFC_V12_BIT)
 #define MFC_V6PLUS_BITS		(MFC_V6_BIT | MFC_V7_BIT | MFC_V8_BIT | \
-					MFC_V10_BIT)
-#define MFC_V7PLUS_BITS		(MFC_V7_BIT | MFC_V8_BIT | MFC_V10_BIT)
+					MFC_V10_BIT | MFC_V12_BIT)
+#define MFC_V7PLUS_BITS		(MFC_V7_BIT | MFC_V8_BIT | MFC_V10_BIT | \
+					MFC_V12_BIT)
+
+#define MFC_V10PLUS_BITS	(MFC_V10_BIT | MFC_V12_BIT)
 
 #endif /* S5P_MFC_COMMON_H_ */
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
index 54b54b2fa9b1..b49159142c53 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
@@ -130,7 +130,7 @@ int s5p_mfc_reset(struct s5p_mfc_dev *dev)
 			mfc_write(dev, 0, S5P_FIMV_REG_CLEAR_BEGIN_V6 + (i*4));
 
 		/* check bus reset control before reset */
-		if (dev->risc_on)
+		if (dev->risc_on && !IS_MFCV12(dev))
 			if (s5p_mfc_bus_reset(dev))
 				return -EIO;
 		/* Reset
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
index 268ffe4da53c..e219cbcd86d5 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
@@ -146,7 +146,7 @@ static struct s5p_mfc_fmt formats[] = {
 		.codec_mode	= S5P_FIMV_CODEC_HEVC_DEC,
 		.type		= MFC_FMT_DEC,
 		.num_planes	= 1,
-		.versions	= MFC_V10_BIT,
+		.versions	= MFC_V10PLUS_BITS,
 		.flags		= V4L2_FMT_FLAG_DYN_RESOLUTION |
 				  V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM,
 	},
@@ -155,7 +155,7 @@ static struct s5p_mfc_fmt formats[] = {
 		.codec_mode	= S5P_FIMV_CODEC_VP9_DEC,
 		.type		= MFC_FMT_DEC,
 		.num_planes	= 1,
-		.versions	= MFC_V10_BIT,
+		.versions	= MFC_V10PLUS_BITS,
 		.flags		= V4L2_FMT_FLAG_DYN_RESOLUTION,
 	},
 };
@@ -355,7 +355,7 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
 		pix_mp->width = ctx->buf_width;
 		pix_mp->height = ctx->buf_height;
 		pix_mp->field = V4L2_FIELD_NONE;
-		pix_mp->num_planes = 2;
+		pix_mp->num_planes = ctx->dst_fmt->num_planes;
 		/* Set pixelformat to the format in which MFC
 		   outputs the decoded frame */
 		pix_mp->pixelformat = ctx->dst_fmt->fourcc;
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
index f62703cebb77..e4d6e7c117b5 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
@@ -92,7 +92,7 @@ static struct s5p_mfc_fmt formats[] = {
 		.codec_mode	= S5P_FIMV_CODEC_HEVC_ENC,
 		.type		= MFC_FMT_ENC,
 		.num_planes	= 1,
-		.versions	= MFC_V10_BIT,
+		.versions	= MFC_V10PLUS_BITS,
 	},
 };
 
@@ -1179,7 +1179,8 @@ static int enc_post_seq_start(struct s5p_mfc_ctx *ctx)
 		if (FW_HAS_E_MIN_SCRATCH_BUF(dev)) {
 			ctx->scratch_buf_size = s5p_mfc_hw_call(dev->mfc_ops,
 					get_e_min_scratch_buf_size, dev);
-			ctx->bank1.size += ctx->scratch_buf_size;
+			if (!IS_MFCV12(dev))
+				ctx->bank1.size += ctx->scratch_buf_size;
 		}
 		ctx->state = MFCINST_HEAD_PRODUCED;
 	}
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
index b9831275f3ab..87ac56756a16 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
@@ -166,9 +166,9 @@ struct s5p_mfc_regs {
 	void __iomem *d_decoded_third_addr;/* only v7 */
 	void __iomem *d_used_dpb_flag_upper;/* v7 and v8 */
 	void __iomem *d_used_dpb_flag_lower;/* v7 and v8 */
-	void __iomem *d_min_scratch_buffer_size; /* v10 */
-	void __iomem *d_static_buffer_addr; /* v10 */
-	void __iomem *d_static_buffer_size; /* v10 */
+	void __iomem *d_min_scratch_buffer_size; /* v10 and v12 */
+	void __iomem *d_static_buffer_addr; /* v10 and v12 */
+	void __iomem *d_static_buffer_size; /* v10 and v12 */
 
 	/* encoder registers */
 	void __iomem *e_frame_width;
@@ -268,7 +268,7 @@ struct s5p_mfc_regs {
 	void __iomem *e_vp8_hierarchical_qp_layer0;/* v7 and v8 */
 	void __iomem *e_vp8_hierarchical_qp_layer1;/* v7 and v8 */
 	void __iomem *e_vp8_hierarchical_qp_layer2;/* v7 and v8 */
-	void __iomem *e_min_scratch_buffer_size; /* v10 */
+	void __iomem *e_min_scratch_buffer_size; /* v10 and v12 */
 	void __iomem *e_num_t_layer; /* v10 */
 	void __iomem *e_hier_qp_layer0; /* v10 */
 	void __iomem *e_hier_bit_rate_layer0; /* v10 */
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
index 882166e4ac50..fb3f0718821d 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
@@ -60,12 +60,14 @@ static void s5p_mfc_release_dec_desc_buffer_v6(struct s5p_mfc_ctx *ctx)
 static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 {
 	struct s5p_mfc_dev *dev = ctx->dev;
-	unsigned int mb_width, mb_height;
+	unsigned int mb_width, mb_height, width64, height32;
 	unsigned int lcu_width = 0, lcu_height = 0;
 	int ret;
 
 	mb_width = MB_WIDTH(ctx->img_width);
 	mb_height = MB_HEIGHT(ctx->img_height);
+	width64 = ALIGN(ctx->img_width, 64);
+	height32 = ALIGN(ctx->img_height, 32);
 
 	if (ctx->type == MFCINST_DECODER) {
 		mfc_debug(2, "Luma size:%d Chroma size:%d MV size:%d\n",
@@ -82,7 +84,44 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 			ctx->tmv_buffer_size = S5P_FIMV_NUM_TMV_BUFFERS_V6 *
 			ALIGN(S5P_FIMV_TMV_BUFFER_SIZE_V6(mb_width, mb_height),
 			S5P_FIMV_TMV_BUFFER_ALIGN_V6);
-		if (IS_MFCV10_PLUS(dev)) {
+		if (IS_MFCV12(dev)) {
+			lcu_width = S5P_MFC_LCU_WIDTH(ctx->img_width);
+			lcu_height = S5P_MFC_LCU_HEIGHT(ctx->img_height);
+			if (ctx->codec_mode == S5P_FIMV_CODEC_HEVC_ENC &&
+								ctx->is_10bit) {
+				ctx->luma_dpb_size =
+					width64 * height32 +
+					ALIGN(DIV_ROUND_UP(lcu_width * 32, 4),
+							16) * height32 + 128;
+				if (ctx->is_422)
+					ctx->chroma_dpb_size =
+						ctx->luma_dpb_size;
+				else
+					ctx->chroma_dpb_size =
+						width64 * height32 / 2 +
+						ALIGN(DIV_ROUND_UP(lcu_width *
+						32, 4), 16) * height32 / 2 + 128;
+			} else if (ctx->codec_mode == S5P_FIMV_CODEC_VP9_ENC &&
+					ctx->is_10bit) {
+				ctx->luma_dpb_size =
+					ALIGN(ctx->img_width * 2, 128) *
+					height32 + 64;
+				ctx->chroma_dpb_size =
+					ALIGN(ctx->img_width * 2, 128) *
+					height32 / 2 + 64;
+			} else {
+				ctx->luma_dpb_size =
+					width64 * height32 + 64;
+				if (ctx->is_422)
+					ctx->chroma_dpb_size =
+						ctx->luma_dpb_size;
+				else
+					ctx->chroma_dpb_size =
+						width64 * height32 / 2 + 64;
+			}
+			ctx->luma_dpb_size = ALIGN(ctx->luma_dpb_size + 256, SZ_2K);
+			ctx->chroma_dpb_size = ALIGN(ctx->chroma_dpb_size + 256, SZ_2K);
+		} else if (IS_MFCV10_PLUS(dev)) {
 			lcu_width = S5P_MFC_LCU_WIDTH(ctx->img_width);
 			lcu_height = S5P_MFC_LCU_HEIGHT(ctx->img_height);
 			if (ctx->codec_mode != S5P_FIMV_CODEC_HEVC_ENC) {
@@ -230,7 +269,11 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 			DEC_VP9_STATIC_BUFFER_SIZE;
 		break;
 	case S5P_MFC_CODEC_H264_ENC:
-		if (IS_MFCV10_PLUS(dev)) {
+		if (IS_MFCV12(dev)) {
+			mfc_debug(2, "Use min scratch buffer size\n");
+			ctx->me_buffer_size =
+				ENC_V120_H264_ME_SIZE(mb_width, mb_height);
+		} else if (IS_MFCV10_PLUS(dev)) {
 			mfc_debug(2, "Use min scratch buffer size\n");
 			ctx->me_buffer_size =
 			ALIGN(ENC_V100_H264_ME_SIZE(mb_width, mb_height), 16);
@@ -254,7 +297,11 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 		break;
 	case S5P_MFC_CODEC_MPEG4_ENC:
 	case S5P_MFC_CODEC_H263_ENC:
-		if (IS_MFCV10_PLUS(dev)) {
+		if (IS_MFCV12(dev)) {
+			mfc_debug(2, "Use min scratch buffer size\n");
+			ctx->me_buffer_size =
+				ENC_V120_MPEG4_ME_SIZE(mb_width, mb_height);
+		} else if (IS_MFCV10_PLUS(dev)) {
 			mfc_debug(2, "Use min scratch buffer size\n");
 			ctx->me_buffer_size =
 				ALIGN(ENC_V100_MPEG4_ME_SIZE(mb_width,
@@ -273,7 +320,11 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 		ctx->bank2.size = 0;
 		break;
 	case S5P_MFC_CODEC_VP8_ENC:
-		if (IS_MFCV10_PLUS(dev)) {
+		if (IS_MFCV12(dev)) {
+			mfc_debug(2, "Use min scratch buffer size\n");
+			ctx->me_buffer_size =
+				ENC_V120_VP8_ME_SIZE(mb_width, mb_height);
+		} else if (IS_MFCV10_PLUS(dev)) {
 			mfc_debug(2, "Use min scratch buffer size\n");
 			ctx->me_buffer_size =
 				ALIGN(ENC_V100_VP8_ME_SIZE(mb_width, mb_height),
@@ -297,9 +348,14 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
 		ctx->bank2.size = 0;
 		break;
 	case S5P_MFC_CODEC_HEVC_ENC:
+		if (IS_MFCV12(dev))
+			ctx->me_buffer_size =
+				ENC_V120_HEVC_ME_SIZE(lcu_width, lcu_height);
+		else
+			ctx->me_buffer_size =
+				ALIGN(ENC_V100_HEVC_ME_SIZE(lcu_width,
+							lcu_height), 16);
 		mfc_debug(2, "Use min scratch buffer size\n");
-		ctx->me_buffer_size =
-			ALIGN(ENC_V100_HEVC_ME_SIZE(lcu_width, lcu_height), 16);
 		ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, 256);
 		ctx->bank1.size =
 			ctx->scratch_buf_size + ctx->tmv_buffer_size +
@@ -452,12 +508,15 @@ static void s5p_mfc_dec_calc_dpb_size_v6(struct s5p_mfc_ctx *ctx)
 
 	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
 			ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC) {
-		if (IS_MFCV10_PLUS(dev)) {
-			ctx->mv_size = S5P_MFC_DEC_MV_SIZE_V10(ctx->img_width,
-					ctx->img_height);
+		if (IS_MFCV12(dev)) {
+			ctx->mv_size = S5P_MFC_DEC_MV_SIZE(ctx->img_width,
+					ctx->img_height, 1024);
+		} else if (IS_MFCV10_PLUS(dev)) {
+			ctx->mv_size = S5P_MFC_DEC_MV_SIZE(ctx->img_width,
+					ctx->img_height, 512);
 		} else {
-			ctx->mv_size = S5P_MFC_DEC_MV_SIZE_V6(ctx->img_width,
-					ctx->img_height);
+			ctx->mv_size = S5P_MFC_DEC_MV_SIZE(ctx->img_width,
+					ctx->img_height, 128);
 		}
 	} else if (ctx->codec_mode == S5P_MFC_CODEC_HEVC_DEC) {
 		ctx->mv_size = s5p_mfc_dec_hevc_mv_size(ctx->img_width,
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
index e4dd03c5454c..30269f3e68e8 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
@@ -19,10 +19,8 @@
 
 #define MB_WIDTH(x_size)		DIV_ROUND_UP(x_size, 16)
 #define MB_HEIGHT(y_size)		DIV_ROUND_UP(y_size, 16)
-#define S5P_MFC_DEC_MV_SIZE_V6(x, y)	(MB_WIDTH(x) * \
-					(((MB_HEIGHT(y)+1)/2)*2) * 64 + 128)
-#define S5P_MFC_DEC_MV_SIZE_V10(x, y)	(MB_WIDTH(x) * \
-					(((MB_HEIGHT(y)+1)/2)*2) * 64 + 512)
+#define S5P_MFC_DEC_MV_SIZE(x, y, offset)	(MB_WIDTH(x) * \
+					(((MB_HEIGHT(y)+1)/2)*2) * 64 + offset)
 #define S5P_MFC_LCU_WIDTH(x_size)	DIV_ROUND_UP(x_size, 32)
 #define S5P_MFC_LCU_HEIGHT(y_size)	DIV_ROUND_UP(y_size, 32)
 
-- 
2.17.1


_______________________________________________
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] 54+ messages in thread

* [Patch v4 04/11] media: s5p-mfc: Add YV12 and I420 multiplanar format support
       [not found]   ` <CGME20231025102243epcas5p1cdd0eb385d2381943d6d194eec3a569d@epcas5p1.samsung.com>
@ 2023-10-25 10:22       ` Aakarsh Jain
  0 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-10-25 10:22 UTC (permalink / raw)
  To: linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	aakarsh.jain, linux-fsd, Smitha T Murthy

YV12 and I420 format (3-plane) support is added. Stride information is
added to all formats and planes since it is necessary for YV12/I420
which are different from width.

Cc: linux-fsd@tesla.com
Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
---
 .../platform/samsung/s5p-mfc/regs-mfc-v12.h   |   2 +
 .../platform/samsung/s5p-mfc/regs-mfc-v7.h    |   1 +
 .../platform/samsung/s5p-mfc/regs-mfc-v8.h    |   3 +
 .../platform/samsung/s5p-mfc/s5p_mfc_common.h |   4 +
 .../platform/samsung/s5p-mfc/s5p_mfc_dec.c    |  45 ++++-
 .../platform/samsung/s5p-mfc/s5p_mfc_enc.c    |  86 +++++++--
 .../platform/samsung/s5p-mfc/s5p_mfc_opr.h    |   6 +-
 .../platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c |  12 +-
 .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 168 +++++++++++++++---
 9 files changed, 281 insertions(+), 46 deletions(-)

diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
index 6c68a45082d0..70464f47c1f9 100644
--- a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
+++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
@@ -26,6 +26,8 @@
 #define MFC_VERSION_V12			0xC0
 #define MFC_NUM_PORTS_V12		1
 #define S5P_FIMV_CODEC_VP9_ENC		27
+#define MFC_CHROMA_PAD_BYTES_V12        256
+#define S5P_FIMV_D_ALIGN_PLANE_SIZE_V12 256
 
 /* Encoder buffer size for MFCv12 */
 #define ENC_V120_BASE_SIZE(x, y) \
diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
index 4a7adfdaa359..50f9bf0603c1 100644
--- a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
+++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
@@ -24,6 +24,7 @@
 
 #define S5P_FIMV_E_ENCODED_SOURCE_FIRST_ADDR_V7		0xfa70
 #define S5P_FIMV_E_ENCODED_SOURCE_SECOND_ADDR_V7	0xfa74
+#define S5P_FIMV_E_ENCODED_SOURCE_THIRD_ADDR_V7		0xfa78
 
 #define S5P_FIMV_E_VP8_OPTIONS_V7			0xfdb0
 #define S5P_FIMV_E_VP8_FILTER_OPTIONS_V7		0xfdb4
diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
index 162e3c7e920f..0ef9eb2dff22 100644
--- a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
+++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
@@ -17,13 +17,16 @@
 #define S5P_FIMV_D_MIN_SCRATCH_BUFFER_SIZE_V8	0xf108
 #define S5P_FIMV_D_FIRST_PLANE_DPB_SIZE_V8	0xf144
 #define S5P_FIMV_D_SECOND_PLANE_DPB_SIZE_V8	0xf148
+#define S5P_FIMV_D_THIRD_PLANE_DPB_SIZE_V8	0xf14C
 #define S5P_FIMV_D_MV_BUFFER_SIZE_V8		0xf150
 
 #define S5P_FIMV_D_FIRST_PLANE_DPB_STRIDE_SIZE_V8	0xf138
 #define S5P_FIMV_D_SECOND_PLANE_DPB_STRIDE_SIZE_V8	0xf13c
+#define S5P_FIMV_D_THIRD_PLANE_DPB_STRIDE_SIZE_V8	0xf140
 
 #define S5P_FIMV_D_FIRST_PLANE_DPB_V8		0xf160
 #define S5P_FIMV_D_SECOND_PLANE_DPB_V8		0xf260
+#define S5P_FIMV_D_THIRD_PLANE_DPB_V8		0xf360
 #define S5P_FIMV_D_MV_BUFFER_V8			0xf460
 
 #define S5P_FIMV_D_NUM_MV_V8			0xf134
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
index dd2e9f7704ab..9a39cccfe002 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
@@ -56,6 +56,7 @@
 #define MFC_NO_INSTANCE_SET	-1
 #define MFC_ENC_CAP_PLANE_COUNT	1
 #define MFC_ENC_OUT_PLANE_COUNT	2
+#define VB2_MAX_PLANE_COUNT	3
 #define STUFF_BYTE		4
 #define MFC_MAX_CTRLS		128
 
@@ -181,6 +182,7 @@ struct s5p_mfc_buf {
 		struct {
 			size_t luma;
 			size_t chroma;
+			size_t chroma_1;
 		} raw;
 		size_t stream;
 	} cookie;
@@ -657,6 +659,7 @@ struct s5p_mfc_ctx {
 
 	int luma_size;
 	int chroma_size;
+	int chroma_size_1;
 	int mv_size;
 
 	unsigned long consumed_stream;
@@ -722,6 +725,7 @@ struct s5p_mfc_ctx {
 	size_t scratch_buf_size;
 	int is_10bit;
 	int is_422;
+	int stride[VB2_MAX_PLANE_COUNT];
 };
 
 /*
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
index e219cbcd86d5..317f796fffa1 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
@@ -56,6 +56,20 @@ static struct s5p_mfc_fmt formats[] = {
 		.num_planes	= 2,
 		.versions	= MFC_V6PLUS_BITS,
 	},
+	{
+		.fourcc         = V4L2_PIX_FMT_YUV420M,
+		.codec_mode     = S5P_MFC_CODEC_NONE,
+		.type           = MFC_FMT_RAW,
+		.num_planes     = 3,
+		.versions       = MFC_V12_BIT,
+	},
+	{
+		.fourcc         = V4L2_PIX_FMT_YVU420M,
+		.codec_mode     = S5P_MFC_CODEC_NONE,
+		.type           = MFC_FMT_RAW,
+		.num_planes     = 3,
+		.versions       = MFC_V12_BIT
+	},
 	{
 		.fourcc		= V4L2_PIX_FMT_H264,
 		.codec_mode	= S5P_MFC_CODEC_H264_DEC,
@@ -359,10 +373,15 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
 		/* Set pixelformat to the format in which MFC
 		   outputs the decoded frame */
 		pix_mp->pixelformat = ctx->dst_fmt->fourcc;
-		pix_mp->plane_fmt[0].bytesperline = ctx->buf_width;
+		pix_mp->plane_fmt[0].bytesperline = ctx->stride[0];
 		pix_mp->plane_fmt[0].sizeimage = ctx->luma_size;
-		pix_mp->plane_fmt[1].bytesperline = ctx->buf_width;
+		pix_mp->plane_fmt[1].bytesperline = ctx->stride[1];
 		pix_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
+		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
+			pix_mp->plane_fmt[2].bytesperline = ctx->stride[2];
+			pix_mp->plane_fmt[2].sizeimage = ctx->chroma_size_1;
+		}
 	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
 		/* This is run on OUTPUT
 		   The buffer contains compressed image
@@ -937,6 +956,9 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
 		   vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
 		/* Output plane count is 2 - one for Y and one for CbCr */
 		*plane_count = 2;
+		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
+			*plane_count = 3;
 		/* Setup buffer count */
 		if (*buf_count < ctx->pb_count)
 			*buf_count = ctx->pb_count;
@@ -955,12 +977,17 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
 	    vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
 		psize[0] = ctx->luma_size;
 		psize[1] = ctx->chroma_size;
-
+		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
+			psize[2] = ctx->chroma_size_1;
 		if (IS_MFCV6_PLUS(dev))
 			alloc_devs[0] = ctx->dev->mem_dev[BANK_L_CTX];
 		else
 			alloc_devs[0] = ctx->dev->mem_dev[BANK_R_CTX];
 		alloc_devs[1] = ctx->dev->mem_dev[BANK_L_CTX];
+		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
+			alloc_devs[2] = ctx->dev->mem_dev[BANK_L_CTX];
 	} else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
 		   ctx->state == MFCINST_INIT) {
 		psize[0] = ctx->dec_src_buf_size;
@@ -994,12 +1021,24 @@ static int s5p_mfc_buf_init(struct vb2_buffer *vb)
 			mfc_err("Plane buffer (CAPTURE) is too small\n");
 			return -EINVAL;
 		}
+		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
+			if (vb2_plane_size(vb, 2) < ctx->chroma_size_1) {
+				mfc_err("Plane buffer (CAPTURE) is too small\n");
+				return -EINVAL;
+			}
+		}
 		i = vb->index;
 		ctx->dst_bufs[i].b = vbuf;
 		ctx->dst_bufs[i].cookie.raw.luma =
 					vb2_dma_contig_plane_dma_addr(vb, 0);
 		ctx->dst_bufs[i].cookie.raw.chroma =
 					vb2_dma_contig_plane_dma_addr(vb, 1);
+		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
+			ctx->dst_bufs[i].cookie.raw.chroma_1 =
+					vb2_dma_contig_plane_dma_addr(vb, 2);
+		}
 		ctx->dst_bufs_cnt++;
 	} else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
 		if (IS_ERR_OR_NULL(ERR_PTR(
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
index e4d6e7c117b5..0eec04eb3ef3 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
@@ -59,6 +59,20 @@ static struct s5p_mfc_fmt formats[] = {
 		.num_planes	= 2,
 		.versions	= MFC_V6PLUS_BITS,
 	},
+	{
+		.fourcc         = V4L2_PIX_FMT_YUV420M,
+		.codec_mode     = S5P_MFC_CODEC_NONE,
+		.type           = MFC_FMT_RAW,
+		.num_planes     = 3,
+		.versions       = MFC_V12_BIT,
+	},
+	{
+		.fourcc         = V4L2_PIX_FMT_YVU420M,
+		.codec_mode     = S5P_MFC_CODEC_NONE,
+		.type           = MFC_FMT_RAW,
+		.num_planes     = 3,
+		.versions       = MFC_V12_BIT,
+	},
 	{
 		.fourcc		= V4L2_PIX_FMT_H264,
 		.codec_mode	= S5P_MFC_CODEC_H264_ENC,
@@ -1193,14 +1207,20 @@ static int enc_pre_frame_start(struct s5p_mfc_ctx *ctx)
 	struct s5p_mfc_dev *dev = ctx->dev;
 	struct s5p_mfc_buf *dst_mb;
 	struct s5p_mfc_buf *src_mb;
-	unsigned long src_y_addr, src_c_addr, dst_addr;
+	unsigned long src_y_addr, src_c_addr, src_c_1_addr, dst_addr;
 	unsigned int dst_size;
 
 	src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
 	src_y_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 0);
 	src_c_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 1);
+	if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+			ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
+		src_c_1_addr =
+			vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 2);
+	else
+		src_c_1_addr = 0;
 	s5p_mfc_hw_call(dev->mfc_ops, set_enc_frame_buffer, ctx,
-							src_y_addr, src_c_addr);
+					src_y_addr, src_c_addr, src_c_1_addr);
 
 	dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
 	dst_addr = vb2_dma_contig_plane_dma_addr(&dst_mb->b->vb2_buf, 0);
@@ -1215,8 +1235,8 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
 {
 	struct s5p_mfc_dev *dev = ctx->dev;
 	struct s5p_mfc_buf *mb_entry;
-	unsigned long enc_y_addr = 0, enc_c_addr = 0;
-	unsigned long mb_y_addr, mb_c_addr;
+	unsigned long enc_y_addr = 0, enc_c_addr = 0, enc_c_1_addr = 0;
+	unsigned long mb_y_addr, mb_c_addr, mb_c_1_addr;
 	int slice_type;
 	unsigned int strm_size;
 	bool src_ready;
@@ -1229,14 +1249,21 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
 		  mfc_read(dev, S5P_FIMV_ENC_SI_PIC_CNT));
 	if (slice_type >= 0) {
 		s5p_mfc_hw_call(dev->mfc_ops, get_enc_frame_buffer, ctx,
-				&enc_y_addr, &enc_c_addr);
+				&enc_y_addr, &enc_c_addr, &enc_c_1_addr);
 		list_for_each_entry(mb_entry, &ctx->src_queue, list) {
 			mb_y_addr = vb2_dma_contig_plane_dma_addr(
 					&mb_entry->b->vb2_buf, 0);
 			mb_c_addr = vb2_dma_contig_plane_dma_addr(
 					&mb_entry->b->vb2_buf, 1);
-			if ((enc_y_addr == mb_y_addr) &&
-						(enc_c_addr == mb_c_addr)) {
+			if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
+				mb_c_1_addr = vb2_dma_contig_plane_dma_addr
+						(&mb_entry->b->vb2_buf, 2);
+			else
+				mb_c_1_addr = 0;
+			if ((enc_y_addr == mb_y_addr)
+					&& (enc_c_addr == mb_c_addr)
+					&& (enc_c_1_addr == mb_c_1_addr)) {
 				list_del(&mb_entry->list);
 				ctx->src_queue_cnt--;
 				vb2_buffer_done(&mb_entry->b->vb2_buf,
@@ -1249,8 +1276,15 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
 					&mb_entry->b->vb2_buf, 0);
 			mb_c_addr = vb2_dma_contig_plane_dma_addr(
 					&mb_entry->b->vb2_buf, 1);
-			if ((enc_y_addr == mb_y_addr) &&
-						(enc_c_addr == mb_c_addr)) {
+			if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
+				mb_c_1_addr = vb2_dma_contig_plane_dma_addr(
+						&mb_entry->b->vb2_buf, 2);
+			else
+				mb_c_1_addr = 0;
+			if ((enc_y_addr == mb_y_addr)
+					&& (enc_c_addr == mb_c_addr)
+					&& (enc_c_1_addr == mb_c_1_addr)) {
 				list_del(&mb_entry->list);
 				ctx->ref_queue_cnt--;
 				vb2_buffer_done(&mb_entry->b->vb2_buf,
@@ -1381,10 +1415,15 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
 		pix_fmt_mp->pixelformat = ctx->src_fmt->fourcc;
 		pix_fmt_mp->num_planes = ctx->src_fmt->num_planes;
 
-		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
+		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->stride[0];
 		pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
-		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
+		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->stride[1];
 		pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
+		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
+			pix_fmt_mp->plane_fmt[2].bytesperline = ctx->stride[2];
+			pix_fmt_mp->plane_fmt[2].sizeimage = ctx->chroma_size_1;
+		}
 	} else {
 		mfc_err("invalid buf type\n");
 		return -EINVAL;
@@ -1468,9 +1507,14 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
 
 		s5p_mfc_hw_call(dev->mfc_ops, enc_calc_src_size, ctx);
 		pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
-		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
+		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->stride[0];
 		pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
-		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
+		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->stride[1];
+		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
+			pix_fmt_mp->plane_fmt[2].bytesperline = ctx->stride[2];
+			pix_fmt_mp->plane_fmt[2].sizeimage = ctx->chroma_size_1;
+		}
 
 		ctx->src_bufs_cnt = 0;
 		ctx->output_state = QUEUE_FREE;
@@ -2414,10 +2458,16 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
 
 		psize[0] = ctx->luma_size;
 		psize[1] = ctx->chroma_size;
+		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
+			psize[2] = ctx->chroma_size_1;
 
 		if (IS_MFCV6_PLUS(dev)) {
 			alloc_devs[0] = ctx->dev->mem_dev[BANK_L_CTX];
 			alloc_devs[1] = ctx->dev->mem_dev[BANK_L_CTX];
+			if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
+				alloc_devs[2] = ctx->dev->mem_dev[BANK_L_CTX];
 		} else {
 			alloc_devs[0] = ctx->dev->mem_dev[BANK_R_CTX];
 			alloc_devs[1] = ctx->dev->mem_dev[BANK_R_CTX];
@@ -2456,6 +2506,10 @@ static int s5p_mfc_buf_init(struct vb2_buffer *vb)
 					vb2_dma_contig_plane_dma_addr(vb, 0);
 		ctx->src_bufs[i].cookie.raw.chroma =
 					vb2_dma_contig_plane_dma_addr(vb, 1);
+		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
+			ctx->src_bufs[i].cookie.raw.chroma_1 =
+					vb2_dma_contig_plane_dma_addr(vb, 2);
 		ctx->src_bufs_cnt++;
 	} else {
 		mfc_err("invalid queue type: %d\n", vq->type);
@@ -2493,6 +2547,12 @@ static int s5p_mfc_buf_prepare(struct vb2_buffer *vb)
 			mfc_err("plane size is too small for output\n");
 			return -EINVAL;
 		}
+		if ((ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+		     ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) &&
+		    (vb2_plane_size(vb, 2) < ctx->chroma_size_1)) {
+			mfc_err("plane size is too small for output\n");
+			return -EINVAL;
+		}
 	} else {
 		mfc_err("invalid queue type: %d\n", vq->type);
 		return -EINVAL;
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
index 87ac56756a16..7c5e851c8191 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
@@ -293,9 +293,11 @@ struct s5p_mfc_hw_ops {
 	int (*set_enc_stream_buffer)(struct s5p_mfc_ctx *ctx,
 			unsigned long addr, unsigned int size);
 	void (*set_enc_frame_buffer)(struct s5p_mfc_ctx *ctx,
-			unsigned long y_addr, unsigned long c_addr);
+			unsigned long y_addr, unsigned long c_addr,
+			unsigned long c_1_addr);
 	void (*get_enc_frame_buffer)(struct s5p_mfc_ctx *ctx,
-			unsigned long *y_addr, unsigned long *c_addr);
+			unsigned long *y_addr, unsigned long *c_addr,
+			unsigned long *c_1_addr);
 	void (*try_run)(struct s5p_mfc_dev *dev);
 	void (*clear_int_flags)(struct s5p_mfc_dev *dev);
 	int (*get_dspl_y_adr)(struct s5p_mfc_dev *dev);
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
index 28a06dc343fd..fcfaf125a5a1 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
@@ -516,7 +516,8 @@ static int s5p_mfc_set_enc_stream_buffer_v5(struct s5p_mfc_ctx *ctx,
 }
 
 static void s5p_mfc_set_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,
-		unsigned long y_addr, unsigned long c_addr)
+		unsigned long y_addr, unsigned long c_addr,
+		unsigned long c_1_addr)
 {
 	struct s5p_mfc_dev *dev = ctx->dev;
 
@@ -525,7 +526,8 @@ static void s5p_mfc_set_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,
 }
 
 static void s5p_mfc_get_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,
-		unsigned long *y_addr, unsigned long *c_addr)
+		unsigned long *y_addr, unsigned long *c_addr,
+		unsigned long *c_1_addr)
 {
 	struct s5p_mfc_dev *dev = ctx->dev;
 
@@ -1210,7 +1212,7 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
 	if (list_empty(&ctx->src_queue)) {
 		/* send null frame */
 		s5p_mfc_set_enc_frame_buffer_v5(ctx, dev->dma_base[BANK_R_CTX],
-						dev->dma_base[BANK_R_CTX]);
+						dev->dma_base[BANK_R_CTX], 0);
 		src_mb = NULL;
 	} else {
 		src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf,
@@ -1220,7 +1222,7 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
 			/* send null frame */
 			s5p_mfc_set_enc_frame_buffer_v5(ctx,
 						dev->dma_base[BANK_R_CTX],
-						dev->dma_base[BANK_R_CTX]);
+						dev->dma_base[BANK_R_CTX], 0);
 			ctx->state = MFCINST_FINISHING;
 		} else {
 			src_y_addr = vb2_dma_contig_plane_dma_addr(
@@ -1228,7 +1230,7 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
 			src_c_addr = vb2_dma_contig_plane_dma_addr(
 					&src_mb->b->vb2_buf, 1);
 			s5p_mfc_set_enc_frame_buffer_v5(ctx, src_y_addr,
-								src_c_addr);
+								src_c_addr, 0);
 			if (src_mb->flags & MFC_BUF_FLAG_EOS)
 				ctx->state = MFCINST_FINISHING;
 		}
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
index fb3f0718821d..e579c765e902 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
@@ -494,16 +494,43 @@ static void s5p_mfc_dec_calc_dpb_size_v6(struct s5p_mfc_ctx *ctx)
 	struct s5p_mfc_dev *dev = ctx->dev;
 	ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN_V6);
 	ctx->buf_height = ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN_V6);
+	ctx->chroma_size_1 = 0;
 	mfc_debug(2, "SEQ Done: Movie dimensions %dx%d,\n"
 			"buffer dimensions: %dx%d\n", ctx->img_width,
 			ctx->img_height, ctx->buf_width, ctx->buf_height);
 
-	ctx->luma_size = calc_plane(ctx->img_width, ctx->img_height);
-	ctx->chroma_size = calc_plane(ctx->img_width, (ctx->img_height >> 1));
+	switch (ctx->dst_fmt->fourcc) {
+	case V4L2_PIX_FMT_NV12M:
+	case V4L2_PIX_FMT_NV21M:
+		ctx->stride[0] = ALIGN(ctx->img_width,
+					S5P_FIMV_NV12MT_HALIGN_V6);
+		ctx->stride[1] = ALIGN(ctx->img_width,
+					S5P_FIMV_NV12MT_HALIGN_V6);
+		ctx->luma_size = calc_plane(ctx->stride[0], ctx->img_height);
+		ctx->chroma_size = calc_plane(ctx->stride[1],
+					(ctx->img_height / 2));
+		break;
+	case V4L2_PIX_FMT_YUV420M:
+	case V4L2_PIX_FMT_YVU420M:
+		ctx->stride[0] = ALIGN(ctx->img_width,
+					S5P_FIMV_NV12MT_HALIGN_V6);
+		ctx->stride[1] = ALIGN(ctx->img_width / 2,
+					S5P_FIMV_NV12MT_HALIGN_V6);
+		ctx->stride[2] = ALIGN(ctx->img_width / 2,
+					S5P_FIMV_NV12MT_HALIGN_V6);
+		ctx->luma_size = calc_plane(ctx->stride[0], ctx->img_height);
+		ctx->chroma_size = calc_plane(ctx->stride[1],
+					(ctx->img_height / 2));
+		ctx->chroma_size_1 = calc_plane(ctx->stride[2],
+					(ctx->img_height / 2));
+		break;
+	}
+
 	if (IS_MFCV8_PLUS(ctx->dev)) {
 		/* MFCv8 needs additional 64 bytes for luma,chroma dpb*/
 		ctx->luma_size += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8;
 		ctx->chroma_size += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8;
+		ctx->chroma_size_1 += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8;
 	}
 
 	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
@@ -534,15 +561,53 @@ static void s5p_mfc_enc_calc_src_size_v6(struct s5p_mfc_ctx *ctx)
 	mb_width = MB_WIDTH(ctx->img_width);
 	mb_height = MB_HEIGHT(ctx->img_height);
 
-	ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN_V6);
-	ctx->luma_size = ALIGN((mb_width * mb_height) * 256, 256);
-	ctx->chroma_size = ALIGN((mb_width * mb_height) * 128, 256);
-
-	/* MFCv7 needs pad bytes for Luma and Chroma */
-	if (IS_MFCV7_PLUS(ctx->dev)) {
+	if (IS_MFCV12(ctx->dev)) {
+		switch (ctx->src_fmt->fourcc) {
+		case V4L2_PIX_FMT_NV12M:
+		case V4L2_PIX_FMT_NV21M:
+			ctx->stride[0] = ALIGN(ctx->img_width,
+						S5P_FIMV_NV12M_HALIGN_V6);
+			ctx->stride[1] = ALIGN(ctx->img_width,
+						S5P_FIMV_NV12M_HALIGN_V6);
+			ctx->luma_size = ctx->stride[0] *
+						ALIGN(ctx->img_height, 16);
+			ctx->chroma_size =  ctx->stride[0] *
+						ALIGN(ctx->img_height / 2, 16);
+			break;
+		case V4L2_PIX_FMT_YUV420M:
+		case V4L2_PIX_FMT_YVU420M:
+			ctx->stride[0] = ALIGN(ctx->img_width,
+						S5P_FIMV_NV12M_HALIGN_V6);
+			ctx->stride[1] = ALIGN(ctx->img_width / 2,
+						S5P_FIMV_NV12M_HALIGN_V6);
+			ctx->stride[2] = ALIGN(ctx->img_width / 2,
+						S5P_FIMV_NV12M_HALIGN_V6);
+			ctx->luma_size = ctx->stride[0] *
+						ALIGN(ctx->img_height, 16);
+			ctx->chroma_size =  ctx->stride[1] *
+						ALIGN(ctx->img_height / 2, 16);
+			ctx->chroma_size_1 =  ctx->stride[2] *
+						ALIGN(ctx->img_height / 2, 16);
+			break;
+		}
 		ctx->luma_size += MFC_LUMA_PAD_BYTES_V7;
-		ctx->chroma_size += MFC_CHROMA_PAD_BYTES_V7;
+		ctx->chroma_size += MFC_CHROMA_PAD_BYTES_V12;
+		ctx->chroma_size_1 += MFC_CHROMA_PAD_BYTES_V12;
+	} else {
+		ctx->buf_width = ALIGN(ctx->img_width,
+					S5P_FIMV_NV12M_HALIGN_V6);
+		ctx->stride[0] = ctx->buf_width;
+		ctx->stride[1] = ctx->buf_width;
+		ctx->luma_size = ALIGN((mb_width * mb_height) * 256, 256);
+		ctx->chroma_size = ALIGN((mb_width * mb_height) * 128, 256);
+		ctx->chroma_size_1 = 0;
+		/* MFCv7 needs pad bytes for Luma and Chroma */
+		if (IS_MFCV7_PLUS(ctx->dev)) {
+			ctx->luma_size += MFC_LUMA_PAD_BYTES_V7;
+			ctx->chroma_size += MFC_LUMA_PAD_BYTES_V7;
+		}
 	}
+
 }
 
 /* Set registers for decoding stream buffer */
@@ -588,15 +653,21 @@ static int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx)
 	writel(ctx->total_dpb_count, mfc_regs->d_num_dpb);
 	writel(ctx->luma_size, mfc_regs->d_first_plane_dpb_size);
 	writel(ctx->chroma_size, mfc_regs->d_second_plane_dpb_size);
-
+	if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+			ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
+		writel(ctx->chroma_size_1, mfc_regs->d_third_plane_dpb_size);
 	writel(buf_addr1, mfc_regs->d_scratch_buffer_addr);
 	writel(ctx->scratch_buf_size, mfc_regs->d_scratch_buffer_size);
 
 	if (IS_MFCV8_PLUS(dev)) {
-		writel(ctx->img_width,
+		writel(ctx->stride[0],
 			mfc_regs->d_first_plane_dpb_stride_size);
-		writel(ctx->img_width,
+		writel(ctx->stride[1],
 			mfc_regs->d_second_plane_dpb_stride_size);
+		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
+			writel(ctx->stride[2],
+				mfc_regs->d_third_plane_dpb_stride_size);
 	}
 
 	buf_addr1 += ctx->scratch_buf_size;
@@ -625,6 +696,13 @@ static int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx)
 					ctx->dst_bufs[i].cookie.raw.chroma);
 		writel(ctx->dst_bufs[i].cookie.raw.chroma,
 				mfc_regs->d_second_plane_dpb + i * 4);
+		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
+			mfc_debug(2, "\tChroma_1 %d: %zx\n", i,
+					ctx->dst_bufs[i].cookie.raw.chroma_1);
+			writel(ctx->dst_bufs[i].cookie.raw.chroma_1,
+					mfc_regs->d_third_plane_dpb + i * 4);
+		}
 	}
 	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
 			ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC ||
@@ -683,20 +761,24 @@ static int s5p_mfc_set_enc_stream_buffer_v6(struct s5p_mfc_ctx *ctx,
 }
 
 static void s5p_mfc_set_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
-		unsigned long y_addr, unsigned long c_addr)
+		unsigned long y_addr, unsigned long c_addr,
+		unsigned long c_1_addr)
 {
 	struct s5p_mfc_dev *dev = ctx->dev;
 	const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs;
 
 	writel(y_addr, mfc_regs->e_source_first_plane_addr);
 	writel(c_addr, mfc_regs->e_source_second_plane_addr);
+	writel(c_1_addr, mfc_regs->e_source_third_plane_addr);
 
 	mfc_debug(2, "enc src y buf addr: 0x%08lx\n", y_addr);
 	mfc_debug(2, "enc src c buf addr: 0x%08lx\n", c_addr);
+	mfc_debug(2, "enc src cr buf addr: 0x%08lx\n", c_1_addr);
 }
 
 static void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
-		unsigned long *y_addr, unsigned long *c_addr)
+		unsigned long *y_addr, unsigned long *c_addr,
+		unsigned long *c_1_addr)
 {
 	struct s5p_mfc_dev *dev = ctx->dev;
 	const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs;
@@ -704,12 +786,17 @@ static void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
 
 	*y_addr = readl(mfc_regs->e_encoded_source_first_plane_addr);
 	*c_addr = readl(mfc_regs->e_encoded_source_second_plane_addr);
+	if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+			ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
+		*c_1_addr = readl(mfc_regs->e_encoded_source_third_plane_addr);
+	else
+		*c_1_addr = 0;
 
 	enc_recon_y_addr = readl(mfc_regs->e_recon_luma_dpb_addr);
 	enc_recon_c_addr = readl(mfc_regs->e_recon_chroma_dpb_addr);
 
 	mfc_debug(2, "recon y addr: 0x%08lx y_addr: 0x%08lx\n", enc_recon_y_addr, *y_addr);
-	mfc_debug(2, "recon c addr: 0x%08lx\n", enc_recon_c_addr);
+	mfc_debug(2, "recon c addr: 0x%08lx c_addr: 0x%08lx\n", enc_recon_c_addr, *c_addr);
 }
 
 /* Set encoding ref & codec buffer */
@@ -886,6 +973,20 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
 		writel(reg, mfc_regs->e_enc_options);
 		/* 0: NV12(CbCr), 1: NV21(CrCb) */
 		writel(0x0, mfc_regs->pixel_format);
+	} else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
+		/* 0: Linear, 1: 2D tiled*/
+		reg = readl(mfc_regs->e_enc_options);
+		reg &= ~(0x1 << 7);
+		writel(reg, mfc_regs->e_enc_options);
+		/* 2: YV12(CrCb), 3: I420(CrCb) */
+		writel(0x2, mfc_regs->pixel_format);
+	} else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M) {
+		/* 0: Linear, 1: 2D tiled*/
+		reg = readl(mfc_regs->e_enc_options);
+		reg &= ~(0x1 << 7);
+		writel(reg, mfc_regs->e_enc_options);
+		/* 2: YV12(CrCb), 3: I420(CrCb) */
+		writel(0x3, mfc_regs->pixel_format);
 	}
 
 	/* memory structure recon. frame */
@@ -1696,8 +1797,12 @@ static int s5p_mfc_init_decode_v6(struct s5p_mfc_ctx *ctx)
 	else
 		writel(reg, mfc_regs->d_dec_options);
 
-	/* 0: NV12(CbCr), 1: NV21(CrCb) */
-	if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV21M)
+	/* 0: NV12(CbCr), 1: NV21(CrCb), 2: YV12(CrCb), 3: I420(CbCr) */
+	if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M)
+		writel(0x3, mfc_regs->pixel_format);
+	else if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
+		writel(0x2, mfc_regs->pixel_format);
+	else if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV21M)
 		writel(0x1, mfc_regs->pixel_format);
 	else
 		writel(0x0, mfc_regs->pixel_format);
@@ -1781,8 +1886,12 @@ static int s5p_mfc_init_encode_v6(struct s5p_mfc_ctx *ctx)
 
 	/* Set stride lengths for v7 & above */
 	if (IS_MFCV7_PLUS(dev)) {
-		writel(ctx->img_width, mfc_regs->e_source_first_plane_stride);
-		writel(ctx->img_width, mfc_regs->e_source_second_plane_stride);
+		writel(ctx->stride[0], mfc_regs->e_source_first_plane_stride);
+		writel(ctx->stride[1], mfc_regs->e_source_second_plane_stride);
+		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
+			writel(ctx->stride[2],
+					mfc_regs->e_source_third_plane_stride);
 	}
 
 	writel(ctx->inst_no, mfc_regs->instance_id);
@@ -1891,7 +2000,7 @@ static inline int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
 	struct s5p_mfc_dev *dev = ctx->dev;
 	struct s5p_mfc_buf *dst_mb;
 	struct s5p_mfc_buf *src_mb;
-	unsigned long src_y_addr, src_c_addr, dst_addr;
+	unsigned long src_y_addr, src_c_addr, src_c_1_addr, dst_addr;
 	/*
 	unsigned int src_y_size, src_c_size;
 	*/
@@ -1909,22 +2018,29 @@ static inline int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
 
 	if (list_empty(&ctx->src_queue)) {
 		/* send null frame */
-		s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0);
+		s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0, 0);
 		src_mb = NULL;
 	} else {
 		src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
 		src_mb->flags |= MFC_BUF_FLAG_USED;
 		if (src_mb->b->vb2_buf.planes[0].bytesused == 0) {
-			s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0);
+			s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0, 0);
 			ctx->state = MFCINST_FINISHING;
 		} else {
 			src_y_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 0);
 			src_c_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 1);
+			if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
+				src_c_1_addr = vb2_dma_contig_plane_dma_addr
+						(&src_mb->b->vb2_buf, 2);
+			else
+				src_c_1_addr = 0;
 
 			mfc_debug(2, "enc src y addr: 0x%08lx\n", src_y_addr);
 			mfc_debug(2, "enc src c addr: 0x%08lx\n", src_c_addr);
 
-			s5p_mfc_set_enc_frame_buffer_v6(ctx, src_y_addr, src_c_addr);
+			s5p_mfc_set_enc_frame_buffer_v6(ctx, src_y_addr,
+						src_c_addr, src_c_1_addr);
 			if (src_mb->flags & MFC_BUF_FLAG_EOS)
 				ctx->state = MFCINST_FINISHING;
 		}
@@ -2450,6 +2566,8 @@ const struct s5p_mfc_regs *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev)
 			S5P_FIMV_E_ENCODED_SOURCE_FIRST_ADDR_V7);
 	R(e_encoded_source_second_plane_addr,
 			S5P_FIMV_E_ENCODED_SOURCE_SECOND_ADDR_V7);
+	R(e_encoded_source_third_plane_addr,
+			S5P_FIMV_E_ENCODED_SOURCE_THIRD_ADDR_V7);
 	R(e_vp8_options, S5P_FIMV_E_VP8_OPTIONS_V7);
 
 	if (!IS_MFCV8_PLUS(dev))
@@ -2464,16 +2582,20 @@ const struct s5p_mfc_regs *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev)
 	R(d_cpb_buffer_offset, S5P_FIMV_D_CPB_BUFFER_OFFSET_V8);
 	R(d_first_plane_dpb_size, S5P_FIMV_D_FIRST_PLANE_DPB_SIZE_V8);
 	R(d_second_plane_dpb_size, S5P_FIMV_D_SECOND_PLANE_DPB_SIZE_V8);
+	R(d_third_plane_dpb_size, S5P_FIMV_D_THIRD_PLANE_DPB_SIZE_V8);
 	R(d_scratch_buffer_addr, S5P_FIMV_D_SCRATCH_BUFFER_ADDR_V8);
 	R(d_scratch_buffer_size, S5P_FIMV_D_SCRATCH_BUFFER_SIZE_V8);
 	R(d_first_plane_dpb_stride_size,
 			S5P_FIMV_D_FIRST_PLANE_DPB_STRIDE_SIZE_V8);
 	R(d_second_plane_dpb_stride_size,
 			S5P_FIMV_D_SECOND_PLANE_DPB_STRIDE_SIZE_V8);
+	R(d_third_plane_dpb_stride_size,
+			S5P_FIMV_D_THIRD_PLANE_DPB_STRIDE_SIZE_V8);
 	R(d_mv_buffer_size, S5P_FIMV_D_MV_BUFFER_SIZE_V8);
 	R(d_num_mv, S5P_FIMV_D_NUM_MV_V8);
 	R(d_first_plane_dpb, S5P_FIMV_D_FIRST_PLANE_DPB_V8);
 	R(d_second_plane_dpb, S5P_FIMV_D_SECOND_PLANE_DPB_V8);
+	R(d_third_plane_dpb, S5P_FIMV_D_THIRD_PLANE_DPB_V8);
 	R(d_mv_buffer, S5P_FIMV_D_MV_BUFFER_V8);
 	R(d_init_buffer_options, S5P_FIMV_D_INIT_BUFFER_OPTIONS_V8);
 	R(d_available_dpb_flag_lower, S5P_FIMV_D_AVAILABLE_DPB_FLAG_LOWER_V8);
-- 
2.17.1


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

* [Patch v4 04/11] media: s5p-mfc: Add YV12 and I420 multiplanar format support
@ 2023-10-25 10:22       ` Aakarsh Jain
  0 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-10-25 10:22 UTC (permalink / raw)
  To: linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	aakarsh.jain, linux-fsd, Smitha T Murthy

YV12 and I420 format (3-plane) support is added. Stride information is
added to all formats and planes since it is necessary for YV12/I420
which are different from width.

Cc: linux-fsd@tesla.com
Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
---
 .../platform/samsung/s5p-mfc/regs-mfc-v12.h   |   2 +
 .../platform/samsung/s5p-mfc/regs-mfc-v7.h    |   1 +
 .../platform/samsung/s5p-mfc/regs-mfc-v8.h    |   3 +
 .../platform/samsung/s5p-mfc/s5p_mfc_common.h |   4 +
 .../platform/samsung/s5p-mfc/s5p_mfc_dec.c    |  45 ++++-
 .../platform/samsung/s5p-mfc/s5p_mfc_enc.c    |  86 +++++++--
 .../platform/samsung/s5p-mfc/s5p_mfc_opr.h    |   6 +-
 .../platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c |  12 +-
 .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 168 +++++++++++++++---
 9 files changed, 281 insertions(+), 46 deletions(-)

diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
index 6c68a45082d0..70464f47c1f9 100644
--- a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
+++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
@@ -26,6 +26,8 @@
 #define MFC_VERSION_V12			0xC0
 #define MFC_NUM_PORTS_V12		1
 #define S5P_FIMV_CODEC_VP9_ENC		27
+#define MFC_CHROMA_PAD_BYTES_V12        256
+#define S5P_FIMV_D_ALIGN_PLANE_SIZE_V12 256
 
 /* Encoder buffer size for MFCv12 */
 #define ENC_V120_BASE_SIZE(x, y) \
diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
index 4a7adfdaa359..50f9bf0603c1 100644
--- a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
+++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
@@ -24,6 +24,7 @@
 
 #define S5P_FIMV_E_ENCODED_SOURCE_FIRST_ADDR_V7		0xfa70
 #define S5P_FIMV_E_ENCODED_SOURCE_SECOND_ADDR_V7	0xfa74
+#define S5P_FIMV_E_ENCODED_SOURCE_THIRD_ADDR_V7		0xfa78
 
 #define S5P_FIMV_E_VP8_OPTIONS_V7			0xfdb0
 #define S5P_FIMV_E_VP8_FILTER_OPTIONS_V7		0xfdb4
diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
index 162e3c7e920f..0ef9eb2dff22 100644
--- a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
+++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
@@ -17,13 +17,16 @@
 #define S5P_FIMV_D_MIN_SCRATCH_BUFFER_SIZE_V8	0xf108
 #define S5P_FIMV_D_FIRST_PLANE_DPB_SIZE_V8	0xf144
 #define S5P_FIMV_D_SECOND_PLANE_DPB_SIZE_V8	0xf148
+#define S5P_FIMV_D_THIRD_PLANE_DPB_SIZE_V8	0xf14C
 #define S5P_FIMV_D_MV_BUFFER_SIZE_V8		0xf150
 
 #define S5P_FIMV_D_FIRST_PLANE_DPB_STRIDE_SIZE_V8	0xf138
 #define S5P_FIMV_D_SECOND_PLANE_DPB_STRIDE_SIZE_V8	0xf13c
+#define S5P_FIMV_D_THIRD_PLANE_DPB_STRIDE_SIZE_V8	0xf140
 
 #define S5P_FIMV_D_FIRST_PLANE_DPB_V8		0xf160
 #define S5P_FIMV_D_SECOND_PLANE_DPB_V8		0xf260
+#define S5P_FIMV_D_THIRD_PLANE_DPB_V8		0xf360
 #define S5P_FIMV_D_MV_BUFFER_V8			0xf460
 
 #define S5P_FIMV_D_NUM_MV_V8			0xf134
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
index dd2e9f7704ab..9a39cccfe002 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
@@ -56,6 +56,7 @@
 #define MFC_NO_INSTANCE_SET	-1
 #define MFC_ENC_CAP_PLANE_COUNT	1
 #define MFC_ENC_OUT_PLANE_COUNT	2
+#define VB2_MAX_PLANE_COUNT	3
 #define STUFF_BYTE		4
 #define MFC_MAX_CTRLS		128
 
@@ -181,6 +182,7 @@ struct s5p_mfc_buf {
 		struct {
 			size_t luma;
 			size_t chroma;
+			size_t chroma_1;
 		} raw;
 		size_t stream;
 	} cookie;
@@ -657,6 +659,7 @@ struct s5p_mfc_ctx {
 
 	int luma_size;
 	int chroma_size;
+	int chroma_size_1;
 	int mv_size;
 
 	unsigned long consumed_stream;
@@ -722,6 +725,7 @@ struct s5p_mfc_ctx {
 	size_t scratch_buf_size;
 	int is_10bit;
 	int is_422;
+	int stride[VB2_MAX_PLANE_COUNT];
 };
 
 /*
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
index e219cbcd86d5..317f796fffa1 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
@@ -56,6 +56,20 @@ static struct s5p_mfc_fmt formats[] = {
 		.num_planes	= 2,
 		.versions	= MFC_V6PLUS_BITS,
 	},
+	{
+		.fourcc         = V4L2_PIX_FMT_YUV420M,
+		.codec_mode     = S5P_MFC_CODEC_NONE,
+		.type           = MFC_FMT_RAW,
+		.num_planes     = 3,
+		.versions       = MFC_V12_BIT,
+	},
+	{
+		.fourcc         = V4L2_PIX_FMT_YVU420M,
+		.codec_mode     = S5P_MFC_CODEC_NONE,
+		.type           = MFC_FMT_RAW,
+		.num_planes     = 3,
+		.versions       = MFC_V12_BIT
+	},
 	{
 		.fourcc		= V4L2_PIX_FMT_H264,
 		.codec_mode	= S5P_MFC_CODEC_H264_DEC,
@@ -359,10 +373,15 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
 		/* Set pixelformat to the format in which MFC
 		   outputs the decoded frame */
 		pix_mp->pixelformat = ctx->dst_fmt->fourcc;
-		pix_mp->plane_fmt[0].bytesperline = ctx->buf_width;
+		pix_mp->plane_fmt[0].bytesperline = ctx->stride[0];
 		pix_mp->plane_fmt[0].sizeimage = ctx->luma_size;
-		pix_mp->plane_fmt[1].bytesperline = ctx->buf_width;
+		pix_mp->plane_fmt[1].bytesperline = ctx->stride[1];
 		pix_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
+		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
+			pix_mp->plane_fmt[2].bytesperline = ctx->stride[2];
+			pix_mp->plane_fmt[2].sizeimage = ctx->chroma_size_1;
+		}
 	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
 		/* This is run on OUTPUT
 		   The buffer contains compressed image
@@ -937,6 +956,9 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
 		   vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
 		/* Output plane count is 2 - one for Y and one for CbCr */
 		*plane_count = 2;
+		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
+			*plane_count = 3;
 		/* Setup buffer count */
 		if (*buf_count < ctx->pb_count)
 			*buf_count = ctx->pb_count;
@@ -955,12 +977,17 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
 	    vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
 		psize[0] = ctx->luma_size;
 		psize[1] = ctx->chroma_size;
-
+		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
+			psize[2] = ctx->chroma_size_1;
 		if (IS_MFCV6_PLUS(dev))
 			alloc_devs[0] = ctx->dev->mem_dev[BANK_L_CTX];
 		else
 			alloc_devs[0] = ctx->dev->mem_dev[BANK_R_CTX];
 		alloc_devs[1] = ctx->dev->mem_dev[BANK_L_CTX];
+		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
+			alloc_devs[2] = ctx->dev->mem_dev[BANK_L_CTX];
 	} else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
 		   ctx->state == MFCINST_INIT) {
 		psize[0] = ctx->dec_src_buf_size;
@@ -994,12 +1021,24 @@ static int s5p_mfc_buf_init(struct vb2_buffer *vb)
 			mfc_err("Plane buffer (CAPTURE) is too small\n");
 			return -EINVAL;
 		}
+		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
+			if (vb2_plane_size(vb, 2) < ctx->chroma_size_1) {
+				mfc_err("Plane buffer (CAPTURE) is too small\n");
+				return -EINVAL;
+			}
+		}
 		i = vb->index;
 		ctx->dst_bufs[i].b = vbuf;
 		ctx->dst_bufs[i].cookie.raw.luma =
 					vb2_dma_contig_plane_dma_addr(vb, 0);
 		ctx->dst_bufs[i].cookie.raw.chroma =
 					vb2_dma_contig_plane_dma_addr(vb, 1);
+		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
+			ctx->dst_bufs[i].cookie.raw.chroma_1 =
+					vb2_dma_contig_plane_dma_addr(vb, 2);
+		}
 		ctx->dst_bufs_cnt++;
 	} else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
 		if (IS_ERR_OR_NULL(ERR_PTR(
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
index e4d6e7c117b5..0eec04eb3ef3 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
@@ -59,6 +59,20 @@ static struct s5p_mfc_fmt formats[] = {
 		.num_planes	= 2,
 		.versions	= MFC_V6PLUS_BITS,
 	},
+	{
+		.fourcc         = V4L2_PIX_FMT_YUV420M,
+		.codec_mode     = S5P_MFC_CODEC_NONE,
+		.type           = MFC_FMT_RAW,
+		.num_planes     = 3,
+		.versions       = MFC_V12_BIT,
+	},
+	{
+		.fourcc         = V4L2_PIX_FMT_YVU420M,
+		.codec_mode     = S5P_MFC_CODEC_NONE,
+		.type           = MFC_FMT_RAW,
+		.num_planes     = 3,
+		.versions       = MFC_V12_BIT,
+	},
 	{
 		.fourcc		= V4L2_PIX_FMT_H264,
 		.codec_mode	= S5P_MFC_CODEC_H264_ENC,
@@ -1193,14 +1207,20 @@ static int enc_pre_frame_start(struct s5p_mfc_ctx *ctx)
 	struct s5p_mfc_dev *dev = ctx->dev;
 	struct s5p_mfc_buf *dst_mb;
 	struct s5p_mfc_buf *src_mb;
-	unsigned long src_y_addr, src_c_addr, dst_addr;
+	unsigned long src_y_addr, src_c_addr, src_c_1_addr, dst_addr;
 	unsigned int dst_size;
 
 	src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
 	src_y_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 0);
 	src_c_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 1);
+	if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+			ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
+		src_c_1_addr =
+			vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 2);
+	else
+		src_c_1_addr = 0;
 	s5p_mfc_hw_call(dev->mfc_ops, set_enc_frame_buffer, ctx,
-							src_y_addr, src_c_addr);
+					src_y_addr, src_c_addr, src_c_1_addr);
 
 	dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
 	dst_addr = vb2_dma_contig_plane_dma_addr(&dst_mb->b->vb2_buf, 0);
@@ -1215,8 +1235,8 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
 {
 	struct s5p_mfc_dev *dev = ctx->dev;
 	struct s5p_mfc_buf *mb_entry;
-	unsigned long enc_y_addr = 0, enc_c_addr = 0;
-	unsigned long mb_y_addr, mb_c_addr;
+	unsigned long enc_y_addr = 0, enc_c_addr = 0, enc_c_1_addr = 0;
+	unsigned long mb_y_addr, mb_c_addr, mb_c_1_addr;
 	int slice_type;
 	unsigned int strm_size;
 	bool src_ready;
@@ -1229,14 +1249,21 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
 		  mfc_read(dev, S5P_FIMV_ENC_SI_PIC_CNT));
 	if (slice_type >= 0) {
 		s5p_mfc_hw_call(dev->mfc_ops, get_enc_frame_buffer, ctx,
-				&enc_y_addr, &enc_c_addr);
+				&enc_y_addr, &enc_c_addr, &enc_c_1_addr);
 		list_for_each_entry(mb_entry, &ctx->src_queue, list) {
 			mb_y_addr = vb2_dma_contig_plane_dma_addr(
 					&mb_entry->b->vb2_buf, 0);
 			mb_c_addr = vb2_dma_contig_plane_dma_addr(
 					&mb_entry->b->vb2_buf, 1);
-			if ((enc_y_addr == mb_y_addr) &&
-						(enc_c_addr == mb_c_addr)) {
+			if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
+				mb_c_1_addr = vb2_dma_contig_plane_dma_addr
+						(&mb_entry->b->vb2_buf, 2);
+			else
+				mb_c_1_addr = 0;
+			if ((enc_y_addr == mb_y_addr)
+					&& (enc_c_addr == mb_c_addr)
+					&& (enc_c_1_addr == mb_c_1_addr)) {
 				list_del(&mb_entry->list);
 				ctx->src_queue_cnt--;
 				vb2_buffer_done(&mb_entry->b->vb2_buf,
@@ -1249,8 +1276,15 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
 					&mb_entry->b->vb2_buf, 0);
 			mb_c_addr = vb2_dma_contig_plane_dma_addr(
 					&mb_entry->b->vb2_buf, 1);
-			if ((enc_y_addr == mb_y_addr) &&
-						(enc_c_addr == mb_c_addr)) {
+			if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
+				mb_c_1_addr = vb2_dma_contig_plane_dma_addr(
+						&mb_entry->b->vb2_buf, 2);
+			else
+				mb_c_1_addr = 0;
+			if ((enc_y_addr == mb_y_addr)
+					&& (enc_c_addr == mb_c_addr)
+					&& (enc_c_1_addr == mb_c_1_addr)) {
 				list_del(&mb_entry->list);
 				ctx->ref_queue_cnt--;
 				vb2_buffer_done(&mb_entry->b->vb2_buf,
@@ -1381,10 +1415,15 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
 		pix_fmt_mp->pixelformat = ctx->src_fmt->fourcc;
 		pix_fmt_mp->num_planes = ctx->src_fmt->num_planes;
 
-		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
+		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->stride[0];
 		pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
-		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
+		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->stride[1];
 		pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
+		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
+			pix_fmt_mp->plane_fmt[2].bytesperline = ctx->stride[2];
+			pix_fmt_mp->plane_fmt[2].sizeimage = ctx->chroma_size_1;
+		}
 	} else {
 		mfc_err("invalid buf type\n");
 		return -EINVAL;
@@ -1468,9 +1507,14 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
 
 		s5p_mfc_hw_call(dev->mfc_ops, enc_calc_src_size, ctx);
 		pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
-		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
+		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->stride[0];
 		pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
-		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
+		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->stride[1];
+		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
+			pix_fmt_mp->plane_fmt[2].bytesperline = ctx->stride[2];
+			pix_fmt_mp->plane_fmt[2].sizeimage = ctx->chroma_size_1;
+		}
 
 		ctx->src_bufs_cnt = 0;
 		ctx->output_state = QUEUE_FREE;
@@ -2414,10 +2458,16 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
 
 		psize[0] = ctx->luma_size;
 		psize[1] = ctx->chroma_size;
+		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
+			psize[2] = ctx->chroma_size_1;
 
 		if (IS_MFCV6_PLUS(dev)) {
 			alloc_devs[0] = ctx->dev->mem_dev[BANK_L_CTX];
 			alloc_devs[1] = ctx->dev->mem_dev[BANK_L_CTX];
+			if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
+				alloc_devs[2] = ctx->dev->mem_dev[BANK_L_CTX];
 		} else {
 			alloc_devs[0] = ctx->dev->mem_dev[BANK_R_CTX];
 			alloc_devs[1] = ctx->dev->mem_dev[BANK_R_CTX];
@@ -2456,6 +2506,10 @@ static int s5p_mfc_buf_init(struct vb2_buffer *vb)
 					vb2_dma_contig_plane_dma_addr(vb, 0);
 		ctx->src_bufs[i].cookie.raw.chroma =
 					vb2_dma_contig_plane_dma_addr(vb, 1);
+		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
+			ctx->src_bufs[i].cookie.raw.chroma_1 =
+					vb2_dma_contig_plane_dma_addr(vb, 2);
 		ctx->src_bufs_cnt++;
 	} else {
 		mfc_err("invalid queue type: %d\n", vq->type);
@@ -2493,6 +2547,12 @@ static int s5p_mfc_buf_prepare(struct vb2_buffer *vb)
 			mfc_err("plane size is too small for output\n");
 			return -EINVAL;
 		}
+		if ((ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+		     ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) &&
+		    (vb2_plane_size(vb, 2) < ctx->chroma_size_1)) {
+			mfc_err("plane size is too small for output\n");
+			return -EINVAL;
+		}
 	} else {
 		mfc_err("invalid queue type: %d\n", vq->type);
 		return -EINVAL;
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
index 87ac56756a16..7c5e851c8191 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
@@ -293,9 +293,11 @@ struct s5p_mfc_hw_ops {
 	int (*set_enc_stream_buffer)(struct s5p_mfc_ctx *ctx,
 			unsigned long addr, unsigned int size);
 	void (*set_enc_frame_buffer)(struct s5p_mfc_ctx *ctx,
-			unsigned long y_addr, unsigned long c_addr);
+			unsigned long y_addr, unsigned long c_addr,
+			unsigned long c_1_addr);
 	void (*get_enc_frame_buffer)(struct s5p_mfc_ctx *ctx,
-			unsigned long *y_addr, unsigned long *c_addr);
+			unsigned long *y_addr, unsigned long *c_addr,
+			unsigned long *c_1_addr);
 	void (*try_run)(struct s5p_mfc_dev *dev);
 	void (*clear_int_flags)(struct s5p_mfc_dev *dev);
 	int (*get_dspl_y_adr)(struct s5p_mfc_dev *dev);
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
index 28a06dc343fd..fcfaf125a5a1 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
@@ -516,7 +516,8 @@ static int s5p_mfc_set_enc_stream_buffer_v5(struct s5p_mfc_ctx *ctx,
 }
 
 static void s5p_mfc_set_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,
-		unsigned long y_addr, unsigned long c_addr)
+		unsigned long y_addr, unsigned long c_addr,
+		unsigned long c_1_addr)
 {
 	struct s5p_mfc_dev *dev = ctx->dev;
 
@@ -525,7 +526,8 @@ static void s5p_mfc_set_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,
 }
 
 static void s5p_mfc_get_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,
-		unsigned long *y_addr, unsigned long *c_addr)
+		unsigned long *y_addr, unsigned long *c_addr,
+		unsigned long *c_1_addr)
 {
 	struct s5p_mfc_dev *dev = ctx->dev;
 
@@ -1210,7 +1212,7 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
 	if (list_empty(&ctx->src_queue)) {
 		/* send null frame */
 		s5p_mfc_set_enc_frame_buffer_v5(ctx, dev->dma_base[BANK_R_CTX],
-						dev->dma_base[BANK_R_CTX]);
+						dev->dma_base[BANK_R_CTX], 0);
 		src_mb = NULL;
 	} else {
 		src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf,
@@ -1220,7 +1222,7 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
 			/* send null frame */
 			s5p_mfc_set_enc_frame_buffer_v5(ctx,
 						dev->dma_base[BANK_R_CTX],
-						dev->dma_base[BANK_R_CTX]);
+						dev->dma_base[BANK_R_CTX], 0);
 			ctx->state = MFCINST_FINISHING;
 		} else {
 			src_y_addr = vb2_dma_contig_plane_dma_addr(
@@ -1228,7 +1230,7 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
 			src_c_addr = vb2_dma_contig_plane_dma_addr(
 					&src_mb->b->vb2_buf, 1);
 			s5p_mfc_set_enc_frame_buffer_v5(ctx, src_y_addr,
-								src_c_addr);
+								src_c_addr, 0);
 			if (src_mb->flags & MFC_BUF_FLAG_EOS)
 				ctx->state = MFCINST_FINISHING;
 		}
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
index fb3f0718821d..e579c765e902 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
@@ -494,16 +494,43 @@ static void s5p_mfc_dec_calc_dpb_size_v6(struct s5p_mfc_ctx *ctx)
 	struct s5p_mfc_dev *dev = ctx->dev;
 	ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN_V6);
 	ctx->buf_height = ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN_V6);
+	ctx->chroma_size_1 = 0;
 	mfc_debug(2, "SEQ Done: Movie dimensions %dx%d,\n"
 			"buffer dimensions: %dx%d\n", ctx->img_width,
 			ctx->img_height, ctx->buf_width, ctx->buf_height);
 
-	ctx->luma_size = calc_plane(ctx->img_width, ctx->img_height);
-	ctx->chroma_size = calc_plane(ctx->img_width, (ctx->img_height >> 1));
+	switch (ctx->dst_fmt->fourcc) {
+	case V4L2_PIX_FMT_NV12M:
+	case V4L2_PIX_FMT_NV21M:
+		ctx->stride[0] = ALIGN(ctx->img_width,
+					S5P_FIMV_NV12MT_HALIGN_V6);
+		ctx->stride[1] = ALIGN(ctx->img_width,
+					S5P_FIMV_NV12MT_HALIGN_V6);
+		ctx->luma_size = calc_plane(ctx->stride[0], ctx->img_height);
+		ctx->chroma_size = calc_plane(ctx->stride[1],
+					(ctx->img_height / 2));
+		break;
+	case V4L2_PIX_FMT_YUV420M:
+	case V4L2_PIX_FMT_YVU420M:
+		ctx->stride[0] = ALIGN(ctx->img_width,
+					S5P_FIMV_NV12MT_HALIGN_V6);
+		ctx->stride[1] = ALIGN(ctx->img_width / 2,
+					S5P_FIMV_NV12MT_HALIGN_V6);
+		ctx->stride[2] = ALIGN(ctx->img_width / 2,
+					S5P_FIMV_NV12MT_HALIGN_V6);
+		ctx->luma_size = calc_plane(ctx->stride[0], ctx->img_height);
+		ctx->chroma_size = calc_plane(ctx->stride[1],
+					(ctx->img_height / 2));
+		ctx->chroma_size_1 = calc_plane(ctx->stride[2],
+					(ctx->img_height / 2));
+		break;
+	}
+
 	if (IS_MFCV8_PLUS(ctx->dev)) {
 		/* MFCv8 needs additional 64 bytes for luma,chroma dpb*/
 		ctx->luma_size += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8;
 		ctx->chroma_size += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8;
+		ctx->chroma_size_1 += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8;
 	}
 
 	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
@@ -534,15 +561,53 @@ static void s5p_mfc_enc_calc_src_size_v6(struct s5p_mfc_ctx *ctx)
 	mb_width = MB_WIDTH(ctx->img_width);
 	mb_height = MB_HEIGHT(ctx->img_height);
 
-	ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN_V6);
-	ctx->luma_size = ALIGN((mb_width * mb_height) * 256, 256);
-	ctx->chroma_size = ALIGN((mb_width * mb_height) * 128, 256);
-
-	/* MFCv7 needs pad bytes for Luma and Chroma */
-	if (IS_MFCV7_PLUS(ctx->dev)) {
+	if (IS_MFCV12(ctx->dev)) {
+		switch (ctx->src_fmt->fourcc) {
+		case V4L2_PIX_FMT_NV12M:
+		case V4L2_PIX_FMT_NV21M:
+			ctx->stride[0] = ALIGN(ctx->img_width,
+						S5P_FIMV_NV12M_HALIGN_V6);
+			ctx->stride[1] = ALIGN(ctx->img_width,
+						S5P_FIMV_NV12M_HALIGN_V6);
+			ctx->luma_size = ctx->stride[0] *
+						ALIGN(ctx->img_height, 16);
+			ctx->chroma_size =  ctx->stride[0] *
+						ALIGN(ctx->img_height / 2, 16);
+			break;
+		case V4L2_PIX_FMT_YUV420M:
+		case V4L2_PIX_FMT_YVU420M:
+			ctx->stride[0] = ALIGN(ctx->img_width,
+						S5P_FIMV_NV12M_HALIGN_V6);
+			ctx->stride[1] = ALIGN(ctx->img_width / 2,
+						S5P_FIMV_NV12M_HALIGN_V6);
+			ctx->stride[2] = ALIGN(ctx->img_width / 2,
+						S5P_FIMV_NV12M_HALIGN_V6);
+			ctx->luma_size = ctx->stride[0] *
+						ALIGN(ctx->img_height, 16);
+			ctx->chroma_size =  ctx->stride[1] *
+						ALIGN(ctx->img_height / 2, 16);
+			ctx->chroma_size_1 =  ctx->stride[2] *
+						ALIGN(ctx->img_height / 2, 16);
+			break;
+		}
 		ctx->luma_size += MFC_LUMA_PAD_BYTES_V7;
-		ctx->chroma_size += MFC_CHROMA_PAD_BYTES_V7;
+		ctx->chroma_size += MFC_CHROMA_PAD_BYTES_V12;
+		ctx->chroma_size_1 += MFC_CHROMA_PAD_BYTES_V12;
+	} else {
+		ctx->buf_width = ALIGN(ctx->img_width,
+					S5P_FIMV_NV12M_HALIGN_V6);
+		ctx->stride[0] = ctx->buf_width;
+		ctx->stride[1] = ctx->buf_width;
+		ctx->luma_size = ALIGN((mb_width * mb_height) * 256, 256);
+		ctx->chroma_size = ALIGN((mb_width * mb_height) * 128, 256);
+		ctx->chroma_size_1 = 0;
+		/* MFCv7 needs pad bytes for Luma and Chroma */
+		if (IS_MFCV7_PLUS(ctx->dev)) {
+			ctx->luma_size += MFC_LUMA_PAD_BYTES_V7;
+			ctx->chroma_size += MFC_LUMA_PAD_BYTES_V7;
+		}
 	}
+
 }
 
 /* Set registers for decoding stream buffer */
@@ -588,15 +653,21 @@ static int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx)
 	writel(ctx->total_dpb_count, mfc_regs->d_num_dpb);
 	writel(ctx->luma_size, mfc_regs->d_first_plane_dpb_size);
 	writel(ctx->chroma_size, mfc_regs->d_second_plane_dpb_size);
-
+	if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+			ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
+		writel(ctx->chroma_size_1, mfc_regs->d_third_plane_dpb_size);
 	writel(buf_addr1, mfc_regs->d_scratch_buffer_addr);
 	writel(ctx->scratch_buf_size, mfc_regs->d_scratch_buffer_size);
 
 	if (IS_MFCV8_PLUS(dev)) {
-		writel(ctx->img_width,
+		writel(ctx->stride[0],
 			mfc_regs->d_first_plane_dpb_stride_size);
-		writel(ctx->img_width,
+		writel(ctx->stride[1],
 			mfc_regs->d_second_plane_dpb_stride_size);
+		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
+			writel(ctx->stride[2],
+				mfc_regs->d_third_plane_dpb_stride_size);
 	}
 
 	buf_addr1 += ctx->scratch_buf_size;
@@ -625,6 +696,13 @@ static int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx)
 					ctx->dst_bufs[i].cookie.raw.chroma);
 		writel(ctx->dst_bufs[i].cookie.raw.chroma,
 				mfc_regs->d_second_plane_dpb + i * 4);
+		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
+			mfc_debug(2, "\tChroma_1 %d: %zx\n", i,
+					ctx->dst_bufs[i].cookie.raw.chroma_1);
+			writel(ctx->dst_bufs[i].cookie.raw.chroma_1,
+					mfc_regs->d_third_plane_dpb + i * 4);
+		}
 	}
 	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
 			ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC ||
@@ -683,20 +761,24 @@ static int s5p_mfc_set_enc_stream_buffer_v6(struct s5p_mfc_ctx *ctx,
 }
 
 static void s5p_mfc_set_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
-		unsigned long y_addr, unsigned long c_addr)
+		unsigned long y_addr, unsigned long c_addr,
+		unsigned long c_1_addr)
 {
 	struct s5p_mfc_dev *dev = ctx->dev;
 	const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs;
 
 	writel(y_addr, mfc_regs->e_source_first_plane_addr);
 	writel(c_addr, mfc_regs->e_source_second_plane_addr);
+	writel(c_1_addr, mfc_regs->e_source_third_plane_addr);
 
 	mfc_debug(2, "enc src y buf addr: 0x%08lx\n", y_addr);
 	mfc_debug(2, "enc src c buf addr: 0x%08lx\n", c_addr);
+	mfc_debug(2, "enc src cr buf addr: 0x%08lx\n", c_1_addr);
 }
 
 static void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
-		unsigned long *y_addr, unsigned long *c_addr)
+		unsigned long *y_addr, unsigned long *c_addr,
+		unsigned long *c_1_addr)
 {
 	struct s5p_mfc_dev *dev = ctx->dev;
 	const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs;
@@ -704,12 +786,17 @@ static void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
 
 	*y_addr = readl(mfc_regs->e_encoded_source_first_plane_addr);
 	*c_addr = readl(mfc_regs->e_encoded_source_second_plane_addr);
+	if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+			ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
+		*c_1_addr = readl(mfc_regs->e_encoded_source_third_plane_addr);
+	else
+		*c_1_addr = 0;
 
 	enc_recon_y_addr = readl(mfc_regs->e_recon_luma_dpb_addr);
 	enc_recon_c_addr = readl(mfc_regs->e_recon_chroma_dpb_addr);
 
 	mfc_debug(2, "recon y addr: 0x%08lx y_addr: 0x%08lx\n", enc_recon_y_addr, *y_addr);
-	mfc_debug(2, "recon c addr: 0x%08lx\n", enc_recon_c_addr);
+	mfc_debug(2, "recon c addr: 0x%08lx c_addr: 0x%08lx\n", enc_recon_c_addr, *c_addr);
 }
 
 /* Set encoding ref & codec buffer */
@@ -886,6 +973,20 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
 		writel(reg, mfc_regs->e_enc_options);
 		/* 0: NV12(CbCr), 1: NV21(CrCb) */
 		writel(0x0, mfc_regs->pixel_format);
+	} else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
+		/* 0: Linear, 1: 2D tiled*/
+		reg = readl(mfc_regs->e_enc_options);
+		reg &= ~(0x1 << 7);
+		writel(reg, mfc_regs->e_enc_options);
+		/* 2: YV12(CrCb), 3: I420(CrCb) */
+		writel(0x2, mfc_regs->pixel_format);
+	} else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M) {
+		/* 0: Linear, 1: 2D tiled*/
+		reg = readl(mfc_regs->e_enc_options);
+		reg &= ~(0x1 << 7);
+		writel(reg, mfc_regs->e_enc_options);
+		/* 2: YV12(CrCb), 3: I420(CrCb) */
+		writel(0x3, mfc_regs->pixel_format);
 	}
 
 	/* memory structure recon. frame */
@@ -1696,8 +1797,12 @@ static int s5p_mfc_init_decode_v6(struct s5p_mfc_ctx *ctx)
 	else
 		writel(reg, mfc_regs->d_dec_options);
 
-	/* 0: NV12(CbCr), 1: NV21(CrCb) */
-	if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV21M)
+	/* 0: NV12(CbCr), 1: NV21(CrCb), 2: YV12(CrCb), 3: I420(CbCr) */
+	if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M)
+		writel(0x3, mfc_regs->pixel_format);
+	else if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
+		writel(0x2, mfc_regs->pixel_format);
+	else if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV21M)
 		writel(0x1, mfc_regs->pixel_format);
 	else
 		writel(0x0, mfc_regs->pixel_format);
@@ -1781,8 +1886,12 @@ static int s5p_mfc_init_encode_v6(struct s5p_mfc_ctx *ctx)
 
 	/* Set stride lengths for v7 & above */
 	if (IS_MFCV7_PLUS(dev)) {
-		writel(ctx->img_width, mfc_regs->e_source_first_plane_stride);
-		writel(ctx->img_width, mfc_regs->e_source_second_plane_stride);
+		writel(ctx->stride[0], mfc_regs->e_source_first_plane_stride);
+		writel(ctx->stride[1], mfc_regs->e_source_second_plane_stride);
+		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
+			writel(ctx->stride[2],
+					mfc_regs->e_source_third_plane_stride);
 	}
 
 	writel(ctx->inst_no, mfc_regs->instance_id);
@@ -1891,7 +2000,7 @@ static inline int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
 	struct s5p_mfc_dev *dev = ctx->dev;
 	struct s5p_mfc_buf *dst_mb;
 	struct s5p_mfc_buf *src_mb;
-	unsigned long src_y_addr, src_c_addr, dst_addr;
+	unsigned long src_y_addr, src_c_addr, src_c_1_addr, dst_addr;
 	/*
 	unsigned int src_y_size, src_c_size;
 	*/
@@ -1909,22 +2018,29 @@ static inline int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
 
 	if (list_empty(&ctx->src_queue)) {
 		/* send null frame */
-		s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0);
+		s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0, 0);
 		src_mb = NULL;
 	} else {
 		src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
 		src_mb->flags |= MFC_BUF_FLAG_USED;
 		if (src_mb->b->vb2_buf.planes[0].bytesused == 0) {
-			s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0);
+			s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0, 0);
 			ctx->state = MFCINST_FINISHING;
 		} else {
 			src_y_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 0);
 			src_c_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 1);
+			if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
+				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
+				src_c_1_addr = vb2_dma_contig_plane_dma_addr
+						(&src_mb->b->vb2_buf, 2);
+			else
+				src_c_1_addr = 0;
 
 			mfc_debug(2, "enc src y addr: 0x%08lx\n", src_y_addr);
 			mfc_debug(2, "enc src c addr: 0x%08lx\n", src_c_addr);
 
-			s5p_mfc_set_enc_frame_buffer_v6(ctx, src_y_addr, src_c_addr);
+			s5p_mfc_set_enc_frame_buffer_v6(ctx, src_y_addr,
+						src_c_addr, src_c_1_addr);
 			if (src_mb->flags & MFC_BUF_FLAG_EOS)
 				ctx->state = MFCINST_FINISHING;
 		}
@@ -2450,6 +2566,8 @@ const struct s5p_mfc_regs *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev)
 			S5P_FIMV_E_ENCODED_SOURCE_FIRST_ADDR_V7);
 	R(e_encoded_source_second_plane_addr,
 			S5P_FIMV_E_ENCODED_SOURCE_SECOND_ADDR_V7);
+	R(e_encoded_source_third_plane_addr,
+			S5P_FIMV_E_ENCODED_SOURCE_THIRD_ADDR_V7);
 	R(e_vp8_options, S5P_FIMV_E_VP8_OPTIONS_V7);
 
 	if (!IS_MFCV8_PLUS(dev))
@@ -2464,16 +2582,20 @@ const struct s5p_mfc_regs *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev)
 	R(d_cpb_buffer_offset, S5P_FIMV_D_CPB_BUFFER_OFFSET_V8);
 	R(d_first_plane_dpb_size, S5P_FIMV_D_FIRST_PLANE_DPB_SIZE_V8);
 	R(d_second_plane_dpb_size, S5P_FIMV_D_SECOND_PLANE_DPB_SIZE_V8);
+	R(d_third_plane_dpb_size, S5P_FIMV_D_THIRD_PLANE_DPB_SIZE_V8);
 	R(d_scratch_buffer_addr, S5P_FIMV_D_SCRATCH_BUFFER_ADDR_V8);
 	R(d_scratch_buffer_size, S5P_FIMV_D_SCRATCH_BUFFER_SIZE_V8);
 	R(d_first_plane_dpb_stride_size,
 			S5P_FIMV_D_FIRST_PLANE_DPB_STRIDE_SIZE_V8);
 	R(d_second_plane_dpb_stride_size,
 			S5P_FIMV_D_SECOND_PLANE_DPB_STRIDE_SIZE_V8);
+	R(d_third_plane_dpb_stride_size,
+			S5P_FIMV_D_THIRD_PLANE_DPB_STRIDE_SIZE_V8);
 	R(d_mv_buffer_size, S5P_FIMV_D_MV_BUFFER_SIZE_V8);
 	R(d_num_mv, S5P_FIMV_D_NUM_MV_V8);
 	R(d_first_plane_dpb, S5P_FIMV_D_FIRST_PLANE_DPB_V8);
 	R(d_second_plane_dpb, S5P_FIMV_D_SECOND_PLANE_DPB_V8);
+	R(d_third_plane_dpb, S5P_FIMV_D_THIRD_PLANE_DPB_V8);
 	R(d_mv_buffer, S5P_FIMV_D_MV_BUFFER_V8);
 	R(d_init_buffer_options, S5P_FIMV_D_INIT_BUFFER_OPTIONS_V8);
 	R(d_available_dpb_flag_lower, S5P_FIMV_D_AVAILABLE_DPB_FLAG_LOWER_V8);
-- 
2.17.1


_______________________________________________
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] 54+ messages in thread

* [Patch v4 05/11] media: s5p-mfc: Add support for rate controls in MFCv12
       [not found]   ` <CGME20231025102247epcas5p1103ae6d3194f2ffc354984e263ab7b4a@epcas5p1.samsung.com>
@ 2023-10-25 10:22       ` Aakarsh Jain
  0 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-10-25 10:22 UTC (permalink / raw)
  To: linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	aakarsh.jain, linux-fsd, Smitha T Murthy

In MFCv12, the rc configs are changed with support for CBR loose,
CBR tight and Variable Bitrate (VBR) added.

Cc: linux-fsd@tesla.com
Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
---
 .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 22 +++++++++++++++----
 .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h |  1 +
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
index e579c765e902..bed45857bd6c 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
@@ -1025,10 +1025,24 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
 
 	/* reaction coefficient */
 	if (p->rc_frame) {
-		if (p->rc_reaction_coeff < TIGHT_CBR_MAX) /* tight CBR */
-			writel(1, mfc_regs->e_rc_mode);
-		else					  /* loose CBR */
-			writel(2, mfc_regs->e_rc_mode);
+		if (IS_MFCV12(dev)) {
+			/* loose CBR */
+			if (p->rc_reaction_coeff < LOOSE_CBR_MAX)
+				writel(1, mfc_regs->e_rc_mode);
+			/* tight CBR */
+			else if (p->rc_reaction_coeff < TIGHT_CBR_MAX)
+				writel(0, mfc_regs->e_rc_mode);
+			/* VBR */
+			else
+				writel(2, mfc_regs->e_rc_mode);
+		} else {
+			/* tight CBR */
+			if (p->rc_reaction_coeff < TIGHT_CBR_MAX)
+				writel(1, mfc_regs->e_rc_mode);
+			/* loose CBR */
+			else
+				writel(2, mfc_regs->e_rc_mode);
+		}
 	}
 
 	/* seq header ctrl */
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
index 30269f3e68e8..24752a712fbf 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
@@ -40,6 +40,7 @@
 #define ENC_H264_LEVEL_MAX		42
 #define ENC_MPEG4_VOP_TIME_RES_MAX	((1 << 16) - 1)
 #define FRAME_DELTA_H264_H263		1
+#define LOOSE_CBR_MAX			5
 #define TIGHT_CBR_MAX			10
 #define ENC_HEVC_RC_FRAME_RATE_MAX	((1 << 16) - 1)
 #define ENC_HEVC_QP_INDEX_MIN		-12
-- 
2.17.1


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

* [Patch v4 05/11] media: s5p-mfc: Add support for rate controls in MFCv12
@ 2023-10-25 10:22       ` Aakarsh Jain
  0 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-10-25 10:22 UTC (permalink / raw)
  To: linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	aakarsh.jain, linux-fsd, Smitha T Murthy

In MFCv12, the rc configs are changed with support for CBR loose,
CBR tight and Variable Bitrate (VBR) added.

Cc: linux-fsd@tesla.com
Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
---
 .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 22 +++++++++++++++----
 .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h |  1 +
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
index e579c765e902..bed45857bd6c 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
@@ -1025,10 +1025,24 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
 
 	/* reaction coefficient */
 	if (p->rc_frame) {
-		if (p->rc_reaction_coeff < TIGHT_CBR_MAX) /* tight CBR */
-			writel(1, mfc_regs->e_rc_mode);
-		else					  /* loose CBR */
-			writel(2, mfc_regs->e_rc_mode);
+		if (IS_MFCV12(dev)) {
+			/* loose CBR */
+			if (p->rc_reaction_coeff < LOOSE_CBR_MAX)
+				writel(1, mfc_regs->e_rc_mode);
+			/* tight CBR */
+			else if (p->rc_reaction_coeff < TIGHT_CBR_MAX)
+				writel(0, mfc_regs->e_rc_mode);
+			/* VBR */
+			else
+				writel(2, mfc_regs->e_rc_mode);
+		} else {
+			/* tight CBR */
+			if (p->rc_reaction_coeff < TIGHT_CBR_MAX)
+				writel(1, mfc_regs->e_rc_mode);
+			/* loose CBR */
+			else
+				writel(2, mfc_regs->e_rc_mode);
+		}
 	}
 
 	/* seq header ctrl */
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
index 30269f3e68e8..24752a712fbf 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
@@ -40,6 +40,7 @@
 #define ENC_H264_LEVEL_MAX		42
 #define ENC_MPEG4_VOP_TIME_RES_MAX	((1 << 16) - 1)
 #define FRAME_DELTA_H264_H263		1
+#define LOOSE_CBR_MAX			5
 #define TIGHT_CBR_MAX			10
 #define ENC_HEVC_RC_FRAME_RATE_MAX	((1 << 16) - 1)
 #define ENC_HEVC_QP_INDEX_MIN		-12
-- 
2.17.1


_______________________________________________
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] 54+ messages in thread

* [Patch v4 06/11] media: s5p-mfc: Add support for UHD encoding.
       [not found]   ` <CGME20231025102250epcas5p375603c0f150fd508f0c0aa3ec6305517@epcas5p3.samsung.com>
@ 2023-10-25 10:22       ` Aakarsh Jain
  0 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-10-25 10:22 UTC (permalink / raw)
  To: linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	aakarsh.jain, linux-fsd, Smitha T Murthy

MFC driver had restriction on max resolution of 1080p, updated it for
UHD. Added corresponding support to set recommended profile and level
for H264 in UHD scenario.

Cc: linux-fsd@tesla.com
Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
---
 drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c |  9 ++++++---
 .../media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c  | 12 ++++++++++++
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
index 0eec04eb3ef3..0afa8426ca4e 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
@@ -1460,9 +1460,12 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
 			mfc_err("Unsupported format by this MFC version.\n");
 			return -EINVAL;
 		}
-
-		v4l_bound_align_image(&pix_fmt_mp->width, 8, 1920, 1,
-			&pix_fmt_mp->height, 4, 1080, 1, 0);
+		if (IS_MFCV12(dev))
+			v4l_bound_align_image(&pix_fmt_mp->width, 8, 3840, 1,
+					&pix_fmt_mp->height, 4, 2160, 1, 0);
+		else
+			v4l_bound_align_image(&pix_fmt_mp->width, 8, 1920, 1,
+					&pix_fmt_mp->height, 4, 1080, 1, 0);
 	} else {
 		mfc_err("invalid buf type\n");
 		return -EINVAL;
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
index bed45857bd6c..290d82e99940 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
@@ -1104,6 +1104,18 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
 	reg |= ((p->num_b_frame & 0x3) << 16);
 	writel(reg, mfc_regs->e_gop_config);
 
+	/* UHD encoding case */
+	if ((ctx->img_width == 3840) && ctx->img_height == 2160) {
+		if (p_h264->level < 51) {
+			mfc_debug(2, "Set Level 5.1 for UHD\n");
+			p_h264->level = 51;
+		}
+		if (p_h264->profile != 0x2) {
+			mfc_debug(2, "Set High profile for UHD\n");
+			p_h264->profile = 0x2;
+		}
+	}
+
 	/* profile & level */
 	reg = 0;
 	/** level */
-- 
2.17.1


_______________________________________________
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] 54+ messages in thread

* [Patch v4 06/11] media: s5p-mfc: Add support for UHD encoding.
@ 2023-10-25 10:22       ` Aakarsh Jain
  0 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-10-25 10:22 UTC (permalink / raw)
  To: linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	aakarsh.jain, linux-fsd, Smitha T Murthy

MFC driver had restriction on max resolution of 1080p, updated it for
UHD. Added corresponding support to set recommended profile and level
for H264 in UHD scenario.

Cc: linux-fsd@tesla.com
Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
---
 drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c |  9 ++++++---
 .../media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c  | 12 ++++++++++++
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
index 0eec04eb3ef3..0afa8426ca4e 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
@@ -1460,9 +1460,12 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
 			mfc_err("Unsupported format by this MFC version.\n");
 			return -EINVAL;
 		}
-
-		v4l_bound_align_image(&pix_fmt_mp->width, 8, 1920, 1,
-			&pix_fmt_mp->height, 4, 1080, 1, 0);
+		if (IS_MFCV12(dev))
+			v4l_bound_align_image(&pix_fmt_mp->width, 8, 3840, 1,
+					&pix_fmt_mp->height, 4, 2160, 1, 0);
+		else
+			v4l_bound_align_image(&pix_fmt_mp->width, 8, 1920, 1,
+					&pix_fmt_mp->height, 4, 1080, 1, 0);
 	} else {
 		mfc_err("invalid buf type\n");
 		return -EINVAL;
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
index bed45857bd6c..290d82e99940 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
@@ -1104,6 +1104,18 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
 	reg |= ((p->num_b_frame & 0x3) << 16);
 	writel(reg, mfc_regs->e_gop_config);
 
+	/* UHD encoding case */
+	if ((ctx->img_width == 3840) && ctx->img_height == 2160) {
+		if (p_h264->level < 51) {
+			mfc_debug(2, "Set Level 5.1 for UHD\n");
+			p_h264->level = 51;
+		}
+		if (p_h264->profile != 0x2) {
+			mfc_debug(2, "Set High profile for UHD\n");
+			p_h264->profile = 0x2;
+		}
+	}
+
 	/* profile & level */
 	reg = 0;
 	/** level */
-- 
2.17.1


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

* [Patch v4 07/11] media: s5p-mfc: Add support for DMABUF for encoder
       [not found]   ` <CGME20231025102253epcas5p4e57ce0924392b879d8d296f66613a798@epcas5p4.samsung.com>
@ 2023-10-25 10:22       ` Aakarsh Jain
  0 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-10-25 10:22 UTC (permalink / raw)
  To: linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	aakarsh.jain, linux-fsd, Smitha T Murthy

Add dmabuf support for mfc encoder

Cc: linux-fsd@tesla.com
Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
---
 .../media/platform/samsung/s5p-mfc/s5p_mfc.c  |  4 ++--
 .../platform/samsung/s5p-mfc/s5p_mfc_enc.c    | 21 +++++++++++--------
 2 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
index dee9ef017997..bd055dea827e 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
@@ -865,7 +865,7 @@ static int s5p_mfc_open(struct file *file)
 		q->io_modes = VB2_MMAP;
 		q->ops = get_dec_queue_ops();
 	} else if (vdev == dev->vfd_enc) {
-		q->io_modes = VB2_MMAP | VB2_USERPTR;
+		q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
 		q->ops = get_enc_queue_ops();
 	} else {
 		ret = -ENOENT;
@@ -892,7 +892,7 @@ static int s5p_mfc_open(struct file *file)
 		q->io_modes = VB2_MMAP;
 		q->ops = get_dec_queue_ops();
 	} else if (vdev == dev->vfd_enc) {
-		q->io_modes = VB2_MMAP | VB2_USERPTR;
+		q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
 		q->ops = get_enc_queue_ops();
 	} else {
 		ret = -ENOENT;
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
index 0afa8426ca4e..80a97b86977e 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
@@ -1537,9 +1537,10 @@ static int vidioc_reqbufs(struct file *file, void *priv,
 	struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
 	int ret = 0;
 
-	/* if memory is not mmp or userptr return error */
+	/* if memory is not mmp or userptr or dmabuf return error */
 	if ((reqbufs->memory != V4L2_MEMORY_MMAP) &&
-		(reqbufs->memory != V4L2_MEMORY_USERPTR))
+		(reqbufs->memory != V4L2_MEMORY_USERPTR) &&
+		(reqbufs->memory != V4L2_MEMORY_DMABUF))
 		return -EINVAL;
 	if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
 		if (reqbufs->count == 0) {
@@ -1616,9 +1617,10 @@ static int vidioc_querybuf(struct file *file, void *priv,
 	struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
 	int ret = 0;
 
-	/* if memory is not mmp or userptr return error */
+	/* if memory is not mmp or userptr or dmabuf return error */
 	if ((buf->memory != V4L2_MEMORY_MMAP) &&
-		(buf->memory != V4L2_MEMORY_USERPTR))
+		(buf->memory != V4L2_MEMORY_USERPTR) &&
+		(buf->memory != V4L2_MEMORY_DMABUF))
 		return -EINVAL;
 	if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
 		if (ctx->state != MFCINST_GOT_INST) {
@@ -2577,11 +2579,12 @@ static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count)
 						S5P_MFC_R2H_CMD_SEQ_DONE_RET,
 						0);
 		}
-
-		if (ctx->src_bufs_cnt < ctx->pb_count) {
-			mfc_err("Need minimum %d OUTPUT buffers\n",
-					ctx->pb_count);
-			return -ENOBUFS;
+		if (q->memory != V4L2_MEMORY_DMABUF) {
+			if (ctx->src_bufs_cnt < ctx->pb_count) {
+				mfc_err("Need minimum %d OUTPUT buffers\n",
+						ctx->pb_count);
+				return -ENOBUFS;
+			}
 		}
 	}
 
-- 
2.17.1


_______________________________________________
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] 54+ messages in thread

* [Patch v4 07/11] media: s5p-mfc: Add support for DMABUF for encoder
@ 2023-10-25 10:22       ` Aakarsh Jain
  0 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-10-25 10:22 UTC (permalink / raw)
  To: linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	aakarsh.jain, linux-fsd, Smitha T Murthy

Add dmabuf support for mfc encoder

Cc: linux-fsd@tesla.com
Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
---
 .../media/platform/samsung/s5p-mfc/s5p_mfc.c  |  4 ++--
 .../platform/samsung/s5p-mfc/s5p_mfc_enc.c    | 21 +++++++++++--------
 2 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
index dee9ef017997..bd055dea827e 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
@@ -865,7 +865,7 @@ static int s5p_mfc_open(struct file *file)
 		q->io_modes = VB2_MMAP;
 		q->ops = get_dec_queue_ops();
 	} else if (vdev == dev->vfd_enc) {
-		q->io_modes = VB2_MMAP | VB2_USERPTR;
+		q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
 		q->ops = get_enc_queue_ops();
 	} else {
 		ret = -ENOENT;
@@ -892,7 +892,7 @@ static int s5p_mfc_open(struct file *file)
 		q->io_modes = VB2_MMAP;
 		q->ops = get_dec_queue_ops();
 	} else if (vdev == dev->vfd_enc) {
-		q->io_modes = VB2_MMAP | VB2_USERPTR;
+		q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
 		q->ops = get_enc_queue_ops();
 	} else {
 		ret = -ENOENT;
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
index 0afa8426ca4e..80a97b86977e 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
@@ -1537,9 +1537,10 @@ static int vidioc_reqbufs(struct file *file, void *priv,
 	struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
 	int ret = 0;
 
-	/* if memory is not mmp or userptr return error */
+	/* if memory is not mmp or userptr or dmabuf return error */
 	if ((reqbufs->memory != V4L2_MEMORY_MMAP) &&
-		(reqbufs->memory != V4L2_MEMORY_USERPTR))
+		(reqbufs->memory != V4L2_MEMORY_USERPTR) &&
+		(reqbufs->memory != V4L2_MEMORY_DMABUF))
 		return -EINVAL;
 	if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
 		if (reqbufs->count == 0) {
@@ -1616,9 +1617,10 @@ static int vidioc_querybuf(struct file *file, void *priv,
 	struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
 	int ret = 0;
 
-	/* if memory is not mmp or userptr return error */
+	/* if memory is not mmp or userptr or dmabuf return error */
 	if ((buf->memory != V4L2_MEMORY_MMAP) &&
-		(buf->memory != V4L2_MEMORY_USERPTR))
+		(buf->memory != V4L2_MEMORY_USERPTR) &&
+		(buf->memory != V4L2_MEMORY_DMABUF))
 		return -EINVAL;
 	if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
 		if (ctx->state != MFCINST_GOT_INST) {
@@ -2577,11 +2579,12 @@ static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count)
 						S5P_MFC_R2H_CMD_SEQ_DONE_RET,
 						0);
 		}
-
-		if (ctx->src_bufs_cnt < ctx->pb_count) {
-			mfc_err("Need minimum %d OUTPUT buffers\n",
-					ctx->pb_count);
-			return -ENOBUFS;
+		if (q->memory != V4L2_MEMORY_DMABUF) {
+			if (ctx->src_bufs_cnt < ctx->pb_count) {
+				mfc_err("Need minimum %d OUTPUT buffers\n",
+						ctx->pb_count);
+				return -ENOBUFS;
+			}
 		}
 	}
 
-- 
2.17.1


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

* [Patch v4 08/11] media: s5p-mfc: Set context for valid case before calling try_run
       [not found]   ` <CGME20231025102257epcas5p4bf00a54078bf640dfb2e2e03e671453c@epcas5p4.samsung.com>
@ 2023-10-25 10:22       ` Aakarsh Jain
  0 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-10-25 10:22 UTC (permalink / raw)
  To: linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	aakarsh.jain, linux-fsd, Smitha T Murthy

Context bit is set for hardware execution if there is a buffer in
source and destination queue before calling try_run in the
init_buffers function. Now there will be a new context created and
hardware will be invoked for the buffer queued instead of waiting for
another buffer to be queued from userspace to set this context bit for
hw execution.

Cc: linux-fsd@tesla.com
Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
---
 drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
index bd055dea827e..fbb047eadf5a 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
@@ -604,6 +604,8 @@ static void s5p_mfc_handle_init_buffers(struct s5p_mfc_ctx *ctx,
 		s5p_mfc_clock_off();
 
 		wake_up(&ctx->queue);
+		if (ctx->src_queue_cnt >= 1 && ctx->dst_queue_cnt >= 1)
+			set_work_bit_irqsave(ctx);
 		s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
 	} else {
 		WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0);
-- 
2.17.1


_______________________________________________
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] 54+ messages in thread

* [Patch v4 08/11] media: s5p-mfc: Set context for valid case before calling try_run
@ 2023-10-25 10:22       ` Aakarsh Jain
  0 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-10-25 10:22 UTC (permalink / raw)
  To: linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	aakarsh.jain, linux-fsd, Smitha T Murthy

Context bit is set for hardware execution if there is a buffer in
source and destination queue before calling try_run in the
init_buffers function. Now there will be a new context created and
hardware will be invoked for the buffer queued instead of waiting for
another buffer to be queued from userspace to set this context bit for
hw execution.

Cc: linux-fsd@tesla.com
Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
---
 drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
index bd055dea827e..fbb047eadf5a 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
@@ -604,6 +604,8 @@ static void s5p_mfc_handle_init_buffers(struct s5p_mfc_ctx *ctx,
 		s5p_mfc_clock_off();
 
 		wake_up(&ctx->queue);
+		if (ctx->src_queue_cnt >= 1 && ctx->dst_queue_cnt >= 1)
+			set_work_bit_irqsave(ctx);
 		s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
 	} else {
 		WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0);
-- 
2.17.1


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

* [Patch v4 09/11] media: s5p-mfc: Load firmware for each run in MFCv12.
       [not found]   ` <CGME20231025102300epcas5p2c266a078b70614dc948b0e47cd5cf788@epcas5p2.samsung.com>
@ 2023-10-25 10:22       ` Aakarsh Jain
  0 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-10-25 10:22 UTC (permalink / raw)
  To: linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	aakarsh.jain, linux-fsd, Smitha T Murthy

In MFCv12, some section of firmware gets updated at each MFC run.
Hence we need to reload original firmware for each run at the start.

Cc: linux-fsd@tesla.com
Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
---
 drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
index b49159142c53..057088b9d327 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
@@ -51,8 +51,9 @@ int s5p_mfc_load_firmware(struct s5p_mfc_dev *dev)
 	 * into kernel. */
 	mfc_debug_enter();
 
-	if (dev->fw_get_done)
-		return 0;
+	if (!IS_MFCV12(dev))
+		if (dev->fw_get_done)
+			return 0;
 
 	for (i = MFC_FW_MAX_VERSIONS - 1; i >= 0; i--) {
 		if (!dev->variant->fw_name[i])
-- 
2.17.1


_______________________________________________
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] 54+ messages in thread

* [Patch v4 09/11] media: s5p-mfc: Load firmware for each run in MFCv12.
@ 2023-10-25 10:22       ` Aakarsh Jain
  0 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-10-25 10:22 UTC (permalink / raw)
  To: linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	aakarsh.jain, linux-fsd, Smitha T Murthy

In MFCv12, some section of firmware gets updated at each MFC run.
Hence we need to reload original firmware for each run at the start.

Cc: linux-fsd@tesla.com
Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
---
 drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
index b49159142c53..057088b9d327 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
@@ -51,8 +51,9 @@ int s5p_mfc_load_firmware(struct s5p_mfc_dev *dev)
 	 * into kernel. */
 	mfc_debug_enter();
 
-	if (dev->fw_get_done)
-		return 0;
+	if (!IS_MFCV12(dev))
+		if (dev->fw_get_done)
+			return 0;
 
 	for (i = MFC_FW_MAX_VERSIONS - 1; i >= 0; i--) {
 		if (!dev->variant->fw_name[i])
-- 
2.17.1


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

* [Patch v4 10/11] media: s5p-mfc: DPB Count Independent of VIDIOC_REQBUF
       [not found]   ` <CGME20231025102304epcas5p2065f908cb77558ef5573fbaab82352bd@epcas5p2.samsung.com>
@ 2023-10-25 10:22       ` Aakarsh Jain
  0 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-10-25 10:22 UTC (permalink / raw)
  To: linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	aakarsh.jain, linux-fsd, Smitha T Murthy

Add allocation of DPB buffers based on MFC requirement so,
codec buffers allocations has been moved after state
MFCINST_HEAD_PRODUCED. It is taken care that codec buffer allocation
is performed in process context from userspace IOCTL call.

Cc: linux-fsd@tesla.com
Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
---
 .../platform/samsung/s5p-mfc/s5p_mfc_enc.c      | 17 ++---------------
 .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c   |  8 ++++++++
 2 files changed, 10 insertions(+), 15 deletions(-)

diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
index 80a97b86977e..fceceade979a 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
@@ -1164,7 +1164,6 @@ static int enc_post_seq_start(struct s5p_mfc_ctx *ctx)
 	struct s5p_mfc_dev *dev = ctx->dev;
 	struct s5p_mfc_enc_params *p = &ctx->enc_params;
 	struct s5p_mfc_buf *dst_mb;
-	unsigned int enc_pb_count;
 
 	if (p->seq_hdr_mode == V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) {
 		if (!list_empty(&ctx->dst_queue)) {
@@ -1186,10 +1185,8 @@ static int enc_post_seq_start(struct s5p_mfc_ctx *ctx)
 			set_work_bit_irqsave(ctx);
 		s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
 	} else {
-		enc_pb_count = s5p_mfc_hw_call(dev->mfc_ops,
+		ctx->pb_count = s5p_mfc_hw_call(dev->mfc_ops,
 				get_enc_dpb_count, dev);
-		if (ctx->pb_count < enc_pb_count)
-			ctx->pb_count = enc_pb_count;
 		if (FW_HAS_E_MIN_SCRATCH_BUF(dev)) {
 			ctx->scratch_buf_size = s5p_mfc_hw_call(dev->mfc_ops,
 					get_e_min_scratch_buf_size, dev);
@@ -1563,14 +1560,6 @@ static int vidioc_reqbufs(struct file *file, void *priv,
 		}
 		ctx->capture_state = QUEUE_BUFS_REQUESTED;
 
-		ret = s5p_mfc_hw_call(ctx->dev->mfc_ops,
-				alloc_codec_buffers, ctx);
-		if (ret) {
-			mfc_err("Failed to allocate encoding buffers\n");
-			reqbufs->count = 0;
-			ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
-			return -ENOMEM;
-		}
 	} else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
 		if (reqbufs->count == 0) {
 			mfc_debug(2, "Freeing buffers\n");
@@ -1586,15 +1575,13 @@ static int vidioc_reqbufs(struct file *file, void *priv,
 			return -EINVAL;
 		}
 
-		if (IS_MFCV6_PLUS(dev)) {
+		if (IS_MFCV6_PLUS(dev) && (!IS_MFCV12(dev))) {
 			/* Check for min encoder buffers */
 			if (ctx->pb_count &&
 				(reqbufs->count < ctx->pb_count)) {
 				reqbufs->count = ctx->pb_count;
 				mfc_debug(2, "Minimum %d output buffers needed\n",
 						ctx->pb_count);
-			} else {
-				ctx->pb_count = reqbufs->count;
 			}
 		}
 
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
index 290d82e99940..7029a259157a 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
@@ -2145,6 +2145,14 @@ static inline int s5p_mfc_run_init_enc_buffers(struct s5p_mfc_ctx *ctx)
 	struct s5p_mfc_dev *dev = ctx->dev;
 	int ret;
 
+	ret = s5p_mfc_hw_call(ctx->dev->mfc_ops,
+			alloc_codec_buffers, ctx);
+	if (ret) {
+		mfc_err("Failed to allocate encoding buffers\n");
+		return -ENOMEM;
+	}
+	mfc_debug(2, "Allocated Internal Encoding Buffers\n");
+
 	dev->curr_ctx = ctx->num;
 	ret = s5p_mfc_set_enc_ref_buffer_v6(ctx);
 	if (ret) {
-- 
2.17.1


_______________________________________________
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] 54+ messages in thread

* [Patch v4 10/11] media: s5p-mfc: DPB Count Independent of VIDIOC_REQBUF
@ 2023-10-25 10:22       ` Aakarsh Jain
  0 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-10-25 10:22 UTC (permalink / raw)
  To: linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	aakarsh.jain, linux-fsd, Smitha T Murthy

Add allocation of DPB buffers based on MFC requirement so,
codec buffers allocations has been moved after state
MFCINST_HEAD_PRODUCED. It is taken care that codec buffer allocation
is performed in process context from userspace IOCTL call.

Cc: linux-fsd@tesla.com
Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
---
 .../platform/samsung/s5p-mfc/s5p_mfc_enc.c      | 17 ++---------------
 .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c   |  8 ++++++++
 2 files changed, 10 insertions(+), 15 deletions(-)

diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
index 80a97b86977e..fceceade979a 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
@@ -1164,7 +1164,6 @@ static int enc_post_seq_start(struct s5p_mfc_ctx *ctx)
 	struct s5p_mfc_dev *dev = ctx->dev;
 	struct s5p_mfc_enc_params *p = &ctx->enc_params;
 	struct s5p_mfc_buf *dst_mb;
-	unsigned int enc_pb_count;
 
 	if (p->seq_hdr_mode == V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) {
 		if (!list_empty(&ctx->dst_queue)) {
@@ -1186,10 +1185,8 @@ static int enc_post_seq_start(struct s5p_mfc_ctx *ctx)
 			set_work_bit_irqsave(ctx);
 		s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
 	} else {
-		enc_pb_count = s5p_mfc_hw_call(dev->mfc_ops,
+		ctx->pb_count = s5p_mfc_hw_call(dev->mfc_ops,
 				get_enc_dpb_count, dev);
-		if (ctx->pb_count < enc_pb_count)
-			ctx->pb_count = enc_pb_count;
 		if (FW_HAS_E_MIN_SCRATCH_BUF(dev)) {
 			ctx->scratch_buf_size = s5p_mfc_hw_call(dev->mfc_ops,
 					get_e_min_scratch_buf_size, dev);
@@ -1563,14 +1560,6 @@ static int vidioc_reqbufs(struct file *file, void *priv,
 		}
 		ctx->capture_state = QUEUE_BUFS_REQUESTED;
 
-		ret = s5p_mfc_hw_call(ctx->dev->mfc_ops,
-				alloc_codec_buffers, ctx);
-		if (ret) {
-			mfc_err("Failed to allocate encoding buffers\n");
-			reqbufs->count = 0;
-			ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
-			return -ENOMEM;
-		}
 	} else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
 		if (reqbufs->count == 0) {
 			mfc_debug(2, "Freeing buffers\n");
@@ -1586,15 +1575,13 @@ static int vidioc_reqbufs(struct file *file, void *priv,
 			return -EINVAL;
 		}
 
-		if (IS_MFCV6_PLUS(dev)) {
+		if (IS_MFCV6_PLUS(dev) && (!IS_MFCV12(dev))) {
 			/* Check for min encoder buffers */
 			if (ctx->pb_count &&
 				(reqbufs->count < ctx->pb_count)) {
 				reqbufs->count = ctx->pb_count;
 				mfc_debug(2, "Minimum %d output buffers needed\n",
 						ctx->pb_count);
-			} else {
-				ctx->pb_count = reqbufs->count;
 			}
 		}
 
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
index 290d82e99940..7029a259157a 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
@@ -2145,6 +2145,14 @@ static inline int s5p_mfc_run_init_enc_buffers(struct s5p_mfc_ctx *ctx)
 	struct s5p_mfc_dev *dev = ctx->dev;
 	int ret;
 
+	ret = s5p_mfc_hw_call(ctx->dev->mfc_ops,
+			alloc_codec_buffers, ctx);
+	if (ret) {
+		mfc_err("Failed to allocate encoding buffers\n");
+		return -ENOMEM;
+	}
+	mfc_debug(2, "Allocated Internal Encoding Buffers\n");
+
 	dev->curr_ctx = ctx->num;
 	ret = s5p_mfc_set_enc_ref_buffer_v6(ctx);
 	if (ret) {
-- 
2.17.1


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

* [Patch v4 11/11] arm64: dts: fsd: Add MFC related DT enteries
       [not found]   ` <CGME20231025102307epcas5p1fde3d5b0095477a8a565ce9f913e71e5@epcas5p1.samsung.com>
@ 2023-10-25 10:22       ` Aakarsh Jain
  0 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-10-25 10:22 UTC (permalink / raw)
  To: linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	aakarsh.jain, linux-fsd, Smitha T Murthy

Add MFC DT node and reserve memory node for MFC usage.

Cc: linux-fsd@tesla.com
Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
---
 arch/arm64/boot/dts/tesla/fsd.dtsi | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm64/boot/dts/tesla/fsd.dtsi b/arch/arm64/boot/dts/tesla/fsd.dtsi
index bb50a9f7db4a..f421012b0a4a 100644
--- a/arch/arm64/boot/dts/tesla/fsd.dtsi
+++ b/arch/arm64/boot/dts/tesla/fsd.dtsi
@@ -342,6 +342,18 @@
 		#clock-cells = <0>;
 	};
 
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		mfc_left: region@84000000 {
+			compatible = "shared-dma-pool";
+			no-map;
+			reg = <0 0x84000000 0 0x8000000>;
+		};
+	};
+
 	soc: soc@0 {
 		compatible = "simple-bus";
 		#address-cells = <2>;
@@ -956,6 +968,15 @@
 			clock-names = "fin_pll", "mct";
 		};
 
+		mfc: mfc@12880000 {
+			compatible = "tesla,fsd-mfc";
+			reg = <0x0 0x12880000 0x0 0x10000>;
+			interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
+			clock-names = "mfc";
+			clocks = <&clock_mfc MFC_MFC_IPCLKPORT_ACLK>;
+			memory-region = <&mfc_left>;
+		};
+
 		ufs: ufs@15120000 {
 			compatible = "tesla,fsd-ufs";
 			reg = <0x0 0x15120000 0x0 0x200>,  /* 0: HCI standard */
-- 
2.17.1


_______________________________________________
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] 54+ messages in thread

* [Patch v4 11/11] arm64: dts: fsd: Add MFC related DT enteries
@ 2023-10-25 10:22       ` Aakarsh Jain
  0 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-10-25 10:22 UTC (permalink / raw)
  To: linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	aakarsh.jain, linux-fsd, Smitha T Murthy

Add MFC DT node and reserve memory node for MFC usage.

Cc: linux-fsd@tesla.com
Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
---
 arch/arm64/boot/dts/tesla/fsd.dtsi | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm64/boot/dts/tesla/fsd.dtsi b/arch/arm64/boot/dts/tesla/fsd.dtsi
index bb50a9f7db4a..f421012b0a4a 100644
--- a/arch/arm64/boot/dts/tesla/fsd.dtsi
+++ b/arch/arm64/boot/dts/tesla/fsd.dtsi
@@ -342,6 +342,18 @@
 		#clock-cells = <0>;
 	};
 
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		mfc_left: region@84000000 {
+			compatible = "shared-dma-pool";
+			no-map;
+			reg = <0 0x84000000 0 0x8000000>;
+		};
+	};
+
 	soc: soc@0 {
 		compatible = "simple-bus";
 		#address-cells = <2>;
@@ -956,6 +968,15 @@
 			clock-names = "fin_pll", "mct";
 		};
 
+		mfc: mfc@12880000 {
+			compatible = "tesla,fsd-mfc";
+			reg = <0x0 0x12880000 0x0 0x10000>;
+			interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
+			clock-names = "mfc";
+			clocks = <&clock_mfc MFC_MFC_IPCLKPORT_ACLK>;
+			memory-region = <&mfc_left>;
+		};
+
 		ufs: ufs@15120000 {
 			compatible = "tesla,fsd-ufs";
 			reg = <0x0 0x15120000 0x0 0x200>,  /* 0: HCI standard */
-- 
2.17.1


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

* Re: [Patch v4 01/11] dt-bindings: media: s5p-mfc: Add mfcv12 variant
  2023-10-25 10:22       ` Aakarsh Jain
@ 2023-10-25 13:00         ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 54+ messages in thread
From: Krzysztof Kozlowski @ 2023-10-25 13:00 UTC (permalink / raw)
  To: Aakarsh Jain, linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	linux-fsd

On 25/10/2023 12:22, Aakarsh Jain wrote:
> Add Tesla FSD MFC(MFC v12) compatible.
> 
> Cc: linux-fsd@tesla.com
> Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
> ---

No changelog and your cover letter does not explain what happened here.
Specifically, why did you decide to ignore received tag.

>  .../bindings/media/samsung,s5p-mfc.yaml          | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/media/samsung,s5p-mfc.yaml b/Documentation/devicetree/bindings/media/samsung,s5p-mfc.yaml
> index 084b44582a43..c30eb309f670 100644
> --- a/Documentation/devicetree/bindings/media/samsung,s5p-mfc.yaml
> +++ b/Documentation/devicetree/bindings/media/samsung,s5p-mfc.yaml
> @@ -24,6 +24,7 @@ properties:
>            - samsung,mfc-v7                # Exynos5420
>            - samsung,mfc-v8                # Exynos5800
>            - samsung,mfc-v10               # Exynos7880
> +          - tesla,fsd-mfc                 # Tesla FSD
>        - items:
>            - enum:
>                - samsung,exynos3250-mfc    # Exynos3250
> @@ -165,6 +166,21 @@ allOf:
>            minItems: 1
>            maxItems: 2
>  
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - tesla,fsd-mfc
> +    then:
> +      properties:
> +        clocks:
> +          maxItems: 1
> +        clock-names:
> +          items:
> +            - const: mfc
> +        iommus: false

That's odd. How so? MFC v12 does not support IOMMU?

Best regards,
Krzysztof


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

* Re: [Patch v4 01/11] dt-bindings: media: s5p-mfc: Add mfcv12 variant
@ 2023-10-25 13:00         ` Krzysztof Kozlowski
  0 siblings, 0 replies; 54+ messages in thread
From: Krzysztof Kozlowski @ 2023-10-25 13:00 UTC (permalink / raw)
  To: Aakarsh Jain, linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	linux-fsd

On 25/10/2023 12:22, Aakarsh Jain wrote:
> Add Tesla FSD MFC(MFC v12) compatible.
> 
> Cc: linux-fsd@tesla.com
> Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
> ---

No changelog and your cover letter does not explain what happened here.
Specifically, why did you decide to ignore received tag.

>  .../bindings/media/samsung,s5p-mfc.yaml          | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/media/samsung,s5p-mfc.yaml b/Documentation/devicetree/bindings/media/samsung,s5p-mfc.yaml
> index 084b44582a43..c30eb309f670 100644
> --- a/Documentation/devicetree/bindings/media/samsung,s5p-mfc.yaml
> +++ b/Documentation/devicetree/bindings/media/samsung,s5p-mfc.yaml
> @@ -24,6 +24,7 @@ properties:
>            - samsung,mfc-v7                # Exynos5420
>            - samsung,mfc-v8                # Exynos5800
>            - samsung,mfc-v10               # Exynos7880
> +          - tesla,fsd-mfc                 # Tesla FSD
>        - items:
>            - enum:
>                - samsung,exynos3250-mfc    # Exynos3250
> @@ -165,6 +166,21 @@ allOf:
>            minItems: 1
>            maxItems: 2
>  
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - tesla,fsd-mfc
> +    then:
> +      properties:
> +        clocks:
> +          maxItems: 1
> +        clock-names:
> +          items:
> +            - const: mfc
> +        iommus: false

That's odd. How so? MFC v12 does not support IOMMU?

Best regards,
Krzysztof


_______________________________________________
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] 54+ messages in thread

* RE: [Patch v4 01/11] dt-bindings: media: s5p-mfc: Add mfcv12 variant
  2023-10-25 13:00         ` Krzysztof Kozlowski
@ 2023-10-26 13:31           ` Aakarsh Jain
  -1 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-10-26 13:31 UTC (permalink / raw)
  To: 'Krzysztof Kozlowski',
	linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	linux-fsd

Hello Krzysztof

> -----Original Message-----
> From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> Sent: 25 October 2023 18:30
> To: Aakarsh Jain <aakarsh.jain@samsung.com>; linux-arm-
> kernel@lists.infradead.org; linux-media@vger.kernel.org; linux-
> kernel@vger.kernel.org; devicetree@vger.kernel.org
> Cc: m.szyprowski@samsung.com; andrzej.hajda@intel.com;
> mchehab@kernel.org; hverkuil-cisco@xs4all.nl;
> krzysztof.kozlowski+dt@linaro.org; dillon.minfei@gmail.com;
> david.plowman@raspberrypi.com; mark.rutland@arm.com;
> robh+dt@kernel.org; conor+dt@kernel.org; linux-samsung-
> soc@vger.kernel.org; andi@etezian.org; gost.dev@samsung.com;
> alim.akhtar@samsung.com; aswani.reddy@samsung.com;
> pankaj.dubey@samsung.com; ajaykumar.rs@samsung.com; linux-
> fsd@tesla.com
> Subject: Re: [Patch v4 01/11] dt-bindings: media: s5p-mfc: Add mfcv12
> variant
> 
> On 25/10/2023 12:22, Aakarsh Jain wrote:
> > Add Tesla FSD MFC(MFC v12) compatible.
> >
> > Cc: linux-fsd@tesla.com
> > Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
> > ---
> 
> No changelog and your cover letter does not explain what happened here.
> Specifically, why did you decide to ignore received tag.
> 
Last patch series we had two different patches for schema which was one for adding MFCv12 compatible string and other for adding its HW properties.
In one of the patches you gave reviewed-by tag. Since mfc dt_schema got merged already, and this is relatively  new patch so thought of getting reviewed again.

Link to those patches:
https://patchwork.kernel.org/project/linux-media/patch/20221011122516.32135-2-aakarsh.jain@samsung.com/
https://patchwork.kernel.org/project/linux-media/patch/20221011122516.32135-3-aakarsh.jain@samsung.com/    

if you are ok, I will add your reviewed-by in next patch series.

> >  .../bindings/media/samsung,s5p-mfc.yaml          | 16 ++++++++++++++++
> >  1 file changed, 16 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/media/samsung,s5p-
> mfc.yaml b/Documentation/devicetree/bindings/media/samsung,s5p-
> mfc.yaml
> > index 084b44582a43..c30eb309f670 100644
> > --- a/Documentation/devicetree/bindings/media/samsung,s5p-mfc.yaml
> > +++ b/Documentation/devicetree/bindings/media/samsung,s5p-mfc.yaml
> > @@ -24,6 +24,7 @@ properties:
> >            - samsung,mfc-v7                # Exynos5420
> >            - samsung,mfc-v8                # Exynos5800
> >            - samsung,mfc-v10               # Exynos7880
> > +          - tesla,fsd-mfc                 # Tesla FSD
> >        - items:
> >            - enum:
> >                - samsung,exynos3250-mfc    # Exynos3250
> > @@ -165,6 +166,21 @@ allOf:
> >            minItems: 1
> >            maxItems: 2
> >
> > +  - if:
> > +      properties:
> > +        compatible:
> > +          contains:
> > +            enum:
> > +              - tesla,fsd-mfc
> > +    then:
> > +      properties:
> > +        clocks:
> > +          maxItems: 1
> > +        clock-names:
> > +          items:
> > +            - const: mfc
> > +        iommus: false
> 
> That's odd. How so? MFC v12 does not support IOMMU?
> 
MFC v12 do support IOMMU. But currently it is not enabled in SW (has dependencies on some of the floating dma-mapping patches) and not tested on upstream kernel. Current patch sets intend to add support for MFCv12 using reserve memory and later patches related to enable iommu will be posted (after resolving the dependencies). So I marked iommu property as false. 
Now what is your suggestion here? Should I keep iommu as false or add memory-region as below?
Ex-
  - if:
      properties:
        compatible:
          contains:
            enum:
              - tesla,fsd-mfc
    then:
      properties:
        clocks:
          maxItems: 1
        clock-names:
          items:
            - const: mfc
        memory-region:
          maxItems: 1


> Best regards,
> Krzysztof

Thanks for review.


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

* RE: [Patch v4 01/11] dt-bindings: media: s5p-mfc: Add mfcv12 variant
@ 2023-10-26 13:31           ` Aakarsh Jain
  0 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-10-26 13:31 UTC (permalink / raw)
  To: 'Krzysztof Kozlowski',
	linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	linux-fsd

Hello Krzysztof

> -----Original Message-----
> From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> Sent: 25 October 2023 18:30
> To: Aakarsh Jain <aakarsh.jain@samsung.com>; linux-arm-
> kernel@lists.infradead.org; linux-media@vger.kernel.org; linux-
> kernel@vger.kernel.org; devicetree@vger.kernel.org
> Cc: m.szyprowski@samsung.com; andrzej.hajda@intel.com;
> mchehab@kernel.org; hverkuil-cisco@xs4all.nl;
> krzysztof.kozlowski+dt@linaro.org; dillon.minfei@gmail.com;
> david.plowman@raspberrypi.com; mark.rutland@arm.com;
> robh+dt@kernel.org; conor+dt@kernel.org; linux-samsung-
> soc@vger.kernel.org; andi@etezian.org; gost.dev@samsung.com;
> alim.akhtar@samsung.com; aswani.reddy@samsung.com;
> pankaj.dubey@samsung.com; ajaykumar.rs@samsung.com; linux-
> fsd@tesla.com
> Subject: Re: [Patch v4 01/11] dt-bindings: media: s5p-mfc: Add mfcv12
> variant
> 
> On 25/10/2023 12:22, Aakarsh Jain wrote:
> > Add Tesla FSD MFC(MFC v12) compatible.
> >
> > Cc: linux-fsd@tesla.com
> > Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
> > ---
> 
> No changelog and your cover letter does not explain what happened here.
> Specifically, why did you decide to ignore received tag.
> 
Last patch series we had two different patches for schema which was one for adding MFCv12 compatible string and other for adding its HW properties.
In one of the patches you gave reviewed-by tag. Since mfc dt_schema got merged already, and this is relatively  new patch so thought of getting reviewed again.

Link to those patches:
https://patchwork.kernel.org/project/linux-media/patch/20221011122516.32135-2-aakarsh.jain@samsung.com/
https://patchwork.kernel.org/project/linux-media/patch/20221011122516.32135-3-aakarsh.jain@samsung.com/    

if you are ok, I will add your reviewed-by in next patch series.

> >  .../bindings/media/samsung,s5p-mfc.yaml          | 16 ++++++++++++++++
> >  1 file changed, 16 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/media/samsung,s5p-
> mfc.yaml b/Documentation/devicetree/bindings/media/samsung,s5p-
> mfc.yaml
> > index 084b44582a43..c30eb309f670 100644
> > --- a/Documentation/devicetree/bindings/media/samsung,s5p-mfc.yaml
> > +++ b/Documentation/devicetree/bindings/media/samsung,s5p-mfc.yaml
> > @@ -24,6 +24,7 @@ properties:
> >            - samsung,mfc-v7                # Exynos5420
> >            - samsung,mfc-v8                # Exynos5800
> >            - samsung,mfc-v10               # Exynos7880
> > +          - tesla,fsd-mfc                 # Tesla FSD
> >        - items:
> >            - enum:
> >                - samsung,exynos3250-mfc    # Exynos3250
> > @@ -165,6 +166,21 @@ allOf:
> >            minItems: 1
> >            maxItems: 2
> >
> > +  - if:
> > +      properties:
> > +        compatible:
> > +          contains:
> > +            enum:
> > +              - tesla,fsd-mfc
> > +    then:
> > +      properties:
> > +        clocks:
> > +          maxItems: 1
> > +        clock-names:
> > +          items:
> > +            - const: mfc
> > +        iommus: false
> 
> That's odd. How so? MFC v12 does not support IOMMU?
> 
MFC v12 do support IOMMU. But currently it is not enabled in SW (has dependencies on some of the floating dma-mapping patches) and not tested on upstream kernel. Current patch sets intend to add support for MFCv12 using reserve memory and later patches related to enable iommu will be posted (after resolving the dependencies). So I marked iommu property as false. 
Now what is your suggestion here? Should I keep iommu as false or add memory-region as below?
Ex-
  - if:
      properties:
        compatible:
          contains:
            enum:
              - tesla,fsd-mfc
    then:
      properties:
        clocks:
          maxItems: 1
        clock-names:
          items:
            - const: mfc
        memory-region:
          maxItems: 1


> Best regards,
> Krzysztof

Thanks for review.


_______________________________________________
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] 54+ messages in thread

* Re: [Patch v4 01/11] dt-bindings: media: s5p-mfc: Add mfcv12 variant
  2023-10-26 13:31           ` Aakarsh Jain
@ 2023-11-01  8:24             ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 54+ messages in thread
From: Krzysztof Kozlowski @ 2023-11-01  8:24 UTC (permalink / raw)
  To: Aakarsh Jain, linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	linux-fsd

On 26/10/2023 15:31, Aakarsh Jain wrote:
> Hello Krzysztof
> 
>> -----Original Message-----
>> From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
>> Sent: 25 October 2023 18:30
>> To: Aakarsh Jain <aakarsh.jain@samsung.com>; linux-arm-
>> kernel@lists.infradead.org; linux-media@vger.kernel.org; linux-
>> kernel@vger.kernel.org; devicetree@vger.kernel.org
>> Cc: m.szyprowski@samsung.com; andrzej.hajda@intel.com;
>> mchehab@kernel.org; hverkuil-cisco@xs4all.nl;
>> krzysztof.kozlowski+dt@linaro.org; dillon.minfei@gmail.com;
>> david.plowman@raspberrypi.com; mark.rutland@arm.com;
>> robh+dt@kernel.org; conor+dt@kernel.org; linux-samsung-
>> soc@vger.kernel.org; andi@etezian.org; gost.dev@samsung.com;
>> alim.akhtar@samsung.com; aswani.reddy@samsung.com;
>> pankaj.dubey@samsung.com; ajaykumar.rs@samsung.com; linux-
>> fsd@tesla.com
>> Subject: Re: [Patch v4 01/11] dt-bindings: media: s5p-mfc: Add mfcv12
>> variant
>>
>> On 25/10/2023 12:22, Aakarsh Jain wrote:
>>> Add Tesla FSD MFC(MFC v12) compatible.
>>>
>>> Cc: linux-fsd@tesla.com
>>> Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
>>> ---
>>
>> No changelog and your cover letter does not explain what happened here.
>> Specifically, why did you decide to ignore received tag.
>>
> Last patch series we had two different patches for schema which was one for adding MFCv12 compatible string and other for adding its HW properties.
> In one of the patches you gave reviewed-by tag. Since mfc dt_schema got merged already, and this is relatively  new patch so thought of getting reviewed again.
> 
> Link to those patches:
> https://patchwork.kernel.org/project/linux-media/patch/20221011122516.32135-2-aakarsh.jain@samsung.com/
> https://patchwork.kernel.org/project/linux-media/patch/20221011122516.32135-3-aakarsh.jain@samsung.com/    
> 
> if you are ok, I will add your reviewed-by in next patch series.

It is okay to drop Reviewed-by tag, but this should be explicitly
mentioned in the changelog with a reason.

> 
>>>  .../bindings/media/samsung,s5p-mfc.yaml          | 16 ++++++++++++++++
>>>  1 file changed, 16 insertions(+)
>>>
>>> diff --git a/Documentation/devicetree/bindings/media/samsung,s5p-
>> mfc.yaml b/Documentation/devicetree/bindings/media/samsung,s5p-
>> mfc.yaml
>>> index 084b44582a43..c30eb309f670 100644
>>> --- a/Documentation/devicetree/bindings/media/samsung,s5p-mfc.yaml
>>> +++ b/Documentation/devicetree/bindings/media/samsung,s5p-mfc.yaml
>>> @@ -24,6 +24,7 @@ properties:
>>>            - samsung,mfc-v7                # Exynos5420
>>>            - samsung,mfc-v8                # Exynos5800
>>>            - samsung,mfc-v10               # Exynos7880
>>> +          - tesla,fsd-mfc                 # Tesla FSD
>>>        - items:
>>>            - enum:
>>>                - samsung,exynos3250-mfc    # Exynos3250
>>> @@ -165,6 +166,21 @@ allOf:
>>>            minItems: 1
>>>            maxItems: 2
>>>
>>> +  - if:
>>> +      properties:
>>> +        compatible:
>>> +          contains:
>>> +            enum:
>>> +              - tesla,fsd-mfc
>>> +    then:
>>> +      properties:
>>> +        clocks:
>>> +          maxItems: 1
>>> +        clock-names:
>>> +          items:
>>> +            - const: mfc
>>> +        iommus: false
>>
>> That's odd. How so? MFC v12 does not support IOMMU?
>>
> MFC v12 do support IOMMU. But currently it is not enabled in SW (has dependencies on some of the floating dma-mapping patches) and not tested on upstream kernel. 

Bindings describe hardware, not software.

> Current patch sets intend to add support for MFCv12 using reserve memory and later patches related to enable iommu will be posted (after resolving the dependencies). So I marked iommu property as false. 
> Now what is your suggestion here? Should I keep iommu as false or add memory-region as below?

I expect complete picture of the hardware, not something limited to
current driver, so for sure iommus must be there.

Please wrap your emails according to mailing lists rules.

Best regards,
Krzysztof


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

* Re: [Patch v4 01/11] dt-bindings: media: s5p-mfc: Add mfcv12 variant
@ 2023-11-01  8:24             ` Krzysztof Kozlowski
  0 siblings, 0 replies; 54+ messages in thread
From: Krzysztof Kozlowski @ 2023-11-01  8:24 UTC (permalink / raw)
  To: Aakarsh Jain, linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	linux-fsd

On 26/10/2023 15:31, Aakarsh Jain wrote:
> Hello Krzysztof
> 
>> -----Original Message-----
>> From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
>> Sent: 25 October 2023 18:30
>> To: Aakarsh Jain <aakarsh.jain@samsung.com>; linux-arm-
>> kernel@lists.infradead.org; linux-media@vger.kernel.org; linux-
>> kernel@vger.kernel.org; devicetree@vger.kernel.org
>> Cc: m.szyprowski@samsung.com; andrzej.hajda@intel.com;
>> mchehab@kernel.org; hverkuil-cisco@xs4all.nl;
>> krzysztof.kozlowski+dt@linaro.org; dillon.minfei@gmail.com;
>> david.plowman@raspberrypi.com; mark.rutland@arm.com;
>> robh+dt@kernel.org; conor+dt@kernel.org; linux-samsung-
>> soc@vger.kernel.org; andi@etezian.org; gost.dev@samsung.com;
>> alim.akhtar@samsung.com; aswani.reddy@samsung.com;
>> pankaj.dubey@samsung.com; ajaykumar.rs@samsung.com; linux-
>> fsd@tesla.com
>> Subject: Re: [Patch v4 01/11] dt-bindings: media: s5p-mfc: Add mfcv12
>> variant
>>
>> On 25/10/2023 12:22, Aakarsh Jain wrote:
>>> Add Tesla FSD MFC(MFC v12) compatible.
>>>
>>> Cc: linux-fsd@tesla.com
>>> Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
>>> ---
>>
>> No changelog and your cover letter does not explain what happened here.
>> Specifically, why did you decide to ignore received tag.
>>
> Last patch series we had two different patches for schema which was one for adding MFCv12 compatible string and other for adding its HW properties.
> In one of the patches you gave reviewed-by tag. Since mfc dt_schema got merged already, and this is relatively  new patch so thought of getting reviewed again.
> 
> Link to those patches:
> https://patchwork.kernel.org/project/linux-media/patch/20221011122516.32135-2-aakarsh.jain@samsung.com/
> https://patchwork.kernel.org/project/linux-media/patch/20221011122516.32135-3-aakarsh.jain@samsung.com/    
> 
> if you are ok, I will add your reviewed-by in next patch series.

It is okay to drop Reviewed-by tag, but this should be explicitly
mentioned in the changelog with a reason.

> 
>>>  .../bindings/media/samsung,s5p-mfc.yaml          | 16 ++++++++++++++++
>>>  1 file changed, 16 insertions(+)
>>>
>>> diff --git a/Documentation/devicetree/bindings/media/samsung,s5p-
>> mfc.yaml b/Documentation/devicetree/bindings/media/samsung,s5p-
>> mfc.yaml
>>> index 084b44582a43..c30eb309f670 100644
>>> --- a/Documentation/devicetree/bindings/media/samsung,s5p-mfc.yaml
>>> +++ b/Documentation/devicetree/bindings/media/samsung,s5p-mfc.yaml
>>> @@ -24,6 +24,7 @@ properties:
>>>            - samsung,mfc-v7                # Exynos5420
>>>            - samsung,mfc-v8                # Exynos5800
>>>            - samsung,mfc-v10               # Exynos7880
>>> +          - tesla,fsd-mfc                 # Tesla FSD
>>>        - items:
>>>            - enum:
>>>                - samsung,exynos3250-mfc    # Exynos3250
>>> @@ -165,6 +166,21 @@ allOf:
>>>            minItems: 1
>>>            maxItems: 2
>>>
>>> +  - if:
>>> +      properties:
>>> +        compatible:
>>> +          contains:
>>> +            enum:
>>> +              - tesla,fsd-mfc
>>> +    then:
>>> +      properties:
>>> +        clocks:
>>> +          maxItems: 1
>>> +        clock-names:
>>> +          items:
>>> +            - const: mfc
>>> +        iommus: false
>>
>> That's odd. How so? MFC v12 does not support IOMMU?
>>
> MFC v12 do support IOMMU. But currently it is not enabled in SW (has dependencies on some of the floating dma-mapping patches) and not tested on upstream kernel. 

Bindings describe hardware, not software.

> Current patch sets intend to add support for MFCv12 using reserve memory and later patches related to enable iommu will be posted (after resolving the dependencies). So I marked iommu property as false. 
> Now what is your suggestion here? Should I keep iommu as false or add memory-region as below?

I expect complete picture of the hardware, not something limited to
current driver, so for sure iommus must be there.

Please wrap your emails according to mailing lists rules.

Best regards,
Krzysztof


_______________________________________________
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] 54+ messages in thread

* RE: [Patch v4 01/11] dt-bindings: media: s5p-mfc: Add mfcv12 variant
  2023-11-01  8:24             ` Krzysztof Kozlowski
@ 2023-11-08 17:24               ` Alim Akhtar
  -1 siblings, 0 replies; 54+ messages in thread
From: Alim Akhtar @ 2023-11-08 17:24 UTC (permalink / raw)
  To: 'Krzysztof Kozlowski', 'Aakarsh Jain',
	linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, aswani.reddy, pankaj.dubey, ajaykumar.rs, linux-fsd

Hi Aakarsh

> -----Original Message-----
> From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> Sent: Wednesday, November 1, 2023 1:54 PM
> To: Aakarsh Jain <aakarsh.jain@samsung.com>; linux-arm-
> kernel@lists.infradead.org; linux-media@vger.kernel.org; linux-
> kernel@vger.kernel.org; devicetree@vger.kernel.org
> Cc: m.szyprowski@samsung.com; andrzej.hajda@intel.com;
> mchehab@kernel.org; hverkuil-cisco@xs4all.nl;
> krzysztof.kozlowski+dt@linaro.org; dillon.minfei@gmail.com;
> david.plowman@raspberrypi.com; mark.rutland@arm.com;
> robh+dt@kernel.org; conor+dt@kernel.org; linux-samsung-
> soc@vger.kernel.org; andi@etezian.org; gost.dev@samsung.com;
> alim.akhtar@samsung.com; aswani.reddy@samsung.com;
> pankaj.dubey@samsung.com; ajaykumar.rs@samsung.com; linux-
> fsd@tesla.com
> Subject: Re: [Patch v4 01/11] dt-bindings: media: s5p-mfc: Add mfcv12
> variant
> 
> On 26/10/2023 15:31, Aakarsh Jain wrote:
> > Hello Krzysztof
> >
> >> -----Original Message-----
> >> From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> >> Sent: 25 October 2023 18:30
> >> To: Aakarsh Jain <aakarsh.jain@samsung.com>; linux-arm-
> >> kernel@lists.infradead.org; linux-media@vger.kernel.org; linux-
> >> kernel@vger.kernel.org; devicetree@vger.kernel.org
> >> Cc: m.szyprowski@samsung.com; andrzej.hajda@intel.com;
> >> mchehab@kernel.org; hverkuil-cisco@xs4all.nl;
> >> krzysztof.kozlowski+dt@linaro.org; dillon.minfei@gmail.com;
> >> david.plowman@raspberrypi.com; mark.rutland@arm.com;
> >> robh+dt@kernel.org; conor+dt@kernel.org; linux-samsung-
> >> soc@vger.kernel.org; andi@etezian.org; gost.dev@samsung.com;
> >> alim.akhtar@samsung.com; aswani.reddy@samsung.com;
> >> pankaj.dubey@samsung.com; ajaykumar.rs@samsung.com; linux-
> >> fsd@tesla.com
> >> Subject: Re: [Patch v4 01/11] dt-bindings: media: s5p-mfc: Add mfcv12
> >> variant
> >>
> >> On 25/10/2023 12:22, Aakarsh Jain wrote:
> >>> Add Tesla FSD MFC(MFC v12) compatible.
> >>>
> >>> Cc: linux-fsd@tesla.com
> >>> Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
> >>> ---
> >>
> >> No changelog and your cover letter does not explain what happened
> here.
> >> Specifically, why did you decide to ignore received tag.
> >>
> > Last patch series we had two different patches for schema which was one
> for adding MFCv12 compatible string and other for adding its HW properties.
> > In one of the patches you gave reviewed-by tag. Since mfc dt_schema got
> merged already, and this is relatively  new patch so thought of getting
> reviewed again.
> >
> > Link to those patches:
> > https://patchwork.kernel.org/project/linux-
> media/patch/20221011122516.32135-2-aakarsh.jain@samsung.com/
> > https://patchwork.kernel.org/project/linux-
> media/patch/20221011122516.32135-3-aakarsh.jain@samsung.com/
> >
> > if you are ok, I will add your reviewed-by in next patch series.
> 
> It is okay to drop Reviewed-by tag, but this should be explicitly mentioned in
> the changelog with a reason.
> 
> >
> >>>  .../bindings/media/samsung,s5p-mfc.yaml          | 16
> ++++++++++++++++
> >>>  1 file changed, 16 insertions(+)
> >>>
> >>> diff --git a/Documentation/devicetree/bindings/media/samsung,s5p-
> >> mfc.yaml b/Documentation/devicetree/bindings/media/samsung,s5p-
> >> mfc.yaml
> >>> index 084b44582a43..c30eb309f670 100644
> >>> --- a/Documentation/devicetree/bindings/media/samsung,s5p-
> mfc.yaml
> >>> +++ b/Documentation/devicetree/bindings/media/samsung,s5p-
> mfc.yaml
> >>> @@ -24,6 +24,7 @@ properties:
> >>>            - samsung,mfc-v7                # Exynos5420
> >>>            - samsung,mfc-v8                # Exynos5800
> >>>            - samsung,mfc-v10               # Exynos7880
> >>> +          - tesla,fsd-mfc                 # Tesla FSD
> >>>        - items:
> >>>            - enum:
> >>>                - samsung,exynos3250-mfc    # Exynos3250
> >>> @@ -165,6 +166,21 @@ allOf:
> >>>            minItems: 1
> >>>            maxItems: 2
> >>>
> >>> +  - if:
> >>> +      properties:
> >>> +        compatible:
> >>> +          contains:
> >>> +            enum:
> >>> +              - tesla,fsd-mfc
> >>> +    then:
> >>> +      properties:
> >>> +        clocks:
> >>> +          maxItems: 1
> >>> +        clock-names:
> >>> +          items:
> >>> +            - const: mfc
> >>> +        iommus: false
> >>
> >> That's odd. How so? MFC v12 does not support IOMMU?
> >>
> > MFC v12 do support IOMMU. But currently it is not enabled in SW (has
> dependencies on some of the floating dma-mapping patches) and not tested
> on upstream kernel.
> 
> Bindings describe hardware, not software.
> 
> > Current patch sets intend to add support for MFCv12 using reserve
> memory and later patches related to enable iommu will be posted (after
> resolving the dependencies). So I marked iommu property as false.
> > Now what is your suggestion here? Should I keep iommu as false or add
> memory-region as below?
> 
> I expect complete picture of the hardware, not something limited to current
> driver, so for sure iommus must be there.
> 
As Krzysztof mentioned, DT binding should explain all the hardware features supported by SoC / IPs. 
Incase a feature is not enabled for some reason, that need to be handled in the dts file.

> Please wrap your emails according to mailing lists rules.
> 
> Best regards,
> Krzysztof



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

* RE: [Patch v4 01/11] dt-bindings: media: s5p-mfc: Add mfcv12 variant
@ 2023-11-08 17:24               ` Alim Akhtar
  0 siblings, 0 replies; 54+ messages in thread
From: Alim Akhtar @ 2023-11-08 17:24 UTC (permalink / raw)
  To: 'Krzysztof Kozlowski', 'Aakarsh Jain',
	linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, aswani.reddy, pankaj.dubey, ajaykumar.rs, linux-fsd

Hi Aakarsh

> -----Original Message-----
> From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> Sent: Wednesday, November 1, 2023 1:54 PM
> To: Aakarsh Jain <aakarsh.jain@samsung.com>; linux-arm-
> kernel@lists.infradead.org; linux-media@vger.kernel.org; linux-
> kernel@vger.kernel.org; devicetree@vger.kernel.org
> Cc: m.szyprowski@samsung.com; andrzej.hajda@intel.com;
> mchehab@kernel.org; hverkuil-cisco@xs4all.nl;
> krzysztof.kozlowski+dt@linaro.org; dillon.minfei@gmail.com;
> david.plowman@raspberrypi.com; mark.rutland@arm.com;
> robh+dt@kernel.org; conor+dt@kernel.org; linux-samsung-
> soc@vger.kernel.org; andi@etezian.org; gost.dev@samsung.com;
> alim.akhtar@samsung.com; aswani.reddy@samsung.com;
> pankaj.dubey@samsung.com; ajaykumar.rs@samsung.com; linux-
> fsd@tesla.com
> Subject: Re: [Patch v4 01/11] dt-bindings: media: s5p-mfc: Add mfcv12
> variant
> 
> On 26/10/2023 15:31, Aakarsh Jain wrote:
> > Hello Krzysztof
> >
> >> -----Original Message-----
> >> From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> >> Sent: 25 October 2023 18:30
> >> To: Aakarsh Jain <aakarsh.jain@samsung.com>; linux-arm-
> >> kernel@lists.infradead.org; linux-media@vger.kernel.org; linux-
> >> kernel@vger.kernel.org; devicetree@vger.kernel.org
> >> Cc: m.szyprowski@samsung.com; andrzej.hajda@intel.com;
> >> mchehab@kernel.org; hverkuil-cisco@xs4all.nl;
> >> krzysztof.kozlowski+dt@linaro.org; dillon.minfei@gmail.com;
> >> david.plowman@raspberrypi.com; mark.rutland@arm.com;
> >> robh+dt@kernel.org; conor+dt@kernel.org; linux-samsung-
> >> soc@vger.kernel.org; andi@etezian.org; gost.dev@samsung.com;
> >> alim.akhtar@samsung.com; aswani.reddy@samsung.com;
> >> pankaj.dubey@samsung.com; ajaykumar.rs@samsung.com; linux-
> >> fsd@tesla.com
> >> Subject: Re: [Patch v4 01/11] dt-bindings: media: s5p-mfc: Add mfcv12
> >> variant
> >>
> >> On 25/10/2023 12:22, Aakarsh Jain wrote:
> >>> Add Tesla FSD MFC(MFC v12) compatible.
> >>>
> >>> Cc: linux-fsd@tesla.com
> >>> Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
> >>> ---
> >>
> >> No changelog and your cover letter does not explain what happened
> here.
> >> Specifically, why did you decide to ignore received tag.
> >>
> > Last patch series we had two different patches for schema which was one
> for adding MFCv12 compatible string and other for adding its HW properties.
> > In one of the patches you gave reviewed-by tag. Since mfc dt_schema got
> merged already, and this is relatively  new patch so thought of getting
> reviewed again.
> >
> > Link to those patches:
> > https://patchwork.kernel.org/project/linux-
> media/patch/20221011122516.32135-2-aakarsh.jain@samsung.com/
> > https://patchwork.kernel.org/project/linux-
> media/patch/20221011122516.32135-3-aakarsh.jain@samsung.com/
> >
> > if you are ok, I will add your reviewed-by in next patch series.
> 
> It is okay to drop Reviewed-by tag, but this should be explicitly mentioned in
> the changelog with a reason.
> 
> >
> >>>  .../bindings/media/samsung,s5p-mfc.yaml          | 16
> ++++++++++++++++
> >>>  1 file changed, 16 insertions(+)
> >>>
> >>> diff --git a/Documentation/devicetree/bindings/media/samsung,s5p-
> >> mfc.yaml b/Documentation/devicetree/bindings/media/samsung,s5p-
> >> mfc.yaml
> >>> index 084b44582a43..c30eb309f670 100644
> >>> --- a/Documentation/devicetree/bindings/media/samsung,s5p-
> mfc.yaml
> >>> +++ b/Documentation/devicetree/bindings/media/samsung,s5p-
> mfc.yaml
> >>> @@ -24,6 +24,7 @@ properties:
> >>>            - samsung,mfc-v7                # Exynos5420
> >>>            - samsung,mfc-v8                # Exynos5800
> >>>            - samsung,mfc-v10               # Exynos7880
> >>> +          - tesla,fsd-mfc                 # Tesla FSD
> >>>        - items:
> >>>            - enum:
> >>>                - samsung,exynos3250-mfc    # Exynos3250
> >>> @@ -165,6 +166,21 @@ allOf:
> >>>            minItems: 1
> >>>            maxItems: 2
> >>>
> >>> +  - if:
> >>> +      properties:
> >>> +        compatible:
> >>> +          contains:
> >>> +            enum:
> >>> +              - tesla,fsd-mfc
> >>> +    then:
> >>> +      properties:
> >>> +        clocks:
> >>> +          maxItems: 1
> >>> +        clock-names:
> >>> +          items:
> >>> +            - const: mfc
> >>> +        iommus: false
> >>
> >> That's odd. How so? MFC v12 does not support IOMMU?
> >>
> > MFC v12 do support IOMMU. But currently it is not enabled in SW (has
> dependencies on some of the floating dma-mapping patches) and not tested
> on upstream kernel.
> 
> Bindings describe hardware, not software.
> 
> > Current patch sets intend to add support for MFCv12 using reserve
> memory and later patches related to enable iommu will be posted (after
> resolving the dependencies). So I marked iommu property as false.
> > Now what is your suggestion here? Should I keep iommu as false or add
> memory-region as below?
> 
> I expect complete picture of the hardware, not something limited to current
> driver, so for sure iommus must be there.
> 
As Krzysztof mentioned, DT binding should explain all the hardware features supported by SoC / IPs. 
Incase a feature is not enabled for some reason, that need to be handled in the dts file.

> Please wrap your emails according to mailing lists rules.
> 
> Best regards,
> Krzysztof



_______________________________________________
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] 54+ messages in thread

* RE: [Patch v4 02/11] media: s5p-mfc: Rename IS_MFCV10 macro
  2023-10-25 10:22       ` Aakarsh Jain
@ 2023-11-16  5:00         ` Alim Akhtar
  -1 siblings, 0 replies; 54+ messages in thread
From: Alim Akhtar @ 2023-11-16  5:00 UTC (permalink / raw)
  To: 'Aakarsh Jain',
	linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, aswani.reddy, pankaj.dubey, ajaykumar.rs, linux-fsd,
	'Smitha T Murthy'

Hi Aakarsh

> -----Original Message-----
> From: Aakarsh Jain <aakarsh.jain@samsung.com>
> Sent: Wednesday, October 25, 2023 3:52 PM
> To: linux-arm-kernel@lists.infradead.org; linux-media@vger.kernel.org;
> linux-kernel@vger.kernel.org; devicetree@vger.kernel.org
> Cc: m.szyprowski@samsung.com; andrzej.hajda@intel.com;
> mchehab@kernel.org; hverkuil-cisco@xs4all.nl;
> krzysztof.kozlowski+dt@linaro.org; dillon.minfei@gmail.com;
> david.plowman@raspberrypi.com; mark.rutland@arm.com;
> robh+dt@kernel.org; conor+dt@kernel.org; linux-samsung-
> soc@vger.kernel.org; andi@etezian.org; gost.dev@samsung.com;
> alim.akhtar@samsung.com; aswani.reddy@samsung.com;
> pankaj.dubey@samsung.com; ajaykumar.rs@samsung.com;
> aakarsh.jain@samsung.com; linux-fsd@tesla.com; Smitha T Murthy
> <smithatmurthy@gmail.com>
> Subject: [Patch v4 02/11] media: s5p-mfc: Rename IS_MFCV10 macro
> 
> Renames macro IS_MFCV10 to IS_MFCV10_PLUS so that the MFCv10 code
> can be resued for MFCv12 support. Since some part of MFCv10 specific code
> holds good for MFCv12 also.
> 
> Cc: linux-fsd@tesla.com
> Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
> Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
> ---

Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com>

>  .../platform/samsung/s5p-mfc/s5p_mfc_common.h | 10 +++----
>  .../platform/samsung/s5p-mfc/s5p_mfc_ctrl.c   |  2 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 28 +++++++++----------
>  3 files changed, 20 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> index 5304f42c8c72..e6ec4a43b290 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> @@ -771,11 +771,11 @@ void s5p_mfc_cleanup_queue(struct list_head *lh,
> struct vb2_queue *vq);
>  #define HAS_PORTNUM(dev)	(dev ? (dev->variant ? \
>  				(dev->variant->port_num ? 1 : 0) : 0) : 0)
>  #define IS_TWOPORT(dev)		(dev->variant->port_num == 2 ? 1 : 0)
> -#define IS_MFCV6_PLUS(dev)	(dev->variant->version >= 0x60 ? 1 :
> 0)
> -#define IS_MFCV7_PLUS(dev)	(dev->variant->version >= 0x70 ? 1 :
> 0)
> -#define IS_MFCV8_PLUS(dev)	(dev->variant->version >= 0x80 ? 1 :
> 0)
> -#define IS_MFCV10(dev)		(dev->variant->version >= 0xA0 ? 1 :
> 0)
> -#define FW_HAS_E_MIN_SCRATCH_BUF(dev) (IS_MFCV10(dev))
> +#define IS_MFCV6_PLUS(dev)	(dev->variant->version >= 0x60)
> +#define IS_MFCV7_PLUS(dev)	(dev->variant->version >= 0x70)
> +#define IS_MFCV8_PLUS(dev)	(dev->variant->version >= 0x80)
> +#define IS_MFCV10_PLUS(dev)	(dev->variant->version >= 0xA0)
> +#define FW_HAS_E_MIN_SCRATCH_BUF(dev) (IS_MFCV10_PLUS(dev))
> 
>  #define MFC_V5_BIT	BIT(0)
>  #define MFC_V6_BIT	BIT(1)
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> index 6d3c92045c05..54b54b2fa9b1 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> @@ -236,7 +236,7 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
>  	else
>  		mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET);
> 
> -	if (IS_MFCV10(dev))
> +	if (IS_MFCV10_PLUS(dev))
>  		mfc_write(dev, 0x0, S5P_FIMV_MFC_CLOCK_OFF_V10);
> 
>  	mfc_debug(2, "Will now wait for completion of firmware
> transfer\n"); diff --git a/drivers/media/platform/samsung/s5p-
> mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/samsung/s5p-
> mfc/s5p_mfc_opr_v6.c
> index c0df5ac9fcff..882166e4ac50 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> @@ -72,9 +72,9 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct
> s5p_mfc_ctx *ctx)
>  			  ctx->luma_size, ctx->chroma_size, ctx->mv_size);
>  		mfc_debug(2, "Totals bufs: %d\n", ctx->total_dpb_count);
>  	} else if (ctx->type == MFCINST_ENCODER) {
> -		if (IS_MFCV10(dev)) {
> +		if (IS_MFCV10_PLUS(dev))
>  			ctx->tmv_buffer_size = 0;
> -		} else if (IS_MFCV8_PLUS(dev))
> +		else if (IS_MFCV8_PLUS(dev))
>  			ctx->tmv_buffer_size =
> S5P_FIMV_NUM_TMV_BUFFERS_V6 *
> 
> 	ALIGN(S5P_FIMV_TMV_BUFFER_SIZE_V8(mb_width, mb_height),
>  			S5P_FIMV_TMV_BUFFER_ALIGN_V6);
> @@ -82,7 +82,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct
> s5p_mfc_ctx *ctx)
>  			ctx->tmv_buffer_size =
> S5P_FIMV_NUM_TMV_BUFFERS_V6 *
> 
> 	ALIGN(S5P_FIMV_TMV_BUFFER_SIZE_V6(mb_width, mb_height),
>  			S5P_FIMV_TMV_BUFFER_ALIGN_V6);
> -		if (IS_MFCV10(dev)) {
> +		if (IS_MFCV10_PLUS(dev)) {
>  			lcu_width = S5P_MFC_LCU_WIDTH(ctx->img_width);
>  			lcu_height = S5P_MFC_LCU_HEIGHT(ctx-
> >img_height);
>  			if (ctx->codec_mode !=
> S5P_FIMV_CODEC_HEVC_ENC) { @@ -133,7 +133,7 @@ static int
> s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
>  	switch (ctx->codec_mode) {
>  	case S5P_MFC_CODEC_H264_DEC:
>  	case S5P_MFC_CODEC_H264_MVC_DEC:
> -		if (IS_MFCV10(dev))
> +		if (IS_MFCV10_PLUS(dev))
>  			mfc_debug(2, "Use min scratch buffer size\n");
>  		else if (IS_MFCV8_PLUS(dev))
>  			ctx->scratch_buf_size =
> @@ -152,7 +152,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct
> s5p_mfc_ctx *ctx)
>  			(ctx->mv_count * ctx->mv_size);
>  		break;
>  	case S5P_MFC_CODEC_MPEG4_DEC:
> -		if (IS_MFCV10(dev))
> +		if (IS_MFCV10_PLUS(dev))
>  			mfc_debug(2, "Use min scratch buffer size\n");
>  		else if (IS_MFCV7_PLUS(dev)) {
>  			ctx->scratch_buf_size =
> @@ -172,7 +172,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct
> s5p_mfc_ctx *ctx)
>  		break;
>  	case S5P_MFC_CODEC_VC1RCV_DEC:
>  	case S5P_MFC_CODEC_VC1_DEC:
> -		if (IS_MFCV10(dev))
> +		if (IS_MFCV10_PLUS(dev))
>  			mfc_debug(2, "Use min scratch buffer size\n");
>  		else
>  			ctx->scratch_buf_size =
> @@ -189,7 +189,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct
> s5p_mfc_ctx *ctx)
>  		ctx->bank2.size = 0;
>  		break;
>  	case S5P_MFC_CODEC_H263_DEC:
> -		if (IS_MFCV10(dev))
> +		if (IS_MFCV10_PLUS(dev))
>  			mfc_debug(2, "Use min scratch buffer size\n");
>  		else
>  			ctx->scratch_buf_size =
> @@ -201,7 +201,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct
> s5p_mfc_ctx *ctx)
>  		ctx->bank1.size = ctx->scratch_buf_size;
>  		break;
>  	case S5P_MFC_CODEC_VP8_DEC:
> -		if (IS_MFCV10(dev))
> +		if (IS_MFCV10_PLUS(dev))
>  			mfc_debug(2, "Use min scratch buffer size\n");
>  		else if (IS_MFCV8_PLUS(dev))
>  			ctx->scratch_buf_size =
> @@ -230,7 +230,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct
> s5p_mfc_ctx *ctx)
>  			DEC_VP9_STATIC_BUFFER_SIZE;
>  		break;
>  	case S5P_MFC_CODEC_H264_ENC:
> -		if (IS_MFCV10(dev)) {
> +		if (IS_MFCV10_PLUS(dev)) {
>  			mfc_debug(2, "Use min scratch buffer size\n");
>  			ctx->me_buffer_size =
>  			ALIGN(ENC_V100_H264_ME_SIZE(mb_width,
> mb_height), 16); @@ -254,7 +254,7 @@ static int
> s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
>  		break;
>  	case S5P_MFC_CODEC_MPEG4_ENC:
>  	case S5P_MFC_CODEC_H263_ENC:
> -		if (IS_MFCV10(dev)) {
> +		if (IS_MFCV10_PLUS(dev)) {
>  			mfc_debug(2, "Use min scratch buffer size\n");
>  			ctx->me_buffer_size =
> 
> 	ALIGN(ENC_V100_MPEG4_ME_SIZE(mb_width,
> @@ -273,7 +273,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct
> s5p_mfc_ctx *ctx)
>  		ctx->bank2.size = 0;
>  		break;
>  	case S5P_MFC_CODEC_VP8_ENC:
> -		if (IS_MFCV10(dev)) {
> +		if (IS_MFCV10_PLUS(dev)) {
>  			mfc_debug(2, "Use min scratch buffer size\n");
>  			ctx->me_buffer_size =
>  				ALIGN(ENC_V100_VP8_ME_SIZE(mb_width,
> mb_height), @@ -452,7 +452,7 @@ static void
> s5p_mfc_dec_calc_dpb_size_v6(struct s5p_mfc_ctx *ctx)
> 
>  	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
>  			ctx->codec_mode ==
> S5P_MFC_CODEC_H264_MVC_DEC) {
> -		if (IS_MFCV10(dev)) {
> +		if (IS_MFCV10_PLUS(dev)) {
>  			ctx->mv_size = S5P_MFC_DEC_MV_SIZE_V10(ctx-
> >img_width,
>  					ctx->img_height);
>  		} else {
> @@ -668,7 +668,7 @@ static int s5p_mfc_set_enc_ref_buffer_v6(struct
> s5p_mfc_ctx *ctx)
> 
>  	mfc_debug(2, "Buf1: %p (%d)\n", (void *)buf_addr1, buf_size1);
> 
> -	if (IS_MFCV10(dev)) {
> +	if (IS_MFCV10_PLUS(dev)) {
>  		/* start address of per buffer is aligned */
>  		for (i = 0; i < ctx->pb_count; i++) {
>  			writel(buf_addr1, mfc_regs->e_luma_dpb + (4 * i));
> @@ -2455,7 +2455,7 @@ const struct s5p_mfc_regs
> *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev)
>  	R(e_h264_options, S5P_FIMV_E_H264_OPTIONS_V8);
>  	R(e_min_scratch_buffer_size,
> S5P_FIMV_E_MIN_SCRATCH_BUFFER_SIZE_V8);
> 
> -	if (!IS_MFCV10(dev))
> +	if (!IS_MFCV10_PLUS(dev))
>  		goto done;
> 
>  	/* Initialize registers used in MFC v10 only.
> --
> 2.17.1



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

* RE: [Patch v4 02/11] media: s5p-mfc: Rename IS_MFCV10 macro
@ 2023-11-16  5:00         ` Alim Akhtar
  0 siblings, 0 replies; 54+ messages in thread
From: Alim Akhtar @ 2023-11-16  5:00 UTC (permalink / raw)
  To: 'Aakarsh Jain',
	linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, aswani.reddy, pankaj.dubey, ajaykumar.rs, linux-fsd,
	'Smitha T Murthy'

Hi Aakarsh

> -----Original Message-----
> From: Aakarsh Jain <aakarsh.jain@samsung.com>
> Sent: Wednesday, October 25, 2023 3:52 PM
> To: linux-arm-kernel@lists.infradead.org; linux-media@vger.kernel.org;
> linux-kernel@vger.kernel.org; devicetree@vger.kernel.org
> Cc: m.szyprowski@samsung.com; andrzej.hajda@intel.com;
> mchehab@kernel.org; hverkuil-cisco@xs4all.nl;
> krzysztof.kozlowski+dt@linaro.org; dillon.minfei@gmail.com;
> david.plowman@raspberrypi.com; mark.rutland@arm.com;
> robh+dt@kernel.org; conor+dt@kernel.org; linux-samsung-
> soc@vger.kernel.org; andi@etezian.org; gost.dev@samsung.com;
> alim.akhtar@samsung.com; aswani.reddy@samsung.com;
> pankaj.dubey@samsung.com; ajaykumar.rs@samsung.com;
> aakarsh.jain@samsung.com; linux-fsd@tesla.com; Smitha T Murthy
> <smithatmurthy@gmail.com>
> Subject: [Patch v4 02/11] media: s5p-mfc: Rename IS_MFCV10 macro
> 
> Renames macro IS_MFCV10 to IS_MFCV10_PLUS so that the MFCv10 code
> can be resued for MFCv12 support. Since some part of MFCv10 specific code
> holds good for MFCv12 also.
> 
> Cc: linux-fsd@tesla.com
> Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
> Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
> ---

Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com>

>  .../platform/samsung/s5p-mfc/s5p_mfc_common.h | 10 +++----
>  .../platform/samsung/s5p-mfc/s5p_mfc_ctrl.c   |  2 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 28 +++++++++----------
>  3 files changed, 20 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> index 5304f42c8c72..e6ec4a43b290 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> @@ -771,11 +771,11 @@ void s5p_mfc_cleanup_queue(struct list_head *lh,
> struct vb2_queue *vq);
>  #define HAS_PORTNUM(dev)	(dev ? (dev->variant ? \
>  				(dev->variant->port_num ? 1 : 0) : 0) : 0)
>  #define IS_TWOPORT(dev)		(dev->variant->port_num == 2 ? 1 : 0)
> -#define IS_MFCV6_PLUS(dev)	(dev->variant->version >= 0x60 ? 1 :
> 0)
> -#define IS_MFCV7_PLUS(dev)	(dev->variant->version >= 0x70 ? 1 :
> 0)
> -#define IS_MFCV8_PLUS(dev)	(dev->variant->version >= 0x80 ? 1 :
> 0)
> -#define IS_MFCV10(dev)		(dev->variant->version >= 0xA0 ? 1 :
> 0)
> -#define FW_HAS_E_MIN_SCRATCH_BUF(dev) (IS_MFCV10(dev))
> +#define IS_MFCV6_PLUS(dev)	(dev->variant->version >= 0x60)
> +#define IS_MFCV7_PLUS(dev)	(dev->variant->version >= 0x70)
> +#define IS_MFCV8_PLUS(dev)	(dev->variant->version >= 0x80)
> +#define IS_MFCV10_PLUS(dev)	(dev->variant->version >= 0xA0)
> +#define FW_HAS_E_MIN_SCRATCH_BUF(dev) (IS_MFCV10_PLUS(dev))
> 
>  #define MFC_V5_BIT	BIT(0)
>  #define MFC_V6_BIT	BIT(1)
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> index 6d3c92045c05..54b54b2fa9b1 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> @@ -236,7 +236,7 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
>  	else
>  		mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET);
> 
> -	if (IS_MFCV10(dev))
> +	if (IS_MFCV10_PLUS(dev))
>  		mfc_write(dev, 0x0, S5P_FIMV_MFC_CLOCK_OFF_V10);
> 
>  	mfc_debug(2, "Will now wait for completion of firmware
> transfer\n"); diff --git a/drivers/media/platform/samsung/s5p-
> mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/samsung/s5p-
> mfc/s5p_mfc_opr_v6.c
> index c0df5ac9fcff..882166e4ac50 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> @@ -72,9 +72,9 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct
> s5p_mfc_ctx *ctx)
>  			  ctx->luma_size, ctx->chroma_size, ctx->mv_size);
>  		mfc_debug(2, "Totals bufs: %d\n", ctx->total_dpb_count);
>  	} else if (ctx->type == MFCINST_ENCODER) {
> -		if (IS_MFCV10(dev)) {
> +		if (IS_MFCV10_PLUS(dev))
>  			ctx->tmv_buffer_size = 0;
> -		} else if (IS_MFCV8_PLUS(dev))
> +		else if (IS_MFCV8_PLUS(dev))
>  			ctx->tmv_buffer_size =
> S5P_FIMV_NUM_TMV_BUFFERS_V6 *
> 
> 	ALIGN(S5P_FIMV_TMV_BUFFER_SIZE_V8(mb_width, mb_height),
>  			S5P_FIMV_TMV_BUFFER_ALIGN_V6);
> @@ -82,7 +82,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct
> s5p_mfc_ctx *ctx)
>  			ctx->tmv_buffer_size =
> S5P_FIMV_NUM_TMV_BUFFERS_V6 *
> 
> 	ALIGN(S5P_FIMV_TMV_BUFFER_SIZE_V6(mb_width, mb_height),
>  			S5P_FIMV_TMV_BUFFER_ALIGN_V6);
> -		if (IS_MFCV10(dev)) {
> +		if (IS_MFCV10_PLUS(dev)) {
>  			lcu_width = S5P_MFC_LCU_WIDTH(ctx->img_width);
>  			lcu_height = S5P_MFC_LCU_HEIGHT(ctx-
> >img_height);
>  			if (ctx->codec_mode !=
> S5P_FIMV_CODEC_HEVC_ENC) { @@ -133,7 +133,7 @@ static int
> s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
>  	switch (ctx->codec_mode) {
>  	case S5P_MFC_CODEC_H264_DEC:
>  	case S5P_MFC_CODEC_H264_MVC_DEC:
> -		if (IS_MFCV10(dev))
> +		if (IS_MFCV10_PLUS(dev))
>  			mfc_debug(2, "Use min scratch buffer size\n");
>  		else if (IS_MFCV8_PLUS(dev))
>  			ctx->scratch_buf_size =
> @@ -152,7 +152,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct
> s5p_mfc_ctx *ctx)
>  			(ctx->mv_count * ctx->mv_size);
>  		break;
>  	case S5P_MFC_CODEC_MPEG4_DEC:
> -		if (IS_MFCV10(dev))
> +		if (IS_MFCV10_PLUS(dev))
>  			mfc_debug(2, "Use min scratch buffer size\n");
>  		else if (IS_MFCV7_PLUS(dev)) {
>  			ctx->scratch_buf_size =
> @@ -172,7 +172,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct
> s5p_mfc_ctx *ctx)
>  		break;
>  	case S5P_MFC_CODEC_VC1RCV_DEC:
>  	case S5P_MFC_CODEC_VC1_DEC:
> -		if (IS_MFCV10(dev))
> +		if (IS_MFCV10_PLUS(dev))
>  			mfc_debug(2, "Use min scratch buffer size\n");
>  		else
>  			ctx->scratch_buf_size =
> @@ -189,7 +189,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct
> s5p_mfc_ctx *ctx)
>  		ctx->bank2.size = 0;
>  		break;
>  	case S5P_MFC_CODEC_H263_DEC:
> -		if (IS_MFCV10(dev))
> +		if (IS_MFCV10_PLUS(dev))
>  			mfc_debug(2, "Use min scratch buffer size\n");
>  		else
>  			ctx->scratch_buf_size =
> @@ -201,7 +201,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct
> s5p_mfc_ctx *ctx)
>  		ctx->bank1.size = ctx->scratch_buf_size;
>  		break;
>  	case S5P_MFC_CODEC_VP8_DEC:
> -		if (IS_MFCV10(dev))
> +		if (IS_MFCV10_PLUS(dev))
>  			mfc_debug(2, "Use min scratch buffer size\n");
>  		else if (IS_MFCV8_PLUS(dev))
>  			ctx->scratch_buf_size =
> @@ -230,7 +230,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct
> s5p_mfc_ctx *ctx)
>  			DEC_VP9_STATIC_BUFFER_SIZE;
>  		break;
>  	case S5P_MFC_CODEC_H264_ENC:
> -		if (IS_MFCV10(dev)) {
> +		if (IS_MFCV10_PLUS(dev)) {
>  			mfc_debug(2, "Use min scratch buffer size\n");
>  			ctx->me_buffer_size =
>  			ALIGN(ENC_V100_H264_ME_SIZE(mb_width,
> mb_height), 16); @@ -254,7 +254,7 @@ static int
> s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
>  		break;
>  	case S5P_MFC_CODEC_MPEG4_ENC:
>  	case S5P_MFC_CODEC_H263_ENC:
> -		if (IS_MFCV10(dev)) {
> +		if (IS_MFCV10_PLUS(dev)) {
>  			mfc_debug(2, "Use min scratch buffer size\n");
>  			ctx->me_buffer_size =
> 
> 	ALIGN(ENC_V100_MPEG4_ME_SIZE(mb_width,
> @@ -273,7 +273,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct
> s5p_mfc_ctx *ctx)
>  		ctx->bank2.size = 0;
>  		break;
>  	case S5P_MFC_CODEC_VP8_ENC:
> -		if (IS_MFCV10(dev)) {
> +		if (IS_MFCV10_PLUS(dev)) {
>  			mfc_debug(2, "Use min scratch buffer size\n");
>  			ctx->me_buffer_size =
>  				ALIGN(ENC_V100_VP8_ME_SIZE(mb_width,
> mb_height), @@ -452,7 +452,7 @@ static void
> s5p_mfc_dec_calc_dpb_size_v6(struct s5p_mfc_ctx *ctx)
> 
>  	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
>  			ctx->codec_mode ==
> S5P_MFC_CODEC_H264_MVC_DEC) {
> -		if (IS_MFCV10(dev)) {
> +		if (IS_MFCV10_PLUS(dev)) {
>  			ctx->mv_size = S5P_MFC_DEC_MV_SIZE_V10(ctx-
> >img_width,
>  					ctx->img_height);
>  		} else {
> @@ -668,7 +668,7 @@ static int s5p_mfc_set_enc_ref_buffer_v6(struct
> s5p_mfc_ctx *ctx)
> 
>  	mfc_debug(2, "Buf1: %p (%d)\n", (void *)buf_addr1, buf_size1);
> 
> -	if (IS_MFCV10(dev)) {
> +	if (IS_MFCV10_PLUS(dev)) {
>  		/* start address of per buffer is aligned */
>  		for (i = 0; i < ctx->pb_count; i++) {
>  			writel(buf_addr1, mfc_regs->e_luma_dpb + (4 * i));
> @@ -2455,7 +2455,7 @@ const struct s5p_mfc_regs
> *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev)
>  	R(e_h264_options, S5P_FIMV_E_H264_OPTIONS_V8);
>  	R(e_min_scratch_buffer_size,
> S5P_FIMV_E_MIN_SCRATCH_BUFFER_SIZE_V8);
> 
> -	if (!IS_MFCV10(dev))
> +	if (!IS_MFCV10_PLUS(dev))
>  		goto done;
> 
>  	/* Initialize registers used in MFC v10 only.
> --
> 2.17.1



_______________________________________________
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] 54+ messages in thread

* RE: [Patch v4 03/11] media: s5p-mfc: Add initial support for MFCv12
  2023-10-25 10:22       ` Aakarsh Jain
@ 2023-11-16  5:44         ` Alim Akhtar
  -1 siblings, 0 replies; 54+ messages in thread
From: Alim Akhtar @ 2023-11-16  5:44 UTC (permalink / raw)
  To: 'Aakarsh Jain',
	linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, aswani.reddy, pankaj.dubey, ajaykumar.rs, linux-fsd,
	'Smitha T Murthy'



> -----Original Message-----
> From: Aakarsh Jain <aakarsh.jain@samsung.com>
> Sent: Wednesday, October 25, 2023 3:52 PM
> To: linux-arm-kernel@lists.infradead.org; linux-media@vger.kernel.org;
> linux-kernel@vger.kernel.org; devicetree@vger.kernel.org
> Cc: m.szyprowski@samsung.com; andrzej.hajda@intel.com;
> mchehab@kernel.org; hverkuil-cisco@xs4all.nl;
> krzysztof.kozlowski+dt@linaro.org; dillon.minfei@gmail.com;
> david.plowman@raspberrypi.com; mark.rutland@arm.com;
> robh+dt@kernel.org; conor+dt@kernel.org; linux-samsung-
> soc@vger.kernel.org; andi@etezian.org; gost.dev@samsung.com;
> alim.akhtar@samsung.com; aswani.reddy@samsung.com;
> pankaj.dubey@samsung.com; ajaykumar.rs@samsung.com;
> aakarsh.jain@samsung.com; linux-fsd@tesla.com; Smitha T Murthy
> <smithatmurthy@gmail.com>
> Subject: [Patch v4 03/11] media: s5p-mfc: Add initial support for MFCv12
> 
> Add support for MFCv12, with a new register file and necessary hw control,
> decoder, encoder and structural changes. Add luma dbp, chroma dpb and mv
> sizes for each codec as per the UM for MFCv12, along with appropriate
> alignment.
> 
> Cc: linux-fsd@tesla.com
> Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
> Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
> ---
>  .../platform/samsung/s5p-mfc/regs-mfc-v12.h   | 50 +++++++++++
>  .../media/platform/samsung/s5p-mfc/s5p_mfc.c  | 30 +++++++
> .../platform/samsung/s5p-mfc/s5p_mfc_common.h | 15 +++-
>  .../platform/samsung/s5p-mfc/s5p_mfc_ctrl.c   |  2 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_dec.c    |  6 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_enc.c    |  5 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_opr.h    |  8 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 83
> ++++++++++++++++---  .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h |
> 6 +-
>  9 files changed, 175 insertions(+), 30 deletions(-)  create mode 100644
> drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> 
> diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> new file mode 100644
> index 000000000000..6c68a45082d0
> --- /dev/null
> +++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> @@ -0,0 +1,50 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Register definition file for Samsung MFC V12.x Interface (FIMV)
> +driver
> + *
> + * Copyright (c) 2020 Samsung Electronics Co., Ltd.
> + *     http://www.samsung.com/
> + */
> +
> +#ifndef _REGS_MFC_V12_H
> +#define _REGS_MFC_V12_H
> +
> +#include <linux/sizes.h>
> +#include "regs-mfc-v10.h"
> +
> +/* MFCv12 Context buffer sizes */
> +#define MFC_CTX_BUF_SIZE_V12		(30 * SZ_1K)
> +#define MFC_H264_DEC_CTX_BUF_SIZE_V12	(2 * SZ_1M)
> +#define MFC_OTHER_DEC_CTX_BUF_SIZE_V12	(30 * SZ_1K)
> +#define MFC_H264_ENC_CTX_BUF_SIZE_V12	(100 * SZ_1K)
> +#define MFC_HEVC_ENC_CTX_BUF_SIZE_V12	(40 * SZ_1K)
> +#define MFC_OTHER_ENC_CTX_BUF_SIZE_V12	(25 * SZ_1K)
> +
> +/* MFCv12 variant defines */
> +#define MAX_FW_SIZE_V12			(SZ_1M)
> +#define MAX_CPB_SIZE_V12		(7 * SZ_1M)
> +#define MFC_VERSION_V12			0xC0
> +#define MFC_NUM_PORTS_V12		1
> +#define S5P_FIMV_CODEC_VP9_ENC		27
> +
> +/* Encoder buffer size for MFCv12 */
> +#define ENC_V120_BASE_SIZE(x, y) \
> +	(((x + 3) * (y + 3) * 8) \
> +	+ (((y * 64) + 2304) * (x + 7) / 8))
> +
> +#define ENC_V120_H264_ME_SIZE(x, y) \
> +	ALIGN((ENC_V120_BASE_SIZE(x, y) \
> +	+ (DIV_ROUND_UP(x * y, 64) * 32)), 256)
> +
> +#define ENC_V120_MPEG4_ME_SIZE(x, y) \
> +	ALIGN((ENC_V120_BASE_SIZE(x, y) \
> +	+ (DIV_ROUND_UP(x * y, 128) * 16)), 256)
> +
> +#define ENC_V120_VP8_ME_SIZE(x, y) \
> +	ALIGN(ENC_V120_BASE_SIZE(x, y), 256)
> +
> +#define ENC_V120_HEVC_ME_SIZE(x, y)     \
> +	ALIGN((((x + 3) * (y + 3) * 32)       \
> +	+ (((y * 128) + 2304) * (x + 3) / 4)), 256)
> +
> +#endif /*_REGS_MFC_V12_H*/
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
> b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
> index e30e54935d79..dee9ef017997 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
> @@ -790,6 +790,8 @@ static int s5p_mfc_open(struct file *file)
>  	INIT_LIST_HEAD(&ctx->dst_queue);
>  	ctx->src_queue_cnt = 0;
>  	ctx->dst_queue_cnt = 0;
> +	ctx->is_422 = 0;
> +	ctx->is_10bit = 0;
>  	/* Get context number */
>  	ctx->num = 0;
>  	while (dev->ctx[ctx->num]) {
> @@ -1660,6 +1662,31 @@ static struct s5p_mfc_variant mfc_drvdata_v10 = {
>  	.fw_name[0]     = "s5p-mfc-v10.fw",
>  };
> 
> +static struct s5p_mfc_buf_size_v6 mfc_buf_size_v12 = {
> +	.dev_ctx        = MFC_CTX_BUF_SIZE_V12,
> +	.h264_dec_ctx   = MFC_H264_DEC_CTX_BUF_SIZE_V12,
> +	.other_dec_ctx  = MFC_OTHER_DEC_CTX_BUF_SIZE_V12,
> +	.h264_enc_ctx   = MFC_H264_ENC_CTX_BUF_SIZE_V12,
> +	.hevc_enc_ctx   = MFC_HEVC_ENC_CTX_BUF_SIZE_V12,
> +	.other_enc_ctx  = MFC_OTHER_ENC_CTX_BUF_SIZE_V12, };
> +
> +static struct s5p_mfc_buf_size buf_size_v12 = {
> +	.fw     = MAX_FW_SIZE_V12,
> +	.cpb    = MAX_CPB_SIZE_V12,
> +	.priv   = &mfc_buf_size_v12,
> +};
> +
> +static struct s5p_mfc_variant mfc_drvdata_v12 = {
> +	.version        = MFC_VERSION_V12,
> +	.version_bit    = MFC_V12_BIT,
> +	.port_num       = MFC_NUM_PORTS_V12,
> +	.buf_size       = &buf_size_v12,
> +	.fw_name[0]     = "s5p-mfc-v12.fw",
> +	.clk_names	= {"mfc"},
> +	.num_clocks	= 1,
> +};
> +
>  static const struct of_device_id exynos_mfc_match[] = {
>  	{
>  		.compatible = "samsung,mfc-v5",
> @@ -1682,6 +1709,9 @@ static const struct of_device_id
> exynos_mfc_match[] = {
>  	}, {
>  		.compatible = "samsung,mfc-v10",
>  		.data = &mfc_drvdata_v10,
> +	}, {
> +		.compatible = "tesla,fsd-mfc",
> +		.data = &mfc_drvdata_v12,
>  	},
>  	{},
>  };
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> index e6ec4a43b290..dd2e9f7704ab 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> @@ -19,7 +19,7 @@
>  #include <media/v4l2-ioctl.h>
>  #include <media/videobuf2-v4l2.h>
>  #include "regs-mfc.h"
> -#include "regs-mfc-v10.h"
> +#include "regs-mfc-v12.h"
> 
>  #define S5P_MFC_NAME		"s5p-mfc"
> 
> @@ -720,6 +720,8 @@ struct s5p_mfc_ctx {
>  	struct v4l2_ctrl *ctrls[MFC_MAX_CTRLS];
>  	struct v4l2_ctrl_handler ctrl_handler;
>  	size_t scratch_buf_size;
> +	int is_10bit;
> +	int is_422;
>  };
> 
>  /*
> @@ -775,6 +777,7 @@ void s5p_mfc_cleanup_queue(struct list_head *lh,
> struct vb2_queue *vq);
>  #define IS_MFCV7_PLUS(dev)	(dev->variant->version >= 0x70)
>  #define IS_MFCV8_PLUS(dev)	(dev->variant->version >= 0x80)
>  #define IS_MFCV10_PLUS(dev)	(dev->variant->version >= 0xA0)
> +#define IS_MFCV12(dev)		(dev->variant->version >= 0xC0)
>  #define FW_HAS_E_MIN_SCRATCH_BUF(dev) (IS_MFCV10_PLUS(dev))
> 
>  #define MFC_V5_BIT	BIT(0)
> @@ -782,11 +785,15 @@ void s5p_mfc_cleanup_queue(struct list_head *lh,
> struct vb2_queue *vq);
>  #define MFC_V7_BIT	BIT(2)
>  #define MFC_V8_BIT	BIT(3)
>  #define MFC_V10_BIT	BIT(5)
> +#define MFC_V12_BIT	BIT(7)
> 
>  #define MFC_V5PLUS_BITS		(MFC_V5_BIT | MFC_V6_BIT |
> MFC_V7_BIT | \
> -					MFC_V8_BIT | MFC_V10_BIT)
> +					MFC_V8_BIT | MFC_V10_BIT |
> MFC_V12_BIT)
>  #define MFC_V6PLUS_BITS		(MFC_V6_BIT | MFC_V7_BIT |
> MFC_V8_BIT | \
> -					MFC_V10_BIT)
> -#define MFC_V7PLUS_BITS		(MFC_V7_BIT | MFC_V8_BIT |
> MFC_V10_BIT)
> +					MFC_V10_BIT | MFC_V12_BIT)
> +#define MFC_V7PLUS_BITS		(MFC_V7_BIT | MFC_V8_BIT |
> MFC_V10_BIT | \
> +					MFC_V12_BIT)
> +
> +#define MFC_V10PLUS_BITS	(MFC_V10_BIT | MFC_V12_BIT)
> 
>  #endif /* S5P_MFC_COMMON_H_ */
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> index 54b54b2fa9b1..b49159142c53 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> @@ -130,7 +130,7 @@ int s5p_mfc_reset(struct s5p_mfc_dev *dev)
>  			mfc_write(dev, 0, S5P_FIMV_REG_CLEAR_BEGIN_V6
> + (i*4));
> 
>  		/* check bus reset control before reset */
> -		if (dev->risc_on)
> +		if (dev->risc_on && !IS_MFCV12(dev))
Please write in the comment why this is needed for V12

>  			if (s5p_mfc_bus_reset(dev))
>  				return -EIO;
>  		/* Reset
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> index 268ffe4da53c..e219cbcd86d5 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> @@ -146,7 +146,7 @@ static struct s5p_mfc_fmt formats[] = {
>  		.codec_mode	= S5P_FIMV_CODEC_HEVC_DEC,
>  		.type		= MFC_FMT_DEC,
>  		.num_planes	= 1,
> -		.versions	= MFC_V10_BIT,
> +		.versions	= MFC_V10PLUS_BITS,
>  		.flags		= V4L2_FMT_FLAG_DYN_RESOLUTION |
> 
> V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM,
>  	},
> @@ -155,7 +155,7 @@ static struct s5p_mfc_fmt formats[] = {
>  		.codec_mode	= S5P_FIMV_CODEC_VP9_DEC,
>  		.type		= MFC_FMT_DEC,
>  		.num_planes	= 1,
> -		.versions	= MFC_V10_BIT,
> +		.versions	= MFC_V10PLUS_BITS,
>  		.flags		= V4L2_FMT_FLAG_DYN_RESOLUTION,
>  	},
>  };
> @@ -355,7 +355,7 @@ static int vidioc_g_fmt(struct file *file, void *priv,
> struct v4l2_format *f)
>  		pix_mp->width = ctx->buf_width;
>  		pix_mp->height = ctx->buf_height;
>  		pix_mp->field = V4L2_FIELD_NONE;
> -		pix_mp->num_planes = 2;
> +		pix_mp->num_planes = ctx->dst_fmt->num_planes;
>  		/* Set pixelformat to the format in which MFC
>  		   outputs the decoded frame */
>  		pix_mp->pixelformat = ctx->dst_fmt->fourcc; diff --git
> a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> index f62703cebb77..e4d6e7c117b5 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> @@ -92,7 +92,7 @@ static struct s5p_mfc_fmt formats[] = {
>  		.codec_mode	= S5P_FIMV_CODEC_HEVC_ENC,
>  		.type		= MFC_FMT_ENC,
>  		.num_planes	= 1,
> -		.versions	= MFC_V10_BIT,
> +		.versions	= MFC_V10PLUS_BITS,
>  	},
>  };
> 
> @@ -1179,7 +1179,8 @@ static int enc_post_seq_start(struct s5p_mfc_ctx
> *ctx)
>  		if (FW_HAS_E_MIN_SCRATCH_BUF(dev)) {
>  			ctx->scratch_buf_size = s5p_mfc_hw_call(dev-
> >mfc_ops,
>  					get_e_min_scratch_buf_size, dev);
> -			ctx->bank1.size += ctx->scratch_buf_size;
> +			if (!IS_MFCV12(dev))
> +				ctx->bank1.size += ctx->scratch_buf_size;
>  		}
>  		ctx->state = MFCINST_HEAD_PRODUCED;
>  	}
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> index b9831275f3ab..87ac56756a16 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> @@ -166,9 +166,9 @@ struct s5p_mfc_regs {
>  	void __iomem *d_decoded_third_addr;/* only v7 */
>  	void __iomem *d_used_dpb_flag_upper;/* v7 and v8 */
>  	void __iomem *d_used_dpb_flag_lower;/* v7 and v8 */
> -	void __iomem *d_min_scratch_buffer_size; /* v10 */
> -	void __iomem *d_static_buffer_addr; /* v10 */
> -	void __iomem *d_static_buffer_size; /* v10 */
> +	void __iomem *d_min_scratch_buffer_size; /* v10 and v12 */
> +	void __iomem *d_static_buffer_addr; /* v10 and v12 */
> +	void __iomem *d_static_buffer_size; /* v10 and v12 */
> 
>  	/* encoder registers */
>  	void __iomem *e_frame_width;
> @@ -268,7 +268,7 @@ struct s5p_mfc_regs {
>  	void __iomem *e_vp8_hierarchical_qp_layer0;/* v7 and v8 */
>  	void __iomem *e_vp8_hierarchical_qp_layer1;/* v7 and v8 */
>  	void __iomem *e_vp8_hierarchical_qp_layer2;/* v7 and v8 */
> -	void __iomem *e_min_scratch_buffer_size; /* v10 */
> +	void __iomem *e_min_scratch_buffer_size; /* v10 and v12 */
>  	void __iomem *e_num_t_layer; /* v10 */
>  	void __iomem *e_hier_qp_layer0; /* v10 */
>  	void __iomem *e_hier_bit_rate_layer0; /* v10 */ diff --git
> a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> index 882166e4ac50..fb3f0718821d 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> @@ -60,12 +60,14 @@ static void
> s5p_mfc_release_dec_desc_buffer_v6(struct s5p_mfc_ctx *ctx)  static int
> s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)  {
>  	struct s5p_mfc_dev *dev = ctx->dev;
> -	unsigned int mb_width, mb_height;
> +	unsigned int mb_width, mb_height, width64, height32;
>  	unsigned int lcu_width = 0, lcu_height = 0;
>  	int ret;
> 
>  	mb_width = MB_WIDTH(ctx->img_width);
>  	mb_height = MB_HEIGHT(ctx->img_height);
> +	width64 = ALIGN(ctx->img_width, 64);
> +	height32 = ALIGN(ctx->img_height, 32);
> 
>  	if (ctx->type == MFCINST_DECODER) {
>  		mfc_debug(2, "Luma size:%d Chroma size:%d MV
> size:%d\n", @@ -82,7 +84,44 @@ static int
> s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
>  			ctx->tmv_buffer_size =
> S5P_FIMV_NUM_TMV_BUFFERS_V6 *
> 
> 	ALIGN(S5P_FIMV_TMV_BUFFER_SIZE_V6(mb_width, mb_height),
>  			S5P_FIMV_TMV_BUFFER_ALIGN_V6);
> -		if (IS_MFCV10_PLUS(dev)) {
> +		if (IS_MFCV12(dev)) {
> +			lcu_width = S5P_MFC_LCU_WIDTH(ctx->img_width);
> +			lcu_height = S5P_MFC_LCU_HEIGHT(ctx-
> >img_height);
> +			if (ctx->codec_mode ==
> S5P_FIMV_CODEC_HEVC_ENC &&
> +								ctx->is_10bit)
> {
> +				ctx->luma_dpb_size =
> +					width64 * height32 +
> +					ALIGN(DIV_ROUND_UP(lcu_width *
> 32, 4),
> +							16) * height32 + 128;
> +				if (ctx->is_422)
> +					ctx->chroma_dpb_size =
> +						ctx->luma_dpb_size;
> +				else
> +					ctx->chroma_dpb_size =
> +						width64 * height32 / 2 +
> +
> 	ALIGN(DIV_ROUND_UP(lcu_width *
> +						32, 4), 16) * height32 / 2 +
> 128;
> +			} else if (ctx->codec_mode ==
> S5P_FIMV_CODEC_VP9_ENC &&
> +					ctx->is_10bit) {
> +				ctx->luma_dpb_size =
> +					ALIGN(ctx->img_width * 2, 128) *
> +					height32 + 64;
> +				ctx->chroma_dpb_size =
> +					ALIGN(ctx->img_width * 2, 128) *
> +					height32 / 2 + 64;
> +			} else {
> +				ctx->luma_dpb_size =
> +					width64 * height32 + 64;
> +				if (ctx->is_422)
> +					ctx->chroma_dpb_size =
> +						ctx->luma_dpb_size;
> +				else
> +					ctx->chroma_dpb_size =
> +						width64 * height32 / 2 + 64;
> +			}
> +			ctx->luma_dpb_size = ALIGN(ctx->luma_dpb_size +
> 256, SZ_2K);
> +			ctx->chroma_dpb_size = ALIGN(ctx-
> >chroma_dpb_size + 256, SZ_2K);
> +		} else if (IS_MFCV10_PLUS(dev)) {
>  			lcu_width = S5P_MFC_LCU_WIDTH(ctx->img_width);
>  			lcu_height = S5P_MFC_LCU_HEIGHT(ctx-
> >img_height);
>  			if (ctx->codec_mode !=
> S5P_FIMV_CODEC_HEVC_ENC) { @@ -230,7 +269,11 @@ static int
> s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
>  			DEC_VP9_STATIC_BUFFER_SIZE;
>  		break;
>  	case S5P_MFC_CODEC_H264_ENC:
> -		if (IS_MFCV10_PLUS(dev)) {
> +		if (IS_MFCV12(dev)) {
> +			mfc_debug(2, "Use min scratch buffer size\n");
> +			ctx->me_buffer_size =
> +				ENC_V120_H264_ME_SIZE(mb_width,
> mb_height);
> +		} else if (IS_MFCV10_PLUS(dev)) {
>  			mfc_debug(2, "Use min scratch buffer size\n");
>  			ctx->me_buffer_size =
>  			ALIGN(ENC_V100_H264_ME_SIZE(mb_width,
> mb_height), 16); @@ -254,7 +297,11 @@ static int
> s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
>  		break;
>  	case S5P_MFC_CODEC_MPEG4_ENC:
>  	case S5P_MFC_CODEC_H263_ENC:
> -		if (IS_MFCV10_PLUS(dev)) {
> +		if (IS_MFCV12(dev)) {
> +			mfc_debug(2, "Use min scratch buffer size\n");
> +			ctx->me_buffer_size =
> +				ENC_V120_MPEG4_ME_SIZE(mb_width,
> mb_height);
> +		} else if (IS_MFCV10_PLUS(dev)) {
>  			mfc_debug(2, "Use min scratch buffer size\n");
>  			ctx->me_buffer_size =
> 
> 	ALIGN(ENC_V100_MPEG4_ME_SIZE(mb_width,
> @@ -273,7 +320,11 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct
> s5p_mfc_ctx *ctx)
>  		ctx->bank2.size = 0;
>  		break;
>  	case S5P_MFC_CODEC_VP8_ENC:
> -		if (IS_MFCV10_PLUS(dev)) {
> +		if (IS_MFCV12(dev)) {
> +			mfc_debug(2, "Use min scratch buffer size\n");
> +			ctx->me_buffer_size =
> +				ENC_V120_VP8_ME_SIZE(mb_width,
> mb_height);
> +		} else if (IS_MFCV10_PLUS(dev)) {
>  			mfc_debug(2, "Use min scratch buffer size\n");
>  			ctx->me_buffer_size =
>  				ALIGN(ENC_V100_VP8_ME_SIZE(mb_width,
> mb_height), @@ -297,9 +348,14 @@ static int
> s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
>  		ctx->bank2.size = 0;
>  		break;
>  	case S5P_MFC_CODEC_HEVC_ENC:
> +		if (IS_MFCV12(dev))
> +			ctx->me_buffer_size =
> +				ENC_V120_HEVC_ME_SIZE(lcu_width,
> lcu_height);
> +		else
> +			ctx->me_buffer_size =
> +				ALIGN(ENC_V100_HEVC_ME_SIZE(lcu_width,
> +							lcu_height), 16);
>  		mfc_debug(2, "Use min scratch buffer size\n");
> -		ctx->me_buffer_size =
> -			ALIGN(ENC_V100_HEVC_ME_SIZE(lcu_width,
> lcu_height), 16);
>  		ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, 256);
>  		ctx->bank1.size =
>  			ctx->scratch_buf_size + ctx->tmv_buffer_size + @@
> -452,12 +508,15 @@ static void s5p_mfc_dec_calc_dpb_size_v6(struct
> s5p_mfc_ctx *ctx)
> 
>  	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
>  			ctx->codec_mode ==
> S5P_MFC_CODEC_H264_MVC_DEC) {
> -		if (IS_MFCV10_PLUS(dev)) {
> -			ctx->mv_size = S5P_MFC_DEC_MV_SIZE_V10(ctx-
> >img_width,
> -					ctx->img_height);
> +		if (IS_MFCV12(dev)) {
> +			ctx->mv_size = S5P_MFC_DEC_MV_SIZE(ctx-
> >img_width,
> +					ctx->img_height, 1024);
> +		} else if (IS_MFCV10_PLUS(dev)) {
> +			ctx->mv_size = S5P_MFC_DEC_MV_SIZE(ctx-
> >img_width,
> +					ctx->img_height, 512);
>  		} else {
> -			ctx->mv_size = S5P_MFC_DEC_MV_SIZE_V6(ctx-
> >img_width,
> -					ctx->img_height);
> +			ctx->mv_size = S5P_MFC_DEC_MV_SIZE(ctx-
> >img_width,
> +					ctx->img_height, 128);
>  		}
>  	} else if (ctx->codec_mode == S5P_MFC_CODEC_HEVC_DEC) {
>  		ctx->mv_size = s5p_mfc_dec_hevc_mv_size(ctx-
> >img_width,
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
> b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
> index e4dd03c5454c..30269f3e68e8 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
> @@ -19,10 +19,8 @@
> 
>  #define MB_WIDTH(x_size)		DIV_ROUND_UP(x_size, 16)
>  #define MB_HEIGHT(y_size)		DIV_ROUND_UP(y_size, 16)
> -#define S5P_MFC_DEC_MV_SIZE_V6(x, y)	(MB_WIDTH(x) * \
> -					(((MB_HEIGHT(y)+1)/2)*2) * 64 +
> 128)
> -#define S5P_MFC_DEC_MV_SIZE_V10(x, y)	(MB_WIDTH(x) * \
> -					(((MB_HEIGHT(y)+1)/2)*2) * 64 +
> 512)
> +#define S5P_MFC_DEC_MV_SIZE(x, y, offset)	(MB_WIDTH(x) * \
> +					(((MB_HEIGHT(y)+1)/2)*2) * 64 +
> offset)
>  #define S5P_MFC_LCU_WIDTH(x_size)	DIV_ROUND_UP(x_size, 32)
>  #define S5P_MFC_LCU_HEIGHT(y_size)	DIV_ROUND_UP(y_size, 32)
> 
> --
> 2.17.1



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

* RE: [Patch v4 03/11] media: s5p-mfc: Add initial support for MFCv12
@ 2023-11-16  5:44         ` Alim Akhtar
  0 siblings, 0 replies; 54+ messages in thread
From: Alim Akhtar @ 2023-11-16  5:44 UTC (permalink / raw)
  To: 'Aakarsh Jain',
	linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, aswani.reddy, pankaj.dubey, ajaykumar.rs, linux-fsd,
	'Smitha T Murthy'



> -----Original Message-----
> From: Aakarsh Jain <aakarsh.jain@samsung.com>
> Sent: Wednesday, October 25, 2023 3:52 PM
> To: linux-arm-kernel@lists.infradead.org; linux-media@vger.kernel.org;
> linux-kernel@vger.kernel.org; devicetree@vger.kernel.org
> Cc: m.szyprowski@samsung.com; andrzej.hajda@intel.com;
> mchehab@kernel.org; hverkuil-cisco@xs4all.nl;
> krzysztof.kozlowski+dt@linaro.org; dillon.minfei@gmail.com;
> david.plowman@raspberrypi.com; mark.rutland@arm.com;
> robh+dt@kernel.org; conor+dt@kernel.org; linux-samsung-
> soc@vger.kernel.org; andi@etezian.org; gost.dev@samsung.com;
> alim.akhtar@samsung.com; aswani.reddy@samsung.com;
> pankaj.dubey@samsung.com; ajaykumar.rs@samsung.com;
> aakarsh.jain@samsung.com; linux-fsd@tesla.com; Smitha T Murthy
> <smithatmurthy@gmail.com>
> Subject: [Patch v4 03/11] media: s5p-mfc: Add initial support for MFCv12
> 
> Add support for MFCv12, with a new register file and necessary hw control,
> decoder, encoder and structural changes. Add luma dbp, chroma dpb and mv
> sizes for each codec as per the UM for MFCv12, along with appropriate
> alignment.
> 
> Cc: linux-fsd@tesla.com
> Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
> Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
> ---
>  .../platform/samsung/s5p-mfc/regs-mfc-v12.h   | 50 +++++++++++
>  .../media/platform/samsung/s5p-mfc/s5p_mfc.c  | 30 +++++++
> .../platform/samsung/s5p-mfc/s5p_mfc_common.h | 15 +++-
>  .../platform/samsung/s5p-mfc/s5p_mfc_ctrl.c   |  2 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_dec.c    |  6 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_enc.c    |  5 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_opr.h    |  8 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 83
> ++++++++++++++++---  .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h |
> 6 +-
>  9 files changed, 175 insertions(+), 30 deletions(-)  create mode 100644
> drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> 
> diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> new file mode 100644
> index 000000000000..6c68a45082d0
> --- /dev/null
> +++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> @@ -0,0 +1,50 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Register definition file for Samsung MFC V12.x Interface (FIMV)
> +driver
> + *
> + * Copyright (c) 2020 Samsung Electronics Co., Ltd.
> + *     http://www.samsung.com/
> + */
> +
> +#ifndef _REGS_MFC_V12_H
> +#define _REGS_MFC_V12_H
> +
> +#include <linux/sizes.h>
> +#include "regs-mfc-v10.h"
> +
> +/* MFCv12 Context buffer sizes */
> +#define MFC_CTX_BUF_SIZE_V12		(30 * SZ_1K)
> +#define MFC_H264_DEC_CTX_BUF_SIZE_V12	(2 * SZ_1M)
> +#define MFC_OTHER_DEC_CTX_BUF_SIZE_V12	(30 * SZ_1K)
> +#define MFC_H264_ENC_CTX_BUF_SIZE_V12	(100 * SZ_1K)
> +#define MFC_HEVC_ENC_CTX_BUF_SIZE_V12	(40 * SZ_1K)
> +#define MFC_OTHER_ENC_CTX_BUF_SIZE_V12	(25 * SZ_1K)
> +
> +/* MFCv12 variant defines */
> +#define MAX_FW_SIZE_V12			(SZ_1M)
> +#define MAX_CPB_SIZE_V12		(7 * SZ_1M)
> +#define MFC_VERSION_V12			0xC0
> +#define MFC_NUM_PORTS_V12		1
> +#define S5P_FIMV_CODEC_VP9_ENC		27
> +
> +/* Encoder buffer size for MFCv12 */
> +#define ENC_V120_BASE_SIZE(x, y) \
> +	(((x + 3) * (y + 3) * 8) \
> +	+ (((y * 64) + 2304) * (x + 7) / 8))
> +
> +#define ENC_V120_H264_ME_SIZE(x, y) \
> +	ALIGN((ENC_V120_BASE_SIZE(x, y) \
> +	+ (DIV_ROUND_UP(x * y, 64) * 32)), 256)
> +
> +#define ENC_V120_MPEG4_ME_SIZE(x, y) \
> +	ALIGN((ENC_V120_BASE_SIZE(x, y) \
> +	+ (DIV_ROUND_UP(x * y, 128) * 16)), 256)
> +
> +#define ENC_V120_VP8_ME_SIZE(x, y) \
> +	ALIGN(ENC_V120_BASE_SIZE(x, y), 256)
> +
> +#define ENC_V120_HEVC_ME_SIZE(x, y)     \
> +	ALIGN((((x + 3) * (y + 3) * 32)       \
> +	+ (((y * 128) + 2304) * (x + 3) / 4)), 256)
> +
> +#endif /*_REGS_MFC_V12_H*/
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
> b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
> index e30e54935d79..dee9ef017997 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
> @@ -790,6 +790,8 @@ static int s5p_mfc_open(struct file *file)
>  	INIT_LIST_HEAD(&ctx->dst_queue);
>  	ctx->src_queue_cnt = 0;
>  	ctx->dst_queue_cnt = 0;
> +	ctx->is_422 = 0;
> +	ctx->is_10bit = 0;
>  	/* Get context number */
>  	ctx->num = 0;
>  	while (dev->ctx[ctx->num]) {
> @@ -1660,6 +1662,31 @@ static struct s5p_mfc_variant mfc_drvdata_v10 = {
>  	.fw_name[0]     = "s5p-mfc-v10.fw",
>  };
> 
> +static struct s5p_mfc_buf_size_v6 mfc_buf_size_v12 = {
> +	.dev_ctx        = MFC_CTX_BUF_SIZE_V12,
> +	.h264_dec_ctx   = MFC_H264_DEC_CTX_BUF_SIZE_V12,
> +	.other_dec_ctx  = MFC_OTHER_DEC_CTX_BUF_SIZE_V12,
> +	.h264_enc_ctx   = MFC_H264_ENC_CTX_BUF_SIZE_V12,
> +	.hevc_enc_ctx   = MFC_HEVC_ENC_CTX_BUF_SIZE_V12,
> +	.other_enc_ctx  = MFC_OTHER_ENC_CTX_BUF_SIZE_V12, };
> +
> +static struct s5p_mfc_buf_size buf_size_v12 = {
> +	.fw     = MAX_FW_SIZE_V12,
> +	.cpb    = MAX_CPB_SIZE_V12,
> +	.priv   = &mfc_buf_size_v12,
> +};
> +
> +static struct s5p_mfc_variant mfc_drvdata_v12 = {
> +	.version        = MFC_VERSION_V12,
> +	.version_bit    = MFC_V12_BIT,
> +	.port_num       = MFC_NUM_PORTS_V12,
> +	.buf_size       = &buf_size_v12,
> +	.fw_name[0]     = "s5p-mfc-v12.fw",
> +	.clk_names	= {"mfc"},
> +	.num_clocks	= 1,
> +};
> +
>  static const struct of_device_id exynos_mfc_match[] = {
>  	{
>  		.compatible = "samsung,mfc-v5",
> @@ -1682,6 +1709,9 @@ static const struct of_device_id
> exynos_mfc_match[] = {
>  	}, {
>  		.compatible = "samsung,mfc-v10",
>  		.data = &mfc_drvdata_v10,
> +	}, {
> +		.compatible = "tesla,fsd-mfc",
> +		.data = &mfc_drvdata_v12,
>  	},
>  	{},
>  };
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> index e6ec4a43b290..dd2e9f7704ab 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> @@ -19,7 +19,7 @@
>  #include <media/v4l2-ioctl.h>
>  #include <media/videobuf2-v4l2.h>
>  #include "regs-mfc.h"
> -#include "regs-mfc-v10.h"
> +#include "regs-mfc-v12.h"
> 
>  #define S5P_MFC_NAME		"s5p-mfc"
> 
> @@ -720,6 +720,8 @@ struct s5p_mfc_ctx {
>  	struct v4l2_ctrl *ctrls[MFC_MAX_CTRLS];
>  	struct v4l2_ctrl_handler ctrl_handler;
>  	size_t scratch_buf_size;
> +	int is_10bit;
> +	int is_422;
>  };
> 
>  /*
> @@ -775,6 +777,7 @@ void s5p_mfc_cleanup_queue(struct list_head *lh,
> struct vb2_queue *vq);
>  #define IS_MFCV7_PLUS(dev)	(dev->variant->version >= 0x70)
>  #define IS_MFCV8_PLUS(dev)	(dev->variant->version >= 0x80)
>  #define IS_MFCV10_PLUS(dev)	(dev->variant->version >= 0xA0)
> +#define IS_MFCV12(dev)		(dev->variant->version >= 0xC0)
>  #define FW_HAS_E_MIN_SCRATCH_BUF(dev) (IS_MFCV10_PLUS(dev))
> 
>  #define MFC_V5_BIT	BIT(0)
> @@ -782,11 +785,15 @@ void s5p_mfc_cleanup_queue(struct list_head *lh,
> struct vb2_queue *vq);
>  #define MFC_V7_BIT	BIT(2)
>  #define MFC_V8_BIT	BIT(3)
>  #define MFC_V10_BIT	BIT(5)
> +#define MFC_V12_BIT	BIT(7)
> 
>  #define MFC_V5PLUS_BITS		(MFC_V5_BIT | MFC_V6_BIT |
> MFC_V7_BIT | \
> -					MFC_V8_BIT | MFC_V10_BIT)
> +					MFC_V8_BIT | MFC_V10_BIT |
> MFC_V12_BIT)
>  #define MFC_V6PLUS_BITS		(MFC_V6_BIT | MFC_V7_BIT |
> MFC_V8_BIT | \
> -					MFC_V10_BIT)
> -#define MFC_V7PLUS_BITS		(MFC_V7_BIT | MFC_V8_BIT |
> MFC_V10_BIT)
> +					MFC_V10_BIT | MFC_V12_BIT)
> +#define MFC_V7PLUS_BITS		(MFC_V7_BIT | MFC_V8_BIT |
> MFC_V10_BIT | \
> +					MFC_V12_BIT)
> +
> +#define MFC_V10PLUS_BITS	(MFC_V10_BIT | MFC_V12_BIT)
> 
>  #endif /* S5P_MFC_COMMON_H_ */
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> index 54b54b2fa9b1..b49159142c53 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> @@ -130,7 +130,7 @@ int s5p_mfc_reset(struct s5p_mfc_dev *dev)
>  			mfc_write(dev, 0, S5P_FIMV_REG_CLEAR_BEGIN_V6
> + (i*4));
> 
>  		/* check bus reset control before reset */
> -		if (dev->risc_on)
> +		if (dev->risc_on && !IS_MFCV12(dev))
Please write in the comment why this is needed for V12

>  			if (s5p_mfc_bus_reset(dev))
>  				return -EIO;
>  		/* Reset
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> index 268ffe4da53c..e219cbcd86d5 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> @@ -146,7 +146,7 @@ static struct s5p_mfc_fmt formats[] = {
>  		.codec_mode	= S5P_FIMV_CODEC_HEVC_DEC,
>  		.type		= MFC_FMT_DEC,
>  		.num_planes	= 1,
> -		.versions	= MFC_V10_BIT,
> +		.versions	= MFC_V10PLUS_BITS,
>  		.flags		= V4L2_FMT_FLAG_DYN_RESOLUTION |
> 
> V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM,
>  	},
> @@ -155,7 +155,7 @@ static struct s5p_mfc_fmt formats[] = {
>  		.codec_mode	= S5P_FIMV_CODEC_VP9_DEC,
>  		.type		= MFC_FMT_DEC,
>  		.num_planes	= 1,
> -		.versions	= MFC_V10_BIT,
> +		.versions	= MFC_V10PLUS_BITS,
>  		.flags		= V4L2_FMT_FLAG_DYN_RESOLUTION,
>  	},
>  };
> @@ -355,7 +355,7 @@ static int vidioc_g_fmt(struct file *file, void *priv,
> struct v4l2_format *f)
>  		pix_mp->width = ctx->buf_width;
>  		pix_mp->height = ctx->buf_height;
>  		pix_mp->field = V4L2_FIELD_NONE;
> -		pix_mp->num_planes = 2;
> +		pix_mp->num_planes = ctx->dst_fmt->num_planes;
>  		/* Set pixelformat to the format in which MFC
>  		   outputs the decoded frame */
>  		pix_mp->pixelformat = ctx->dst_fmt->fourcc; diff --git
> a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> index f62703cebb77..e4d6e7c117b5 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> @@ -92,7 +92,7 @@ static struct s5p_mfc_fmt formats[] = {
>  		.codec_mode	= S5P_FIMV_CODEC_HEVC_ENC,
>  		.type		= MFC_FMT_ENC,
>  		.num_planes	= 1,
> -		.versions	= MFC_V10_BIT,
> +		.versions	= MFC_V10PLUS_BITS,
>  	},
>  };
> 
> @@ -1179,7 +1179,8 @@ static int enc_post_seq_start(struct s5p_mfc_ctx
> *ctx)
>  		if (FW_HAS_E_MIN_SCRATCH_BUF(dev)) {
>  			ctx->scratch_buf_size = s5p_mfc_hw_call(dev-
> >mfc_ops,
>  					get_e_min_scratch_buf_size, dev);
> -			ctx->bank1.size += ctx->scratch_buf_size;
> +			if (!IS_MFCV12(dev))
> +				ctx->bank1.size += ctx->scratch_buf_size;
>  		}
>  		ctx->state = MFCINST_HEAD_PRODUCED;
>  	}
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> index b9831275f3ab..87ac56756a16 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> @@ -166,9 +166,9 @@ struct s5p_mfc_regs {
>  	void __iomem *d_decoded_third_addr;/* only v7 */
>  	void __iomem *d_used_dpb_flag_upper;/* v7 and v8 */
>  	void __iomem *d_used_dpb_flag_lower;/* v7 and v8 */
> -	void __iomem *d_min_scratch_buffer_size; /* v10 */
> -	void __iomem *d_static_buffer_addr; /* v10 */
> -	void __iomem *d_static_buffer_size; /* v10 */
> +	void __iomem *d_min_scratch_buffer_size; /* v10 and v12 */
> +	void __iomem *d_static_buffer_addr; /* v10 and v12 */
> +	void __iomem *d_static_buffer_size; /* v10 and v12 */
> 
>  	/* encoder registers */
>  	void __iomem *e_frame_width;
> @@ -268,7 +268,7 @@ struct s5p_mfc_regs {
>  	void __iomem *e_vp8_hierarchical_qp_layer0;/* v7 and v8 */
>  	void __iomem *e_vp8_hierarchical_qp_layer1;/* v7 and v8 */
>  	void __iomem *e_vp8_hierarchical_qp_layer2;/* v7 and v8 */
> -	void __iomem *e_min_scratch_buffer_size; /* v10 */
> +	void __iomem *e_min_scratch_buffer_size; /* v10 and v12 */
>  	void __iomem *e_num_t_layer; /* v10 */
>  	void __iomem *e_hier_qp_layer0; /* v10 */
>  	void __iomem *e_hier_bit_rate_layer0; /* v10 */ diff --git
> a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> index 882166e4ac50..fb3f0718821d 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> @@ -60,12 +60,14 @@ static void
> s5p_mfc_release_dec_desc_buffer_v6(struct s5p_mfc_ctx *ctx)  static int
> s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)  {
>  	struct s5p_mfc_dev *dev = ctx->dev;
> -	unsigned int mb_width, mb_height;
> +	unsigned int mb_width, mb_height, width64, height32;
>  	unsigned int lcu_width = 0, lcu_height = 0;
>  	int ret;
> 
>  	mb_width = MB_WIDTH(ctx->img_width);
>  	mb_height = MB_HEIGHT(ctx->img_height);
> +	width64 = ALIGN(ctx->img_width, 64);
> +	height32 = ALIGN(ctx->img_height, 32);
> 
>  	if (ctx->type == MFCINST_DECODER) {
>  		mfc_debug(2, "Luma size:%d Chroma size:%d MV
> size:%d\n", @@ -82,7 +84,44 @@ static int
> s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
>  			ctx->tmv_buffer_size =
> S5P_FIMV_NUM_TMV_BUFFERS_V6 *
> 
> 	ALIGN(S5P_FIMV_TMV_BUFFER_SIZE_V6(mb_width, mb_height),
>  			S5P_FIMV_TMV_BUFFER_ALIGN_V6);
> -		if (IS_MFCV10_PLUS(dev)) {
> +		if (IS_MFCV12(dev)) {
> +			lcu_width = S5P_MFC_LCU_WIDTH(ctx->img_width);
> +			lcu_height = S5P_MFC_LCU_HEIGHT(ctx-
> >img_height);
> +			if (ctx->codec_mode ==
> S5P_FIMV_CODEC_HEVC_ENC &&
> +								ctx->is_10bit)
> {
> +				ctx->luma_dpb_size =
> +					width64 * height32 +
> +					ALIGN(DIV_ROUND_UP(lcu_width *
> 32, 4),
> +							16) * height32 + 128;
> +				if (ctx->is_422)
> +					ctx->chroma_dpb_size =
> +						ctx->luma_dpb_size;
> +				else
> +					ctx->chroma_dpb_size =
> +						width64 * height32 / 2 +
> +
> 	ALIGN(DIV_ROUND_UP(lcu_width *
> +						32, 4), 16) * height32 / 2 +
> 128;
> +			} else if (ctx->codec_mode ==
> S5P_FIMV_CODEC_VP9_ENC &&
> +					ctx->is_10bit) {
> +				ctx->luma_dpb_size =
> +					ALIGN(ctx->img_width * 2, 128) *
> +					height32 + 64;
> +				ctx->chroma_dpb_size =
> +					ALIGN(ctx->img_width * 2, 128) *
> +					height32 / 2 + 64;
> +			} else {
> +				ctx->luma_dpb_size =
> +					width64 * height32 + 64;
> +				if (ctx->is_422)
> +					ctx->chroma_dpb_size =
> +						ctx->luma_dpb_size;
> +				else
> +					ctx->chroma_dpb_size =
> +						width64 * height32 / 2 + 64;
> +			}
> +			ctx->luma_dpb_size = ALIGN(ctx->luma_dpb_size +
> 256, SZ_2K);
> +			ctx->chroma_dpb_size = ALIGN(ctx-
> >chroma_dpb_size + 256, SZ_2K);
> +		} else if (IS_MFCV10_PLUS(dev)) {
>  			lcu_width = S5P_MFC_LCU_WIDTH(ctx->img_width);
>  			lcu_height = S5P_MFC_LCU_HEIGHT(ctx-
> >img_height);
>  			if (ctx->codec_mode !=
> S5P_FIMV_CODEC_HEVC_ENC) { @@ -230,7 +269,11 @@ static int
> s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
>  			DEC_VP9_STATIC_BUFFER_SIZE;
>  		break;
>  	case S5P_MFC_CODEC_H264_ENC:
> -		if (IS_MFCV10_PLUS(dev)) {
> +		if (IS_MFCV12(dev)) {
> +			mfc_debug(2, "Use min scratch buffer size\n");
> +			ctx->me_buffer_size =
> +				ENC_V120_H264_ME_SIZE(mb_width,
> mb_height);
> +		} else if (IS_MFCV10_PLUS(dev)) {
>  			mfc_debug(2, "Use min scratch buffer size\n");
>  			ctx->me_buffer_size =
>  			ALIGN(ENC_V100_H264_ME_SIZE(mb_width,
> mb_height), 16); @@ -254,7 +297,11 @@ static int
> s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
>  		break;
>  	case S5P_MFC_CODEC_MPEG4_ENC:
>  	case S5P_MFC_CODEC_H263_ENC:
> -		if (IS_MFCV10_PLUS(dev)) {
> +		if (IS_MFCV12(dev)) {
> +			mfc_debug(2, "Use min scratch buffer size\n");
> +			ctx->me_buffer_size =
> +				ENC_V120_MPEG4_ME_SIZE(mb_width,
> mb_height);
> +		} else if (IS_MFCV10_PLUS(dev)) {
>  			mfc_debug(2, "Use min scratch buffer size\n");
>  			ctx->me_buffer_size =
> 
> 	ALIGN(ENC_V100_MPEG4_ME_SIZE(mb_width,
> @@ -273,7 +320,11 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct
> s5p_mfc_ctx *ctx)
>  		ctx->bank2.size = 0;
>  		break;
>  	case S5P_MFC_CODEC_VP8_ENC:
> -		if (IS_MFCV10_PLUS(dev)) {
> +		if (IS_MFCV12(dev)) {
> +			mfc_debug(2, "Use min scratch buffer size\n");
> +			ctx->me_buffer_size =
> +				ENC_V120_VP8_ME_SIZE(mb_width,
> mb_height);
> +		} else if (IS_MFCV10_PLUS(dev)) {
>  			mfc_debug(2, "Use min scratch buffer size\n");
>  			ctx->me_buffer_size =
>  				ALIGN(ENC_V100_VP8_ME_SIZE(mb_width,
> mb_height), @@ -297,9 +348,14 @@ static int
> s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
>  		ctx->bank2.size = 0;
>  		break;
>  	case S5P_MFC_CODEC_HEVC_ENC:
> +		if (IS_MFCV12(dev))
> +			ctx->me_buffer_size =
> +				ENC_V120_HEVC_ME_SIZE(lcu_width,
> lcu_height);
> +		else
> +			ctx->me_buffer_size =
> +				ALIGN(ENC_V100_HEVC_ME_SIZE(lcu_width,
> +							lcu_height), 16);
>  		mfc_debug(2, "Use min scratch buffer size\n");
> -		ctx->me_buffer_size =
> -			ALIGN(ENC_V100_HEVC_ME_SIZE(lcu_width,
> lcu_height), 16);
>  		ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, 256);
>  		ctx->bank1.size =
>  			ctx->scratch_buf_size + ctx->tmv_buffer_size + @@
> -452,12 +508,15 @@ static void s5p_mfc_dec_calc_dpb_size_v6(struct
> s5p_mfc_ctx *ctx)
> 
>  	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
>  			ctx->codec_mode ==
> S5P_MFC_CODEC_H264_MVC_DEC) {
> -		if (IS_MFCV10_PLUS(dev)) {
> -			ctx->mv_size = S5P_MFC_DEC_MV_SIZE_V10(ctx-
> >img_width,
> -					ctx->img_height);
> +		if (IS_MFCV12(dev)) {
> +			ctx->mv_size = S5P_MFC_DEC_MV_SIZE(ctx-
> >img_width,
> +					ctx->img_height, 1024);
> +		} else if (IS_MFCV10_PLUS(dev)) {
> +			ctx->mv_size = S5P_MFC_DEC_MV_SIZE(ctx-
> >img_width,
> +					ctx->img_height, 512);
>  		} else {
> -			ctx->mv_size = S5P_MFC_DEC_MV_SIZE_V6(ctx-
> >img_width,
> -					ctx->img_height);
> +			ctx->mv_size = S5P_MFC_DEC_MV_SIZE(ctx-
> >img_width,
> +					ctx->img_height, 128);
>  		}
>  	} else if (ctx->codec_mode == S5P_MFC_CODEC_HEVC_DEC) {
>  		ctx->mv_size = s5p_mfc_dec_hevc_mv_size(ctx-
> >img_width,
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
> b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
> index e4dd03c5454c..30269f3e68e8 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
> @@ -19,10 +19,8 @@
> 
>  #define MB_WIDTH(x_size)		DIV_ROUND_UP(x_size, 16)
>  #define MB_HEIGHT(y_size)		DIV_ROUND_UP(y_size, 16)
> -#define S5P_MFC_DEC_MV_SIZE_V6(x, y)	(MB_WIDTH(x) * \
> -					(((MB_HEIGHT(y)+1)/2)*2) * 64 +
> 128)
> -#define S5P_MFC_DEC_MV_SIZE_V10(x, y)	(MB_WIDTH(x) * \
> -					(((MB_HEIGHT(y)+1)/2)*2) * 64 +
> 512)
> +#define S5P_MFC_DEC_MV_SIZE(x, y, offset)	(MB_WIDTH(x) * \
> +					(((MB_HEIGHT(y)+1)/2)*2) * 64 +
> offset)
>  #define S5P_MFC_LCU_WIDTH(x_size)	DIV_ROUND_UP(x_size, 32)
>  #define S5P_MFC_LCU_HEIGHT(y_size)	DIV_ROUND_UP(y_size, 32)
> 
> --
> 2.17.1



_______________________________________________
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] 54+ messages in thread

* RE: [Patch v4 00/11] Add MFC V12 support
  2023-10-25 10:22   ` Aakarsh Jain
@ 2023-11-20 12:48     ` Aakarsh Jain
  -1 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-11-20 12:48 UTC (permalink / raw)
  To: linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs

Hello,

> -----Original Message-----
> From: Aakarsh Jain <aakarsh.jain@samsung.com>
> Sent: 25 October 2023 15:52
> To: linux-arm-kernel@lists.infradead.org; linux-media@vger.kernel.org;
> linux-kernel@vger.kernel.org; devicetree@vger.kernel.org
> Cc: m.szyprowski@samsung.com; andrzej.hajda@intel.com;
> mchehab@kernel.org; hverkuil-cisco@xs4all.nl;
> krzysztof.kozlowski+dt@linaro.org; dillon.minfei@gmail.com;
> david.plowman@raspberrypi.com; mark.rutland@arm.com;
> robh+dt@kernel.org; conor+dt@kernel.org; linux-samsung-
> soc@vger.kernel.org; andi@etezian.org; gost.dev@samsung.com;
> alim.akhtar@samsung.com; aswani.reddy@samsung.com;
> pankaj.dubey@samsung.com; ajaykumar.rs@samsung.com;
> aakarsh.jain@samsung.com
> Subject: [Patch v4 00/11] Add MFC V12 support
> 
> This patch series adds MFC v12 support. MFC v12 is used in Tesla FSD SoC.
> 
> This adds support for following:
> 
> -Add support for YV12 and I420 format (3-plane) -Add support for Rate
> Control, UHD and DMABUF for encoder -Add support for DPB buffers
> allocation based on MFC requirement
> 
> Changes since v3:
> -Removed vp9 codec support for now and just keeping MFC v12 base
> patches with necessary hardware controls, decoder, encoder and structural
> changes. Also covers luma dbp, chroma dpb and mv sizes for each codec as
> per the UM for MFCv12, along with appropriate alignment.
> v3 link: https://patchwork.kernel.org/project/linux-
> media/cover/20221011122516.32135-1-aakarsh.jain@samsung.com/
> 
> Changes since v2:
> -Addressed review comments by Rob Herring.
> This was regarding the errors found by Rob bot in yaml file. File
> 'samsung,s5p-mfc.yaml' is already converted into json schema and is
> merged.
> 
> -Addressed review comments by Krzysztof Kozlowski.
> This was regarding depricated properties mentioned in s5p-mfc.txt file.
> Review comment was addressed and 'samsung,s5p-mfc.yaml' is already
> merged now.
> 
> -Addressed review comments by Andi Shyti.
> This was regarding addition of 'MFC_V10PLUS_BITS' macro in
> 's5p_mfc_common.h file.
> v2 link: https://patchwork.kernel.org/project/linux-
> media/cover/20220907064715.55778-1-smitha.t@samsung.com/
> 
> Changes since v1:
> -Addressed review comments by Krzysztof Kozlowski.
> Separated bug fixes patches, resent again with fix tag and those are merged
> now.
> -Added SoC based compatible string.
> 
> -Addressed review comments by Andrzej Hajda Assigned width64 and
> height32 variable with ALIGN(ctx->img_..) used in the code in
> 's5p_mfc_opr_v6.c' file.
> v1 link: https://patchwork.kernel.org/project/linux-
> media/patch/20220517125548.14746-2-smitha.t@samsung.com/
> 
> Aakarsh Jain (11):
>   dt-bindings: media: s5p-mfc: Add mfcv12 variant
>   media: s5p-mfc: Rename IS_MFCV10 macro
>   media: s5p-mfc: Add initial support for MFCv12
>   media: s5p-mfc: Add YV12 and I420 multiplanar format support
>   media: s5p-mfc: Add support for rate controls in MFCv12
>   media: s5p-mfc: Add support for UHD encoding.
>   media: s5p-mfc: Add support for DMABUF for encoder
>   media: s5p-mfc: Set context for valid case before calling try_run
>   media: s5p-mfc: Load firmware for each run in MFCv12.
>   media: s5p-mfc: DPB Count Independent of VIDIOC_REQBUF
>   arm64: dts: fsd: Add MFC related DT enteries
> 
>  .../bindings/media/samsung,s5p-mfc.yaml       |  16 +
>  arch/arm64/boot/dts/tesla/fsd.dtsi            |  21 ++
>  .../platform/samsung/s5p-mfc/regs-mfc-v12.h   |  52 +++
>  .../platform/samsung/s5p-mfc/regs-mfc-v7.h    |   1 +
>  .../platform/samsung/s5p-mfc/regs-mfc-v8.h    |   3 +
>  .../media/platform/samsung/s5p-mfc/s5p_mfc.c  |  36 +-
> .../platform/samsung/s5p-mfc/s5p_mfc_common.h |  29 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_ctrl.c   |   9 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_dec.c    |  51 ++-
>  .../platform/samsung/s5p-mfc/s5p_mfc_enc.c    | 138 +++++---
>  .../platform/samsung/s5p-mfc/s5p_mfc_opr.h    |  14 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c |  12 +-
> .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 312 +++++++++++++++-
> --
>  .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h |   7 +-
>  14 files changed, 574 insertions(+), 127 deletions(-)  create mode 100644
> drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> 
> --
> 2.17.1


Gentle reminder to review MFC v12 patches.
I see Krzysztof have some comments on dt-schema patch. Waiting for reviewers to review driver changes as well. Post which I can send v5 changes.

Thanks



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

* RE: [Patch v4 00/11] Add MFC V12 support
@ 2023-11-20 12:48     ` Aakarsh Jain
  0 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-11-20 12:48 UTC (permalink / raw)
  To: linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs

Hello,

> -----Original Message-----
> From: Aakarsh Jain <aakarsh.jain@samsung.com>
> Sent: 25 October 2023 15:52
> To: linux-arm-kernel@lists.infradead.org; linux-media@vger.kernel.org;
> linux-kernel@vger.kernel.org; devicetree@vger.kernel.org
> Cc: m.szyprowski@samsung.com; andrzej.hajda@intel.com;
> mchehab@kernel.org; hverkuil-cisco@xs4all.nl;
> krzysztof.kozlowski+dt@linaro.org; dillon.minfei@gmail.com;
> david.plowman@raspberrypi.com; mark.rutland@arm.com;
> robh+dt@kernel.org; conor+dt@kernel.org; linux-samsung-
> soc@vger.kernel.org; andi@etezian.org; gost.dev@samsung.com;
> alim.akhtar@samsung.com; aswani.reddy@samsung.com;
> pankaj.dubey@samsung.com; ajaykumar.rs@samsung.com;
> aakarsh.jain@samsung.com
> Subject: [Patch v4 00/11] Add MFC V12 support
> 
> This patch series adds MFC v12 support. MFC v12 is used in Tesla FSD SoC.
> 
> This adds support for following:
> 
> -Add support for YV12 and I420 format (3-plane) -Add support for Rate
> Control, UHD and DMABUF for encoder -Add support for DPB buffers
> allocation based on MFC requirement
> 
> Changes since v3:
> -Removed vp9 codec support for now and just keeping MFC v12 base
> patches with necessary hardware controls, decoder, encoder and structural
> changes. Also covers luma dbp, chroma dpb and mv sizes for each codec as
> per the UM for MFCv12, along with appropriate alignment.
> v3 link: https://patchwork.kernel.org/project/linux-
> media/cover/20221011122516.32135-1-aakarsh.jain@samsung.com/
> 
> Changes since v2:
> -Addressed review comments by Rob Herring.
> This was regarding the errors found by Rob bot in yaml file. File
> 'samsung,s5p-mfc.yaml' is already converted into json schema and is
> merged.
> 
> -Addressed review comments by Krzysztof Kozlowski.
> This was regarding depricated properties mentioned in s5p-mfc.txt file.
> Review comment was addressed and 'samsung,s5p-mfc.yaml' is already
> merged now.
> 
> -Addressed review comments by Andi Shyti.
> This was regarding addition of 'MFC_V10PLUS_BITS' macro in
> 's5p_mfc_common.h file.
> v2 link: https://patchwork.kernel.org/project/linux-
> media/cover/20220907064715.55778-1-smitha.t@samsung.com/
> 
> Changes since v1:
> -Addressed review comments by Krzysztof Kozlowski.
> Separated bug fixes patches, resent again with fix tag and those are merged
> now.
> -Added SoC based compatible string.
> 
> -Addressed review comments by Andrzej Hajda Assigned width64 and
> height32 variable with ALIGN(ctx->img_..) used in the code in
> 's5p_mfc_opr_v6.c' file.
> v1 link: https://patchwork.kernel.org/project/linux-
> media/patch/20220517125548.14746-2-smitha.t@samsung.com/
> 
> Aakarsh Jain (11):
>   dt-bindings: media: s5p-mfc: Add mfcv12 variant
>   media: s5p-mfc: Rename IS_MFCV10 macro
>   media: s5p-mfc: Add initial support for MFCv12
>   media: s5p-mfc: Add YV12 and I420 multiplanar format support
>   media: s5p-mfc: Add support for rate controls in MFCv12
>   media: s5p-mfc: Add support for UHD encoding.
>   media: s5p-mfc: Add support for DMABUF for encoder
>   media: s5p-mfc: Set context for valid case before calling try_run
>   media: s5p-mfc: Load firmware for each run in MFCv12.
>   media: s5p-mfc: DPB Count Independent of VIDIOC_REQBUF
>   arm64: dts: fsd: Add MFC related DT enteries
> 
>  .../bindings/media/samsung,s5p-mfc.yaml       |  16 +
>  arch/arm64/boot/dts/tesla/fsd.dtsi            |  21 ++
>  .../platform/samsung/s5p-mfc/regs-mfc-v12.h   |  52 +++
>  .../platform/samsung/s5p-mfc/regs-mfc-v7.h    |   1 +
>  .../platform/samsung/s5p-mfc/regs-mfc-v8.h    |   3 +
>  .../media/platform/samsung/s5p-mfc/s5p_mfc.c  |  36 +-
> .../platform/samsung/s5p-mfc/s5p_mfc_common.h |  29 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_ctrl.c   |   9 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_dec.c    |  51 ++-
>  .../platform/samsung/s5p-mfc/s5p_mfc_enc.c    | 138 +++++---
>  .../platform/samsung/s5p-mfc/s5p_mfc_opr.h    |  14 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c |  12 +-
> .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 312 +++++++++++++++-
> --
>  .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h |   7 +-
>  14 files changed, 574 insertions(+), 127 deletions(-)  create mode 100644
> drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> 
> --
> 2.17.1


Gentle reminder to review MFC v12 patches.
I see Krzysztof have some comments on dt-schema patch. Waiting for reviewers to review driver changes as well. Post which I can send v5 changes.

Thanks



_______________________________________________
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] 54+ messages in thread

* Re: [Patch v4 03/11] media: s5p-mfc: Add initial support for MFCv12
  2023-10-25 10:22       ` Aakarsh Jain
@ 2023-11-22 15:34         ` Hans Verkuil
  -1 siblings, 0 replies; 54+ messages in thread
From: Hans Verkuil @ 2023-11-22 15:34 UTC (permalink / raw)
  To: Aakarsh Jain, linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, krzysztof.kozlowski+dt,
	dillon.minfei, david.plowman, mark.rutland, robh+dt, conor+dt,
	linux-samsung-soc, andi, gost.dev, alim.akhtar, aswani.reddy,
	pankaj.dubey, ajaykumar.rs, linux-fsd, Smitha T Murthy

On 25/10/2023 12:22, Aakarsh Jain wrote:
> Add support for MFCv12, with a new register file and necessary hw
> control, decoder, encoder and structural changes. Add luma dbp, chroma
> dpb and mv sizes for each codec as per the UM for MFCv12, along with
> appropriate alignment.
> 
> Cc: linux-fsd@tesla.com
> Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
> Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
> ---
>  .../platform/samsung/s5p-mfc/regs-mfc-v12.h   | 50 +++++++++++
>  .../media/platform/samsung/s5p-mfc/s5p_mfc.c  | 30 +++++++
>  .../platform/samsung/s5p-mfc/s5p_mfc_common.h | 15 +++-
>  .../platform/samsung/s5p-mfc/s5p_mfc_ctrl.c   |  2 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_dec.c    |  6 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_enc.c    |  5 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_opr.h    |  8 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 83 ++++++++++++++++---
>  .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h |  6 +-
>  9 files changed, 175 insertions(+), 30 deletions(-)
>  create mode 100644 drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> 
> diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> new file mode 100644
> index 000000000000..6c68a45082d0
> --- /dev/null
> +++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> @@ -0,0 +1,50 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Register definition file for Samsung MFC V12.x Interface (FIMV) driver
> + *
> + * Copyright (c) 2020 Samsung Electronics Co., Ltd.
> + *     http://www.samsung.com/
> + */
> +
> +#ifndef _REGS_MFC_V12_H
> +#define _REGS_MFC_V12_H
> +
> +#include <linux/sizes.h>
> +#include "regs-mfc-v10.h"
> +
> +/* MFCv12 Context buffer sizes */
> +#define MFC_CTX_BUF_SIZE_V12		(30 * SZ_1K)
> +#define MFC_H264_DEC_CTX_BUF_SIZE_V12	(2 * SZ_1M)
> +#define MFC_OTHER_DEC_CTX_BUF_SIZE_V12	(30 * SZ_1K)
> +#define MFC_H264_ENC_CTX_BUF_SIZE_V12	(100 * SZ_1K)
> +#define MFC_HEVC_ENC_CTX_BUF_SIZE_V12	(40 * SZ_1K)
> +#define MFC_OTHER_ENC_CTX_BUF_SIZE_V12	(25 * SZ_1K)
> +
> +/* MFCv12 variant defines */
> +#define MAX_FW_SIZE_V12			(SZ_1M)
> +#define MAX_CPB_SIZE_V12		(7 * SZ_1M)
> +#define MFC_VERSION_V12			0xC0
> +#define MFC_NUM_PORTS_V12		1
> +#define S5P_FIMV_CODEC_VP9_ENC		27
> +
> +/* Encoder buffer size for MFCv12 */
> +#define ENC_V120_BASE_SIZE(x, y) \
> +	(((x + 3) * (y + 3) * 8) \
> +	+ (((y * 64) + 2304) * (x + 7) / 8))
> +
> +#define ENC_V120_H264_ME_SIZE(x, y) \
> +	ALIGN((ENC_V120_BASE_SIZE(x, y) \
> +	+ (DIV_ROUND_UP(x * y, 64) * 32)), 256)
> +
> +#define ENC_V120_MPEG4_ME_SIZE(x, y) \
> +	ALIGN((ENC_V120_BASE_SIZE(x, y) \
> +	+ (DIV_ROUND_UP(x * y, 128) * 16)), 256)
> +
> +#define ENC_V120_VP8_ME_SIZE(x, y) \
> +	ALIGN(ENC_V120_BASE_SIZE(x, y), 256)
> +
> +#define ENC_V120_HEVC_ME_SIZE(x, y)     \
> +	ALIGN((((x + 3) * (y + 3) * 32)       \
> +	+ (((y * 128) + 2304) * (x + 3) / 4)), 256)
> +
> +#endif /*_REGS_MFC_V12_H*/
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
> index e30e54935d79..dee9ef017997 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
> @@ -790,6 +790,8 @@ static int s5p_mfc_open(struct file *file)
>  	INIT_LIST_HEAD(&ctx->dst_queue);
>  	ctx->src_queue_cnt = 0;
>  	ctx->dst_queue_cnt = 0;
> +	ctx->is_422 = 0;
> +	ctx->is_10bit = 0;
>  	/* Get context number */
>  	ctx->num = 0;
>  	while (dev->ctx[ctx->num]) {
> @@ -1660,6 +1662,31 @@ static struct s5p_mfc_variant mfc_drvdata_v10 = {
>  	.fw_name[0]     = "s5p-mfc-v10.fw",
>  };
>  
> +static struct s5p_mfc_buf_size_v6 mfc_buf_size_v12 = {
> +	.dev_ctx        = MFC_CTX_BUF_SIZE_V12,
> +	.h264_dec_ctx   = MFC_H264_DEC_CTX_BUF_SIZE_V12,
> +	.other_dec_ctx  = MFC_OTHER_DEC_CTX_BUF_SIZE_V12,
> +	.h264_enc_ctx   = MFC_H264_ENC_CTX_BUF_SIZE_V12,
> +	.hevc_enc_ctx   = MFC_HEVC_ENC_CTX_BUF_SIZE_V12,
> +	.other_enc_ctx  = MFC_OTHER_ENC_CTX_BUF_SIZE_V12,
> +};
> +
> +static struct s5p_mfc_buf_size buf_size_v12 = {
> +	.fw     = MAX_FW_SIZE_V12,
> +	.cpb    = MAX_CPB_SIZE_V12,
> +	.priv   = &mfc_buf_size_v12,
> +};
> +
> +static struct s5p_mfc_variant mfc_drvdata_v12 = {
> +	.version        = MFC_VERSION_V12,
> +	.version_bit    = MFC_V12_BIT,
> +	.port_num       = MFC_NUM_PORTS_V12,
> +	.buf_size       = &buf_size_v12,
> +	.fw_name[0]     = "s5p-mfc-v12.fw",

Is this fw in the process of being added to linux-firmware? (Or perhaps it
is already there).

Regards,

	Hans

> +	.clk_names	= {"mfc"},
> +	.num_clocks	= 1,
> +};
> +
>  static const struct of_device_id exynos_mfc_match[] = {
>  	{
>  		.compatible = "samsung,mfc-v5",
> @@ -1682,6 +1709,9 @@ static const struct of_device_id exynos_mfc_match[] = {
>  	}, {
>  		.compatible = "samsung,mfc-v10",
>  		.data = &mfc_drvdata_v10,
> +	}, {
> +		.compatible = "tesla,fsd-mfc",
> +		.data = &mfc_drvdata_v12,
>  	},
>  	{},
>  };
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> index e6ec4a43b290..dd2e9f7704ab 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> @@ -19,7 +19,7 @@
>  #include <media/v4l2-ioctl.h>
>  #include <media/videobuf2-v4l2.h>
>  #include "regs-mfc.h"
> -#include "regs-mfc-v10.h"
> +#include "regs-mfc-v12.h"
>  
>  #define S5P_MFC_NAME		"s5p-mfc"
>  
> @@ -720,6 +720,8 @@ struct s5p_mfc_ctx {
>  	struct v4l2_ctrl *ctrls[MFC_MAX_CTRLS];
>  	struct v4l2_ctrl_handler ctrl_handler;
>  	size_t scratch_buf_size;
> +	int is_10bit;
> +	int is_422;
>  };
>  
>  /*
> @@ -775,6 +777,7 @@ void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq);
>  #define IS_MFCV7_PLUS(dev)	(dev->variant->version >= 0x70)
>  #define IS_MFCV8_PLUS(dev)	(dev->variant->version >= 0x80)
>  #define IS_MFCV10_PLUS(dev)	(dev->variant->version >= 0xA0)
> +#define IS_MFCV12(dev)		(dev->variant->version >= 0xC0)
>  #define FW_HAS_E_MIN_SCRATCH_BUF(dev) (IS_MFCV10_PLUS(dev))
>  
>  #define MFC_V5_BIT	BIT(0)
> @@ -782,11 +785,15 @@ void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq);
>  #define MFC_V7_BIT	BIT(2)
>  #define MFC_V8_BIT	BIT(3)
>  #define MFC_V10_BIT	BIT(5)
> +#define MFC_V12_BIT	BIT(7)
>  
>  #define MFC_V5PLUS_BITS		(MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | \
> -					MFC_V8_BIT | MFC_V10_BIT)
> +					MFC_V8_BIT | MFC_V10_BIT | MFC_V12_BIT)
>  #define MFC_V6PLUS_BITS		(MFC_V6_BIT | MFC_V7_BIT | MFC_V8_BIT | \
> -					MFC_V10_BIT)
> -#define MFC_V7PLUS_BITS		(MFC_V7_BIT | MFC_V8_BIT | MFC_V10_BIT)
> +					MFC_V10_BIT | MFC_V12_BIT)
> +#define MFC_V7PLUS_BITS		(MFC_V7_BIT | MFC_V8_BIT | MFC_V10_BIT | \
> +					MFC_V12_BIT)
> +
> +#define MFC_V10PLUS_BITS	(MFC_V10_BIT | MFC_V12_BIT)
>  
>  #endif /* S5P_MFC_COMMON_H_ */
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> index 54b54b2fa9b1..b49159142c53 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> @@ -130,7 +130,7 @@ int s5p_mfc_reset(struct s5p_mfc_dev *dev)
>  			mfc_write(dev, 0, S5P_FIMV_REG_CLEAR_BEGIN_V6 + (i*4));
>  
>  		/* check bus reset control before reset */
> -		if (dev->risc_on)
> +		if (dev->risc_on && !IS_MFCV12(dev))
>  			if (s5p_mfc_bus_reset(dev))
>  				return -EIO;
>  		/* Reset
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> index 268ffe4da53c..e219cbcd86d5 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> @@ -146,7 +146,7 @@ static struct s5p_mfc_fmt formats[] = {
>  		.codec_mode	= S5P_FIMV_CODEC_HEVC_DEC,
>  		.type		= MFC_FMT_DEC,
>  		.num_planes	= 1,
> -		.versions	= MFC_V10_BIT,
> +		.versions	= MFC_V10PLUS_BITS,
>  		.flags		= V4L2_FMT_FLAG_DYN_RESOLUTION |
>  				  V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM,
>  	},
> @@ -155,7 +155,7 @@ static struct s5p_mfc_fmt formats[] = {
>  		.codec_mode	= S5P_FIMV_CODEC_VP9_DEC,
>  		.type		= MFC_FMT_DEC,
>  		.num_planes	= 1,
> -		.versions	= MFC_V10_BIT,
> +		.versions	= MFC_V10PLUS_BITS,
>  		.flags		= V4L2_FMT_FLAG_DYN_RESOLUTION,
>  	},
>  };
> @@ -355,7 +355,7 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
>  		pix_mp->width = ctx->buf_width;
>  		pix_mp->height = ctx->buf_height;
>  		pix_mp->field = V4L2_FIELD_NONE;
> -		pix_mp->num_planes = 2;
> +		pix_mp->num_planes = ctx->dst_fmt->num_planes;
>  		/* Set pixelformat to the format in which MFC
>  		   outputs the decoded frame */
>  		pix_mp->pixelformat = ctx->dst_fmt->fourcc;
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> index f62703cebb77..e4d6e7c117b5 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> @@ -92,7 +92,7 @@ static struct s5p_mfc_fmt formats[] = {
>  		.codec_mode	= S5P_FIMV_CODEC_HEVC_ENC,
>  		.type		= MFC_FMT_ENC,
>  		.num_planes	= 1,
> -		.versions	= MFC_V10_BIT,
> +		.versions	= MFC_V10PLUS_BITS,
>  	},
>  };
>  
> @@ -1179,7 +1179,8 @@ static int enc_post_seq_start(struct s5p_mfc_ctx *ctx)
>  		if (FW_HAS_E_MIN_SCRATCH_BUF(dev)) {
>  			ctx->scratch_buf_size = s5p_mfc_hw_call(dev->mfc_ops,
>  					get_e_min_scratch_buf_size, dev);
> -			ctx->bank1.size += ctx->scratch_buf_size;
> +			if (!IS_MFCV12(dev))
> +				ctx->bank1.size += ctx->scratch_buf_size;
>  		}
>  		ctx->state = MFCINST_HEAD_PRODUCED;
>  	}
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> index b9831275f3ab..87ac56756a16 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> @@ -166,9 +166,9 @@ struct s5p_mfc_regs {
>  	void __iomem *d_decoded_third_addr;/* only v7 */
>  	void __iomem *d_used_dpb_flag_upper;/* v7 and v8 */
>  	void __iomem *d_used_dpb_flag_lower;/* v7 and v8 */
> -	void __iomem *d_min_scratch_buffer_size; /* v10 */
> -	void __iomem *d_static_buffer_addr; /* v10 */
> -	void __iomem *d_static_buffer_size; /* v10 */
> +	void __iomem *d_min_scratch_buffer_size; /* v10 and v12 */
> +	void __iomem *d_static_buffer_addr; /* v10 and v12 */
> +	void __iomem *d_static_buffer_size; /* v10 and v12 */
>  
>  	/* encoder registers */
>  	void __iomem *e_frame_width;
> @@ -268,7 +268,7 @@ struct s5p_mfc_regs {
>  	void __iomem *e_vp8_hierarchical_qp_layer0;/* v7 and v8 */
>  	void __iomem *e_vp8_hierarchical_qp_layer1;/* v7 and v8 */
>  	void __iomem *e_vp8_hierarchical_qp_layer2;/* v7 and v8 */
> -	void __iomem *e_min_scratch_buffer_size; /* v10 */
> +	void __iomem *e_min_scratch_buffer_size; /* v10 and v12 */
>  	void __iomem *e_num_t_layer; /* v10 */
>  	void __iomem *e_hier_qp_layer0; /* v10 */
>  	void __iomem *e_hier_bit_rate_layer0; /* v10 */
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> index 882166e4ac50..fb3f0718821d 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> @@ -60,12 +60,14 @@ static void s5p_mfc_release_dec_desc_buffer_v6(struct s5p_mfc_ctx *ctx)
>  static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
>  {
>  	struct s5p_mfc_dev *dev = ctx->dev;
> -	unsigned int mb_width, mb_height;
> +	unsigned int mb_width, mb_height, width64, height32;
>  	unsigned int lcu_width = 0, lcu_height = 0;
>  	int ret;
>  
>  	mb_width = MB_WIDTH(ctx->img_width);
>  	mb_height = MB_HEIGHT(ctx->img_height);
> +	width64 = ALIGN(ctx->img_width, 64);
> +	height32 = ALIGN(ctx->img_height, 32);
>  
>  	if (ctx->type == MFCINST_DECODER) {
>  		mfc_debug(2, "Luma size:%d Chroma size:%d MV size:%d\n",
> @@ -82,7 +84,44 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
>  			ctx->tmv_buffer_size = S5P_FIMV_NUM_TMV_BUFFERS_V6 *
>  			ALIGN(S5P_FIMV_TMV_BUFFER_SIZE_V6(mb_width, mb_height),
>  			S5P_FIMV_TMV_BUFFER_ALIGN_V6);
> -		if (IS_MFCV10_PLUS(dev)) {
> +		if (IS_MFCV12(dev)) {
> +			lcu_width = S5P_MFC_LCU_WIDTH(ctx->img_width);
> +			lcu_height = S5P_MFC_LCU_HEIGHT(ctx->img_height);
> +			if (ctx->codec_mode == S5P_FIMV_CODEC_HEVC_ENC &&
> +								ctx->is_10bit) {
> +				ctx->luma_dpb_size =
> +					width64 * height32 +
> +					ALIGN(DIV_ROUND_UP(lcu_width * 32, 4),
> +							16) * height32 + 128;
> +				if (ctx->is_422)
> +					ctx->chroma_dpb_size =
> +						ctx->luma_dpb_size;
> +				else
> +					ctx->chroma_dpb_size =
> +						width64 * height32 / 2 +
> +						ALIGN(DIV_ROUND_UP(lcu_width *
> +						32, 4), 16) * height32 / 2 + 128;
> +			} else if (ctx->codec_mode == S5P_FIMV_CODEC_VP9_ENC &&
> +					ctx->is_10bit) {
> +				ctx->luma_dpb_size =
> +					ALIGN(ctx->img_width * 2, 128) *
> +					height32 + 64;
> +				ctx->chroma_dpb_size =
> +					ALIGN(ctx->img_width * 2, 128) *
> +					height32 / 2 + 64;
> +			} else {
> +				ctx->luma_dpb_size =
> +					width64 * height32 + 64;
> +				if (ctx->is_422)
> +					ctx->chroma_dpb_size =
> +						ctx->luma_dpb_size;
> +				else
> +					ctx->chroma_dpb_size =
> +						width64 * height32 / 2 + 64;
> +			}
> +			ctx->luma_dpb_size = ALIGN(ctx->luma_dpb_size + 256, SZ_2K);
> +			ctx->chroma_dpb_size = ALIGN(ctx->chroma_dpb_size + 256, SZ_2K);
> +		} else if (IS_MFCV10_PLUS(dev)) {
>  			lcu_width = S5P_MFC_LCU_WIDTH(ctx->img_width);
>  			lcu_height = S5P_MFC_LCU_HEIGHT(ctx->img_height);
>  			if (ctx->codec_mode != S5P_FIMV_CODEC_HEVC_ENC) {
> @@ -230,7 +269,11 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
>  			DEC_VP9_STATIC_BUFFER_SIZE;
>  		break;
>  	case S5P_MFC_CODEC_H264_ENC:
> -		if (IS_MFCV10_PLUS(dev)) {
> +		if (IS_MFCV12(dev)) {
> +			mfc_debug(2, "Use min scratch buffer size\n");
> +			ctx->me_buffer_size =
> +				ENC_V120_H264_ME_SIZE(mb_width, mb_height);
> +		} else if (IS_MFCV10_PLUS(dev)) {
>  			mfc_debug(2, "Use min scratch buffer size\n");
>  			ctx->me_buffer_size =
>  			ALIGN(ENC_V100_H264_ME_SIZE(mb_width, mb_height), 16);
> @@ -254,7 +297,11 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
>  		break;
>  	case S5P_MFC_CODEC_MPEG4_ENC:
>  	case S5P_MFC_CODEC_H263_ENC:
> -		if (IS_MFCV10_PLUS(dev)) {
> +		if (IS_MFCV12(dev)) {
> +			mfc_debug(2, "Use min scratch buffer size\n");
> +			ctx->me_buffer_size =
> +				ENC_V120_MPEG4_ME_SIZE(mb_width, mb_height);
> +		} else if (IS_MFCV10_PLUS(dev)) {
>  			mfc_debug(2, "Use min scratch buffer size\n");
>  			ctx->me_buffer_size =
>  				ALIGN(ENC_V100_MPEG4_ME_SIZE(mb_width,
> @@ -273,7 +320,11 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
>  		ctx->bank2.size = 0;
>  		break;
>  	case S5P_MFC_CODEC_VP8_ENC:
> -		if (IS_MFCV10_PLUS(dev)) {
> +		if (IS_MFCV12(dev)) {
> +			mfc_debug(2, "Use min scratch buffer size\n");
> +			ctx->me_buffer_size =
> +				ENC_V120_VP8_ME_SIZE(mb_width, mb_height);
> +		} else if (IS_MFCV10_PLUS(dev)) {
>  			mfc_debug(2, "Use min scratch buffer size\n");
>  			ctx->me_buffer_size =
>  				ALIGN(ENC_V100_VP8_ME_SIZE(mb_width, mb_height),
> @@ -297,9 +348,14 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
>  		ctx->bank2.size = 0;
>  		break;
>  	case S5P_MFC_CODEC_HEVC_ENC:
> +		if (IS_MFCV12(dev))
> +			ctx->me_buffer_size =
> +				ENC_V120_HEVC_ME_SIZE(lcu_width, lcu_height);
> +		else
> +			ctx->me_buffer_size =
> +				ALIGN(ENC_V100_HEVC_ME_SIZE(lcu_width,
> +							lcu_height), 16);
>  		mfc_debug(2, "Use min scratch buffer size\n");
> -		ctx->me_buffer_size =
> -			ALIGN(ENC_V100_HEVC_ME_SIZE(lcu_width, lcu_height), 16);
>  		ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, 256);
>  		ctx->bank1.size =
>  			ctx->scratch_buf_size + ctx->tmv_buffer_size +
> @@ -452,12 +508,15 @@ static void s5p_mfc_dec_calc_dpb_size_v6(struct s5p_mfc_ctx *ctx)
>  
>  	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
>  			ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC) {
> -		if (IS_MFCV10_PLUS(dev)) {
> -			ctx->mv_size = S5P_MFC_DEC_MV_SIZE_V10(ctx->img_width,
> -					ctx->img_height);
> +		if (IS_MFCV12(dev)) {
> +			ctx->mv_size = S5P_MFC_DEC_MV_SIZE(ctx->img_width,
> +					ctx->img_height, 1024);
> +		} else if (IS_MFCV10_PLUS(dev)) {
> +			ctx->mv_size = S5P_MFC_DEC_MV_SIZE(ctx->img_width,
> +					ctx->img_height, 512);
>  		} else {
> -			ctx->mv_size = S5P_MFC_DEC_MV_SIZE_V6(ctx->img_width,
> -					ctx->img_height);
> +			ctx->mv_size = S5P_MFC_DEC_MV_SIZE(ctx->img_width,
> +					ctx->img_height, 128);
>  		}
>  	} else if (ctx->codec_mode == S5P_MFC_CODEC_HEVC_DEC) {
>  		ctx->mv_size = s5p_mfc_dec_hevc_mv_size(ctx->img_width,
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
> index e4dd03c5454c..30269f3e68e8 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
> @@ -19,10 +19,8 @@
>  
>  #define MB_WIDTH(x_size)		DIV_ROUND_UP(x_size, 16)
>  #define MB_HEIGHT(y_size)		DIV_ROUND_UP(y_size, 16)
> -#define S5P_MFC_DEC_MV_SIZE_V6(x, y)	(MB_WIDTH(x) * \
> -					(((MB_HEIGHT(y)+1)/2)*2) * 64 + 128)
> -#define S5P_MFC_DEC_MV_SIZE_V10(x, y)	(MB_WIDTH(x) * \
> -					(((MB_HEIGHT(y)+1)/2)*2) * 64 + 512)
> +#define S5P_MFC_DEC_MV_SIZE(x, y, offset)	(MB_WIDTH(x) * \
> +					(((MB_HEIGHT(y)+1)/2)*2) * 64 + offset)
>  #define S5P_MFC_LCU_WIDTH(x_size)	DIV_ROUND_UP(x_size, 32)
>  #define S5P_MFC_LCU_HEIGHT(y_size)	DIV_ROUND_UP(y_size, 32)
>  


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

* Re: [Patch v4 03/11] media: s5p-mfc: Add initial support for MFCv12
@ 2023-11-22 15:34         ` Hans Verkuil
  0 siblings, 0 replies; 54+ messages in thread
From: Hans Verkuil @ 2023-11-22 15:34 UTC (permalink / raw)
  To: Aakarsh Jain, linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, krzysztof.kozlowski+dt,
	dillon.minfei, david.plowman, mark.rutland, robh+dt, conor+dt,
	linux-samsung-soc, andi, gost.dev, alim.akhtar, aswani.reddy,
	pankaj.dubey, ajaykumar.rs, linux-fsd, Smitha T Murthy

On 25/10/2023 12:22, Aakarsh Jain wrote:
> Add support for MFCv12, with a new register file and necessary hw
> control, decoder, encoder and structural changes. Add luma dbp, chroma
> dpb and mv sizes for each codec as per the UM for MFCv12, along with
> appropriate alignment.
> 
> Cc: linux-fsd@tesla.com
> Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
> Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
> ---
>  .../platform/samsung/s5p-mfc/regs-mfc-v12.h   | 50 +++++++++++
>  .../media/platform/samsung/s5p-mfc/s5p_mfc.c  | 30 +++++++
>  .../platform/samsung/s5p-mfc/s5p_mfc_common.h | 15 +++-
>  .../platform/samsung/s5p-mfc/s5p_mfc_ctrl.c   |  2 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_dec.c    |  6 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_enc.c    |  5 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_opr.h    |  8 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 83 ++++++++++++++++---
>  .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h |  6 +-
>  9 files changed, 175 insertions(+), 30 deletions(-)
>  create mode 100644 drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> 
> diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> new file mode 100644
> index 000000000000..6c68a45082d0
> --- /dev/null
> +++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> @@ -0,0 +1,50 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Register definition file for Samsung MFC V12.x Interface (FIMV) driver
> + *
> + * Copyright (c) 2020 Samsung Electronics Co., Ltd.
> + *     http://www.samsung.com/
> + */
> +
> +#ifndef _REGS_MFC_V12_H
> +#define _REGS_MFC_V12_H
> +
> +#include <linux/sizes.h>
> +#include "regs-mfc-v10.h"
> +
> +/* MFCv12 Context buffer sizes */
> +#define MFC_CTX_BUF_SIZE_V12		(30 * SZ_1K)
> +#define MFC_H264_DEC_CTX_BUF_SIZE_V12	(2 * SZ_1M)
> +#define MFC_OTHER_DEC_CTX_BUF_SIZE_V12	(30 * SZ_1K)
> +#define MFC_H264_ENC_CTX_BUF_SIZE_V12	(100 * SZ_1K)
> +#define MFC_HEVC_ENC_CTX_BUF_SIZE_V12	(40 * SZ_1K)
> +#define MFC_OTHER_ENC_CTX_BUF_SIZE_V12	(25 * SZ_1K)
> +
> +/* MFCv12 variant defines */
> +#define MAX_FW_SIZE_V12			(SZ_1M)
> +#define MAX_CPB_SIZE_V12		(7 * SZ_1M)
> +#define MFC_VERSION_V12			0xC0
> +#define MFC_NUM_PORTS_V12		1
> +#define S5P_FIMV_CODEC_VP9_ENC		27
> +
> +/* Encoder buffer size for MFCv12 */
> +#define ENC_V120_BASE_SIZE(x, y) \
> +	(((x + 3) * (y + 3) * 8) \
> +	+ (((y * 64) + 2304) * (x + 7) / 8))
> +
> +#define ENC_V120_H264_ME_SIZE(x, y) \
> +	ALIGN((ENC_V120_BASE_SIZE(x, y) \
> +	+ (DIV_ROUND_UP(x * y, 64) * 32)), 256)
> +
> +#define ENC_V120_MPEG4_ME_SIZE(x, y) \
> +	ALIGN((ENC_V120_BASE_SIZE(x, y) \
> +	+ (DIV_ROUND_UP(x * y, 128) * 16)), 256)
> +
> +#define ENC_V120_VP8_ME_SIZE(x, y) \
> +	ALIGN(ENC_V120_BASE_SIZE(x, y), 256)
> +
> +#define ENC_V120_HEVC_ME_SIZE(x, y)     \
> +	ALIGN((((x + 3) * (y + 3) * 32)       \
> +	+ (((y * 128) + 2304) * (x + 3) / 4)), 256)
> +
> +#endif /*_REGS_MFC_V12_H*/
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
> index e30e54935d79..dee9ef017997 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
> @@ -790,6 +790,8 @@ static int s5p_mfc_open(struct file *file)
>  	INIT_LIST_HEAD(&ctx->dst_queue);
>  	ctx->src_queue_cnt = 0;
>  	ctx->dst_queue_cnt = 0;
> +	ctx->is_422 = 0;
> +	ctx->is_10bit = 0;
>  	/* Get context number */
>  	ctx->num = 0;
>  	while (dev->ctx[ctx->num]) {
> @@ -1660,6 +1662,31 @@ static struct s5p_mfc_variant mfc_drvdata_v10 = {
>  	.fw_name[0]     = "s5p-mfc-v10.fw",
>  };
>  
> +static struct s5p_mfc_buf_size_v6 mfc_buf_size_v12 = {
> +	.dev_ctx        = MFC_CTX_BUF_SIZE_V12,
> +	.h264_dec_ctx   = MFC_H264_DEC_CTX_BUF_SIZE_V12,
> +	.other_dec_ctx  = MFC_OTHER_DEC_CTX_BUF_SIZE_V12,
> +	.h264_enc_ctx   = MFC_H264_ENC_CTX_BUF_SIZE_V12,
> +	.hevc_enc_ctx   = MFC_HEVC_ENC_CTX_BUF_SIZE_V12,
> +	.other_enc_ctx  = MFC_OTHER_ENC_CTX_BUF_SIZE_V12,
> +};
> +
> +static struct s5p_mfc_buf_size buf_size_v12 = {
> +	.fw     = MAX_FW_SIZE_V12,
> +	.cpb    = MAX_CPB_SIZE_V12,
> +	.priv   = &mfc_buf_size_v12,
> +};
> +
> +static struct s5p_mfc_variant mfc_drvdata_v12 = {
> +	.version        = MFC_VERSION_V12,
> +	.version_bit    = MFC_V12_BIT,
> +	.port_num       = MFC_NUM_PORTS_V12,
> +	.buf_size       = &buf_size_v12,
> +	.fw_name[0]     = "s5p-mfc-v12.fw",

Is this fw in the process of being added to linux-firmware? (Or perhaps it
is already there).

Regards,

	Hans

> +	.clk_names	= {"mfc"},
> +	.num_clocks	= 1,
> +};
> +
>  static const struct of_device_id exynos_mfc_match[] = {
>  	{
>  		.compatible = "samsung,mfc-v5",
> @@ -1682,6 +1709,9 @@ static const struct of_device_id exynos_mfc_match[] = {
>  	}, {
>  		.compatible = "samsung,mfc-v10",
>  		.data = &mfc_drvdata_v10,
> +	}, {
> +		.compatible = "tesla,fsd-mfc",
> +		.data = &mfc_drvdata_v12,
>  	},
>  	{},
>  };
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> index e6ec4a43b290..dd2e9f7704ab 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> @@ -19,7 +19,7 @@
>  #include <media/v4l2-ioctl.h>
>  #include <media/videobuf2-v4l2.h>
>  #include "regs-mfc.h"
> -#include "regs-mfc-v10.h"
> +#include "regs-mfc-v12.h"
>  
>  #define S5P_MFC_NAME		"s5p-mfc"
>  
> @@ -720,6 +720,8 @@ struct s5p_mfc_ctx {
>  	struct v4l2_ctrl *ctrls[MFC_MAX_CTRLS];
>  	struct v4l2_ctrl_handler ctrl_handler;
>  	size_t scratch_buf_size;
> +	int is_10bit;
> +	int is_422;
>  };
>  
>  /*
> @@ -775,6 +777,7 @@ void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq);
>  #define IS_MFCV7_PLUS(dev)	(dev->variant->version >= 0x70)
>  #define IS_MFCV8_PLUS(dev)	(dev->variant->version >= 0x80)
>  #define IS_MFCV10_PLUS(dev)	(dev->variant->version >= 0xA0)
> +#define IS_MFCV12(dev)		(dev->variant->version >= 0xC0)
>  #define FW_HAS_E_MIN_SCRATCH_BUF(dev) (IS_MFCV10_PLUS(dev))
>  
>  #define MFC_V5_BIT	BIT(0)
> @@ -782,11 +785,15 @@ void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq);
>  #define MFC_V7_BIT	BIT(2)
>  #define MFC_V8_BIT	BIT(3)
>  #define MFC_V10_BIT	BIT(5)
> +#define MFC_V12_BIT	BIT(7)
>  
>  #define MFC_V5PLUS_BITS		(MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | \
> -					MFC_V8_BIT | MFC_V10_BIT)
> +					MFC_V8_BIT | MFC_V10_BIT | MFC_V12_BIT)
>  #define MFC_V6PLUS_BITS		(MFC_V6_BIT | MFC_V7_BIT | MFC_V8_BIT | \
> -					MFC_V10_BIT)
> -#define MFC_V7PLUS_BITS		(MFC_V7_BIT | MFC_V8_BIT | MFC_V10_BIT)
> +					MFC_V10_BIT | MFC_V12_BIT)
> +#define MFC_V7PLUS_BITS		(MFC_V7_BIT | MFC_V8_BIT | MFC_V10_BIT | \
> +					MFC_V12_BIT)
> +
> +#define MFC_V10PLUS_BITS	(MFC_V10_BIT | MFC_V12_BIT)
>  
>  #endif /* S5P_MFC_COMMON_H_ */
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> index 54b54b2fa9b1..b49159142c53 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> @@ -130,7 +130,7 @@ int s5p_mfc_reset(struct s5p_mfc_dev *dev)
>  			mfc_write(dev, 0, S5P_FIMV_REG_CLEAR_BEGIN_V6 + (i*4));
>  
>  		/* check bus reset control before reset */
> -		if (dev->risc_on)
> +		if (dev->risc_on && !IS_MFCV12(dev))
>  			if (s5p_mfc_bus_reset(dev))
>  				return -EIO;
>  		/* Reset
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> index 268ffe4da53c..e219cbcd86d5 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> @@ -146,7 +146,7 @@ static struct s5p_mfc_fmt formats[] = {
>  		.codec_mode	= S5P_FIMV_CODEC_HEVC_DEC,
>  		.type		= MFC_FMT_DEC,
>  		.num_planes	= 1,
> -		.versions	= MFC_V10_BIT,
> +		.versions	= MFC_V10PLUS_BITS,
>  		.flags		= V4L2_FMT_FLAG_DYN_RESOLUTION |
>  				  V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM,
>  	},
> @@ -155,7 +155,7 @@ static struct s5p_mfc_fmt formats[] = {
>  		.codec_mode	= S5P_FIMV_CODEC_VP9_DEC,
>  		.type		= MFC_FMT_DEC,
>  		.num_planes	= 1,
> -		.versions	= MFC_V10_BIT,
> +		.versions	= MFC_V10PLUS_BITS,
>  		.flags		= V4L2_FMT_FLAG_DYN_RESOLUTION,
>  	},
>  };
> @@ -355,7 +355,7 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
>  		pix_mp->width = ctx->buf_width;
>  		pix_mp->height = ctx->buf_height;
>  		pix_mp->field = V4L2_FIELD_NONE;
> -		pix_mp->num_planes = 2;
> +		pix_mp->num_planes = ctx->dst_fmt->num_planes;
>  		/* Set pixelformat to the format in which MFC
>  		   outputs the decoded frame */
>  		pix_mp->pixelformat = ctx->dst_fmt->fourcc;
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> index f62703cebb77..e4d6e7c117b5 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> @@ -92,7 +92,7 @@ static struct s5p_mfc_fmt formats[] = {
>  		.codec_mode	= S5P_FIMV_CODEC_HEVC_ENC,
>  		.type		= MFC_FMT_ENC,
>  		.num_planes	= 1,
> -		.versions	= MFC_V10_BIT,
> +		.versions	= MFC_V10PLUS_BITS,
>  	},
>  };
>  
> @@ -1179,7 +1179,8 @@ static int enc_post_seq_start(struct s5p_mfc_ctx *ctx)
>  		if (FW_HAS_E_MIN_SCRATCH_BUF(dev)) {
>  			ctx->scratch_buf_size = s5p_mfc_hw_call(dev->mfc_ops,
>  					get_e_min_scratch_buf_size, dev);
> -			ctx->bank1.size += ctx->scratch_buf_size;
> +			if (!IS_MFCV12(dev))
> +				ctx->bank1.size += ctx->scratch_buf_size;
>  		}
>  		ctx->state = MFCINST_HEAD_PRODUCED;
>  	}
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> index b9831275f3ab..87ac56756a16 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> @@ -166,9 +166,9 @@ struct s5p_mfc_regs {
>  	void __iomem *d_decoded_third_addr;/* only v7 */
>  	void __iomem *d_used_dpb_flag_upper;/* v7 and v8 */
>  	void __iomem *d_used_dpb_flag_lower;/* v7 and v8 */
> -	void __iomem *d_min_scratch_buffer_size; /* v10 */
> -	void __iomem *d_static_buffer_addr; /* v10 */
> -	void __iomem *d_static_buffer_size; /* v10 */
> +	void __iomem *d_min_scratch_buffer_size; /* v10 and v12 */
> +	void __iomem *d_static_buffer_addr; /* v10 and v12 */
> +	void __iomem *d_static_buffer_size; /* v10 and v12 */
>  
>  	/* encoder registers */
>  	void __iomem *e_frame_width;
> @@ -268,7 +268,7 @@ struct s5p_mfc_regs {
>  	void __iomem *e_vp8_hierarchical_qp_layer0;/* v7 and v8 */
>  	void __iomem *e_vp8_hierarchical_qp_layer1;/* v7 and v8 */
>  	void __iomem *e_vp8_hierarchical_qp_layer2;/* v7 and v8 */
> -	void __iomem *e_min_scratch_buffer_size; /* v10 */
> +	void __iomem *e_min_scratch_buffer_size; /* v10 and v12 */
>  	void __iomem *e_num_t_layer; /* v10 */
>  	void __iomem *e_hier_qp_layer0; /* v10 */
>  	void __iomem *e_hier_bit_rate_layer0; /* v10 */
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> index 882166e4ac50..fb3f0718821d 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> @@ -60,12 +60,14 @@ static void s5p_mfc_release_dec_desc_buffer_v6(struct s5p_mfc_ctx *ctx)
>  static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
>  {
>  	struct s5p_mfc_dev *dev = ctx->dev;
> -	unsigned int mb_width, mb_height;
> +	unsigned int mb_width, mb_height, width64, height32;
>  	unsigned int lcu_width = 0, lcu_height = 0;
>  	int ret;
>  
>  	mb_width = MB_WIDTH(ctx->img_width);
>  	mb_height = MB_HEIGHT(ctx->img_height);
> +	width64 = ALIGN(ctx->img_width, 64);
> +	height32 = ALIGN(ctx->img_height, 32);
>  
>  	if (ctx->type == MFCINST_DECODER) {
>  		mfc_debug(2, "Luma size:%d Chroma size:%d MV size:%d\n",
> @@ -82,7 +84,44 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
>  			ctx->tmv_buffer_size = S5P_FIMV_NUM_TMV_BUFFERS_V6 *
>  			ALIGN(S5P_FIMV_TMV_BUFFER_SIZE_V6(mb_width, mb_height),
>  			S5P_FIMV_TMV_BUFFER_ALIGN_V6);
> -		if (IS_MFCV10_PLUS(dev)) {
> +		if (IS_MFCV12(dev)) {
> +			lcu_width = S5P_MFC_LCU_WIDTH(ctx->img_width);
> +			lcu_height = S5P_MFC_LCU_HEIGHT(ctx->img_height);
> +			if (ctx->codec_mode == S5P_FIMV_CODEC_HEVC_ENC &&
> +								ctx->is_10bit) {
> +				ctx->luma_dpb_size =
> +					width64 * height32 +
> +					ALIGN(DIV_ROUND_UP(lcu_width * 32, 4),
> +							16) * height32 + 128;
> +				if (ctx->is_422)
> +					ctx->chroma_dpb_size =
> +						ctx->luma_dpb_size;
> +				else
> +					ctx->chroma_dpb_size =
> +						width64 * height32 / 2 +
> +						ALIGN(DIV_ROUND_UP(lcu_width *
> +						32, 4), 16) * height32 / 2 + 128;
> +			} else if (ctx->codec_mode == S5P_FIMV_CODEC_VP9_ENC &&
> +					ctx->is_10bit) {
> +				ctx->luma_dpb_size =
> +					ALIGN(ctx->img_width * 2, 128) *
> +					height32 + 64;
> +				ctx->chroma_dpb_size =
> +					ALIGN(ctx->img_width * 2, 128) *
> +					height32 / 2 + 64;
> +			} else {
> +				ctx->luma_dpb_size =
> +					width64 * height32 + 64;
> +				if (ctx->is_422)
> +					ctx->chroma_dpb_size =
> +						ctx->luma_dpb_size;
> +				else
> +					ctx->chroma_dpb_size =
> +						width64 * height32 / 2 + 64;
> +			}
> +			ctx->luma_dpb_size = ALIGN(ctx->luma_dpb_size + 256, SZ_2K);
> +			ctx->chroma_dpb_size = ALIGN(ctx->chroma_dpb_size + 256, SZ_2K);
> +		} else if (IS_MFCV10_PLUS(dev)) {
>  			lcu_width = S5P_MFC_LCU_WIDTH(ctx->img_width);
>  			lcu_height = S5P_MFC_LCU_HEIGHT(ctx->img_height);
>  			if (ctx->codec_mode != S5P_FIMV_CODEC_HEVC_ENC) {
> @@ -230,7 +269,11 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
>  			DEC_VP9_STATIC_BUFFER_SIZE;
>  		break;
>  	case S5P_MFC_CODEC_H264_ENC:
> -		if (IS_MFCV10_PLUS(dev)) {
> +		if (IS_MFCV12(dev)) {
> +			mfc_debug(2, "Use min scratch buffer size\n");
> +			ctx->me_buffer_size =
> +				ENC_V120_H264_ME_SIZE(mb_width, mb_height);
> +		} else if (IS_MFCV10_PLUS(dev)) {
>  			mfc_debug(2, "Use min scratch buffer size\n");
>  			ctx->me_buffer_size =
>  			ALIGN(ENC_V100_H264_ME_SIZE(mb_width, mb_height), 16);
> @@ -254,7 +297,11 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
>  		break;
>  	case S5P_MFC_CODEC_MPEG4_ENC:
>  	case S5P_MFC_CODEC_H263_ENC:
> -		if (IS_MFCV10_PLUS(dev)) {
> +		if (IS_MFCV12(dev)) {
> +			mfc_debug(2, "Use min scratch buffer size\n");
> +			ctx->me_buffer_size =
> +				ENC_V120_MPEG4_ME_SIZE(mb_width, mb_height);
> +		} else if (IS_MFCV10_PLUS(dev)) {
>  			mfc_debug(2, "Use min scratch buffer size\n");
>  			ctx->me_buffer_size =
>  				ALIGN(ENC_V100_MPEG4_ME_SIZE(mb_width,
> @@ -273,7 +320,11 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
>  		ctx->bank2.size = 0;
>  		break;
>  	case S5P_MFC_CODEC_VP8_ENC:
> -		if (IS_MFCV10_PLUS(dev)) {
> +		if (IS_MFCV12(dev)) {
> +			mfc_debug(2, "Use min scratch buffer size\n");
> +			ctx->me_buffer_size =
> +				ENC_V120_VP8_ME_SIZE(mb_width, mb_height);
> +		} else if (IS_MFCV10_PLUS(dev)) {
>  			mfc_debug(2, "Use min scratch buffer size\n");
>  			ctx->me_buffer_size =
>  				ALIGN(ENC_V100_VP8_ME_SIZE(mb_width, mb_height),
> @@ -297,9 +348,14 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
>  		ctx->bank2.size = 0;
>  		break;
>  	case S5P_MFC_CODEC_HEVC_ENC:
> +		if (IS_MFCV12(dev))
> +			ctx->me_buffer_size =
> +				ENC_V120_HEVC_ME_SIZE(lcu_width, lcu_height);
> +		else
> +			ctx->me_buffer_size =
> +				ALIGN(ENC_V100_HEVC_ME_SIZE(lcu_width,
> +							lcu_height), 16);
>  		mfc_debug(2, "Use min scratch buffer size\n");
> -		ctx->me_buffer_size =
> -			ALIGN(ENC_V100_HEVC_ME_SIZE(lcu_width, lcu_height), 16);
>  		ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, 256);
>  		ctx->bank1.size =
>  			ctx->scratch_buf_size + ctx->tmv_buffer_size +
> @@ -452,12 +508,15 @@ static void s5p_mfc_dec_calc_dpb_size_v6(struct s5p_mfc_ctx *ctx)
>  
>  	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
>  			ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC) {
> -		if (IS_MFCV10_PLUS(dev)) {
> -			ctx->mv_size = S5P_MFC_DEC_MV_SIZE_V10(ctx->img_width,
> -					ctx->img_height);
> +		if (IS_MFCV12(dev)) {
> +			ctx->mv_size = S5P_MFC_DEC_MV_SIZE(ctx->img_width,
> +					ctx->img_height, 1024);
> +		} else if (IS_MFCV10_PLUS(dev)) {
> +			ctx->mv_size = S5P_MFC_DEC_MV_SIZE(ctx->img_width,
> +					ctx->img_height, 512);
>  		} else {
> -			ctx->mv_size = S5P_MFC_DEC_MV_SIZE_V6(ctx->img_width,
> -					ctx->img_height);
> +			ctx->mv_size = S5P_MFC_DEC_MV_SIZE(ctx->img_width,
> +					ctx->img_height, 128);
>  		}
>  	} else if (ctx->codec_mode == S5P_MFC_CODEC_HEVC_DEC) {
>  		ctx->mv_size = s5p_mfc_dec_hevc_mv_size(ctx->img_width,
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
> index e4dd03c5454c..30269f3e68e8 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
> @@ -19,10 +19,8 @@
>  
>  #define MB_WIDTH(x_size)		DIV_ROUND_UP(x_size, 16)
>  #define MB_HEIGHT(y_size)		DIV_ROUND_UP(y_size, 16)
> -#define S5P_MFC_DEC_MV_SIZE_V6(x, y)	(MB_WIDTH(x) * \
> -					(((MB_HEIGHT(y)+1)/2)*2) * 64 + 128)
> -#define S5P_MFC_DEC_MV_SIZE_V10(x, y)	(MB_WIDTH(x) * \
> -					(((MB_HEIGHT(y)+1)/2)*2) * 64 + 512)
> +#define S5P_MFC_DEC_MV_SIZE(x, y, offset)	(MB_WIDTH(x) * \
> +					(((MB_HEIGHT(y)+1)/2)*2) * 64 + offset)
>  #define S5P_MFC_LCU_WIDTH(x_size)	DIV_ROUND_UP(x_size, 32)
>  #define S5P_MFC_LCU_HEIGHT(y_size)	DIV_ROUND_UP(y_size, 32)
>  


_______________________________________________
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] 54+ messages in thread

* Re: [Patch v4 04/11] media: s5p-mfc: Add YV12 and I420 multiplanar format support
  2023-10-25 10:22       ` Aakarsh Jain
@ 2023-11-22 15:40         ` Hans Verkuil
  -1 siblings, 0 replies; 54+ messages in thread
From: Hans Verkuil @ 2023-11-22 15:40 UTC (permalink / raw)
  To: Aakarsh Jain, linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, krzysztof.kozlowski+dt,
	dillon.minfei, david.plowman, mark.rutland, robh+dt, conor+dt,
	linux-samsung-soc, andi, gost.dev, alim.akhtar, aswani.reddy,
	pankaj.dubey, ajaykumar.rs, linux-fsd, Smitha T Murthy

On 25/10/2023 12:22, Aakarsh Jain wrote:
> YV12 and I420 format (3-plane) support is added. Stride information is
> added to all formats and planes since it is necessary for YV12/I420
> which are different from width.
> 
> Cc: linux-fsd@tesla.com
> Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
> Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
> ---
>  .../platform/samsung/s5p-mfc/regs-mfc-v12.h   |   2 +
>  .../platform/samsung/s5p-mfc/regs-mfc-v7.h    |   1 +
>  .../platform/samsung/s5p-mfc/regs-mfc-v8.h    |   3 +
>  .../platform/samsung/s5p-mfc/s5p_mfc_common.h |   4 +
>  .../platform/samsung/s5p-mfc/s5p_mfc_dec.c    |  45 ++++-
>  .../platform/samsung/s5p-mfc/s5p_mfc_enc.c    |  86 +++++++--
>  .../platform/samsung/s5p-mfc/s5p_mfc_opr.h    |   6 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c |  12 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 168 +++++++++++++++---
>  9 files changed, 281 insertions(+), 46 deletions(-)
> 
> diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> index 6c68a45082d0..70464f47c1f9 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> @@ -26,6 +26,8 @@
>  #define MFC_VERSION_V12			0xC0
>  #define MFC_NUM_PORTS_V12		1
>  #define S5P_FIMV_CODEC_VP9_ENC		27
> +#define MFC_CHROMA_PAD_BYTES_V12        256
> +#define S5P_FIMV_D_ALIGN_PLANE_SIZE_V12 256
>  
>  /* Encoder buffer size for MFCv12 */
>  #define ENC_V120_BASE_SIZE(x, y) \
> diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
> index 4a7adfdaa359..50f9bf0603c1 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
> @@ -24,6 +24,7 @@
>  
>  #define S5P_FIMV_E_ENCODED_SOURCE_FIRST_ADDR_V7		0xfa70
>  #define S5P_FIMV_E_ENCODED_SOURCE_SECOND_ADDR_V7	0xfa74
> +#define S5P_FIMV_E_ENCODED_SOURCE_THIRD_ADDR_V7		0xfa78
>  
>  #define S5P_FIMV_E_VP8_OPTIONS_V7			0xfdb0
>  #define S5P_FIMV_E_VP8_FILTER_OPTIONS_V7		0xfdb4
> diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
> index 162e3c7e920f..0ef9eb2dff22 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
> @@ -17,13 +17,16 @@
>  #define S5P_FIMV_D_MIN_SCRATCH_BUFFER_SIZE_V8	0xf108
>  #define S5P_FIMV_D_FIRST_PLANE_DPB_SIZE_V8	0xf144
>  #define S5P_FIMV_D_SECOND_PLANE_DPB_SIZE_V8	0xf148
> +#define S5P_FIMV_D_THIRD_PLANE_DPB_SIZE_V8	0xf14C
>  #define S5P_FIMV_D_MV_BUFFER_SIZE_V8		0xf150
>  
>  #define S5P_FIMV_D_FIRST_PLANE_DPB_STRIDE_SIZE_V8	0xf138
>  #define S5P_FIMV_D_SECOND_PLANE_DPB_STRIDE_SIZE_V8	0xf13c
> +#define S5P_FIMV_D_THIRD_PLANE_DPB_STRIDE_SIZE_V8	0xf140
>  
>  #define S5P_FIMV_D_FIRST_PLANE_DPB_V8		0xf160
>  #define S5P_FIMV_D_SECOND_PLANE_DPB_V8		0xf260
> +#define S5P_FIMV_D_THIRD_PLANE_DPB_V8		0xf360
>  #define S5P_FIMV_D_MV_BUFFER_V8			0xf460
>  
>  #define S5P_FIMV_D_NUM_MV_V8			0xf134
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> index dd2e9f7704ab..9a39cccfe002 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> @@ -56,6 +56,7 @@
>  #define MFC_NO_INSTANCE_SET	-1
>  #define MFC_ENC_CAP_PLANE_COUNT	1
>  #define MFC_ENC_OUT_PLANE_COUNT	2
> +#define VB2_MAX_PLANE_COUNT	3
>  #define STUFF_BYTE		4
>  #define MFC_MAX_CTRLS		128
>  
> @@ -181,6 +182,7 @@ struct s5p_mfc_buf {
>  		struct {
>  			size_t luma;
>  			size_t chroma;
> +			size_t chroma_1;
>  		} raw;
>  		size_t stream;
>  	} cookie;
> @@ -657,6 +659,7 @@ struct s5p_mfc_ctx {
>  
>  	int luma_size;
>  	int chroma_size;
> +	int chroma_size_1;
>  	int mv_size;
>  
>  	unsigned long consumed_stream;
> @@ -722,6 +725,7 @@ struct s5p_mfc_ctx {
>  	size_t scratch_buf_size;
>  	int is_10bit;
>  	int is_422;
> +	int stride[VB2_MAX_PLANE_COUNT];
>  };
>  
>  /*
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> index e219cbcd86d5..317f796fffa1 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> @@ -56,6 +56,20 @@ static struct s5p_mfc_fmt formats[] = {
>  		.num_planes	= 2,
>  		.versions	= MFC_V6PLUS_BITS,
>  	},
> +	{
> +		.fourcc         = V4L2_PIX_FMT_YUV420M,
> +		.codec_mode     = S5P_MFC_CODEC_NONE,
> +		.type           = MFC_FMT_RAW,
> +		.num_planes     = 3,
> +		.versions       = MFC_V12_BIT,
> +	},
> +	{
> +		.fourcc         = V4L2_PIX_FMT_YVU420M,
> +		.codec_mode     = S5P_MFC_CODEC_NONE,
> +		.type           = MFC_FMT_RAW,
> +		.num_planes     = 3,
> +		.versions       = MFC_V12_BIT
> +	},
>  	{
>  		.fourcc		= V4L2_PIX_FMT_H264,
>  		.codec_mode	= S5P_MFC_CODEC_H264_DEC,
> @@ -359,10 +373,15 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
>  		/* Set pixelformat to the format in which MFC
>  		   outputs the decoded frame */
>  		pix_mp->pixelformat = ctx->dst_fmt->fourcc;
> -		pix_mp->plane_fmt[0].bytesperline = ctx->buf_width;
> +		pix_mp->plane_fmt[0].bytesperline = ctx->stride[0];
>  		pix_mp->plane_fmt[0].sizeimage = ctx->luma_size;
> -		pix_mp->plane_fmt[1].bytesperline = ctx->buf_width;
> +		pix_mp->plane_fmt[1].bytesperline = ctx->stride[1];
>  		pix_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> +			pix_mp->plane_fmt[2].bytesperline = ctx->stride[2];
> +			pix_mp->plane_fmt[2].sizeimage = ctx->chroma_size_1;
> +		}
>  	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
>  		/* This is run on OUTPUT
>  		   The buffer contains compressed image
> @@ -937,6 +956,9 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
>  		   vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
>  		/* Output plane count is 2 - one for Y and one for CbCr */
>  		*plane_count = 2;
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)

These misalignments produce a lot of checkpatch warnings.

Make sure you run your patch series through 'checkpatch.pl --strict'!

Regards,

	Hans

> +			*plane_count = 3;
>  		/* Setup buffer count */
>  		if (*buf_count < ctx->pb_count)
>  			*buf_count = ctx->pb_count;
> @@ -955,12 +977,17 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
>  	    vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
>  		psize[0] = ctx->luma_size;
>  		psize[1] = ctx->chroma_size;
> -
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +			psize[2] = ctx->chroma_size_1;
>  		if (IS_MFCV6_PLUS(dev))
>  			alloc_devs[0] = ctx->dev->mem_dev[BANK_L_CTX];
>  		else
>  			alloc_devs[0] = ctx->dev->mem_dev[BANK_R_CTX];
>  		alloc_devs[1] = ctx->dev->mem_dev[BANK_L_CTX];
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +			alloc_devs[2] = ctx->dev->mem_dev[BANK_L_CTX];
>  	} else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
>  		   ctx->state == MFCINST_INIT) {
>  		psize[0] = ctx->dec_src_buf_size;
> @@ -994,12 +1021,24 @@ static int s5p_mfc_buf_init(struct vb2_buffer *vb)
>  			mfc_err("Plane buffer (CAPTURE) is too small\n");
>  			return -EINVAL;
>  		}
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> +			if (vb2_plane_size(vb, 2) < ctx->chroma_size_1) {
> +				mfc_err("Plane buffer (CAPTURE) is too small\n");
> +				return -EINVAL;
> +			}
> +		}
>  		i = vb->index;
>  		ctx->dst_bufs[i].b = vbuf;
>  		ctx->dst_bufs[i].cookie.raw.luma =
>  					vb2_dma_contig_plane_dma_addr(vb, 0);
>  		ctx->dst_bufs[i].cookie.raw.chroma =
>  					vb2_dma_contig_plane_dma_addr(vb, 1);
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> +			ctx->dst_bufs[i].cookie.raw.chroma_1 =
> +					vb2_dma_contig_plane_dma_addr(vb, 2);
> +		}
>  		ctx->dst_bufs_cnt++;
>  	} else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
>  		if (IS_ERR_OR_NULL(ERR_PTR(
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> index e4d6e7c117b5..0eec04eb3ef3 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> @@ -59,6 +59,20 @@ static struct s5p_mfc_fmt formats[] = {
>  		.num_planes	= 2,
>  		.versions	= MFC_V6PLUS_BITS,
>  	},
> +	{
> +		.fourcc         = V4L2_PIX_FMT_YUV420M,
> +		.codec_mode     = S5P_MFC_CODEC_NONE,
> +		.type           = MFC_FMT_RAW,
> +		.num_planes     = 3,
> +		.versions       = MFC_V12_BIT,
> +	},
> +	{
> +		.fourcc         = V4L2_PIX_FMT_YVU420M,
> +		.codec_mode     = S5P_MFC_CODEC_NONE,
> +		.type           = MFC_FMT_RAW,
> +		.num_planes     = 3,
> +		.versions       = MFC_V12_BIT,
> +	},
>  	{
>  		.fourcc		= V4L2_PIX_FMT_H264,
>  		.codec_mode	= S5P_MFC_CODEC_H264_ENC,
> @@ -1193,14 +1207,20 @@ static int enc_pre_frame_start(struct s5p_mfc_ctx *ctx)
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  	struct s5p_mfc_buf *dst_mb;
>  	struct s5p_mfc_buf *src_mb;
> -	unsigned long src_y_addr, src_c_addr, dst_addr;
> +	unsigned long src_y_addr, src_c_addr, src_c_1_addr, dst_addr;
>  	unsigned int dst_size;
>  
>  	src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
>  	src_y_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 0);
>  	src_c_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 1);
> +	if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +			ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +		src_c_1_addr =
> +			vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 2);
> +	else
> +		src_c_1_addr = 0;
>  	s5p_mfc_hw_call(dev->mfc_ops, set_enc_frame_buffer, ctx,
> -							src_y_addr, src_c_addr);
> +					src_y_addr, src_c_addr, src_c_1_addr);
>  
>  	dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
>  	dst_addr = vb2_dma_contig_plane_dma_addr(&dst_mb->b->vb2_buf, 0);
> @@ -1215,8 +1235,8 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
>  {
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  	struct s5p_mfc_buf *mb_entry;
> -	unsigned long enc_y_addr = 0, enc_c_addr = 0;
> -	unsigned long mb_y_addr, mb_c_addr;
> +	unsigned long enc_y_addr = 0, enc_c_addr = 0, enc_c_1_addr = 0;
> +	unsigned long mb_y_addr, mb_c_addr, mb_c_1_addr;
>  	int slice_type;
>  	unsigned int strm_size;
>  	bool src_ready;
> @@ -1229,14 +1249,21 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
>  		  mfc_read(dev, S5P_FIMV_ENC_SI_PIC_CNT));
>  	if (slice_type >= 0) {
>  		s5p_mfc_hw_call(dev->mfc_ops, get_enc_frame_buffer, ctx,
> -				&enc_y_addr, &enc_c_addr);
> +				&enc_y_addr, &enc_c_addr, &enc_c_1_addr);
>  		list_for_each_entry(mb_entry, &ctx->src_queue, list) {
>  			mb_y_addr = vb2_dma_contig_plane_dma_addr(
>  					&mb_entry->b->vb2_buf, 0);
>  			mb_c_addr = vb2_dma_contig_plane_dma_addr(
>  					&mb_entry->b->vb2_buf, 1);
> -			if ((enc_y_addr == mb_y_addr) &&
> -						(enc_c_addr == mb_c_addr)) {
> +			if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +				mb_c_1_addr = vb2_dma_contig_plane_dma_addr
> +						(&mb_entry->b->vb2_buf, 2);
> +			else
> +				mb_c_1_addr = 0;
> +			if ((enc_y_addr == mb_y_addr)
> +					&& (enc_c_addr == mb_c_addr)
> +					&& (enc_c_1_addr == mb_c_1_addr)) {
>  				list_del(&mb_entry->list);
>  				ctx->src_queue_cnt--;
>  				vb2_buffer_done(&mb_entry->b->vb2_buf,
> @@ -1249,8 +1276,15 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
>  					&mb_entry->b->vb2_buf, 0);
>  			mb_c_addr = vb2_dma_contig_plane_dma_addr(
>  					&mb_entry->b->vb2_buf, 1);
> -			if ((enc_y_addr == mb_y_addr) &&
> -						(enc_c_addr == mb_c_addr)) {
> +			if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +				mb_c_1_addr = vb2_dma_contig_plane_dma_addr(
> +						&mb_entry->b->vb2_buf, 2);
> +			else
> +				mb_c_1_addr = 0;
> +			if ((enc_y_addr == mb_y_addr)
> +					&& (enc_c_addr == mb_c_addr)
> +					&& (enc_c_1_addr == mb_c_1_addr)) {
>  				list_del(&mb_entry->list);
>  				ctx->ref_queue_cnt--;
>  				vb2_buffer_done(&mb_entry->b->vb2_buf,
> @@ -1381,10 +1415,15 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
>  		pix_fmt_mp->pixelformat = ctx->src_fmt->fourcc;
>  		pix_fmt_mp->num_planes = ctx->src_fmt->num_planes;
>  
> -		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
> +		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->stride[0];
>  		pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
> -		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
> +		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->stride[1];
>  		pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
> +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> +			pix_fmt_mp->plane_fmt[2].bytesperline = ctx->stride[2];
> +			pix_fmt_mp->plane_fmt[2].sizeimage = ctx->chroma_size_1;
> +		}
>  	} else {
>  		mfc_err("invalid buf type\n");
>  		return -EINVAL;
> @@ -1468,9 +1507,14 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
>  
>  		s5p_mfc_hw_call(dev->mfc_ops, enc_calc_src_size, ctx);
>  		pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
> -		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
> +		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->stride[0];
>  		pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
> -		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
> +		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->stride[1];
> +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> +			pix_fmt_mp->plane_fmt[2].bytesperline = ctx->stride[2];
> +			pix_fmt_mp->plane_fmt[2].sizeimage = ctx->chroma_size_1;
> +		}
>  
>  		ctx->src_bufs_cnt = 0;
>  		ctx->output_state = QUEUE_FREE;
> @@ -2414,10 +2458,16 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
>  
>  		psize[0] = ctx->luma_size;
>  		psize[1] = ctx->chroma_size;
> +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +			psize[2] = ctx->chroma_size_1;
>  
>  		if (IS_MFCV6_PLUS(dev)) {
>  			alloc_devs[0] = ctx->dev->mem_dev[BANK_L_CTX];
>  			alloc_devs[1] = ctx->dev->mem_dev[BANK_L_CTX];
> +			if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +				alloc_devs[2] = ctx->dev->mem_dev[BANK_L_CTX];
>  		} else {
>  			alloc_devs[0] = ctx->dev->mem_dev[BANK_R_CTX];
>  			alloc_devs[1] = ctx->dev->mem_dev[BANK_R_CTX];
> @@ -2456,6 +2506,10 @@ static int s5p_mfc_buf_init(struct vb2_buffer *vb)
>  					vb2_dma_contig_plane_dma_addr(vb, 0);
>  		ctx->src_bufs[i].cookie.raw.chroma =
>  					vb2_dma_contig_plane_dma_addr(vb, 1);
> +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +			ctx->src_bufs[i].cookie.raw.chroma_1 =
> +					vb2_dma_contig_plane_dma_addr(vb, 2);
>  		ctx->src_bufs_cnt++;
>  	} else {
>  		mfc_err("invalid queue type: %d\n", vq->type);
> @@ -2493,6 +2547,12 @@ static int s5p_mfc_buf_prepare(struct vb2_buffer *vb)
>  			mfc_err("plane size is too small for output\n");
>  			return -EINVAL;
>  		}
> +		if ((ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +		     ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) &&
> +		    (vb2_plane_size(vb, 2) < ctx->chroma_size_1)) {
> +			mfc_err("plane size is too small for output\n");
> +			return -EINVAL;
> +		}
>  	} else {
>  		mfc_err("invalid queue type: %d\n", vq->type);
>  		return -EINVAL;
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> index 87ac56756a16..7c5e851c8191 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> @@ -293,9 +293,11 @@ struct s5p_mfc_hw_ops {
>  	int (*set_enc_stream_buffer)(struct s5p_mfc_ctx *ctx,
>  			unsigned long addr, unsigned int size);
>  	void (*set_enc_frame_buffer)(struct s5p_mfc_ctx *ctx,
> -			unsigned long y_addr, unsigned long c_addr);
> +			unsigned long y_addr, unsigned long c_addr,
> +			unsigned long c_1_addr);
>  	void (*get_enc_frame_buffer)(struct s5p_mfc_ctx *ctx,
> -			unsigned long *y_addr, unsigned long *c_addr);
> +			unsigned long *y_addr, unsigned long *c_addr,
> +			unsigned long *c_1_addr);
>  	void (*try_run)(struct s5p_mfc_dev *dev);
>  	void (*clear_int_flags)(struct s5p_mfc_dev *dev);
>  	int (*get_dspl_y_adr)(struct s5p_mfc_dev *dev);
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
> index 28a06dc343fd..fcfaf125a5a1 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
> @@ -516,7 +516,8 @@ static int s5p_mfc_set_enc_stream_buffer_v5(struct s5p_mfc_ctx *ctx,
>  }
>  
>  static void s5p_mfc_set_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,
> -		unsigned long y_addr, unsigned long c_addr)
> +		unsigned long y_addr, unsigned long c_addr,
> +		unsigned long c_1_addr)
>  {
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  
> @@ -525,7 +526,8 @@ static void s5p_mfc_set_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,
>  }
>  
>  static void s5p_mfc_get_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,
> -		unsigned long *y_addr, unsigned long *c_addr)
> +		unsigned long *y_addr, unsigned long *c_addr,
> +		unsigned long *c_1_addr)
>  {
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  
> @@ -1210,7 +1212,7 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
>  	if (list_empty(&ctx->src_queue)) {
>  		/* send null frame */
>  		s5p_mfc_set_enc_frame_buffer_v5(ctx, dev->dma_base[BANK_R_CTX],
> -						dev->dma_base[BANK_R_CTX]);
> +						dev->dma_base[BANK_R_CTX], 0);
>  		src_mb = NULL;
>  	} else {
>  		src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf,
> @@ -1220,7 +1222,7 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
>  			/* send null frame */
>  			s5p_mfc_set_enc_frame_buffer_v5(ctx,
>  						dev->dma_base[BANK_R_CTX],
> -						dev->dma_base[BANK_R_CTX]);
> +						dev->dma_base[BANK_R_CTX], 0);
>  			ctx->state = MFCINST_FINISHING;
>  		} else {
>  			src_y_addr = vb2_dma_contig_plane_dma_addr(
> @@ -1228,7 +1230,7 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
>  			src_c_addr = vb2_dma_contig_plane_dma_addr(
>  					&src_mb->b->vb2_buf, 1);
>  			s5p_mfc_set_enc_frame_buffer_v5(ctx, src_y_addr,
> -								src_c_addr);
> +								src_c_addr, 0);
>  			if (src_mb->flags & MFC_BUF_FLAG_EOS)
>  				ctx->state = MFCINST_FINISHING;
>  		}
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> index fb3f0718821d..e579c765e902 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> @@ -494,16 +494,43 @@ static void s5p_mfc_dec_calc_dpb_size_v6(struct s5p_mfc_ctx *ctx)
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  	ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN_V6);
>  	ctx->buf_height = ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN_V6);
> +	ctx->chroma_size_1 = 0;
>  	mfc_debug(2, "SEQ Done: Movie dimensions %dx%d,\n"
>  			"buffer dimensions: %dx%d\n", ctx->img_width,
>  			ctx->img_height, ctx->buf_width, ctx->buf_height);
>  
> -	ctx->luma_size = calc_plane(ctx->img_width, ctx->img_height);
> -	ctx->chroma_size = calc_plane(ctx->img_width, (ctx->img_height >> 1));
> +	switch (ctx->dst_fmt->fourcc) {
> +	case V4L2_PIX_FMT_NV12M:
> +	case V4L2_PIX_FMT_NV21M:
> +		ctx->stride[0] = ALIGN(ctx->img_width,
> +					S5P_FIMV_NV12MT_HALIGN_V6);
> +		ctx->stride[1] = ALIGN(ctx->img_width,
> +					S5P_FIMV_NV12MT_HALIGN_V6);
> +		ctx->luma_size = calc_plane(ctx->stride[0], ctx->img_height);
> +		ctx->chroma_size = calc_plane(ctx->stride[1],
> +					(ctx->img_height / 2));
> +		break;
> +	case V4L2_PIX_FMT_YUV420M:
> +	case V4L2_PIX_FMT_YVU420M:
> +		ctx->stride[0] = ALIGN(ctx->img_width,
> +					S5P_FIMV_NV12MT_HALIGN_V6);
> +		ctx->stride[1] = ALIGN(ctx->img_width / 2,
> +					S5P_FIMV_NV12MT_HALIGN_V6);
> +		ctx->stride[2] = ALIGN(ctx->img_width / 2,
> +					S5P_FIMV_NV12MT_HALIGN_V6);
> +		ctx->luma_size = calc_plane(ctx->stride[0], ctx->img_height);
> +		ctx->chroma_size = calc_plane(ctx->stride[1],
> +					(ctx->img_height / 2));
> +		ctx->chroma_size_1 = calc_plane(ctx->stride[2],
> +					(ctx->img_height / 2));
> +		break;
> +	}
> +
>  	if (IS_MFCV8_PLUS(ctx->dev)) {
>  		/* MFCv8 needs additional 64 bytes for luma,chroma dpb*/
>  		ctx->luma_size += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8;
>  		ctx->chroma_size += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8;
> +		ctx->chroma_size_1 += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8;
>  	}
>  
>  	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
> @@ -534,15 +561,53 @@ static void s5p_mfc_enc_calc_src_size_v6(struct s5p_mfc_ctx *ctx)
>  	mb_width = MB_WIDTH(ctx->img_width);
>  	mb_height = MB_HEIGHT(ctx->img_height);
>  
> -	ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN_V6);
> -	ctx->luma_size = ALIGN((mb_width * mb_height) * 256, 256);
> -	ctx->chroma_size = ALIGN((mb_width * mb_height) * 128, 256);
> -
> -	/* MFCv7 needs pad bytes for Luma and Chroma */
> -	if (IS_MFCV7_PLUS(ctx->dev)) {
> +	if (IS_MFCV12(ctx->dev)) {
> +		switch (ctx->src_fmt->fourcc) {
> +		case V4L2_PIX_FMT_NV12M:
> +		case V4L2_PIX_FMT_NV21M:
> +			ctx->stride[0] = ALIGN(ctx->img_width,
> +						S5P_FIMV_NV12M_HALIGN_V6);
> +			ctx->stride[1] = ALIGN(ctx->img_width,
> +						S5P_FIMV_NV12M_HALIGN_V6);
> +			ctx->luma_size = ctx->stride[0] *
> +						ALIGN(ctx->img_height, 16);
> +			ctx->chroma_size =  ctx->stride[0] *
> +						ALIGN(ctx->img_height / 2, 16);
> +			break;
> +		case V4L2_PIX_FMT_YUV420M:
> +		case V4L2_PIX_FMT_YVU420M:
> +			ctx->stride[0] = ALIGN(ctx->img_width,
> +						S5P_FIMV_NV12M_HALIGN_V6);
> +			ctx->stride[1] = ALIGN(ctx->img_width / 2,
> +						S5P_FIMV_NV12M_HALIGN_V6);
> +			ctx->stride[2] = ALIGN(ctx->img_width / 2,
> +						S5P_FIMV_NV12M_HALIGN_V6);
> +			ctx->luma_size = ctx->stride[0] *
> +						ALIGN(ctx->img_height, 16);
> +			ctx->chroma_size =  ctx->stride[1] *
> +						ALIGN(ctx->img_height / 2, 16);
> +			ctx->chroma_size_1 =  ctx->stride[2] *
> +						ALIGN(ctx->img_height / 2, 16);
> +			break;
> +		}
>  		ctx->luma_size += MFC_LUMA_PAD_BYTES_V7;
> -		ctx->chroma_size += MFC_CHROMA_PAD_BYTES_V7;
> +		ctx->chroma_size += MFC_CHROMA_PAD_BYTES_V12;
> +		ctx->chroma_size_1 += MFC_CHROMA_PAD_BYTES_V12;
> +	} else {
> +		ctx->buf_width = ALIGN(ctx->img_width,
> +					S5P_FIMV_NV12M_HALIGN_V6);
> +		ctx->stride[0] = ctx->buf_width;
> +		ctx->stride[1] = ctx->buf_width;
> +		ctx->luma_size = ALIGN((mb_width * mb_height) * 256, 256);
> +		ctx->chroma_size = ALIGN((mb_width * mb_height) * 128, 256);
> +		ctx->chroma_size_1 = 0;
> +		/* MFCv7 needs pad bytes for Luma and Chroma */
> +		if (IS_MFCV7_PLUS(ctx->dev)) {
> +			ctx->luma_size += MFC_LUMA_PAD_BYTES_V7;
> +			ctx->chroma_size += MFC_LUMA_PAD_BYTES_V7;
> +		}
>  	}
> +
>  }
>  
>  /* Set registers for decoding stream buffer */
> @@ -588,15 +653,21 @@ static int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx)
>  	writel(ctx->total_dpb_count, mfc_regs->d_num_dpb);
>  	writel(ctx->luma_size, mfc_regs->d_first_plane_dpb_size);
>  	writel(ctx->chroma_size, mfc_regs->d_second_plane_dpb_size);
> -
> +	if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +			ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +		writel(ctx->chroma_size_1, mfc_regs->d_third_plane_dpb_size);
>  	writel(buf_addr1, mfc_regs->d_scratch_buffer_addr);
>  	writel(ctx->scratch_buf_size, mfc_regs->d_scratch_buffer_size);
>  
>  	if (IS_MFCV8_PLUS(dev)) {
> -		writel(ctx->img_width,
> +		writel(ctx->stride[0],
>  			mfc_regs->d_first_plane_dpb_stride_size);
> -		writel(ctx->img_width,
> +		writel(ctx->stride[1],
>  			mfc_regs->d_second_plane_dpb_stride_size);
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +			writel(ctx->stride[2],
> +				mfc_regs->d_third_plane_dpb_stride_size);
>  	}
>  
>  	buf_addr1 += ctx->scratch_buf_size;
> @@ -625,6 +696,13 @@ static int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx)
>  					ctx->dst_bufs[i].cookie.raw.chroma);
>  		writel(ctx->dst_bufs[i].cookie.raw.chroma,
>  				mfc_regs->d_second_plane_dpb + i * 4);
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> +			mfc_debug(2, "\tChroma_1 %d: %zx\n", i,
> +					ctx->dst_bufs[i].cookie.raw.chroma_1);
> +			writel(ctx->dst_bufs[i].cookie.raw.chroma_1,
> +					mfc_regs->d_third_plane_dpb + i * 4);
> +		}
>  	}
>  	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
>  			ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC ||
> @@ -683,20 +761,24 @@ static int s5p_mfc_set_enc_stream_buffer_v6(struct s5p_mfc_ctx *ctx,
>  }
>  
>  static void s5p_mfc_set_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
> -		unsigned long y_addr, unsigned long c_addr)
> +		unsigned long y_addr, unsigned long c_addr,
> +		unsigned long c_1_addr)
>  {
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  	const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs;
>  
>  	writel(y_addr, mfc_regs->e_source_first_plane_addr);
>  	writel(c_addr, mfc_regs->e_source_second_plane_addr);
> +	writel(c_1_addr, mfc_regs->e_source_third_plane_addr);
>  
>  	mfc_debug(2, "enc src y buf addr: 0x%08lx\n", y_addr);
>  	mfc_debug(2, "enc src c buf addr: 0x%08lx\n", c_addr);
> +	mfc_debug(2, "enc src cr buf addr: 0x%08lx\n", c_1_addr);
>  }
>  
>  static void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
> -		unsigned long *y_addr, unsigned long *c_addr)
> +		unsigned long *y_addr, unsigned long *c_addr,
> +		unsigned long *c_1_addr)
>  {
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  	const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs;
> @@ -704,12 +786,17 @@ static void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
>  
>  	*y_addr = readl(mfc_regs->e_encoded_source_first_plane_addr);
>  	*c_addr = readl(mfc_regs->e_encoded_source_second_plane_addr);
> +	if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +			ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +		*c_1_addr = readl(mfc_regs->e_encoded_source_third_plane_addr);
> +	else
> +		*c_1_addr = 0;
>  
>  	enc_recon_y_addr = readl(mfc_regs->e_recon_luma_dpb_addr);
>  	enc_recon_c_addr = readl(mfc_regs->e_recon_chroma_dpb_addr);
>  
>  	mfc_debug(2, "recon y addr: 0x%08lx y_addr: 0x%08lx\n", enc_recon_y_addr, *y_addr);
> -	mfc_debug(2, "recon c addr: 0x%08lx\n", enc_recon_c_addr);
> +	mfc_debug(2, "recon c addr: 0x%08lx c_addr: 0x%08lx\n", enc_recon_c_addr, *c_addr);
>  }
>  
>  /* Set encoding ref & codec buffer */
> @@ -886,6 +973,20 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
>  		writel(reg, mfc_regs->e_enc_options);
>  		/* 0: NV12(CbCr), 1: NV21(CrCb) */
>  		writel(0x0, mfc_regs->pixel_format);
> +	} else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> +		/* 0: Linear, 1: 2D tiled*/
> +		reg = readl(mfc_regs->e_enc_options);
> +		reg &= ~(0x1 << 7);
> +		writel(reg, mfc_regs->e_enc_options);
> +		/* 2: YV12(CrCb), 3: I420(CrCb) */
> +		writel(0x2, mfc_regs->pixel_format);
> +	} else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M) {
> +		/* 0: Linear, 1: 2D tiled*/
> +		reg = readl(mfc_regs->e_enc_options);
> +		reg &= ~(0x1 << 7);
> +		writel(reg, mfc_regs->e_enc_options);
> +		/* 2: YV12(CrCb), 3: I420(CrCb) */
> +		writel(0x3, mfc_regs->pixel_format);
>  	}
>  
>  	/* memory structure recon. frame */
> @@ -1696,8 +1797,12 @@ static int s5p_mfc_init_decode_v6(struct s5p_mfc_ctx *ctx)
>  	else
>  		writel(reg, mfc_regs->d_dec_options);
>  
> -	/* 0: NV12(CbCr), 1: NV21(CrCb) */
> -	if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV21M)
> +	/* 0: NV12(CbCr), 1: NV21(CrCb), 2: YV12(CrCb), 3: I420(CbCr) */
> +	if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M)
> +		writel(0x3, mfc_regs->pixel_format);
> +	else if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +		writel(0x2, mfc_regs->pixel_format);
> +	else if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV21M)
>  		writel(0x1, mfc_regs->pixel_format);
>  	else
>  		writel(0x0, mfc_regs->pixel_format);
> @@ -1781,8 +1886,12 @@ static int s5p_mfc_init_encode_v6(struct s5p_mfc_ctx *ctx)
>  
>  	/* Set stride lengths for v7 & above */
>  	if (IS_MFCV7_PLUS(dev)) {
> -		writel(ctx->img_width, mfc_regs->e_source_first_plane_stride);
> -		writel(ctx->img_width, mfc_regs->e_source_second_plane_stride);
> +		writel(ctx->stride[0], mfc_regs->e_source_first_plane_stride);
> +		writel(ctx->stride[1], mfc_regs->e_source_second_plane_stride);
> +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +			writel(ctx->stride[2],
> +					mfc_regs->e_source_third_plane_stride);
>  	}
>  
>  	writel(ctx->inst_no, mfc_regs->instance_id);
> @@ -1891,7 +2000,7 @@ static inline int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  	struct s5p_mfc_buf *dst_mb;
>  	struct s5p_mfc_buf *src_mb;
> -	unsigned long src_y_addr, src_c_addr, dst_addr;
> +	unsigned long src_y_addr, src_c_addr, src_c_1_addr, dst_addr;
>  	/*
>  	unsigned int src_y_size, src_c_size;
>  	*/
> @@ -1909,22 +2018,29 @@ static inline int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
>  
>  	if (list_empty(&ctx->src_queue)) {
>  		/* send null frame */
> -		s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0);
> +		s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0, 0);
>  		src_mb = NULL;
>  	} else {
>  		src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
>  		src_mb->flags |= MFC_BUF_FLAG_USED;
>  		if (src_mb->b->vb2_buf.planes[0].bytesused == 0) {
> -			s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0);
> +			s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0, 0);
>  			ctx->state = MFCINST_FINISHING;
>  		} else {
>  			src_y_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 0);
>  			src_c_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 1);
> +			if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +				src_c_1_addr = vb2_dma_contig_plane_dma_addr
> +						(&src_mb->b->vb2_buf, 2);
> +			else
> +				src_c_1_addr = 0;
>  
>  			mfc_debug(2, "enc src y addr: 0x%08lx\n", src_y_addr);
>  			mfc_debug(2, "enc src c addr: 0x%08lx\n", src_c_addr);
>  
> -			s5p_mfc_set_enc_frame_buffer_v6(ctx, src_y_addr, src_c_addr);
> +			s5p_mfc_set_enc_frame_buffer_v6(ctx, src_y_addr,
> +						src_c_addr, src_c_1_addr);
>  			if (src_mb->flags & MFC_BUF_FLAG_EOS)
>  				ctx->state = MFCINST_FINISHING;
>  		}
> @@ -2450,6 +2566,8 @@ const struct s5p_mfc_regs *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev)
>  			S5P_FIMV_E_ENCODED_SOURCE_FIRST_ADDR_V7);
>  	R(e_encoded_source_second_plane_addr,
>  			S5P_FIMV_E_ENCODED_SOURCE_SECOND_ADDR_V7);
> +	R(e_encoded_source_third_plane_addr,
> +			S5P_FIMV_E_ENCODED_SOURCE_THIRD_ADDR_V7);
>  	R(e_vp8_options, S5P_FIMV_E_VP8_OPTIONS_V7);
>  
>  	if (!IS_MFCV8_PLUS(dev))
> @@ -2464,16 +2582,20 @@ const struct s5p_mfc_regs *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev)
>  	R(d_cpb_buffer_offset, S5P_FIMV_D_CPB_BUFFER_OFFSET_V8);
>  	R(d_first_plane_dpb_size, S5P_FIMV_D_FIRST_PLANE_DPB_SIZE_V8);
>  	R(d_second_plane_dpb_size, S5P_FIMV_D_SECOND_PLANE_DPB_SIZE_V8);
> +	R(d_third_plane_dpb_size, S5P_FIMV_D_THIRD_PLANE_DPB_SIZE_V8);
>  	R(d_scratch_buffer_addr, S5P_FIMV_D_SCRATCH_BUFFER_ADDR_V8);
>  	R(d_scratch_buffer_size, S5P_FIMV_D_SCRATCH_BUFFER_SIZE_V8);
>  	R(d_first_plane_dpb_stride_size,
>  			S5P_FIMV_D_FIRST_PLANE_DPB_STRIDE_SIZE_V8);
>  	R(d_second_plane_dpb_stride_size,
>  			S5P_FIMV_D_SECOND_PLANE_DPB_STRIDE_SIZE_V8);
> +	R(d_third_plane_dpb_stride_size,
> +			S5P_FIMV_D_THIRD_PLANE_DPB_STRIDE_SIZE_V8);
>  	R(d_mv_buffer_size, S5P_FIMV_D_MV_BUFFER_SIZE_V8);
>  	R(d_num_mv, S5P_FIMV_D_NUM_MV_V8);
>  	R(d_first_plane_dpb, S5P_FIMV_D_FIRST_PLANE_DPB_V8);
>  	R(d_second_plane_dpb, S5P_FIMV_D_SECOND_PLANE_DPB_V8);
> +	R(d_third_plane_dpb, S5P_FIMV_D_THIRD_PLANE_DPB_V8);
>  	R(d_mv_buffer, S5P_FIMV_D_MV_BUFFER_V8);
>  	R(d_init_buffer_options, S5P_FIMV_D_INIT_BUFFER_OPTIONS_V8);
>  	R(d_available_dpb_flag_lower, S5P_FIMV_D_AVAILABLE_DPB_FLAG_LOWER_V8);


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

* Re: [Patch v4 04/11] media: s5p-mfc: Add YV12 and I420 multiplanar format support
@ 2023-11-22 15:40         ` Hans Verkuil
  0 siblings, 0 replies; 54+ messages in thread
From: Hans Verkuil @ 2023-11-22 15:40 UTC (permalink / raw)
  To: Aakarsh Jain, linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, krzysztof.kozlowski+dt,
	dillon.minfei, david.plowman, mark.rutland, robh+dt, conor+dt,
	linux-samsung-soc, andi, gost.dev, alim.akhtar, aswani.reddy,
	pankaj.dubey, ajaykumar.rs, linux-fsd, Smitha T Murthy

On 25/10/2023 12:22, Aakarsh Jain wrote:
> YV12 and I420 format (3-plane) support is added. Stride information is
> added to all formats and planes since it is necessary for YV12/I420
> which are different from width.
> 
> Cc: linux-fsd@tesla.com
> Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
> Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
> ---
>  .../platform/samsung/s5p-mfc/regs-mfc-v12.h   |   2 +
>  .../platform/samsung/s5p-mfc/regs-mfc-v7.h    |   1 +
>  .../platform/samsung/s5p-mfc/regs-mfc-v8.h    |   3 +
>  .../platform/samsung/s5p-mfc/s5p_mfc_common.h |   4 +
>  .../platform/samsung/s5p-mfc/s5p_mfc_dec.c    |  45 ++++-
>  .../platform/samsung/s5p-mfc/s5p_mfc_enc.c    |  86 +++++++--
>  .../platform/samsung/s5p-mfc/s5p_mfc_opr.h    |   6 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c |  12 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 168 +++++++++++++++---
>  9 files changed, 281 insertions(+), 46 deletions(-)
> 
> diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> index 6c68a45082d0..70464f47c1f9 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> @@ -26,6 +26,8 @@
>  #define MFC_VERSION_V12			0xC0
>  #define MFC_NUM_PORTS_V12		1
>  #define S5P_FIMV_CODEC_VP9_ENC		27
> +#define MFC_CHROMA_PAD_BYTES_V12        256
> +#define S5P_FIMV_D_ALIGN_PLANE_SIZE_V12 256
>  
>  /* Encoder buffer size for MFCv12 */
>  #define ENC_V120_BASE_SIZE(x, y) \
> diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
> index 4a7adfdaa359..50f9bf0603c1 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
> @@ -24,6 +24,7 @@
>  
>  #define S5P_FIMV_E_ENCODED_SOURCE_FIRST_ADDR_V7		0xfa70
>  #define S5P_FIMV_E_ENCODED_SOURCE_SECOND_ADDR_V7	0xfa74
> +#define S5P_FIMV_E_ENCODED_SOURCE_THIRD_ADDR_V7		0xfa78
>  
>  #define S5P_FIMV_E_VP8_OPTIONS_V7			0xfdb0
>  #define S5P_FIMV_E_VP8_FILTER_OPTIONS_V7		0xfdb4
> diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
> index 162e3c7e920f..0ef9eb2dff22 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
> @@ -17,13 +17,16 @@
>  #define S5P_FIMV_D_MIN_SCRATCH_BUFFER_SIZE_V8	0xf108
>  #define S5P_FIMV_D_FIRST_PLANE_DPB_SIZE_V8	0xf144
>  #define S5P_FIMV_D_SECOND_PLANE_DPB_SIZE_V8	0xf148
> +#define S5P_FIMV_D_THIRD_PLANE_DPB_SIZE_V8	0xf14C
>  #define S5P_FIMV_D_MV_BUFFER_SIZE_V8		0xf150
>  
>  #define S5P_FIMV_D_FIRST_PLANE_DPB_STRIDE_SIZE_V8	0xf138
>  #define S5P_FIMV_D_SECOND_PLANE_DPB_STRIDE_SIZE_V8	0xf13c
> +#define S5P_FIMV_D_THIRD_PLANE_DPB_STRIDE_SIZE_V8	0xf140
>  
>  #define S5P_FIMV_D_FIRST_PLANE_DPB_V8		0xf160
>  #define S5P_FIMV_D_SECOND_PLANE_DPB_V8		0xf260
> +#define S5P_FIMV_D_THIRD_PLANE_DPB_V8		0xf360
>  #define S5P_FIMV_D_MV_BUFFER_V8			0xf460
>  
>  #define S5P_FIMV_D_NUM_MV_V8			0xf134
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> index dd2e9f7704ab..9a39cccfe002 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> @@ -56,6 +56,7 @@
>  #define MFC_NO_INSTANCE_SET	-1
>  #define MFC_ENC_CAP_PLANE_COUNT	1
>  #define MFC_ENC_OUT_PLANE_COUNT	2
> +#define VB2_MAX_PLANE_COUNT	3
>  #define STUFF_BYTE		4
>  #define MFC_MAX_CTRLS		128
>  
> @@ -181,6 +182,7 @@ struct s5p_mfc_buf {
>  		struct {
>  			size_t luma;
>  			size_t chroma;
> +			size_t chroma_1;
>  		} raw;
>  		size_t stream;
>  	} cookie;
> @@ -657,6 +659,7 @@ struct s5p_mfc_ctx {
>  
>  	int luma_size;
>  	int chroma_size;
> +	int chroma_size_1;
>  	int mv_size;
>  
>  	unsigned long consumed_stream;
> @@ -722,6 +725,7 @@ struct s5p_mfc_ctx {
>  	size_t scratch_buf_size;
>  	int is_10bit;
>  	int is_422;
> +	int stride[VB2_MAX_PLANE_COUNT];
>  };
>  
>  /*
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> index e219cbcd86d5..317f796fffa1 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> @@ -56,6 +56,20 @@ static struct s5p_mfc_fmt formats[] = {
>  		.num_planes	= 2,
>  		.versions	= MFC_V6PLUS_BITS,
>  	},
> +	{
> +		.fourcc         = V4L2_PIX_FMT_YUV420M,
> +		.codec_mode     = S5P_MFC_CODEC_NONE,
> +		.type           = MFC_FMT_RAW,
> +		.num_planes     = 3,
> +		.versions       = MFC_V12_BIT,
> +	},
> +	{
> +		.fourcc         = V4L2_PIX_FMT_YVU420M,
> +		.codec_mode     = S5P_MFC_CODEC_NONE,
> +		.type           = MFC_FMT_RAW,
> +		.num_planes     = 3,
> +		.versions       = MFC_V12_BIT
> +	},
>  	{
>  		.fourcc		= V4L2_PIX_FMT_H264,
>  		.codec_mode	= S5P_MFC_CODEC_H264_DEC,
> @@ -359,10 +373,15 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
>  		/* Set pixelformat to the format in which MFC
>  		   outputs the decoded frame */
>  		pix_mp->pixelformat = ctx->dst_fmt->fourcc;
> -		pix_mp->plane_fmt[0].bytesperline = ctx->buf_width;
> +		pix_mp->plane_fmt[0].bytesperline = ctx->stride[0];
>  		pix_mp->plane_fmt[0].sizeimage = ctx->luma_size;
> -		pix_mp->plane_fmt[1].bytesperline = ctx->buf_width;
> +		pix_mp->plane_fmt[1].bytesperline = ctx->stride[1];
>  		pix_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> +			pix_mp->plane_fmt[2].bytesperline = ctx->stride[2];
> +			pix_mp->plane_fmt[2].sizeimage = ctx->chroma_size_1;
> +		}
>  	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
>  		/* This is run on OUTPUT
>  		   The buffer contains compressed image
> @@ -937,6 +956,9 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
>  		   vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
>  		/* Output plane count is 2 - one for Y and one for CbCr */
>  		*plane_count = 2;
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)

These misalignments produce a lot of checkpatch warnings.

Make sure you run your patch series through 'checkpatch.pl --strict'!

Regards,

	Hans

> +			*plane_count = 3;
>  		/* Setup buffer count */
>  		if (*buf_count < ctx->pb_count)
>  			*buf_count = ctx->pb_count;
> @@ -955,12 +977,17 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
>  	    vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
>  		psize[0] = ctx->luma_size;
>  		psize[1] = ctx->chroma_size;
> -
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +			psize[2] = ctx->chroma_size_1;
>  		if (IS_MFCV6_PLUS(dev))
>  			alloc_devs[0] = ctx->dev->mem_dev[BANK_L_CTX];
>  		else
>  			alloc_devs[0] = ctx->dev->mem_dev[BANK_R_CTX];
>  		alloc_devs[1] = ctx->dev->mem_dev[BANK_L_CTX];
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +			alloc_devs[2] = ctx->dev->mem_dev[BANK_L_CTX];
>  	} else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
>  		   ctx->state == MFCINST_INIT) {
>  		psize[0] = ctx->dec_src_buf_size;
> @@ -994,12 +1021,24 @@ static int s5p_mfc_buf_init(struct vb2_buffer *vb)
>  			mfc_err("Plane buffer (CAPTURE) is too small\n");
>  			return -EINVAL;
>  		}
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> +			if (vb2_plane_size(vb, 2) < ctx->chroma_size_1) {
> +				mfc_err("Plane buffer (CAPTURE) is too small\n");
> +				return -EINVAL;
> +			}
> +		}
>  		i = vb->index;
>  		ctx->dst_bufs[i].b = vbuf;
>  		ctx->dst_bufs[i].cookie.raw.luma =
>  					vb2_dma_contig_plane_dma_addr(vb, 0);
>  		ctx->dst_bufs[i].cookie.raw.chroma =
>  					vb2_dma_contig_plane_dma_addr(vb, 1);
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> +			ctx->dst_bufs[i].cookie.raw.chroma_1 =
> +					vb2_dma_contig_plane_dma_addr(vb, 2);
> +		}
>  		ctx->dst_bufs_cnt++;
>  	} else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
>  		if (IS_ERR_OR_NULL(ERR_PTR(
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> index e4d6e7c117b5..0eec04eb3ef3 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> @@ -59,6 +59,20 @@ static struct s5p_mfc_fmt formats[] = {
>  		.num_planes	= 2,
>  		.versions	= MFC_V6PLUS_BITS,
>  	},
> +	{
> +		.fourcc         = V4L2_PIX_FMT_YUV420M,
> +		.codec_mode     = S5P_MFC_CODEC_NONE,
> +		.type           = MFC_FMT_RAW,
> +		.num_planes     = 3,
> +		.versions       = MFC_V12_BIT,
> +	},
> +	{
> +		.fourcc         = V4L2_PIX_FMT_YVU420M,
> +		.codec_mode     = S5P_MFC_CODEC_NONE,
> +		.type           = MFC_FMT_RAW,
> +		.num_planes     = 3,
> +		.versions       = MFC_V12_BIT,
> +	},
>  	{
>  		.fourcc		= V4L2_PIX_FMT_H264,
>  		.codec_mode	= S5P_MFC_CODEC_H264_ENC,
> @@ -1193,14 +1207,20 @@ static int enc_pre_frame_start(struct s5p_mfc_ctx *ctx)
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  	struct s5p_mfc_buf *dst_mb;
>  	struct s5p_mfc_buf *src_mb;
> -	unsigned long src_y_addr, src_c_addr, dst_addr;
> +	unsigned long src_y_addr, src_c_addr, src_c_1_addr, dst_addr;
>  	unsigned int dst_size;
>  
>  	src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
>  	src_y_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 0);
>  	src_c_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 1);
> +	if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +			ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +		src_c_1_addr =
> +			vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 2);
> +	else
> +		src_c_1_addr = 0;
>  	s5p_mfc_hw_call(dev->mfc_ops, set_enc_frame_buffer, ctx,
> -							src_y_addr, src_c_addr);
> +					src_y_addr, src_c_addr, src_c_1_addr);
>  
>  	dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
>  	dst_addr = vb2_dma_contig_plane_dma_addr(&dst_mb->b->vb2_buf, 0);
> @@ -1215,8 +1235,8 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
>  {
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  	struct s5p_mfc_buf *mb_entry;
> -	unsigned long enc_y_addr = 0, enc_c_addr = 0;
> -	unsigned long mb_y_addr, mb_c_addr;
> +	unsigned long enc_y_addr = 0, enc_c_addr = 0, enc_c_1_addr = 0;
> +	unsigned long mb_y_addr, mb_c_addr, mb_c_1_addr;
>  	int slice_type;
>  	unsigned int strm_size;
>  	bool src_ready;
> @@ -1229,14 +1249,21 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
>  		  mfc_read(dev, S5P_FIMV_ENC_SI_PIC_CNT));
>  	if (slice_type >= 0) {
>  		s5p_mfc_hw_call(dev->mfc_ops, get_enc_frame_buffer, ctx,
> -				&enc_y_addr, &enc_c_addr);
> +				&enc_y_addr, &enc_c_addr, &enc_c_1_addr);
>  		list_for_each_entry(mb_entry, &ctx->src_queue, list) {
>  			mb_y_addr = vb2_dma_contig_plane_dma_addr(
>  					&mb_entry->b->vb2_buf, 0);
>  			mb_c_addr = vb2_dma_contig_plane_dma_addr(
>  					&mb_entry->b->vb2_buf, 1);
> -			if ((enc_y_addr == mb_y_addr) &&
> -						(enc_c_addr == mb_c_addr)) {
> +			if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +				mb_c_1_addr = vb2_dma_contig_plane_dma_addr
> +						(&mb_entry->b->vb2_buf, 2);
> +			else
> +				mb_c_1_addr = 0;
> +			if ((enc_y_addr == mb_y_addr)
> +					&& (enc_c_addr == mb_c_addr)
> +					&& (enc_c_1_addr == mb_c_1_addr)) {
>  				list_del(&mb_entry->list);
>  				ctx->src_queue_cnt--;
>  				vb2_buffer_done(&mb_entry->b->vb2_buf,
> @@ -1249,8 +1276,15 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
>  					&mb_entry->b->vb2_buf, 0);
>  			mb_c_addr = vb2_dma_contig_plane_dma_addr(
>  					&mb_entry->b->vb2_buf, 1);
> -			if ((enc_y_addr == mb_y_addr) &&
> -						(enc_c_addr == mb_c_addr)) {
> +			if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +				mb_c_1_addr = vb2_dma_contig_plane_dma_addr(
> +						&mb_entry->b->vb2_buf, 2);
> +			else
> +				mb_c_1_addr = 0;
> +			if ((enc_y_addr == mb_y_addr)
> +					&& (enc_c_addr == mb_c_addr)
> +					&& (enc_c_1_addr == mb_c_1_addr)) {
>  				list_del(&mb_entry->list);
>  				ctx->ref_queue_cnt--;
>  				vb2_buffer_done(&mb_entry->b->vb2_buf,
> @@ -1381,10 +1415,15 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
>  		pix_fmt_mp->pixelformat = ctx->src_fmt->fourcc;
>  		pix_fmt_mp->num_planes = ctx->src_fmt->num_planes;
>  
> -		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
> +		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->stride[0];
>  		pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
> -		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
> +		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->stride[1];
>  		pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
> +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> +			pix_fmt_mp->plane_fmt[2].bytesperline = ctx->stride[2];
> +			pix_fmt_mp->plane_fmt[2].sizeimage = ctx->chroma_size_1;
> +		}
>  	} else {
>  		mfc_err("invalid buf type\n");
>  		return -EINVAL;
> @@ -1468,9 +1507,14 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
>  
>  		s5p_mfc_hw_call(dev->mfc_ops, enc_calc_src_size, ctx);
>  		pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
> -		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
> +		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->stride[0];
>  		pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
> -		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
> +		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->stride[1];
> +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> +			pix_fmt_mp->plane_fmt[2].bytesperline = ctx->stride[2];
> +			pix_fmt_mp->plane_fmt[2].sizeimage = ctx->chroma_size_1;
> +		}
>  
>  		ctx->src_bufs_cnt = 0;
>  		ctx->output_state = QUEUE_FREE;
> @@ -2414,10 +2458,16 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
>  
>  		psize[0] = ctx->luma_size;
>  		psize[1] = ctx->chroma_size;
> +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +			psize[2] = ctx->chroma_size_1;
>  
>  		if (IS_MFCV6_PLUS(dev)) {
>  			alloc_devs[0] = ctx->dev->mem_dev[BANK_L_CTX];
>  			alloc_devs[1] = ctx->dev->mem_dev[BANK_L_CTX];
> +			if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +				alloc_devs[2] = ctx->dev->mem_dev[BANK_L_CTX];
>  		} else {
>  			alloc_devs[0] = ctx->dev->mem_dev[BANK_R_CTX];
>  			alloc_devs[1] = ctx->dev->mem_dev[BANK_R_CTX];
> @@ -2456,6 +2506,10 @@ static int s5p_mfc_buf_init(struct vb2_buffer *vb)
>  					vb2_dma_contig_plane_dma_addr(vb, 0);
>  		ctx->src_bufs[i].cookie.raw.chroma =
>  					vb2_dma_contig_plane_dma_addr(vb, 1);
> +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +			ctx->src_bufs[i].cookie.raw.chroma_1 =
> +					vb2_dma_contig_plane_dma_addr(vb, 2);
>  		ctx->src_bufs_cnt++;
>  	} else {
>  		mfc_err("invalid queue type: %d\n", vq->type);
> @@ -2493,6 +2547,12 @@ static int s5p_mfc_buf_prepare(struct vb2_buffer *vb)
>  			mfc_err("plane size is too small for output\n");
>  			return -EINVAL;
>  		}
> +		if ((ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +		     ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) &&
> +		    (vb2_plane_size(vb, 2) < ctx->chroma_size_1)) {
> +			mfc_err("plane size is too small for output\n");
> +			return -EINVAL;
> +		}
>  	} else {
>  		mfc_err("invalid queue type: %d\n", vq->type);
>  		return -EINVAL;
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> index 87ac56756a16..7c5e851c8191 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> @@ -293,9 +293,11 @@ struct s5p_mfc_hw_ops {
>  	int (*set_enc_stream_buffer)(struct s5p_mfc_ctx *ctx,
>  			unsigned long addr, unsigned int size);
>  	void (*set_enc_frame_buffer)(struct s5p_mfc_ctx *ctx,
> -			unsigned long y_addr, unsigned long c_addr);
> +			unsigned long y_addr, unsigned long c_addr,
> +			unsigned long c_1_addr);
>  	void (*get_enc_frame_buffer)(struct s5p_mfc_ctx *ctx,
> -			unsigned long *y_addr, unsigned long *c_addr);
> +			unsigned long *y_addr, unsigned long *c_addr,
> +			unsigned long *c_1_addr);
>  	void (*try_run)(struct s5p_mfc_dev *dev);
>  	void (*clear_int_flags)(struct s5p_mfc_dev *dev);
>  	int (*get_dspl_y_adr)(struct s5p_mfc_dev *dev);
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
> index 28a06dc343fd..fcfaf125a5a1 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
> @@ -516,7 +516,8 @@ static int s5p_mfc_set_enc_stream_buffer_v5(struct s5p_mfc_ctx *ctx,
>  }
>  
>  static void s5p_mfc_set_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,
> -		unsigned long y_addr, unsigned long c_addr)
> +		unsigned long y_addr, unsigned long c_addr,
> +		unsigned long c_1_addr)
>  {
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  
> @@ -525,7 +526,8 @@ static void s5p_mfc_set_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,
>  }
>  
>  static void s5p_mfc_get_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,
> -		unsigned long *y_addr, unsigned long *c_addr)
> +		unsigned long *y_addr, unsigned long *c_addr,
> +		unsigned long *c_1_addr)
>  {
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  
> @@ -1210,7 +1212,7 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
>  	if (list_empty(&ctx->src_queue)) {
>  		/* send null frame */
>  		s5p_mfc_set_enc_frame_buffer_v5(ctx, dev->dma_base[BANK_R_CTX],
> -						dev->dma_base[BANK_R_CTX]);
> +						dev->dma_base[BANK_R_CTX], 0);
>  		src_mb = NULL;
>  	} else {
>  		src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf,
> @@ -1220,7 +1222,7 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
>  			/* send null frame */
>  			s5p_mfc_set_enc_frame_buffer_v5(ctx,
>  						dev->dma_base[BANK_R_CTX],
> -						dev->dma_base[BANK_R_CTX]);
> +						dev->dma_base[BANK_R_CTX], 0);
>  			ctx->state = MFCINST_FINISHING;
>  		} else {
>  			src_y_addr = vb2_dma_contig_plane_dma_addr(
> @@ -1228,7 +1230,7 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
>  			src_c_addr = vb2_dma_contig_plane_dma_addr(
>  					&src_mb->b->vb2_buf, 1);
>  			s5p_mfc_set_enc_frame_buffer_v5(ctx, src_y_addr,
> -								src_c_addr);
> +								src_c_addr, 0);
>  			if (src_mb->flags & MFC_BUF_FLAG_EOS)
>  				ctx->state = MFCINST_FINISHING;
>  		}
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> index fb3f0718821d..e579c765e902 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> @@ -494,16 +494,43 @@ static void s5p_mfc_dec_calc_dpb_size_v6(struct s5p_mfc_ctx *ctx)
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  	ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN_V6);
>  	ctx->buf_height = ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN_V6);
> +	ctx->chroma_size_1 = 0;
>  	mfc_debug(2, "SEQ Done: Movie dimensions %dx%d,\n"
>  			"buffer dimensions: %dx%d\n", ctx->img_width,
>  			ctx->img_height, ctx->buf_width, ctx->buf_height);
>  
> -	ctx->luma_size = calc_plane(ctx->img_width, ctx->img_height);
> -	ctx->chroma_size = calc_plane(ctx->img_width, (ctx->img_height >> 1));
> +	switch (ctx->dst_fmt->fourcc) {
> +	case V4L2_PIX_FMT_NV12M:
> +	case V4L2_PIX_FMT_NV21M:
> +		ctx->stride[0] = ALIGN(ctx->img_width,
> +					S5P_FIMV_NV12MT_HALIGN_V6);
> +		ctx->stride[1] = ALIGN(ctx->img_width,
> +					S5P_FIMV_NV12MT_HALIGN_V6);
> +		ctx->luma_size = calc_plane(ctx->stride[0], ctx->img_height);
> +		ctx->chroma_size = calc_plane(ctx->stride[1],
> +					(ctx->img_height / 2));
> +		break;
> +	case V4L2_PIX_FMT_YUV420M:
> +	case V4L2_PIX_FMT_YVU420M:
> +		ctx->stride[0] = ALIGN(ctx->img_width,
> +					S5P_FIMV_NV12MT_HALIGN_V6);
> +		ctx->stride[1] = ALIGN(ctx->img_width / 2,
> +					S5P_FIMV_NV12MT_HALIGN_V6);
> +		ctx->stride[2] = ALIGN(ctx->img_width / 2,
> +					S5P_FIMV_NV12MT_HALIGN_V6);
> +		ctx->luma_size = calc_plane(ctx->stride[0], ctx->img_height);
> +		ctx->chroma_size = calc_plane(ctx->stride[1],
> +					(ctx->img_height / 2));
> +		ctx->chroma_size_1 = calc_plane(ctx->stride[2],
> +					(ctx->img_height / 2));
> +		break;
> +	}
> +
>  	if (IS_MFCV8_PLUS(ctx->dev)) {
>  		/* MFCv8 needs additional 64 bytes for luma,chroma dpb*/
>  		ctx->luma_size += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8;
>  		ctx->chroma_size += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8;
> +		ctx->chroma_size_1 += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8;
>  	}
>  
>  	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
> @@ -534,15 +561,53 @@ static void s5p_mfc_enc_calc_src_size_v6(struct s5p_mfc_ctx *ctx)
>  	mb_width = MB_WIDTH(ctx->img_width);
>  	mb_height = MB_HEIGHT(ctx->img_height);
>  
> -	ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN_V6);
> -	ctx->luma_size = ALIGN((mb_width * mb_height) * 256, 256);
> -	ctx->chroma_size = ALIGN((mb_width * mb_height) * 128, 256);
> -
> -	/* MFCv7 needs pad bytes for Luma and Chroma */
> -	if (IS_MFCV7_PLUS(ctx->dev)) {
> +	if (IS_MFCV12(ctx->dev)) {
> +		switch (ctx->src_fmt->fourcc) {
> +		case V4L2_PIX_FMT_NV12M:
> +		case V4L2_PIX_FMT_NV21M:
> +			ctx->stride[0] = ALIGN(ctx->img_width,
> +						S5P_FIMV_NV12M_HALIGN_V6);
> +			ctx->stride[1] = ALIGN(ctx->img_width,
> +						S5P_FIMV_NV12M_HALIGN_V6);
> +			ctx->luma_size = ctx->stride[0] *
> +						ALIGN(ctx->img_height, 16);
> +			ctx->chroma_size =  ctx->stride[0] *
> +						ALIGN(ctx->img_height / 2, 16);
> +			break;
> +		case V4L2_PIX_FMT_YUV420M:
> +		case V4L2_PIX_FMT_YVU420M:
> +			ctx->stride[0] = ALIGN(ctx->img_width,
> +						S5P_FIMV_NV12M_HALIGN_V6);
> +			ctx->stride[1] = ALIGN(ctx->img_width / 2,
> +						S5P_FIMV_NV12M_HALIGN_V6);
> +			ctx->stride[2] = ALIGN(ctx->img_width / 2,
> +						S5P_FIMV_NV12M_HALIGN_V6);
> +			ctx->luma_size = ctx->stride[0] *
> +						ALIGN(ctx->img_height, 16);
> +			ctx->chroma_size =  ctx->stride[1] *
> +						ALIGN(ctx->img_height / 2, 16);
> +			ctx->chroma_size_1 =  ctx->stride[2] *
> +						ALIGN(ctx->img_height / 2, 16);
> +			break;
> +		}
>  		ctx->luma_size += MFC_LUMA_PAD_BYTES_V7;
> -		ctx->chroma_size += MFC_CHROMA_PAD_BYTES_V7;
> +		ctx->chroma_size += MFC_CHROMA_PAD_BYTES_V12;
> +		ctx->chroma_size_1 += MFC_CHROMA_PAD_BYTES_V12;
> +	} else {
> +		ctx->buf_width = ALIGN(ctx->img_width,
> +					S5P_FIMV_NV12M_HALIGN_V6);
> +		ctx->stride[0] = ctx->buf_width;
> +		ctx->stride[1] = ctx->buf_width;
> +		ctx->luma_size = ALIGN((mb_width * mb_height) * 256, 256);
> +		ctx->chroma_size = ALIGN((mb_width * mb_height) * 128, 256);
> +		ctx->chroma_size_1 = 0;
> +		/* MFCv7 needs pad bytes for Luma and Chroma */
> +		if (IS_MFCV7_PLUS(ctx->dev)) {
> +			ctx->luma_size += MFC_LUMA_PAD_BYTES_V7;
> +			ctx->chroma_size += MFC_LUMA_PAD_BYTES_V7;
> +		}
>  	}
> +
>  }
>  
>  /* Set registers for decoding stream buffer */
> @@ -588,15 +653,21 @@ static int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx)
>  	writel(ctx->total_dpb_count, mfc_regs->d_num_dpb);
>  	writel(ctx->luma_size, mfc_regs->d_first_plane_dpb_size);
>  	writel(ctx->chroma_size, mfc_regs->d_second_plane_dpb_size);
> -
> +	if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +			ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +		writel(ctx->chroma_size_1, mfc_regs->d_third_plane_dpb_size);
>  	writel(buf_addr1, mfc_regs->d_scratch_buffer_addr);
>  	writel(ctx->scratch_buf_size, mfc_regs->d_scratch_buffer_size);
>  
>  	if (IS_MFCV8_PLUS(dev)) {
> -		writel(ctx->img_width,
> +		writel(ctx->stride[0],
>  			mfc_regs->d_first_plane_dpb_stride_size);
> -		writel(ctx->img_width,
> +		writel(ctx->stride[1],
>  			mfc_regs->d_second_plane_dpb_stride_size);
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +			writel(ctx->stride[2],
> +				mfc_regs->d_third_plane_dpb_stride_size);
>  	}
>  
>  	buf_addr1 += ctx->scratch_buf_size;
> @@ -625,6 +696,13 @@ static int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx)
>  					ctx->dst_bufs[i].cookie.raw.chroma);
>  		writel(ctx->dst_bufs[i].cookie.raw.chroma,
>  				mfc_regs->d_second_plane_dpb + i * 4);
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> +			mfc_debug(2, "\tChroma_1 %d: %zx\n", i,
> +					ctx->dst_bufs[i].cookie.raw.chroma_1);
> +			writel(ctx->dst_bufs[i].cookie.raw.chroma_1,
> +					mfc_regs->d_third_plane_dpb + i * 4);
> +		}
>  	}
>  	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
>  			ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC ||
> @@ -683,20 +761,24 @@ static int s5p_mfc_set_enc_stream_buffer_v6(struct s5p_mfc_ctx *ctx,
>  }
>  
>  static void s5p_mfc_set_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
> -		unsigned long y_addr, unsigned long c_addr)
> +		unsigned long y_addr, unsigned long c_addr,
> +		unsigned long c_1_addr)
>  {
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  	const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs;
>  
>  	writel(y_addr, mfc_regs->e_source_first_plane_addr);
>  	writel(c_addr, mfc_regs->e_source_second_plane_addr);
> +	writel(c_1_addr, mfc_regs->e_source_third_plane_addr);
>  
>  	mfc_debug(2, "enc src y buf addr: 0x%08lx\n", y_addr);
>  	mfc_debug(2, "enc src c buf addr: 0x%08lx\n", c_addr);
> +	mfc_debug(2, "enc src cr buf addr: 0x%08lx\n", c_1_addr);
>  }
>  
>  static void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
> -		unsigned long *y_addr, unsigned long *c_addr)
> +		unsigned long *y_addr, unsigned long *c_addr,
> +		unsigned long *c_1_addr)
>  {
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  	const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs;
> @@ -704,12 +786,17 @@ static void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
>  
>  	*y_addr = readl(mfc_regs->e_encoded_source_first_plane_addr);
>  	*c_addr = readl(mfc_regs->e_encoded_source_second_plane_addr);
> +	if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +			ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +		*c_1_addr = readl(mfc_regs->e_encoded_source_third_plane_addr);
> +	else
> +		*c_1_addr = 0;
>  
>  	enc_recon_y_addr = readl(mfc_regs->e_recon_luma_dpb_addr);
>  	enc_recon_c_addr = readl(mfc_regs->e_recon_chroma_dpb_addr);
>  
>  	mfc_debug(2, "recon y addr: 0x%08lx y_addr: 0x%08lx\n", enc_recon_y_addr, *y_addr);
> -	mfc_debug(2, "recon c addr: 0x%08lx\n", enc_recon_c_addr);
> +	mfc_debug(2, "recon c addr: 0x%08lx c_addr: 0x%08lx\n", enc_recon_c_addr, *c_addr);
>  }
>  
>  /* Set encoding ref & codec buffer */
> @@ -886,6 +973,20 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
>  		writel(reg, mfc_regs->e_enc_options);
>  		/* 0: NV12(CbCr), 1: NV21(CrCb) */
>  		writel(0x0, mfc_regs->pixel_format);
> +	} else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> +		/* 0: Linear, 1: 2D tiled*/
> +		reg = readl(mfc_regs->e_enc_options);
> +		reg &= ~(0x1 << 7);
> +		writel(reg, mfc_regs->e_enc_options);
> +		/* 2: YV12(CrCb), 3: I420(CrCb) */
> +		writel(0x2, mfc_regs->pixel_format);
> +	} else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M) {
> +		/* 0: Linear, 1: 2D tiled*/
> +		reg = readl(mfc_regs->e_enc_options);
> +		reg &= ~(0x1 << 7);
> +		writel(reg, mfc_regs->e_enc_options);
> +		/* 2: YV12(CrCb), 3: I420(CrCb) */
> +		writel(0x3, mfc_regs->pixel_format);
>  	}
>  
>  	/* memory structure recon. frame */
> @@ -1696,8 +1797,12 @@ static int s5p_mfc_init_decode_v6(struct s5p_mfc_ctx *ctx)
>  	else
>  		writel(reg, mfc_regs->d_dec_options);
>  
> -	/* 0: NV12(CbCr), 1: NV21(CrCb) */
> -	if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV21M)
> +	/* 0: NV12(CbCr), 1: NV21(CrCb), 2: YV12(CrCb), 3: I420(CbCr) */
> +	if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M)
> +		writel(0x3, mfc_regs->pixel_format);
> +	else if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +		writel(0x2, mfc_regs->pixel_format);
> +	else if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV21M)
>  		writel(0x1, mfc_regs->pixel_format);
>  	else
>  		writel(0x0, mfc_regs->pixel_format);
> @@ -1781,8 +1886,12 @@ static int s5p_mfc_init_encode_v6(struct s5p_mfc_ctx *ctx)
>  
>  	/* Set stride lengths for v7 & above */
>  	if (IS_MFCV7_PLUS(dev)) {
> -		writel(ctx->img_width, mfc_regs->e_source_first_plane_stride);
> -		writel(ctx->img_width, mfc_regs->e_source_second_plane_stride);
> +		writel(ctx->stride[0], mfc_regs->e_source_first_plane_stride);
> +		writel(ctx->stride[1], mfc_regs->e_source_second_plane_stride);
> +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +			writel(ctx->stride[2],
> +					mfc_regs->e_source_third_plane_stride);
>  	}
>  
>  	writel(ctx->inst_no, mfc_regs->instance_id);
> @@ -1891,7 +2000,7 @@ static inline int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  	struct s5p_mfc_buf *dst_mb;
>  	struct s5p_mfc_buf *src_mb;
> -	unsigned long src_y_addr, src_c_addr, dst_addr;
> +	unsigned long src_y_addr, src_c_addr, src_c_1_addr, dst_addr;
>  	/*
>  	unsigned int src_y_size, src_c_size;
>  	*/
> @@ -1909,22 +2018,29 @@ static inline int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
>  
>  	if (list_empty(&ctx->src_queue)) {
>  		/* send null frame */
> -		s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0);
> +		s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0, 0);
>  		src_mb = NULL;
>  	} else {
>  		src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
>  		src_mb->flags |= MFC_BUF_FLAG_USED;
>  		if (src_mb->b->vb2_buf.planes[0].bytesused == 0) {
> -			s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0);
> +			s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0, 0);
>  			ctx->state = MFCINST_FINISHING;
>  		} else {
>  			src_y_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 0);
>  			src_c_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 1);
> +			if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +				src_c_1_addr = vb2_dma_contig_plane_dma_addr
> +						(&src_mb->b->vb2_buf, 2);
> +			else
> +				src_c_1_addr = 0;
>  
>  			mfc_debug(2, "enc src y addr: 0x%08lx\n", src_y_addr);
>  			mfc_debug(2, "enc src c addr: 0x%08lx\n", src_c_addr);
>  
> -			s5p_mfc_set_enc_frame_buffer_v6(ctx, src_y_addr, src_c_addr);
> +			s5p_mfc_set_enc_frame_buffer_v6(ctx, src_y_addr,
> +						src_c_addr, src_c_1_addr);
>  			if (src_mb->flags & MFC_BUF_FLAG_EOS)
>  				ctx->state = MFCINST_FINISHING;
>  		}
> @@ -2450,6 +2566,8 @@ const struct s5p_mfc_regs *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev)
>  			S5P_FIMV_E_ENCODED_SOURCE_FIRST_ADDR_V7);
>  	R(e_encoded_source_second_plane_addr,
>  			S5P_FIMV_E_ENCODED_SOURCE_SECOND_ADDR_V7);
> +	R(e_encoded_source_third_plane_addr,
> +			S5P_FIMV_E_ENCODED_SOURCE_THIRD_ADDR_V7);
>  	R(e_vp8_options, S5P_FIMV_E_VP8_OPTIONS_V7);
>  
>  	if (!IS_MFCV8_PLUS(dev))
> @@ -2464,16 +2582,20 @@ const struct s5p_mfc_regs *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev)
>  	R(d_cpb_buffer_offset, S5P_FIMV_D_CPB_BUFFER_OFFSET_V8);
>  	R(d_first_plane_dpb_size, S5P_FIMV_D_FIRST_PLANE_DPB_SIZE_V8);
>  	R(d_second_plane_dpb_size, S5P_FIMV_D_SECOND_PLANE_DPB_SIZE_V8);
> +	R(d_third_plane_dpb_size, S5P_FIMV_D_THIRD_PLANE_DPB_SIZE_V8);
>  	R(d_scratch_buffer_addr, S5P_FIMV_D_SCRATCH_BUFFER_ADDR_V8);
>  	R(d_scratch_buffer_size, S5P_FIMV_D_SCRATCH_BUFFER_SIZE_V8);
>  	R(d_first_plane_dpb_stride_size,
>  			S5P_FIMV_D_FIRST_PLANE_DPB_STRIDE_SIZE_V8);
>  	R(d_second_plane_dpb_stride_size,
>  			S5P_FIMV_D_SECOND_PLANE_DPB_STRIDE_SIZE_V8);
> +	R(d_third_plane_dpb_stride_size,
> +			S5P_FIMV_D_THIRD_PLANE_DPB_STRIDE_SIZE_V8);
>  	R(d_mv_buffer_size, S5P_FIMV_D_MV_BUFFER_SIZE_V8);
>  	R(d_num_mv, S5P_FIMV_D_NUM_MV_V8);
>  	R(d_first_plane_dpb, S5P_FIMV_D_FIRST_PLANE_DPB_V8);
>  	R(d_second_plane_dpb, S5P_FIMV_D_SECOND_PLANE_DPB_V8);
> +	R(d_third_plane_dpb, S5P_FIMV_D_THIRD_PLANE_DPB_V8);
>  	R(d_mv_buffer, S5P_FIMV_D_MV_BUFFER_V8);
>  	R(d_init_buffer_options, S5P_FIMV_D_INIT_BUFFER_OPTIONS_V8);
>  	R(d_available_dpb_flag_lower, S5P_FIMV_D_AVAILABLE_DPB_FLAG_LOWER_V8);


_______________________________________________
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] 54+ messages in thread

* Re: [Patch v4 09/11] media: s5p-mfc: Load firmware for each run in MFCv12.
  2023-10-25 10:22       ` Aakarsh Jain
@ 2023-11-22 15:44         ` Hans Verkuil
  -1 siblings, 0 replies; 54+ messages in thread
From: Hans Verkuil @ 2023-11-22 15:44 UTC (permalink / raw)
  To: Aakarsh Jain, linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, krzysztof.kozlowski+dt,
	dillon.minfei, david.plowman, mark.rutland, robh+dt, conor+dt,
	linux-samsung-soc, andi, gost.dev, alim.akhtar, aswani.reddy,
	pankaj.dubey, ajaykumar.rs, linux-fsd, Smitha T Murthy

On 25/10/2023 12:22, Aakarsh Jain wrote:
> In MFCv12, some section of firmware gets updated at each MFC run.
> Hence we need to reload original firmware for each run at the start.

Huh? This is very weird. This definitely deserves a comment in the actual
code rather than just the commit log.

Do you know what is going on? What part is updated? Are you sure it isn't
a driver bug somehow?

Regards,

	Hans

> 
> Cc: linux-fsd@tesla.com
> Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
> Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
> ---
>  drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> index b49159142c53..057088b9d327 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> @@ -51,8 +51,9 @@ int s5p_mfc_load_firmware(struct s5p_mfc_dev *dev)
>  	 * into kernel. */
>  	mfc_debug_enter();
>  
> -	if (dev->fw_get_done)
> -		return 0;
> +	if (!IS_MFCV12(dev))
> +		if (dev->fw_get_done)
> +			return 0;
>  
>  	for (i = MFC_FW_MAX_VERSIONS - 1; i >= 0; i--) {
>  		if (!dev->variant->fw_name[i])


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

* Re: [Patch v4 09/11] media: s5p-mfc: Load firmware for each run in MFCv12.
@ 2023-11-22 15:44         ` Hans Verkuil
  0 siblings, 0 replies; 54+ messages in thread
From: Hans Verkuil @ 2023-11-22 15:44 UTC (permalink / raw)
  To: Aakarsh Jain, linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, krzysztof.kozlowski+dt,
	dillon.minfei, david.plowman, mark.rutland, robh+dt, conor+dt,
	linux-samsung-soc, andi, gost.dev, alim.akhtar, aswani.reddy,
	pankaj.dubey, ajaykumar.rs, linux-fsd, Smitha T Murthy

On 25/10/2023 12:22, Aakarsh Jain wrote:
> In MFCv12, some section of firmware gets updated at each MFC run.
> Hence we need to reload original firmware for each run at the start.

Huh? This is very weird. This definitely deserves a comment in the actual
code rather than just the commit log.

Do you know what is going on? What part is updated? Are you sure it isn't
a driver bug somehow?

Regards,

	Hans

> 
> Cc: linux-fsd@tesla.com
> Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
> Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
> ---
>  drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> index b49159142c53..057088b9d327 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> @@ -51,8 +51,9 @@ int s5p_mfc_load_firmware(struct s5p_mfc_dev *dev)
>  	 * into kernel. */
>  	mfc_debug_enter();
>  
> -	if (dev->fw_get_done)
> -		return 0;
> +	if (!IS_MFCV12(dev))
> +		if (dev->fw_get_done)
> +			return 0;
>  
>  	for (i = MFC_FW_MAX_VERSIONS - 1; i >= 0; i--) {
>  		if (!dev->variant->fw_name[i])


_______________________________________________
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] 54+ messages in thread

* Re: [Patch v4 04/11] media: s5p-mfc: Add YV12 and I420 multiplanar format support
  2023-10-25 10:22       ` Aakarsh Jain
@ 2023-11-23 17:25         ` Nicolas Dufresne
  -1 siblings, 0 replies; 54+ messages in thread
From: Nicolas Dufresne @ 2023-11-23 17:25 UTC (permalink / raw)
  To: Aakarsh Jain, linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	linux-fsd, Smitha T Murthy

Le mercredi 25 octobre 2023 à 15:52 +0530, Aakarsh Jain a écrit :
> YV12 and I420 format (3-plane) support is added. Stride information is
> added to all formats and planes since it is necessary for YV12/I420
> which are different from width.
> 
> Cc: linux-fsd@tesla.com
> Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
> Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
> ---
>  .../platform/samsung/s5p-mfc/regs-mfc-v12.h   |   2 +
>  .../platform/samsung/s5p-mfc/regs-mfc-v7.h    |   1 +
>  .../platform/samsung/s5p-mfc/regs-mfc-v8.h    |   3 +
>  .../platform/samsung/s5p-mfc/s5p_mfc_common.h |   4 +
>  .../platform/samsung/s5p-mfc/s5p_mfc_dec.c    |  45 ++++-
>  .../platform/samsung/s5p-mfc/s5p_mfc_enc.c    |  86 +++++++--
>  .../platform/samsung/s5p-mfc/s5p_mfc_opr.h    |   6 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c |  12 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 168 +++++++++++++++---
>  9 files changed, 281 insertions(+), 46 deletions(-)
> 
> diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> index 6c68a45082d0..70464f47c1f9 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> @@ -26,6 +26,8 @@
>  #define MFC_VERSION_V12			0xC0
>  #define MFC_NUM_PORTS_V12		1
>  #define S5P_FIMV_CODEC_VP9_ENC		27
> +#define MFC_CHROMA_PAD_BYTES_V12        256
> +#define S5P_FIMV_D_ALIGN_PLANE_SIZE_V12 256
>  
>  /* Encoder buffer size for MFCv12 */
>  #define ENC_V120_BASE_SIZE(x, y) \
> diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
> index 4a7adfdaa359..50f9bf0603c1 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
> @@ -24,6 +24,7 @@
>  
>  #define S5P_FIMV_E_ENCODED_SOURCE_FIRST_ADDR_V7		0xfa70
>  #define S5P_FIMV_E_ENCODED_SOURCE_SECOND_ADDR_V7	0xfa74
> +#define S5P_FIMV_E_ENCODED_SOURCE_THIRD_ADDR_V7		0xfa78
>  
>  #define S5P_FIMV_E_VP8_OPTIONS_V7			0xfdb0
>  #define S5P_FIMV_E_VP8_FILTER_OPTIONS_V7		0xfdb4
> diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
> index 162e3c7e920f..0ef9eb2dff22 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
> @@ -17,13 +17,16 @@
>  #define S5P_FIMV_D_MIN_SCRATCH_BUFFER_SIZE_V8	0xf108
>  #define S5P_FIMV_D_FIRST_PLANE_DPB_SIZE_V8	0xf144
>  #define S5P_FIMV_D_SECOND_PLANE_DPB_SIZE_V8	0xf148
> +#define S5P_FIMV_D_THIRD_PLANE_DPB_SIZE_V8	0xf14C
>  #define S5P_FIMV_D_MV_BUFFER_SIZE_V8		0xf150
>  
>  #define S5P_FIMV_D_FIRST_PLANE_DPB_STRIDE_SIZE_V8	0xf138
>  #define S5P_FIMV_D_SECOND_PLANE_DPB_STRIDE_SIZE_V8	0xf13c
> +#define S5P_FIMV_D_THIRD_PLANE_DPB_STRIDE_SIZE_V8	0xf140
>  
>  #define S5P_FIMV_D_FIRST_PLANE_DPB_V8		0xf160
>  #define S5P_FIMV_D_SECOND_PLANE_DPB_V8		0xf260
> +#define S5P_FIMV_D_THIRD_PLANE_DPB_V8		0xf360
>  #define S5P_FIMV_D_MV_BUFFER_V8			0xf460
>  
>  #define S5P_FIMV_D_NUM_MV_V8			0xf134
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> index dd2e9f7704ab..9a39cccfe002 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> @@ -56,6 +56,7 @@
>  #define MFC_NO_INSTANCE_SET	-1
>  #define MFC_ENC_CAP_PLANE_COUNT	1
>  #define MFC_ENC_OUT_PLANE_COUNT	2
> +#define VB2_MAX_PLANE_COUNT	3
>  #define STUFF_BYTE		4
>  #define MFC_MAX_CTRLS		128
>  
> @@ -181,6 +182,7 @@ struct s5p_mfc_buf {
>  		struct {
>  			size_t luma;
>  			size_t chroma;
> +			size_t chroma_1;
>  		} raw;
>  		size_t stream;
>  	} cookie;
> @@ -657,6 +659,7 @@ struct s5p_mfc_ctx {
>  
>  	int luma_size;
>  	int chroma_size;
> +	int chroma_size_1;
>  	int mv_size;
>  
>  	unsigned long consumed_stream;
> @@ -722,6 +725,7 @@ struct s5p_mfc_ctx {
>  	size_t scratch_buf_size;
>  	int is_10bit;
>  	int is_422;
> +	int stride[VB2_MAX_PLANE_COUNT];
>  };
>  
>  /*
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> index e219cbcd86d5..317f796fffa1 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> @@ -56,6 +56,20 @@ static struct s5p_mfc_fmt formats[] = {
>  		.num_planes	= 2,
>  		.versions	= MFC_V6PLUS_BITS,
>  	},
> +	{
> +		.fourcc         = V4L2_PIX_FMT_YUV420M,
> +		.codec_mode     = S5P_MFC_CODEC_NONE,
> +		.type           = MFC_FMT_RAW,
> +		.num_planes     = 3,
> +		.versions       = MFC_V12_BIT,
> +	},
> +	{
> +		.fourcc         = V4L2_PIX_FMT_YVU420M,
> +		.codec_mode     = S5P_MFC_CODEC_NONE,
> +		.type           = MFC_FMT_RAW,
> +		.num_planes     = 3,
> +		.versions       = MFC_V12_BIT
> +	},
>  	{
>  		.fourcc		= V4L2_PIX_FMT_H264,
>  		.codec_mode	= S5P_MFC_CODEC_H264_DEC,
> @@ -359,10 +373,15 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
>  		/* Set pixelformat to the format in which MFC
>  		   outputs the decoded frame */
>  		pix_mp->pixelformat = ctx->dst_fmt->fourcc;
> -		pix_mp->plane_fmt[0].bytesperline = ctx->buf_width;
> +		pix_mp->plane_fmt[0].bytesperline = ctx->stride[0];
>  		pix_mp->plane_fmt[0].sizeimage = ctx->luma_size;
> -		pix_mp->plane_fmt[1].bytesperline = ctx->buf_width;
> +		pix_mp->plane_fmt[1].bytesperline = ctx->stride[1];
>  		pix_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> +			pix_mp->plane_fmt[2].bytesperline = ctx->stride[2];
> +			pix_mp->plane_fmt[2].sizeimage = ctx->chroma_size_1;
> +		}
>  	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
>  		/* This is run on OUTPUT
>  		   The buffer contains compressed image
> @@ -937,6 +956,9 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
>  		   vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
>  		/* Output plane count is 2 - one for Y and one for CbCr */
>  		*plane_count = 2;
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +			*plane_count = 3;

I don't usually interfere, this is your driver to maintain, but this becomes
horribly messy. Have you consider de-hardcoding a little and encapsulate per HW
format details into a C structure ? Drivers these days try to make sure of v4l2-
common library, which as a matter of fact knows that YUV420M and YVU420M have 3
places, so that you don't have to duplicate it in your driver.

regards,
Nicolas

>  		/* Setup buffer count */
>  		if (*buf_count < ctx->pb_count)
>  			*buf_count = ctx->pb_count;
> @@ -955,12 +977,17 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
>  	    vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
>  		psize[0] = ctx->luma_size;
>  		psize[1] = ctx->chroma_size;
> -
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +			psize[2] = ctx->chroma_size_1;
>  		if (IS_MFCV6_PLUS(dev))
>  			alloc_devs[0] = ctx->dev->mem_dev[BANK_L_CTX];
>  		else
>  			alloc_devs[0] = ctx->dev->mem_dev[BANK_R_CTX];
>  		alloc_devs[1] = ctx->dev->mem_dev[BANK_L_CTX];
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +			alloc_devs[2] = ctx->dev->mem_dev[BANK_L_CTX];
>  	} else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
>  		   ctx->state == MFCINST_INIT) {
>  		psize[0] = ctx->dec_src_buf_size;
> @@ -994,12 +1021,24 @@ static int s5p_mfc_buf_init(struct vb2_buffer *vb)
>  			mfc_err("Plane buffer (CAPTURE) is too small\n");
>  			return -EINVAL;
>  		}
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> +			if (vb2_plane_size(vb, 2) < ctx->chroma_size_1) {
> +				mfc_err("Plane buffer (CAPTURE) is too small\n");
> +				return -EINVAL;
> +			}
> +		}
>  		i = vb->index;
>  		ctx->dst_bufs[i].b = vbuf;
>  		ctx->dst_bufs[i].cookie.raw.luma =
>  					vb2_dma_contig_plane_dma_addr(vb, 0);
>  		ctx->dst_bufs[i].cookie.raw.chroma =
>  					vb2_dma_contig_plane_dma_addr(vb, 1);
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> +			ctx->dst_bufs[i].cookie.raw.chroma_1 =
> +					vb2_dma_contig_plane_dma_addr(vb, 2);
> +		}
>  		ctx->dst_bufs_cnt++;
>  	} else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
>  		if (IS_ERR_OR_NULL(ERR_PTR(
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> index e4d6e7c117b5..0eec04eb3ef3 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> @@ -59,6 +59,20 @@ static struct s5p_mfc_fmt formats[] = {
>  		.num_planes	= 2,
>  		.versions	= MFC_V6PLUS_BITS,
>  	},
> +	{
> +		.fourcc         = V4L2_PIX_FMT_YUV420M,
> +		.codec_mode     = S5P_MFC_CODEC_NONE,
> +		.type           = MFC_FMT_RAW,
> +		.num_planes     = 3,
> +		.versions       = MFC_V12_BIT,
> +	},
> +	{
> +		.fourcc         = V4L2_PIX_FMT_YVU420M,
> +		.codec_mode     = S5P_MFC_CODEC_NONE,
> +		.type           = MFC_FMT_RAW,
> +		.num_planes     = 3,
> +		.versions       = MFC_V12_BIT,
> +	},
>  	{
>  		.fourcc		= V4L2_PIX_FMT_H264,
>  		.codec_mode	= S5P_MFC_CODEC_H264_ENC,
> @@ -1193,14 +1207,20 @@ static int enc_pre_frame_start(struct s5p_mfc_ctx *ctx)
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  	struct s5p_mfc_buf *dst_mb;
>  	struct s5p_mfc_buf *src_mb;
> -	unsigned long src_y_addr, src_c_addr, dst_addr;
> +	unsigned long src_y_addr, src_c_addr, src_c_1_addr, dst_addr;
>  	unsigned int dst_size;
>  
>  	src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
>  	src_y_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 0);
>  	src_c_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 1);
> +	if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +			ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +		src_c_1_addr =
> +			vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 2);
> +	else
> +		src_c_1_addr = 0;
>  	s5p_mfc_hw_call(dev->mfc_ops, set_enc_frame_buffer, ctx,
> -							src_y_addr, src_c_addr);
> +					src_y_addr, src_c_addr, src_c_1_addr);
>  
>  	dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
>  	dst_addr = vb2_dma_contig_plane_dma_addr(&dst_mb->b->vb2_buf, 0);
> @@ -1215,8 +1235,8 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
>  {
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  	struct s5p_mfc_buf *mb_entry;
> -	unsigned long enc_y_addr = 0, enc_c_addr = 0;
> -	unsigned long mb_y_addr, mb_c_addr;
> +	unsigned long enc_y_addr = 0, enc_c_addr = 0, enc_c_1_addr = 0;
> +	unsigned long mb_y_addr, mb_c_addr, mb_c_1_addr;
>  	int slice_type;
>  	unsigned int strm_size;
>  	bool src_ready;
> @@ -1229,14 +1249,21 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
>  		  mfc_read(dev, S5P_FIMV_ENC_SI_PIC_CNT));
>  	if (slice_type >= 0) {
>  		s5p_mfc_hw_call(dev->mfc_ops, get_enc_frame_buffer, ctx,
> -				&enc_y_addr, &enc_c_addr);
> +				&enc_y_addr, &enc_c_addr, &enc_c_1_addr);
>  		list_for_each_entry(mb_entry, &ctx->src_queue, list) {
>  			mb_y_addr = vb2_dma_contig_plane_dma_addr(
>  					&mb_entry->b->vb2_buf, 0);
>  			mb_c_addr = vb2_dma_contig_plane_dma_addr(
>  					&mb_entry->b->vb2_buf, 1);
> -			if ((enc_y_addr == mb_y_addr) &&
> -						(enc_c_addr == mb_c_addr)) {
> +			if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +				mb_c_1_addr = vb2_dma_contig_plane_dma_addr
> +						(&mb_entry->b->vb2_buf, 2);
> +			else
> +				mb_c_1_addr = 0;
> +			if ((enc_y_addr == mb_y_addr)
> +					&& (enc_c_addr == mb_c_addr)
> +					&& (enc_c_1_addr == mb_c_1_addr)) {
>  				list_del(&mb_entry->list);
>  				ctx->src_queue_cnt--;
>  				vb2_buffer_done(&mb_entry->b->vb2_buf,
> @@ -1249,8 +1276,15 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
>  					&mb_entry->b->vb2_buf, 0);
>  			mb_c_addr = vb2_dma_contig_plane_dma_addr(
>  					&mb_entry->b->vb2_buf, 1);
> -			if ((enc_y_addr == mb_y_addr) &&
> -						(enc_c_addr == mb_c_addr)) {
> +			if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +				mb_c_1_addr = vb2_dma_contig_plane_dma_addr(
> +						&mb_entry->b->vb2_buf, 2);
> +			else
> +				mb_c_1_addr = 0;
> +			if ((enc_y_addr == mb_y_addr)
> +					&& (enc_c_addr == mb_c_addr)
> +					&& (enc_c_1_addr == mb_c_1_addr)) {
>  				list_del(&mb_entry->list);
>  				ctx->ref_queue_cnt--;
>  				vb2_buffer_done(&mb_entry->b->vb2_buf,
> @@ -1381,10 +1415,15 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
>  		pix_fmt_mp->pixelformat = ctx->src_fmt->fourcc;
>  		pix_fmt_mp->num_planes = ctx->src_fmt->num_planes;
>  
> -		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
> +		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->stride[0];
>  		pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
> -		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
> +		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->stride[1];
>  		pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
> +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> +			pix_fmt_mp->plane_fmt[2].bytesperline = ctx->stride[2];
> +			pix_fmt_mp->plane_fmt[2].sizeimage = ctx->chroma_size_1;
> +		}
>  	} else {
>  		mfc_err("invalid buf type\n");
>  		return -EINVAL;
> @@ -1468,9 +1507,14 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
>  
>  		s5p_mfc_hw_call(dev->mfc_ops, enc_calc_src_size, ctx);
>  		pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
> -		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
> +		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->stride[0];
>  		pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
> -		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
> +		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->stride[1];
> +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> +			pix_fmt_mp->plane_fmt[2].bytesperline = ctx->stride[2];
> +			pix_fmt_mp->plane_fmt[2].sizeimage = ctx->chroma_size_1;
> +		}
>  
>  		ctx->src_bufs_cnt = 0;
>  		ctx->output_state = QUEUE_FREE;
> @@ -2414,10 +2458,16 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
>  
>  		psize[0] = ctx->luma_size;
>  		psize[1] = ctx->chroma_size;
> +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +			psize[2] = ctx->chroma_size_1;
>  
>  		if (IS_MFCV6_PLUS(dev)) {
>  			alloc_devs[0] = ctx->dev->mem_dev[BANK_L_CTX];
>  			alloc_devs[1] = ctx->dev->mem_dev[BANK_L_CTX];
> +			if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +				alloc_devs[2] = ctx->dev->mem_dev[BANK_L_CTX];
>  		} else {
>  			alloc_devs[0] = ctx->dev->mem_dev[BANK_R_CTX];
>  			alloc_devs[1] = ctx->dev->mem_dev[BANK_R_CTX];
> @@ -2456,6 +2506,10 @@ static int s5p_mfc_buf_init(struct vb2_buffer *vb)
>  					vb2_dma_contig_plane_dma_addr(vb, 0);
>  		ctx->src_bufs[i].cookie.raw.chroma =
>  					vb2_dma_contig_plane_dma_addr(vb, 1);
> +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +			ctx->src_bufs[i].cookie.raw.chroma_1 =
> +					vb2_dma_contig_plane_dma_addr(vb, 2);
>  		ctx->src_bufs_cnt++;
>  	} else {
>  		mfc_err("invalid queue type: %d\n", vq->type);
> @@ -2493,6 +2547,12 @@ static int s5p_mfc_buf_prepare(struct vb2_buffer *vb)
>  			mfc_err("plane size is too small for output\n");
>  			return -EINVAL;
>  		}
> +		if ((ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +		     ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) &&
> +		    (vb2_plane_size(vb, 2) < ctx->chroma_size_1)) {
> +			mfc_err("plane size is too small for output\n");
> +			return -EINVAL;
> +		}
>  	} else {
>  		mfc_err("invalid queue type: %d\n", vq->type);
>  		return -EINVAL;
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> index 87ac56756a16..7c5e851c8191 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> @@ -293,9 +293,11 @@ struct s5p_mfc_hw_ops {
>  	int (*set_enc_stream_buffer)(struct s5p_mfc_ctx *ctx,
>  			unsigned long addr, unsigned int size);
>  	void (*set_enc_frame_buffer)(struct s5p_mfc_ctx *ctx,
> -			unsigned long y_addr, unsigned long c_addr);
> +			unsigned long y_addr, unsigned long c_addr,
> +			unsigned long c_1_addr);
>  	void (*get_enc_frame_buffer)(struct s5p_mfc_ctx *ctx,
> -			unsigned long *y_addr, unsigned long *c_addr);
> +			unsigned long *y_addr, unsigned long *c_addr,
> +			unsigned long *c_1_addr);
>  	void (*try_run)(struct s5p_mfc_dev *dev);
>  	void (*clear_int_flags)(struct s5p_mfc_dev *dev);
>  	int (*get_dspl_y_adr)(struct s5p_mfc_dev *dev);
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
> index 28a06dc343fd..fcfaf125a5a1 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
> @@ -516,7 +516,8 @@ static int s5p_mfc_set_enc_stream_buffer_v5(struct s5p_mfc_ctx *ctx,
>  }
>  
>  static void s5p_mfc_set_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,
> -		unsigned long y_addr, unsigned long c_addr)
> +		unsigned long y_addr, unsigned long c_addr,
> +		unsigned long c_1_addr)
>  {
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  
> @@ -525,7 +526,8 @@ static void s5p_mfc_set_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,
>  }
>  
>  static void s5p_mfc_get_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,
> -		unsigned long *y_addr, unsigned long *c_addr)
> +		unsigned long *y_addr, unsigned long *c_addr,
> +		unsigned long *c_1_addr)
>  {
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  
> @@ -1210,7 +1212,7 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
>  	if (list_empty(&ctx->src_queue)) {
>  		/* send null frame */
>  		s5p_mfc_set_enc_frame_buffer_v5(ctx, dev->dma_base[BANK_R_CTX],
> -						dev->dma_base[BANK_R_CTX]);
> +						dev->dma_base[BANK_R_CTX], 0);
>  		src_mb = NULL;
>  	} else {
>  		src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf,
> @@ -1220,7 +1222,7 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
>  			/* send null frame */
>  			s5p_mfc_set_enc_frame_buffer_v5(ctx,
>  						dev->dma_base[BANK_R_CTX],
> -						dev->dma_base[BANK_R_CTX]);
> +						dev->dma_base[BANK_R_CTX], 0);
>  			ctx->state = MFCINST_FINISHING;
>  		} else {
>  			src_y_addr = vb2_dma_contig_plane_dma_addr(
> @@ -1228,7 +1230,7 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
>  			src_c_addr = vb2_dma_contig_plane_dma_addr(
>  					&src_mb->b->vb2_buf, 1);
>  			s5p_mfc_set_enc_frame_buffer_v5(ctx, src_y_addr,
> -								src_c_addr);
> +								src_c_addr, 0);
>  			if (src_mb->flags & MFC_BUF_FLAG_EOS)
>  				ctx->state = MFCINST_FINISHING;
>  		}
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> index fb3f0718821d..e579c765e902 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> @@ -494,16 +494,43 @@ static void s5p_mfc_dec_calc_dpb_size_v6(struct s5p_mfc_ctx *ctx)
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  	ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN_V6);
>  	ctx->buf_height = ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN_V6);
> +	ctx->chroma_size_1 = 0;
>  	mfc_debug(2, "SEQ Done: Movie dimensions %dx%d,\n"
>  			"buffer dimensions: %dx%d\n", ctx->img_width,
>  			ctx->img_height, ctx->buf_width, ctx->buf_height);
>  
> -	ctx->luma_size = calc_plane(ctx->img_width, ctx->img_height);
> -	ctx->chroma_size = calc_plane(ctx->img_width, (ctx->img_height >> 1));
> +	switch (ctx->dst_fmt->fourcc) {
> +	case V4L2_PIX_FMT_NV12M:
> +	case V4L2_PIX_FMT_NV21M:
> +		ctx->stride[0] = ALIGN(ctx->img_width,
> +					S5P_FIMV_NV12MT_HALIGN_V6);
> +		ctx->stride[1] = ALIGN(ctx->img_width,
> +					S5P_FIMV_NV12MT_HALIGN_V6);
> +		ctx->luma_size = calc_plane(ctx->stride[0], ctx->img_height);
> +		ctx->chroma_size = calc_plane(ctx->stride[1],
> +					(ctx->img_height / 2));
> +		break;
> +	case V4L2_PIX_FMT_YUV420M:
> +	case V4L2_PIX_FMT_YVU420M:
> +		ctx->stride[0] = ALIGN(ctx->img_width,
> +					S5P_FIMV_NV12MT_HALIGN_V6);
> +		ctx->stride[1] = ALIGN(ctx->img_width / 2,
> +					S5P_FIMV_NV12MT_HALIGN_V6);
> +		ctx->stride[2] = ALIGN(ctx->img_width / 2,
> +					S5P_FIMV_NV12MT_HALIGN_V6);
> +		ctx->luma_size = calc_plane(ctx->stride[0], ctx->img_height);
> +		ctx->chroma_size = calc_plane(ctx->stride[1],
> +					(ctx->img_height / 2));
> +		ctx->chroma_size_1 = calc_plane(ctx->stride[2],
> +					(ctx->img_height / 2));
> +		break;
> +	}
> +
>  	if (IS_MFCV8_PLUS(ctx->dev)) {
>  		/* MFCv8 needs additional 64 bytes for luma,chroma dpb*/
>  		ctx->luma_size += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8;
>  		ctx->chroma_size += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8;
> +		ctx->chroma_size_1 += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8;
>  	}
>  
>  	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
> @@ -534,15 +561,53 @@ static void s5p_mfc_enc_calc_src_size_v6(struct s5p_mfc_ctx *ctx)
>  	mb_width = MB_WIDTH(ctx->img_width);
>  	mb_height = MB_HEIGHT(ctx->img_height);
>  
> -	ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN_V6);
> -	ctx->luma_size = ALIGN((mb_width * mb_height) * 256, 256);
> -	ctx->chroma_size = ALIGN((mb_width * mb_height) * 128, 256);
> -
> -	/* MFCv7 needs pad bytes for Luma and Chroma */
> -	if (IS_MFCV7_PLUS(ctx->dev)) {
> +	if (IS_MFCV12(ctx->dev)) {
> +		switch (ctx->src_fmt->fourcc) {
> +		case V4L2_PIX_FMT_NV12M:
> +		case V4L2_PIX_FMT_NV21M:
> +			ctx->stride[0] = ALIGN(ctx->img_width,
> +						S5P_FIMV_NV12M_HALIGN_V6);
> +			ctx->stride[1] = ALIGN(ctx->img_width,
> +						S5P_FIMV_NV12M_HALIGN_V6);
> +			ctx->luma_size = ctx->stride[0] *
> +						ALIGN(ctx->img_height, 16);
> +			ctx->chroma_size =  ctx->stride[0] *
> +						ALIGN(ctx->img_height / 2, 16);
> +			break;
> +		case V4L2_PIX_FMT_YUV420M:
> +		case V4L2_PIX_FMT_YVU420M:
> +			ctx->stride[0] = ALIGN(ctx->img_width,
> +						S5P_FIMV_NV12M_HALIGN_V6);
> +			ctx->stride[1] = ALIGN(ctx->img_width / 2,
> +						S5P_FIMV_NV12M_HALIGN_V6);
> +			ctx->stride[2] = ALIGN(ctx->img_width / 2,
> +						S5P_FIMV_NV12M_HALIGN_V6);
> +			ctx->luma_size = ctx->stride[0] *
> +						ALIGN(ctx->img_height, 16);
> +			ctx->chroma_size =  ctx->stride[1] *
> +						ALIGN(ctx->img_height / 2, 16);
> +			ctx->chroma_size_1 =  ctx->stride[2] *
> +						ALIGN(ctx->img_height / 2, 16);
> +			break;
> +		}
>  		ctx->luma_size += MFC_LUMA_PAD_BYTES_V7;
> -		ctx->chroma_size += MFC_CHROMA_PAD_BYTES_V7;
> +		ctx->chroma_size += MFC_CHROMA_PAD_BYTES_V12;
> +		ctx->chroma_size_1 += MFC_CHROMA_PAD_BYTES_V12;
> +	} else {
> +		ctx->buf_width = ALIGN(ctx->img_width,
> +					S5P_FIMV_NV12M_HALIGN_V6);
> +		ctx->stride[0] = ctx->buf_width;
> +		ctx->stride[1] = ctx->buf_width;
> +		ctx->luma_size = ALIGN((mb_width * mb_height) * 256, 256);
> +		ctx->chroma_size = ALIGN((mb_width * mb_height) * 128, 256);
> +		ctx->chroma_size_1 = 0;
> +		/* MFCv7 needs pad bytes for Luma and Chroma */
> +		if (IS_MFCV7_PLUS(ctx->dev)) {
> +			ctx->luma_size += MFC_LUMA_PAD_BYTES_V7;
> +			ctx->chroma_size += MFC_LUMA_PAD_BYTES_V7;
> +		}
>  	}
> +
>  }
>  
>  /* Set registers for decoding stream buffer */
> @@ -588,15 +653,21 @@ static int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx)
>  	writel(ctx->total_dpb_count, mfc_regs->d_num_dpb);
>  	writel(ctx->luma_size, mfc_regs->d_first_plane_dpb_size);
>  	writel(ctx->chroma_size, mfc_regs->d_second_plane_dpb_size);
> -
> +	if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +			ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +		writel(ctx->chroma_size_1, mfc_regs->d_third_plane_dpb_size);
>  	writel(buf_addr1, mfc_regs->d_scratch_buffer_addr);
>  	writel(ctx->scratch_buf_size, mfc_regs->d_scratch_buffer_size);
>  
>  	if (IS_MFCV8_PLUS(dev)) {
> -		writel(ctx->img_width,
> +		writel(ctx->stride[0],
>  			mfc_regs->d_first_plane_dpb_stride_size);
> -		writel(ctx->img_width,
> +		writel(ctx->stride[1],
>  			mfc_regs->d_second_plane_dpb_stride_size);
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +			writel(ctx->stride[2],
> +				mfc_regs->d_third_plane_dpb_stride_size);
>  	}
>  
>  	buf_addr1 += ctx->scratch_buf_size;
> @@ -625,6 +696,13 @@ static int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx)
>  					ctx->dst_bufs[i].cookie.raw.chroma);
>  		writel(ctx->dst_bufs[i].cookie.raw.chroma,
>  				mfc_regs->d_second_plane_dpb + i * 4);
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> +			mfc_debug(2, "\tChroma_1 %d: %zx\n", i,
> +					ctx->dst_bufs[i].cookie.raw.chroma_1);
> +			writel(ctx->dst_bufs[i].cookie.raw.chroma_1,
> +					mfc_regs->d_third_plane_dpb + i * 4);
> +		}
>  	}
>  	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
>  			ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC ||
> @@ -683,20 +761,24 @@ static int s5p_mfc_set_enc_stream_buffer_v6(struct s5p_mfc_ctx *ctx,
>  }
>  
>  static void s5p_mfc_set_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
> -		unsigned long y_addr, unsigned long c_addr)
> +		unsigned long y_addr, unsigned long c_addr,
> +		unsigned long c_1_addr)
>  {
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  	const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs;
>  
>  	writel(y_addr, mfc_regs->e_source_first_plane_addr);
>  	writel(c_addr, mfc_regs->e_source_second_plane_addr);
> +	writel(c_1_addr, mfc_regs->e_source_third_plane_addr);
>  
>  	mfc_debug(2, "enc src y buf addr: 0x%08lx\n", y_addr);
>  	mfc_debug(2, "enc src c buf addr: 0x%08lx\n", c_addr);
> +	mfc_debug(2, "enc src cr buf addr: 0x%08lx\n", c_1_addr);
>  }
>  
>  static void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
> -		unsigned long *y_addr, unsigned long *c_addr)
> +		unsigned long *y_addr, unsigned long *c_addr,
> +		unsigned long *c_1_addr)
>  {
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  	const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs;
> @@ -704,12 +786,17 @@ static void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
>  
>  	*y_addr = readl(mfc_regs->e_encoded_source_first_plane_addr);
>  	*c_addr = readl(mfc_regs->e_encoded_source_second_plane_addr);
> +	if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +			ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +		*c_1_addr = readl(mfc_regs->e_encoded_source_third_plane_addr);
> +	else
> +		*c_1_addr = 0;
>  
>  	enc_recon_y_addr = readl(mfc_regs->e_recon_luma_dpb_addr);
>  	enc_recon_c_addr = readl(mfc_regs->e_recon_chroma_dpb_addr);
>  
>  	mfc_debug(2, "recon y addr: 0x%08lx y_addr: 0x%08lx\n", enc_recon_y_addr, *y_addr);
> -	mfc_debug(2, "recon c addr: 0x%08lx\n", enc_recon_c_addr);
> +	mfc_debug(2, "recon c addr: 0x%08lx c_addr: 0x%08lx\n", enc_recon_c_addr, *c_addr);
>  }
>  
>  /* Set encoding ref & codec buffer */
> @@ -886,6 +973,20 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
>  		writel(reg, mfc_regs->e_enc_options);
>  		/* 0: NV12(CbCr), 1: NV21(CrCb) */
>  		writel(0x0, mfc_regs->pixel_format);
> +	} else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> +		/* 0: Linear, 1: 2D tiled*/
> +		reg = readl(mfc_regs->e_enc_options);
> +		reg &= ~(0x1 << 7);
> +		writel(reg, mfc_regs->e_enc_options);
> +		/* 2: YV12(CrCb), 3: I420(CrCb) */
> +		writel(0x2, mfc_regs->pixel_format);
> +	} else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M) {
> +		/* 0: Linear, 1: 2D tiled*/
> +		reg = readl(mfc_regs->e_enc_options);
> +		reg &= ~(0x1 << 7);
> +		writel(reg, mfc_regs->e_enc_options);
> +		/* 2: YV12(CrCb), 3: I420(CrCb) */
> +		writel(0x3, mfc_regs->pixel_format);
>  	}
>  
>  	/* memory structure recon. frame */
> @@ -1696,8 +1797,12 @@ static int s5p_mfc_init_decode_v6(struct s5p_mfc_ctx *ctx)
>  	else
>  		writel(reg, mfc_regs->d_dec_options);
>  
> -	/* 0: NV12(CbCr), 1: NV21(CrCb) */
> -	if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV21M)
> +	/* 0: NV12(CbCr), 1: NV21(CrCb), 2: YV12(CrCb), 3: I420(CbCr) */
> +	if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M)
> +		writel(0x3, mfc_regs->pixel_format);
> +	else if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +		writel(0x2, mfc_regs->pixel_format);
> +	else if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV21M)
>  		writel(0x1, mfc_regs->pixel_format);
>  	else
>  		writel(0x0, mfc_regs->pixel_format);
> @@ -1781,8 +1886,12 @@ static int s5p_mfc_init_encode_v6(struct s5p_mfc_ctx *ctx)
>  
>  	/* Set stride lengths for v7 & above */
>  	if (IS_MFCV7_PLUS(dev)) {
> -		writel(ctx->img_width, mfc_regs->e_source_first_plane_stride);
> -		writel(ctx->img_width, mfc_regs->e_source_second_plane_stride);
> +		writel(ctx->stride[0], mfc_regs->e_source_first_plane_stride);
> +		writel(ctx->stride[1], mfc_regs->e_source_second_plane_stride);
> +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +			writel(ctx->stride[2],
> +					mfc_regs->e_source_third_plane_stride);
>  	}
>  
>  	writel(ctx->inst_no, mfc_regs->instance_id);
> @@ -1891,7 +2000,7 @@ static inline int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  	struct s5p_mfc_buf *dst_mb;
>  	struct s5p_mfc_buf *src_mb;
> -	unsigned long src_y_addr, src_c_addr, dst_addr;
> +	unsigned long src_y_addr, src_c_addr, src_c_1_addr, dst_addr;
>  	/*
>  	unsigned int src_y_size, src_c_size;
>  	*/
> @@ -1909,22 +2018,29 @@ static inline int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
>  
>  	if (list_empty(&ctx->src_queue)) {
>  		/* send null frame */
> -		s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0);
> +		s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0, 0);
>  		src_mb = NULL;
>  	} else {
>  		src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
>  		src_mb->flags |= MFC_BUF_FLAG_USED;
>  		if (src_mb->b->vb2_buf.planes[0].bytesused == 0) {
> -			s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0);
> +			s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0, 0);
>  			ctx->state = MFCINST_FINISHING;
>  		} else {
>  			src_y_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 0);
>  			src_c_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 1);
> +			if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +				src_c_1_addr = vb2_dma_contig_plane_dma_addr
> +						(&src_mb->b->vb2_buf, 2);
> +			else
> +				src_c_1_addr = 0;
>  
>  			mfc_debug(2, "enc src y addr: 0x%08lx\n", src_y_addr);
>  			mfc_debug(2, "enc src c addr: 0x%08lx\n", src_c_addr);
>  
> -			s5p_mfc_set_enc_frame_buffer_v6(ctx, src_y_addr, src_c_addr);
> +			s5p_mfc_set_enc_frame_buffer_v6(ctx, src_y_addr,
> +						src_c_addr, src_c_1_addr);
>  			if (src_mb->flags & MFC_BUF_FLAG_EOS)
>  				ctx->state = MFCINST_FINISHING;
>  		}
> @@ -2450,6 +2566,8 @@ const struct s5p_mfc_regs *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev)
>  			S5P_FIMV_E_ENCODED_SOURCE_FIRST_ADDR_V7);
>  	R(e_encoded_source_second_plane_addr,
>  			S5P_FIMV_E_ENCODED_SOURCE_SECOND_ADDR_V7);
> +	R(e_encoded_source_third_plane_addr,
> +			S5P_FIMV_E_ENCODED_SOURCE_THIRD_ADDR_V7);
>  	R(e_vp8_options, S5P_FIMV_E_VP8_OPTIONS_V7);
>  
>  	if (!IS_MFCV8_PLUS(dev))
> @@ -2464,16 +2582,20 @@ const struct s5p_mfc_regs *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev)
>  	R(d_cpb_buffer_offset, S5P_FIMV_D_CPB_BUFFER_OFFSET_V8);
>  	R(d_first_plane_dpb_size, S5P_FIMV_D_FIRST_PLANE_DPB_SIZE_V8);
>  	R(d_second_plane_dpb_size, S5P_FIMV_D_SECOND_PLANE_DPB_SIZE_V8);
> +	R(d_third_plane_dpb_size, S5P_FIMV_D_THIRD_PLANE_DPB_SIZE_V8);
>  	R(d_scratch_buffer_addr, S5P_FIMV_D_SCRATCH_BUFFER_ADDR_V8);
>  	R(d_scratch_buffer_size, S5P_FIMV_D_SCRATCH_BUFFER_SIZE_V8);
>  	R(d_first_plane_dpb_stride_size,
>  			S5P_FIMV_D_FIRST_PLANE_DPB_STRIDE_SIZE_V8);
>  	R(d_second_plane_dpb_stride_size,
>  			S5P_FIMV_D_SECOND_PLANE_DPB_STRIDE_SIZE_V8);
> +	R(d_third_plane_dpb_stride_size,
> +			S5P_FIMV_D_THIRD_PLANE_DPB_STRIDE_SIZE_V8);
>  	R(d_mv_buffer_size, S5P_FIMV_D_MV_BUFFER_SIZE_V8);
>  	R(d_num_mv, S5P_FIMV_D_NUM_MV_V8);
>  	R(d_first_plane_dpb, S5P_FIMV_D_FIRST_PLANE_DPB_V8);
>  	R(d_second_plane_dpb, S5P_FIMV_D_SECOND_PLANE_DPB_V8);
> +	R(d_third_plane_dpb, S5P_FIMV_D_THIRD_PLANE_DPB_V8);
>  	R(d_mv_buffer, S5P_FIMV_D_MV_BUFFER_V8);
>  	R(d_init_buffer_options, S5P_FIMV_D_INIT_BUFFER_OPTIONS_V8);
>  	R(d_available_dpb_flag_lower, S5P_FIMV_D_AVAILABLE_DPB_FLAG_LOWER_V8);


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

* Re: [Patch v4 04/11] media: s5p-mfc: Add YV12 and I420 multiplanar format support
@ 2023-11-23 17:25         ` Nicolas Dufresne
  0 siblings, 0 replies; 54+ messages in thread
From: Nicolas Dufresne @ 2023-11-23 17:25 UTC (permalink / raw)
  To: Aakarsh Jain, linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	linux-fsd, Smitha T Murthy

Le mercredi 25 octobre 2023 à 15:52 +0530, Aakarsh Jain a écrit :
> YV12 and I420 format (3-plane) support is added. Stride information is
> added to all formats and planes since it is necessary for YV12/I420
> which are different from width.
> 
> Cc: linux-fsd@tesla.com
> Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
> Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
> ---
>  .../platform/samsung/s5p-mfc/regs-mfc-v12.h   |   2 +
>  .../platform/samsung/s5p-mfc/regs-mfc-v7.h    |   1 +
>  .../platform/samsung/s5p-mfc/regs-mfc-v8.h    |   3 +
>  .../platform/samsung/s5p-mfc/s5p_mfc_common.h |   4 +
>  .../platform/samsung/s5p-mfc/s5p_mfc_dec.c    |  45 ++++-
>  .../platform/samsung/s5p-mfc/s5p_mfc_enc.c    |  86 +++++++--
>  .../platform/samsung/s5p-mfc/s5p_mfc_opr.h    |   6 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c |  12 +-
>  .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 168 +++++++++++++++---
>  9 files changed, 281 insertions(+), 46 deletions(-)
> 
> diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> index 6c68a45082d0..70464f47c1f9 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> @@ -26,6 +26,8 @@
>  #define MFC_VERSION_V12			0xC0
>  #define MFC_NUM_PORTS_V12		1
>  #define S5P_FIMV_CODEC_VP9_ENC		27
> +#define MFC_CHROMA_PAD_BYTES_V12        256
> +#define S5P_FIMV_D_ALIGN_PLANE_SIZE_V12 256
>  
>  /* Encoder buffer size for MFCv12 */
>  #define ENC_V120_BASE_SIZE(x, y) \
> diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
> index 4a7adfdaa359..50f9bf0603c1 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
> @@ -24,6 +24,7 @@
>  
>  #define S5P_FIMV_E_ENCODED_SOURCE_FIRST_ADDR_V7		0xfa70
>  #define S5P_FIMV_E_ENCODED_SOURCE_SECOND_ADDR_V7	0xfa74
> +#define S5P_FIMV_E_ENCODED_SOURCE_THIRD_ADDR_V7		0xfa78
>  
>  #define S5P_FIMV_E_VP8_OPTIONS_V7			0xfdb0
>  #define S5P_FIMV_E_VP8_FILTER_OPTIONS_V7		0xfdb4
> diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
> index 162e3c7e920f..0ef9eb2dff22 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
> @@ -17,13 +17,16 @@
>  #define S5P_FIMV_D_MIN_SCRATCH_BUFFER_SIZE_V8	0xf108
>  #define S5P_FIMV_D_FIRST_PLANE_DPB_SIZE_V8	0xf144
>  #define S5P_FIMV_D_SECOND_PLANE_DPB_SIZE_V8	0xf148
> +#define S5P_FIMV_D_THIRD_PLANE_DPB_SIZE_V8	0xf14C
>  #define S5P_FIMV_D_MV_BUFFER_SIZE_V8		0xf150
>  
>  #define S5P_FIMV_D_FIRST_PLANE_DPB_STRIDE_SIZE_V8	0xf138
>  #define S5P_FIMV_D_SECOND_PLANE_DPB_STRIDE_SIZE_V8	0xf13c
> +#define S5P_FIMV_D_THIRD_PLANE_DPB_STRIDE_SIZE_V8	0xf140
>  
>  #define S5P_FIMV_D_FIRST_PLANE_DPB_V8		0xf160
>  #define S5P_FIMV_D_SECOND_PLANE_DPB_V8		0xf260
> +#define S5P_FIMV_D_THIRD_PLANE_DPB_V8		0xf360
>  #define S5P_FIMV_D_MV_BUFFER_V8			0xf460
>  
>  #define S5P_FIMV_D_NUM_MV_V8			0xf134
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> index dd2e9f7704ab..9a39cccfe002 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> @@ -56,6 +56,7 @@
>  #define MFC_NO_INSTANCE_SET	-1
>  #define MFC_ENC_CAP_PLANE_COUNT	1
>  #define MFC_ENC_OUT_PLANE_COUNT	2
> +#define VB2_MAX_PLANE_COUNT	3
>  #define STUFF_BYTE		4
>  #define MFC_MAX_CTRLS		128
>  
> @@ -181,6 +182,7 @@ struct s5p_mfc_buf {
>  		struct {
>  			size_t luma;
>  			size_t chroma;
> +			size_t chroma_1;
>  		} raw;
>  		size_t stream;
>  	} cookie;
> @@ -657,6 +659,7 @@ struct s5p_mfc_ctx {
>  
>  	int luma_size;
>  	int chroma_size;
> +	int chroma_size_1;
>  	int mv_size;
>  
>  	unsigned long consumed_stream;
> @@ -722,6 +725,7 @@ struct s5p_mfc_ctx {
>  	size_t scratch_buf_size;
>  	int is_10bit;
>  	int is_422;
> +	int stride[VB2_MAX_PLANE_COUNT];
>  };
>  
>  /*
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> index e219cbcd86d5..317f796fffa1 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> @@ -56,6 +56,20 @@ static struct s5p_mfc_fmt formats[] = {
>  		.num_planes	= 2,
>  		.versions	= MFC_V6PLUS_BITS,
>  	},
> +	{
> +		.fourcc         = V4L2_PIX_FMT_YUV420M,
> +		.codec_mode     = S5P_MFC_CODEC_NONE,
> +		.type           = MFC_FMT_RAW,
> +		.num_planes     = 3,
> +		.versions       = MFC_V12_BIT,
> +	},
> +	{
> +		.fourcc         = V4L2_PIX_FMT_YVU420M,
> +		.codec_mode     = S5P_MFC_CODEC_NONE,
> +		.type           = MFC_FMT_RAW,
> +		.num_planes     = 3,
> +		.versions       = MFC_V12_BIT
> +	},
>  	{
>  		.fourcc		= V4L2_PIX_FMT_H264,
>  		.codec_mode	= S5P_MFC_CODEC_H264_DEC,
> @@ -359,10 +373,15 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
>  		/* Set pixelformat to the format in which MFC
>  		   outputs the decoded frame */
>  		pix_mp->pixelformat = ctx->dst_fmt->fourcc;
> -		pix_mp->plane_fmt[0].bytesperline = ctx->buf_width;
> +		pix_mp->plane_fmt[0].bytesperline = ctx->stride[0];
>  		pix_mp->plane_fmt[0].sizeimage = ctx->luma_size;
> -		pix_mp->plane_fmt[1].bytesperline = ctx->buf_width;
> +		pix_mp->plane_fmt[1].bytesperline = ctx->stride[1];
>  		pix_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> +			pix_mp->plane_fmt[2].bytesperline = ctx->stride[2];
> +			pix_mp->plane_fmt[2].sizeimage = ctx->chroma_size_1;
> +		}
>  	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
>  		/* This is run on OUTPUT
>  		   The buffer contains compressed image
> @@ -937,6 +956,9 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
>  		   vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
>  		/* Output plane count is 2 - one for Y and one for CbCr */
>  		*plane_count = 2;
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +			*plane_count = 3;

I don't usually interfere, this is your driver to maintain, but this becomes
horribly messy. Have you consider de-hardcoding a little and encapsulate per HW
format details into a C structure ? Drivers these days try to make sure of v4l2-
common library, which as a matter of fact knows that YUV420M and YVU420M have 3
places, so that you don't have to duplicate it in your driver.

regards,
Nicolas

>  		/* Setup buffer count */
>  		if (*buf_count < ctx->pb_count)
>  			*buf_count = ctx->pb_count;
> @@ -955,12 +977,17 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
>  	    vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
>  		psize[0] = ctx->luma_size;
>  		psize[1] = ctx->chroma_size;
> -
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +			psize[2] = ctx->chroma_size_1;
>  		if (IS_MFCV6_PLUS(dev))
>  			alloc_devs[0] = ctx->dev->mem_dev[BANK_L_CTX];
>  		else
>  			alloc_devs[0] = ctx->dev->mem_dev[BANK_R_CTX];
>  		alloc_devs[1] = ctx->dev->mem_dev[BANK_L_CTX];
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +			alloc_devs[2] = ctx->dev->mem_dev[BANK_L_CTX];
>  	} else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
>  		   ctx->state == MFCINST_INIT) {
>  		psize[0] = ctx->dec_src_buf_size;
> @@ -994,12 +1021,24 @@ static int s5p_mfc_buf_init(struct vb2_buffer *vb)
>  			mfc_err("Plane buffer (CAPTURE) is too small\n");
>  			return -EINVAL;
>  		}
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> +			if (vb2_plane_size(vb, 2) < ctx->chroma_size_1) {
> +				mfc_err("Plane buffer (CAPTURE) is too small\n");
> +				return -EINVAL;
> +			}
> +		}
>  		i = vb->index;
>  		ctx->dst_bufs[i].b = vbuf;
>  		ctx->dst_bufs[i].cookie.raw.luma =
>  					vb2_dma_contig_plane_dma_addr(vb, 0);
>  		ctx->dst_bufs[i].cookie.raw.chroma =
>  					vb2_dma_contig_plane_dma_addr(vb, 1);
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> +			ctx->dst_bufs[i].cookie.raw.chroma_1 =
> +					vb2_dma_contig_plane_dma_addr(vb, 2);
> +		}
>  		ctx->dst_bufs_cnt++;
>  	} else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
>  		if (IS_ERR_OR_NULL(ERR_PTR(
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> index e4d6e7c117b5..0eec04eb3ef3 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> @@ -59,6 +59,20 @@ static struct s5p_mfc_fmt formats[] = {
>  		.num_planes	= 2,
>  		.versions	= MFC_V6PLUS_BITS,
>  	},
> +	{
> +		.fourcc         = V4L2_PIX_FMT_YUV420M,
> +		.codec_mode     = S5P_MFC_CODEC_NONE,
> +		.type           = MFC_FMT_RAW,
> +		.num_planes     = 3,
> +		.versions       = MFC_V12_BIT,
> +	},
> +	{
> +		.fourcc         = V4L2_PIX_FMT_YVU420M,
> +		.codec_mode     = S5P_MFC_CODEC_NONE,
> +		.type           = MFC_FMT_RAW,
> +		.num_planes     = 3,
> +		.versions       = MFC_V12_BIT,
> +	},
>  	{
>  		.fourcc		= V4L2_PIX_FMT_H264,
>  		.codec_mode	= S5P_MFC_CODEC_H264_ENC,
> @@ -1193,14 +1207,20 @@ static int enc_pre_frame_start(struct s5p_mfc_ctx *ctx)
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  	struct s5p_mfc_buf *dst_mb;
>  	struct s5p_mfc_buf *src_mb;
> -	unsigned long src_y_addr, src_c_addr, dst_addr;
> +	unsigned long src_y_addr, src_c_addr, src_c_1_addr, dst_addr;
>  	unsigned int dst_size;
>  
>  	src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
>  	src_y_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 0);
>  	src_c_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 1);
> +	if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +			ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +		src_c_1_addr =
> +			vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 2);
> +	else
> +		src_c_1_addr = 0;
>  	s5p_mfc_hw_call(dev->mfc_ops, set_enc_frame_buffer, ctx,
> -							src_y_addr, src_c_addr);
> +					src_y_addr, src_c_addr, src_c_1_addr);
>  
>  	dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
>  	dst_addr = vb2_dma_contig_plane_dma_addr(&dst_mb->b->vb2_buf, 0);
> @@ -1215,8 +1235,8 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
>  {
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  	struct s5p_mfc_buf *mb_entry;
> -	unsigned long enc_y_addr = 0, enc_c_addr = 0;
> -	unsigned long mb_y_addr, mb_c_addr;
> +	unsigned long enc_y_addr = 0, enc_c_addr = 0, enc_c_1_addr = 0;
> +	unsigned long mb_y_addr, mb_c_addr, mb_c_1_addr;
>  	int slice_type;
>  	unsigned int strm_size;
>  	bool src_ready;
> @@ -1229,14 +1249,21 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
>  		  mfc_read(dev, S5P_FIMV_ENC_SI_PIC_CNT));
>  	if (slice_type >= 0) {
>  		s5p_mfc_hw_call(dev->mfc_ops, get_enc_frame_buffer, ctx,
> -				&enc_y_addr, &enc_c_addr);
> +				&enc_y_addr, &enc_c_addr, &enc_c_1_addr);
>  		list_for_each_entry(mb_entry, &ctx->src_queue, list) {
>  			mb_y_addr = vb2_dma_contig_plane_dma_addr(
>  					&mb_entry->b->vb2_buf, 0);
>  			mb_c_addr = vb2_dma_contig_plane_dma_addr(
>  					&mb_entry->b->vb2_buf, 1);
> -			if ((enc_y_addr == mb_y_addr) &&
> -						(enc_c_addr == mb_c_addr)) {
> +			if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +				mb_c_1_addr = vb2_dma_contig_plane_dma_addr
> +						(&mb_entry->b->vb2_buf, 2);
> +			else
> +				mb_c_1_addr = 0;
> +			if ((enc_y_addr == mb_y_addr)
> +					&& (enc_c_addr == mb_c_addr)
> +					&& (enc_c_1_addr == mb_c_1_addr)) {
>  				list_del(&mb_entry->list);
>  				ctx->src_queue_cnt--;
>  				vb2_buffer_done(&mb_entry->b->vb2_buf,
> @@ -1249,8 +1276,15 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
>  					&mb_entry->b->vb2_buf, 0);
>  			mb_c_addr = vb2_dma_contig_plane_dma_addr(
>  					&mb_entry->b->vb2_buf, 1);
> -			if ((enc_y_addr == mb_y_addr) &&
> -						(enc_c_addr == mb_c_addr)) {
> +			if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +				mb_c_1_addr = vb2_dma_contig_plane_dma_addr(
> +						&mb_entry->b->vb2_buf, 2);
> +			else
> +				mb_c_1_addr = 0;
> +			if ((enc_y_addr == mb_y_addr)
> +					&& (enc_c_addr == mb_c_addr)
> +					&& (enc_c_1_addr == mb_c_1_addr)) {
>  				list_del(&mb_entry->list);
>  				ctx->ref_queue_cnt--;
>  				vb2_buffer_done(&mb_entry->b->vb2_buf,
> @@ -1381,10 +1415,15 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
>  		pix_fmt_mp->pixelformat = ctx->src_fmt->fourcc;
>  		pix_fmt_mp->num_planes = ctx->src_fmt->num_planes;
>  
> -		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
> +		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->stride[0];
>  		pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
> -		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
> +		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->stride[1];
>  		pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
> +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> +			pix_fmt_mp->plane_fmt[2].bytesperline = ctx->stride[2];
> +			pix_fmt_mp->plane_fmt[2].sizeimage = ctx->chroma_size_1;
> +		}
>  	} else {
>  		mfc_err("invalid buf type\n");
>  		return -EINVAL;
> @@ -1468,9 +1507,14 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
>  
>  		s5p_mfc_hw_call(dev->mfc_ops, enc_calc_src_size, ctx);
>  		pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
> -		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
> +		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->stride[0];
>  		pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
> -		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
> +		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->stride[1];
> +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> +			pix_fmt_mp->plane_fmt[2].bytesperline = ctx->stride[2];
> +			pix_fmt_mp->plane_fmt[2].sizeimage = ctx->chroma_size_1;
> +		}
>  
>  		ctx->src_bufs_cnt = 0;
>  		ctx->output_state = QUEUE_FREE;
> @@ -2414,10 +2458,16 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
>  
>  		psize[0] = ctx->luma_size;
>  		psize[1] = ctx->chroma_size;
> +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +			psize[2] = ctx->chroma_size_1;
>  
>  		if (IS_MFCV6_PLUS(dev)) {
>  			alloc_devs[0] = ctx->dev->mem_dev[BANK_L_CTX];
>  			alloc_devs[1] = ctx->dev->mem_dev[BANK_L_CTX];
> +			if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +				alloc_devs[2] = ctx->dev->mem_dev[BANK_L_CTX];
>  		} else {
>  			alloc_devs[0] = ctx->dev->mem_dev[BANK_R_CTX];
>  			alloc_devs[1] = ctx->dev->mem_dev[BANK_R_CTX];
> @@ -2456,6 +2506,10 @@ static int s5p_mfc_buf_init(struct vb2_buffer *vb)
>  					vb2_dma_contig_plane_dma_addr(vb, 0);
>  		ctx->src_bufs[i].cookie.raw.chroma =
>  					vb2_dma_contig_plane_dma_addr(vb, 1);
> +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +			ctx->src_bufs[i].cookie.raw.chroma_1 =
> +					vb2_dma_contig_plane_dma_addr(vb, 2);
>  		ctx->src_bufs_cnt++;
>  	} else {
>  		mfc_err("invalid queue type: %d\n", vq->type);
> @@ -2493,6 +2547,12 @@ static int s5p_mfc_buf_prepare(struct vb2_buffer *vb)
>  			mfc_err("plane size is too small for output\n");
>  			return -EINVAL;
>  		}
> +		if ((ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +		     ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) &&
> +		    (vb2_plane_size(vb, 2) < ctx->chroma_size_1)) {
> +			mfc_err("plane size is too small for output\n");
> +			return -EINVAL;
> +		}
>  	} else {
>  		mfc_err("invalid queue type: %d\n", vq->type);
>  		return -EINVAL;
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> index 87ac56756a16..7c5e851c8191 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> @@ -293,9 +293,11 @@ struct s5p_mfc_hw_ops {
>  	int (*set_enc_stream_buffer)(struct s5p_mfc_ctx *ctx,
>  			unsigned long addr, unsigned int size);
>  	void (*set_enc_frame_buffer)(struct s5p_mfc_ctx *ctx,
> -			unsigned long y_addr, unsigned long c_addr);
> +			unsigned long y_addr, unsigned long c_addr,
> +			unsigned long c_1_addr);
>  	void (*get_enc_frame_buffer)(struct s5p_mfc_ctx *ctx,
> -			unsigned long *y_addr, unsigned long *c_addr);
> +			unsigned long *y_addr, unsigned long *c_addr,
> +			unsigned long *c_1_addr);
>  	void (*try_run)(struct s5p_mfc_dev *dev);
>  	void (*clear_int_flags)(struct s5p_mfc_dev *dev);
>  	int (*get_dspl_y_adr)(struct s5p_mfc_dev *dev);
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
> index 28a06dc343fd..fcfaf125a5a1 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
> @@ -516,7 +516,8 @@ static int s5p_mfc_set_enc_stream_buffer_v5(struct s5p_mfc_ctx *ctx,
>  }
>  
>  static void s5p_mfc_set_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,
> -		unsigned long y_addr, unsigned long c_addr)
> +		unsigned long y_addr, unsigned long c_addr,
> +		unsigned long c_1_addr)
>  {
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  
> @@ -525,7 +526,8 @@ static void s5p_mfc_set_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,
>  }
>  
>  static void s5p_mfc_get_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,
> -		unsigned long *y_addr, unsigned long *c_addr)
> +		unsigned long *y_addr, unsigned long *c_addr,
> +		unsigned long *c_1_addr)
>  {
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  
> @@ -1210,7 +1212,7 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
>  	if (list_empty(&ctx->src_queue)) {
>  		/* send null frame */
>  		s5p_mfc_set_enc_frame_buffer_v5(ctx, dev->dma_base[BANK_R_CTX],
> -						dev->dma_base[BANK_R_CTX]);
> +						dev->dma_base[BANK_R_CTX], 0);
>  		src_mb = NULL;
>  	} else {
>  		src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf,
> @@ -1220,7 +1222,7 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
>  			/* send null frame */
>  			s5p_mfc_set_enc_frame_buffer_v5(ctx,
>  						dev->dma_base[BANK_R_CTX],
> -						dev->dma_base[BANK_R_CTX]);
> +						dev->dma_base[BANK_R_CTX], 0);
>  			ctx->state = MFCINST_FINISHING;
>  		} else {
>  			src_y_addr = vb2_dma_contig_plane_dma_addr(
> @@ -1228,7 +1230,7 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
>  			src_c_addr = vb2_dma_contig_plane_dma_addr(
>  					&src_mb->b->vb2_buf, 1);
>  			s5p_mfc_set_enc_frame_buffer_v5(ctx, src_y_addr,
> -								src_c_addr);
> +								src_c_addr, 0);
>  			if (src_mb->flags & MFC_BUF_FLAG_EOS)
>  				ctx->state = MFCINST_FINISHING;
>  		}
> diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> index fb3f0718821d..e579c765e902 100644
> --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> @@ -494,16 +494,43 @@ static void s5p_mfc_dec_calc_dpb_size_v6(struct s5p_mfc_ctx *ctx)
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  	ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN_V6);
>  	ctx->buf_height = ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN_V6);
> +	ctx->chroma_size_1 = 0;
>  	mfc_debug(2, "SEQ Done: Movie dimensions %dx%d,\n"
>  			"buffer dimensions: %dx%d\n", ctx->img_width,
>  			ctx->img_height, ctx->buf_width, ctx->buf_height);
>  
> -	ctx->luma_size = calc_plane(ctx->img_width, ctx->img_height);
> -	ctx->chroma_size = calc_plane(ctx->img_width, (ctx->img_height >> 1));
> +	switch (ctx->dst_fmt->fourcc) {
> +	case V4L2_PIX_FMT_NV12M:
> +	case V4L2_PIX_FMT_NV21M:
> +		ctx->stride[0] = ALIGN(ctx->img_width,
> +					S5P_FIMV_NV12MT_HALIGN_V6);
> +		ctx->stride[1] = ALIGN(ctx->img_width,
> +					S5P_FIMV_NV12MT_HALIGN_V6);
> +		ctx->luma_size = calc_plane(ctx->stride[0], ctx->img_height);
> +		ctx->chroma_size = calc_plane(ctx->stride[1],
> +					(ctx->img_height / 2));
> +		break;
> +	case V4L2_PIX_FMT_YUV420M:
> +	case V4L2_PIX_FMT_YVU420M:
> +		ctx->stride[0] = ALIGN(ctx->img_width,
> +					S5P_FIMV_NV12MT_HALIGN_V6);
> +		ctx->stride[1] = ALIGN(ctx->img_width / 2,
> +					S5P_FIMV_NV12MT_HALIGN_V6);
> +		ctx->stride[2] = ALIGN(ctx->img_width / 2,
> +					S5P_FIMV_NV12MT_HALIGN_V6);
> +		ctx->luma_size = calc_plane(ctx->stride[0], ctx->img_height);
> +		ctx->chroma_size = calc_plane(ctx->stride[1],
> +					(ctx->img_height / 2));
> +		ctx->chroma_size_1 = calc_plane(ctx->stride[2],
> +					(ctx->img_height / 2));
> +		break;
> +	}
> +
>  	if (IS_MFCV8_PLUS(ctx->dev)) {
>  		/* MFCv8 needs additional 64 bytes for luma,chroma dpb*/
>  		ctx->luma_size += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8;
>  		ctx->chroma_size += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8;
> +		ctx->chroma_size_1 += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8;
>  	}
>  
>  	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
> @@ -534,15 +561,53 @@ static void s5p_mfc_enc_calc_src_size_v6(struct s5p_mfc_ctx *ctx)
>  	mb_width = MB_WIDTH(ctx->img_width);
>  	mb_height = MB_HEIGHT(ctx->img_height);
>  
> -	ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN_V6);
> -	ctx->luma_size = ALIGN((mb_width * mb_height) * 256, 256);
> -	ctx->chroma_size = ALIGN((mb_width * mb_height) * 128, 256);
> -
> -	/* MFCv7 needs pad bytes for Luma and Chroma */
> -	if (IS_MFCV7_PLUS(ctx->dev)) {
> +	if (IS_MFCV12(ctx->dev)) {
> +		switch (ctx->src_fmt->fourcc) {
> +		case V4L2_PIX_FMT_NV12M:
> +		case V4L2_PIX_FMT_NV21M:
> +			ctx->stride[0] = ALIGN(ctx->img_width,
> +						S5P_FIMV_NV12M_HALIGN_V6);
> +			ctx->stride[1] = ALIGN(ctx->img_width,
> +						S5P_FIMV_NV12M_HALIGN_V6);
> +			ctx->luma_size = ctx->stride[0] *
> +						ALIGN(ctx->img_height, 16);
> +			ctx->chroma_size =  ctx->stride[0] *
> +						ALIGN(ctx->img_height / 2, 16);
> +			break;
> +		case V4L2_PIX_FMT_YUV420M:
> +		case V4L2_PIX_FMT_YVU420M:
> +			ctx->stride[0] = ALIGN(ctx->img_width,
> +						S5P_FIMV_NV12M_HALIGN_V6);
> +			ctx->stride[1] = ALIGN(ctx->img_width / 2,
> +						S5P_FIMV_NV12M_HALIGN_V6);
> +			ctx->stride[2] = ALIGN(ctx->img_width / 2,
> +						S5P_FIMV_NV12M_HALIGN_V6);
> +			ctx->luma_size = ctx->stride[0] *
> +						ALIGN(ctx->img_height, 16);
> +			ctx->chroma_size =  ctx->stride[1] *
> +						ALIGN(ctx->img_height / 2, 16);
> +			ctx->chroma_size_1 =  ctx->stride[2] *
> +						ALIGN(ctx->img_height / 2, 16);
> +			break;
> +		}
>  		ctx->luma_size += MFC_LUMA_PAD_BYTES_V7;
> -		ctx->chroma_size += MFC_CHROMA_PAD_BYTES_V7;
> +		ctx->chroma_size += MFC_CHROMA_PAD_BYTES_V12;
> +		ctx->chroma_size_1 += MFC_CHROMA_PAD_BYTES_V12;
> +	} else {
> +		ctx->buf_width = ALIGN(ctx->img_width,
> +					S5P_FIMV_NV12M_HALIGN_V6);
> +		ctx->stride[0] = ctx->buf_width;
> +		ctx->stride[1] = ctx->buf_width;
> +		ctx->luma_size = ALIGN((mb_width * mb_height) * 256, 256);
> +		ctx->chroma_size = ALIGN((mb_width * mb_height) * 128, 256);
> +		ctx->chroma_size_1 = 0;
> +		/* MFCv7 needs pad bytes for Luma and Chroma */
> +		if (IS_MFCV7_PLUS(ctx->dev)) {
> +			ctx->luma_size += MFC_LUMA_PAD_BYTES_V7;
> +			ctx->chroma_size += MFC_LUMA_PAD_BYTES_V7;
> +		}
>  	}
> +
>  }
>  
>  /* Set registers for decoding stream buffer */
> @@ -588,15 +653,21 @@ static int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx)
>  	writel(ctx->total_dpb_count, mfc_regs->d_num_dpb);
>  	writel(ctx->luma_size, mfc_regs->d_first_plane_dpb_size);
>  	writel(ctx->chroma_size, mfc_regs->d_second_plane_dpb_size);
> -
> +	if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +			ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +		writel(ctx->chroma_size_1, mfc_regs->d_third_plane_dpb_size);
>  	writel(buf_addr1, mfc_regs->d_scratch_buffer_addr);
>  	writel(ctx->scratch_buf_size, mfc_regs->d_scratch_buffer_size);
>  
>  	if (IS_MFCV8_PLUS(dev)) {
> -		writel(ctx->img_width,
> +		writel(ctx->stride[0],
>  			mfc_regs->d_first_plane_dpb_stride_size);
> -		writel(ctx->img_width,
> +		writel(ctx->stride[1],
>  			mfc_regs->d_second_plane_dpb_stride_size);
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +			writel(ctx->stride[2],
> +				mfc_regs->d_third_plane_dpb_stride_size);
>  	}
>  
>  	buf_addr1 += ctx->scratch_buf_size;
> @@ -625,6 +696,13 @@ static int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx)
>  					ctx->dst_bufs[i].cookie.raw.chroma);
>  		writel(ctx->dst_bufs[i].cookie.raw.chroma,
>  				mfc_regs->d_second_plane_dpb + i * 4);
> +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> +			mfc_debug(2, "\tChroma_1 %d: %zx\n", i,
> +					ctx->dst_bufs[i].cookie.raw.chroma_1);
> +			writel(ctx->dst_bufs[i].cookie.raw.chroma_1,
> +					mfc_regs->d_third_plane_dpb + i * 4);
> +		}
>  	}
>  	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
>  			ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC ||
> @@ -683,20 +761,24 @@ static int s5p_mfc_set_enc_stream_buffer_v6(struct s5p_mfc_ctx *ctx,
>  }
>  
>  static void s5p_mfc_set_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
> -		unsigned long y_addr, unsigned long c_addr)
> +		unsigned long y_addr, unsigned long c_addr,
> +		unsigned long c_1_addr)
>  {
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  	const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs;
>  
>  	writel(y_addr, mfc_regs->e_source_first_plane_addr);
>  	writel(c_addr, mfc_regs->e_source_second_plane_addr);
> +	writel(c_1_addr, mfc_regs->e_source_third_plane_addr);
>  
>  	mfc_debug(2, "enc src y buf addr: 0x%08lx\n", y_addr);
>  	mfc_debug(2, "enc src c buf addr: 0x%08lx\n", c_addr);
> +	mfc_debug(2, "enc src cr buf addr: 0x%08lx\n", c_1_addr);
>  }
>  
>  static void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
> -		unsigned long *y_addr, unsigned long *c_addr)
> +		unsigned long *y_addr, unsigned long *c_addr,
> +		unsigned long *c_1_addr)
>  {
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  	const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs;
> @@ -704,12 +786,17 @@ static void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
>  
>  	*y_addr = readl(mfc_regs->e_encoded_source_first_plane_addr);
>  	*c_addr = readl(mfc_regs->e_encoded_source_second_plane_addr);
> +	if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +			ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +		*c_1_addr = readl(mfc_regs->e_encoded_source_third_plane_addr);
> +	else
> +		*c_1_addr = 0;
>  
>  	enc_recon_y_addr = readl(mfc_regs->e_recon_luma_dpb_addr);
>  	enc_recon_c_addr = readl(mfc_regs->e_recon_chroma_dpb_addr);
>  
>  	mfc_debug(2, "recon y addr: 0x%08lx y_addr: 0x%08lx\n", enc_recon_y_addr, *y_addr);
> -	mfc_debug(2, "recon c addr: 0x%08lx\n", enc_recon_c_addr);
> +	mfc_debug(2, "recon c addr: 0x%08lx c_addr: 0x%08lx\n", enc_recon_c_addr, *c_addr);
>  }
>  
>  /* Set encoding ref & codec buffer */
> @@ -886,6 +973,20 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
>  		writel(reg, mfc_regs->e_enc_options);
>  		/* 0: NV12(CbCr), 1: NV21(CrCb) */
>  		writel(0x0, mfc_regs->pixel_format);
> +	} else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> +		/* 0: Linear, 1: 2D tiled*/
> +		reg = readl(mfc_regs->e_enc_options);
> +		reg &= ~(0x1 << 7);
> +		writel(reg, mfc_regs->e_enc_options);
> +		/* 2: YV12(CrCb), 3: I420(CrCb) */
> +		writel(0x2, mfc_regs->pixel_format);
> +	} else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M) {
> +		/* 0: Linear, 1: 2D tiled*/
> +		reg = readl(mfc_regs->e_enc_options);
> +		reg &= ~(0x1 << 7);
> +		writel(reg, mfc_regs->e_enc_options);
> +		/* 2: YV12(CrCb), 3: I420(CrCb) */
> +		writel(0x3, mfc_regs->pixel_format);
>  	}
>  
>  	/* memory structure recon. frame */
> @@ -1696,8 +1797,12 @@ static int s5p_mfc_init_decode_v6(struct s5p_mfc_ctx *ctx)
>  	else
>  		writel(reg, mfc_regs->d_dec_options);
>  
> -	/* 0: NV12(CbCr), 1: NV21(CrCb) */
> -	if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV21M)
> +	/* 0: NV12(CbCr), 1: NV21(CrCb), 2: YV12(CrCb), 3: I420(CbCr) */
> +	if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M)
> +		writel(0x3, mfc_regs->pixel_format);
> +	else if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +		writel(0x2, mfc_regs->pixel_format);
> +	else if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV21M)
>  		writel(0x1, mfc_regs->pixel_format);
>  	else
>  		writel(0x0, mfc_regs->pixel_format);
> @@ -1781,8 +1886,12 @@ static int s5p_mfc_init_encode_v6(struct s5p_mfc_ctx *ctx)
>  
>  	/* Set stride lengths for v7 & above */
>  	if (IS_MFCV7_PLUS(dev)) {
> -		writel(ctx->img_width, mfc_regs->e_source_first_plane_stride);
> -		writel(ctx->img_width, mfc_regs->e_source_second_plane_stride);
> +		writel(ctx->stride[0], mfc_regs->e_source_first_plane_stride);
> +		writel(ctx->stride[1], mfc_regs->e_source_second_plane_stride);
> +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +			writel(ctx->stride[2],
> +					mfc_regs->e_source_third_plane_stride);
>  	}
>  
>  	writel(ctx->inst_no, mfc_regs->instance_id);
> @@ -1891,7 +2000,7 @@ static inline int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
>  	struct s5p_mfc_dev *dev = ctx->dev;
>  	struct s5p_mfc_buf *dst_mb;
>  	struct s5p_mfc_buf *src_mb;
> -	unsigned long src_y_addr, src_c_addr, dst_addr;
> +	unsigned long src_y_addr, src_c_addr, src_c_1_addr, dst_addr;
>  	/*
>  	unsigned int src_y_size, src_c_size;
>  	*/
> @@ -1909,22 +2018,29 @@ static inline int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
>  
>  	if (list_empty(&ctx->src_queue)) {
>  		/* send null frame */
> -		s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0);
> +		s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0, 0);
>  		src_mb = NULL;
>  	} else {
>  		src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
>  		src_mb->flags |= MFC_BUF_FLAG_USED;
>  		if (src_mb->b->vb2_buf.planes[0].bytesused == 0) {
> -			s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0);
> +			s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0, 0);
>  			ctx->state = MFCINST_FINISHING;
>  		} else {
>  			src_y_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 0);
>  			src_c_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 1);
> +			if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> +				ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> +				src_c_1_addr = vb2_dma_contig_plane_dma_addr
> +						(&src_mb->b->vb2_buf, 2);
> +			else
> +				src_c_1_addr = 0;
>  
>  			mfc_debug(2, "enc src y addr: 0x%08lx\n", src_y_addr);
>  			mfc_debug(2, "enc src c addr: 0x%08lx\n", src_c_addr);
>  
> -			s5p_mfc_set_enc_frame_buffer_v6(ctx, src_y_addr, src_c_addr);
> +			s5p_mfc_set_enc_frame_buffer_v6(ctx, src_y_addr,
> +						src_c_addr, src_c_1_addr);
>  			if (src_mb->flags & MFC_BUF_FLAG_EOS)
>  				ctx->state = MFCINST_FINISHING;
>  		}
> @@ -2450,6 +2566,8 @@ const struct s5p_mfc_regs *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev)
>  			S5P_FIMV_E_ENCODED_SOURCE_FIRST_ADDR_V7);
>  	R(e_encoded_source_second_plane_addr,
>  			S5P_FIMV_E_ENCODED_SOURCE_SECOND_ADDR_V7);
> +	R(e_encoded_source_third_plane_addr,
> +			S5P_FIMV_E_ENCODED_SOURCE_THIRD_ADDR_V7);
>  	R(e_vp8_options, S5P_FIMV_E_VP8_OPTIONS_V7);
>  
>  	if (!IS_MFCV8_PLUS(dev))
> @@ -2464,16 +2582,20 @@ const struct s5p_mfc_regs *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev)
>  	R(d_cpb_buffer_offset, S5P_FIMV_D_CPB_BUFFER_OFFSET_V8);
>  	R(d_first_plane_dpb_size, S5P_FIMV_D_FIRST_PLANE_DPB_SIZE_V8);
>  	R(d_second_plane_dpb_size, S5P_FIMV_D_SECOND_PLANE_DPB_SIZE_V8);
> +	R(d_third_plane_dpb_size, S5P_FIMV_D_THIRD_PLANE_DPB_SIZE_V8);
>  	R(d_scratch_buffer_addr, S5P_FIMV_D_SCRATCH_BUFFER_ADDR_V8);
>  	R(d_scratch_buffer_size, S5P_FIMV_D_SCRATCH_BUFFER_SIZE_V8);
>  	R(d_first_plane_dpb_stride_size,
>  			S5P_FIMV_D_FIRST_PLANE_DPB_STRIDE_SIZE_V8);
>  	R(d_second_plane_dpb_stride_size,
>  			S5P_FIMV_D_SECOND_PLANE_DPB_STRIDE_SIZE_V8);
> +	R(d_third_plane_dpb_stride_size,
> +			S5P_FIMV_D_THIRD_PLANE_DPB_STRIDE_SIZE_V8);
>  	R(d_mv_buffer_size, S5P_FIMV_D_MV_BUFFER_SIZE_V8);
>  	R(d_num_mv, S5P_FIMV_D_NUM_MV_V8);
>  	R(d_first_plane_dpb, S5P_FIMV_D_FIRST_PLANE_DPB_V8);
>  	R(d_second_plane_dpb, S5P_FIMV_D_SECOND_PLANE_DPB_V8);
> +	R(d_third_plane_dpb, S5P_FIMV_D_THIRD_PLANE_DPB_V8);
>  	R(d_mv_buffer, S5P_FIMV_D_MV_BUFFER_V8);
>  	R(d_init_buffer_options, S5P_FIMV_D_INIT_BUFFER_OPTIONS_V8);
>  	R(d_available_dpb_flag_lower, S5P_FIMV_D_AVAILABLE_DPB_FLAG_LOWER_V8);


_______________________________________________
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] 54+ messages in thread

* RE: [Patch v4 03/11] media: s5p-mfc: Add initial support for MFCv12
  2023-11-22 15:34         ` Hans Verkuil
@ 2023-11-27  6:44           ` Aakarsh Jain
  -1 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-11-27  6:44 UTC (permalink / raw)
  To: 'Hans Verkuil',
	linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, krzysztof.kozlowski+dt,
	dillon.minfei, david.plowman, mark.rutland, robh+dt, conor+dt,
	linux-samsung-soc, andi, gost.dev, alim.akhtar, aswani.reddy,
	pankaj.dubey, ajaykumar.rs, linux-fsd, 'Smitha T Murthy'

Hi Hans,

> -----Original Message-----
> From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
> Sent: 22 November 2023 21:04
> To: Aakarsh Jain <aakarsh.jain@samsung.com>; linux-arm-
> kernel@lists.infradead.org; linux-media@vger.kernel.org; linux-
> kernel@vger.kernel.org; devicetree@vger.kernel.org
> Cc: m.szyprowski@samsung.com; andrzej.hajda@intel.com;
> mchehab@kernel.org; krzysztof.kozlowski+dt@linaro.org;
> dillon.minfei@gmail.com; david.plowman@raspberrypi.com;
> mark.rutland@arm.com; robh+dt@kernel.org; conor+dt@kernel.org; linux-
> samsung-soc@vger.kernel.org; andi@etezian.org; gost.dev@samsung.com;
> alim.akhtar@samsung.com; aswani.reddy@samsung.com;
> pankaj.dubey@samsung.com; ajaykumar.rs@samsung.com; linux-
> fsd@tesla.com; Smitha T Murthy <smithatmurthy@gmail.com>
> Subject: Re: [Patch v4 03/11] media: s5p-mfc: Add initial support for MFCv12
> 
> On 25/10/2023 12:22, Aakarsh Jain wrote:
> > Add support for MFCv12, with a new register file and necessary hw
> > control, decoder, encoder and structural changes. Add luma dbp, chroma
> > dpb and mv sizes for each codec as per the UM for MFCv12, along with
> > appropriate alignment.
> >
> > Cc: linux-fsd@tesla.com
> > Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
> > Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
> > ---
> >  .../platform/samsung/s5p-mfc/regs-mfc-v12.h   | 50 +++++++++++
> >  .../media/platform/samsung/s5p-mfc/s5p_mfc.c  | 30 +++++++
> > .../platform/samsung/s5p-mfc/s5p_mfc_common.h | 15 +++-
> >  .../platform/samsung/s5p-mfc/s5p_mfc_ctrl.c   |  2 +-
> >  .../platform/samsung/s5p-mfc/s5p_mfc_dec.c    |  6 +-
> >  .../platform/samsung/s5p-mfc/s5p_mfc_enc.c    |  5 +-
> >  .../platform/samsung/s5p-mfc/s5p_mfc_opr.h    |  8 +-
> >  .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 83
> > ++++++++++++++++---  .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
> |
> > 6 +-
> >  9 files changed, 175 insertions(+), 30 deletions(-)  create mode
> > 100644 drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> >
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> > b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> > new file mode 100644
> > index 000000000000..6c68a45082d0
> > --- /dev/null
> > +++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> > @@ -0,0 +1,50 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +/*
> > + * Register definition file for Samsung MFC V12.x Interface (FIMV)
> > +driver
> > + *
> > + * Copyright (c) 2020 Samsung Electronics Co., Ltd.
> > + *     http://www.samsung.com/
> > + */
> > +
> > +#ifndef _REGS_MFC_V12_H
> > +#define _REGS_MFC_V12_H
> > +
> > +#include <linux/sizes.h>
> > +#include "regs-mfc-v10.h"
> > +
> > +/* MFCv12 Context buffer sizes */
> > +#define MFC_CTX_BUF_SIZE_V12		(30 * SZ_1K)
> > +#define MFC_H264_DEC_CTX_BUF_SIZE_V12	(2 * SZ_1M)
> > +#define MFC_OTHER_DEC_CTX_BUF_SIZE_V12	(30 * SZ_1K)
> > +#define MFC_H264_ENC_CTX_BUF_SIZE_V12	(100 * SZ_1K)
> > +#define MFC_HEVC_ENC_CTX_BUF_SIZE_V12	(40 * SZ_1K)
> > +#define MFC_OTHER_ENC_CTX_BUF_SIZE_V12	(25 * SZ_1K)
> > +
> > +/* MFCv12 variant defines */
> > +#define MAX_FW_SIZE_V12			(SZ_1M)
> > +#define MAX_CPB_SIZE_V12		(7 * SZ_1M)
> > +#define MFC_VERSION_V12			0xC0
> > +#define MFC_NUM_PORTS_V12		1
> > +#define S5P_FIMV_CODEC_VP9_ENC		27
> > +
> > +/* Encoder buffer size for MFCv12 */
> > +#define ENC_V120_BASE_SIZE(x, y) \
> > +	(((x + 3) * (y + 3) * 8) \
> > +	+ (((y * 64) + 2304) * (x + 7) / 8))
> > +
> > +#define ENC_V120_H264_ME_SIZE(x, y) \
> > +	ALIGN((ENC_V120_BASE_SIZE(x, y) \
> > +	+ (DIV_ROUND_UP(x * y, 64) * 32)), 256)
> > +
> > +#define ENC_V120_MPEG4_ME_SIZE(x, y) \
> > +	ALIGN((ENC_V120_BASE_SIZE(x, y) \
> > +	+ (DIV_ROUND_UP(x * y, 128) * 16)), 256)
> > +
> > +#define ENC_V120_VP8_ME_SIZE(x, y) \
> > +	ALIGN(ENC_V120_BASE_SIZE(x, y), 256)
> > +
> > +#define ENC_V120_HEVC_ME_SIZE(x, y)     \
> > +	ALIGN((((x + 3) * (y + 3) * 32)       \
> > +	+ (((y * 128) + 2304) * (x + 3) / 4)), 256)
> > +
> > +#endif /*_REGS_MFC_V12_H*/
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
> > index e30e54935d79..dee9ef017997 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
> > @@ -790,6 +790,8 @@ static int s5p_mfc_open(struct file *file)
> >  	INIT_LIST_HEAD(&ctx->dst_queue);
> >  	ctx->src_queue_cnt = 0;
> >  	ctx->dst_queue_cnt = 0;
> > +	ctx->is_422 = 0;
> > +	ctx->is_10bit = 0;
> >  	/* Get context number */
> >  	ctx->num = 0;
> >  	while (dev->ctx[ctx->num]) {
> > @@ -1660,6 +1662,31 @@ static struct s5p_mfc_variant mfc_drvdata_v10 =
> {
> >  	.fw_name[0]     = "s5p-mfc-v10.fw",
> >  };
> >
> > +static struct s5p_mfc_buf_size_v6 mfc_buf_size_v12 = {
> > +	.dev_ctx        = MFC_CTX_BUF_SIZE_V12,
> > +	.h264_dec_ctx   = MFC_H264_DEC_CTX_BUF_SIZE_V12,
> > +	.other_dec_ctx  = MFC_OTHER_DEC_CTX_BUF_SIZE_V12,
> > +	.h264_enc_ctx   = MFC_H264_ENC_CTX_BUF_SIZE_V12,
> > +	.hevc_enc_ctx   = MFC_HEVC_ENC_CTX_BUF_SIZE_V12,
> > +	.other_enc_ctx  = MFC_OTHER_ENC_CTX_BUF_SIZE_V12, };
> > +
> > +static struct s5p_mfc_buf_size buf_size_v12 = {
> > +	.fw     = MAX_FW_SIZE_V12,
> > +	.cpb    = MAX_CPB_SIZE_V12,
> > +	.priv   = &mfc_buf_size_v12,
> > +};
> > +
> > +static struct s5p_mfc_variant mfc_drvdata_v12 = {
> > +	.version        = MFC_VERSION_V12,
> > +	.version_bit    = MFC_V12_BIT,
> > +	.port_num       = MFC_NUM_PORTS_V12,
> > +	.buf_size       = &buf_size_v12,
> > +	.fw_name[0]     = "s5p-mfc-v12.fw",
> 
> Is this fw in the process of being added to linux-firmware? (Or perhaps it is
> already there).
> 
> Regards,
> 
> 	Hans
> 
Yes, we are in a process of upstreaming MFC v12 firmware bin to linux-firmware.

Thanks for the review.

> > +	.clk_names	= {"mfc"},
> > +	.num_clocks	= 1,
> > +};
> > +
> >  static const struct of_device_id exynos_mfc_match[] = {
> >  	{
> >  		.compatible = "samsung,mfc-v5",
> > @@ -1682,6 +1709,9 @@ static const struct of_device_id
> exynos_mfc_match[] = {
> >  	}, {
> >  		.compatible = "samsung,mfc-v10",
> >  		.data = &mfc_drvdata_v10,
> > +	}, {
> > +		.compatible = "tesla,fsd-mfc",
> > +		.data = &mfc_drvdata_v12,
> >  	},
> >  	{},
> >  };
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> > index e6ec4a43b290..dd2e9f7704ab 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> > @@ -19,7 +19,7 @@
> >  #include <media/v4l2-ioctl.h>
> >  #include <media/videobuf2-v4l2.h>
> >  #include "regs-mfc.h"
> > -#include "regs-mfc-v10.h"
> > +#include "regs-mfc-v12.h"
> >
> >  #define S5P_MFC_NAME		"s5p-mfc"
> >
> > @@ -720,6 +720,8 @@ struct s5p_mfc_ctx {
> >  	struct v4l2_ctrl *ctrls[MFC_MAX_CTRLS];
> >  	struct v4l2_ctrl_handler ctrl_handler;
> >  	size_t scratch_buf_size;
> > +	int is_10bit;
> > +	int is_422;
> >  };
> >
> >  /*
> > @@ -775,6 +777,7 @@ void s5p_mfc_cleanup_queue(struct list_head *lh,
> struct vb2_queue *vq);
> >  #define IS_MFCV7_PLUS(dev)	(dev->variant->version >= 0x70)
> >  #define IS_MFCV8_PLUS(dev)	(dev->variant->version >= 0x80)
> >  #define IS_MFCV10_PLUS(dev)	(dev->variant->version >= 0xA0)
> > +#define IS_MFCV12(dev)		(dev->variant->version >= 0xC0)
> >  #define FW_HAS_E_MIN_SCRATCH_BUF(dev) (IS_MFCV10_PLUS(dev))
> >
> >  #define MFC_V5_BIT	BIT(0)
> > @@ -782,11 +785,15 @@ void s5p_mfc_cleanup_queue(struct list_head
> *lh, struct vb2_queue *vq);
> >  #define MFC_V7_BIT	BIT(2)
> >  #define MFC_V8_BIT	BIT(3)
> >  #define MFC_V10_BIT	BIT(5)
> > +#define MFC_V12_BIT	BIT(7)
> >
> >  #define MFC_V5PLUS_BITS		(MFC_V5_BIT | MFC_V6_BIT |
> MFC_V7_BIT | \
> > -					MFC_V8_BIT | MFC_V10_BIT)
> > +					MFC_V8_BIT | MFC_V10_BIT |
> MFC_V12_BIT)
> >  #define MFC_V6PLUS_BITS		(MFC_V6_BIT | MFC_V7_BIT |
> MFC_V8_BIT | \
> > -					MFC_V10_BIT)
> > -#define MFC_V7PLUS_BITS		(MFC_V7_BIT | MFC_V8_BIT |
> MFC_V10_BIT)
> > +					MFC_V10_BIT | MFC_V12_BIT)
> > +#define MFC_V7PLUS_BITS		(MFC_V7_BIT | MFC_V8_BIT |
> MFC_V10_BIT | \
> > +					MFC_V12_BIT)
> > +
> > +#define MFC_V10PLUS_BITS	(MFC_V10_BIT | MFC_V12_BIT)
> >
> >  #endif /* S5P_MFC_COMMON_H_ */
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> > index 54b54b2fa9b1..b49159142c53 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> > @@ -130,7 +130,7 @@ int s5p_mfc_reset(struct s5p_mfc_dev *dev)
> >  			mfc_write(dev, 0, S5P_FIMV_REG_CLEAR_BEGIN_V6
> + (i*4));
> >
> >  		/* check bus reset control before reset */
> > -		if (dev->risc_on)
> > +		if (dev->risc_on && !IS_MFCV12(dev))
> >  			if (s5p_mfc_bus_reset(dev))
> >  				return -EIO;
> >  		/* Reset
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> > index 268ffe4da53c..e219cbcd86d5 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> > @@ -146,7 +146,7 @@ static struct s5p_mfc_fmt formats[] = {
> >  		.codec_mode	= S5P_FIMV_CODEC_HEVC_DEC,
> >  		.type		= MFC_FMT_DEC,
> >  		.num_planes	= 1,
> > -		.versions	= MFC_V10_BIT,
> > +		.versions	= MFC_V10PLUS_BITS,
> >  		.flags		= V4L2_FMT_FLAG_DYN_RESOLUTION |
> >
> V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM,
> >  	},
> > @@ -155,7 +155,7 @@ static struct s5p_mfc_fmt formats[] = {
> >  		.codec_mode	= S5P_FIMV_CODEC_VP9_DEC,
> >  		.type		= MFC_FMT_DEC,
> >  		.num_planes	= 1,
> > -		.versions	= MFC_V10_BIT,
> > +		.versions	= MFC_V10PLUS_BITS,
> >  		.flags		= V4L2_FMT_FLAG_DYN_RESOLUTION,
> >  	},
> >  };
> > @@ -355,7 +355,7 @@ static int vidioc_g_fmt(struct file *file, void *priv,
> struct v4l2_format *f)
> >  		pix_mp->width = ctx->buf_width;
> >  		pix_mp->height = ctx->buf_height;
> >  		pix_mp->field = V4L2_FIELD_NONE;
> > -		pix_mp->num_planes = 2;
> > +		pix_mp->num_planes = ctx->dst_fmt->num_planes;
> >  		/* Set pixelformat to the format in which MFC
> >  		   outputs the decoded frame */
> >  		pix_mp->pixelformat = ctx->dst_fmt->fourcc; diff --git
> > a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> > index f62703cebb77..e4d6e7c117b5 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> > @@ -92,7 +92,7 @@ static struct s5p_mfc_fmt formats[] = {
> >  		.codec_mode	= S5P_FIMV_CODEC_HEVC_ENC,
> >  		.type		= MFC_FMT_ENC,
> >  		.num_planes	= 1,
> > -		.versions	= MFC_V10_BIT,
> > +		.versions	= MFC_V10PLUS_BITS,
> >  	},
> >  };
> >
> > @@ -1179,7 +1179,8 @@ static int enc_post_seq_start(struct s5p_mfc_ctx
> *ctx)
> >  		if (FW_HAS_E_MIN_SCRATCH_BUF(dev)) {
> >  			ctx->scratch_buf_size = s5p_mfc_hw_call(dev-
> >mfc_ops,
> >  					get_e_min_scratch_buf_size, dev);
> > -			ctx->bank1.size += ctx->scratch_buf_size;
> > +			if (!IS_MFCV12(dev))
> > +				ctx->bank1.size += ctx->scratch_buf_size;
> >  		}
> >  		ctx->state = MFCINST_HEAD_PRODUCED;
> >  	}
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> > index b9831275f3ab..87ac56756a16 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> > @@ -166,9 +166,9 @@ struct s5p_mfc_regs {
> >  	void __iomem *d_decoded_third_addr;/* only v7 */
> >  	void __iomem *d_used_dpb_flag_upper;/* v7 and v8 */
> >  	void __iomem *d_used_dpb_flag_lower;/* v7 and v8 */
> > -	void __iomem *d_min_scratch_buffer_size; /* v10 */
> > -	void __iomem *d_static_buffer_addr; /* v10 */
> > -	void __iomem *d_static_buffer_size; /* v10 */
> > +	void __iomem *d_min_scratch_buffer_size; /* v10 and v12 */
> > +	void __iomem *d_static_buffer_addr; /* v10 and v12 */
> > +	void __iomem *d_static_buffer_size; /* v10 and v12 */
> >
> >  	/* encoder registers */
> >  	void __iomem *e_frame_width;
> > @@ -268,7 +268,7 @@ struct s5p_mfc_regs {
> >  	void __iomem *e_vp8_hierarchical_qp_layer0;/* v7 and v8 */
> >  	void __iomem *e_vp8_hierarchical_qp_layer1;/* v7 and v8 */
> >  	void __iomem *e_vp8_hierarchical_qp_layer2;/* v7 and v8 */
> > -	void __iomem *e_min_scratch_buffer_size; /* v10 */
> > +	void __iomem *e_min_scratch_buffer_size; /* v10 and v12 */
> >  	void __iomem *e_num_t_layer; /* v10 */
> >  	void __iomem *e_hier_qp_layer0; /* v10 */
> >  	void __iomem *e_hier_bit_rate_layer0; /* v10 */ diff --git
> > a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> > index 882166e4ac50..fb3f0718821d 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> > @@ -60,12 +60,14 @@ static void
> > s5p_mfc_release_dec_desc_buffer_v6(struct s5p_mfc_ctx *ctx)  static
> > int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)  {
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> > -	unsigned int mb_width, mb_height;
> > +	unsigned int mb_width, mb_height, width64, height32;
> >  	unsigned int lcu_width = 0, lcu_height = 0;
> >  	int ret;
> >
> >  	mb_width = MB_WIDTH(ctx->img_width);
> >  	mb_height = MB_HEIGHT(ctx->img_height);
> > +	width64 = ALIGN(ctx->img_width, 64);
> > +	height32 = ALIGN(ctx->img_height, 32);
> >
> >  	if (ctx->type == MFCINST_DECODER) {
> >  		mfc_debug(2, "Luma size:%d Chroma size:%d MV
> size:%d\n", @@ -82,7
> > +84,44 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx
> *ctx)
> >  			ctx->tmv_buffer_size =
> S5P_FIMV_NUM_TMV_BUFFERS_V6 *
> >
> 	ALIGN(S5P_FIMV_TMV_BUFFER_SIZE_V6(mb_width, mb_height),
> >  			S5P_FIMV_TMV_BUFFER_ALIGN_V6);
> > -		if (IS_MFCV10_PLUS(dev)) {
> > +		if (IS_MFCV12(dev)) {
> > +			lcu_width = S5P_MFC_LCU_WIDTH(ctx->img_width);
> > +			lcu_height = S5P_MFC_LCU_HEIGHT(ctx-
> >img_height);
> > +			if (ctx->codec_mode ==
> S5P_FIMV_CODEC_HEVC_ENC &&
> > +								ctx->is_10bit)
> {
> > +				ctx->luma_dpb_size =
> > +					width64 * height32 +
> > +					ALIGN(DIV_ROUND_UP(lcu_width *
> 32, 4),
> > +							16) * height32 + 128;
> > +				if (ctx->is_422)
> > +					ctx->chroma_dpb_size =
> > +						ctx->luma_dpb_size;
> > +				else
> > +					ctx->chroma_dpb_size =
> > +						width64 * height32 / 2 +
> > +
> 	ALIGN(DIV_ROUND_UP(lcu_width *
> > +						32, 4), 16) * height32 / 2 +
> 128;
> > +			} else if (ctx->codec_mode ==
> S5P_FIMV_CODEC_VP9_ENC &&
> > +					ctx->is_10bit) {
> > +				ctx->luma_dpb_size =
> > +					ALIGN(ctx->img_width * 2, 128) *
> > +					height32 + 64;
> > +				ctx->chroma_dpb_size =
> > +					ALIGN(ctx->img_width * 2, 128) *
> > +					height32 / 2 + 64;
> > +			} else {
> > +				ctx->luma_dpb_size =
> > +					width64 * height32 + 64;
> > +				if (ctx->is_422)
> > +					ctx->chroma_dpb_size =
> > +						ctx->luma_dpb_size;
> > +				else
> > +					ctx->chroma_dpb_size =
> > +						width64 * height32 / 2 + 64;
> > +			}
> > +			ctx->luma_dpb_size = ALIGN(ctx->luma_dpb_size +
> 256, SZ_2K);
> > +			ctx->chroma_dpb_size = ALIGN(ctx-
> >chroma_dpb_size + 256, SZ_2K);
> > +		} else if (IS_MFCV10_PLUS(dev)) {
> >  			lcu_width = S5P_MFC_LCU_WIDTH(ctx->img_width);
> >  			lcu_height = S5P_MFC_LCU_HEIGHT(ctx-
> >img_height);
> >  			if (ctx->codec_mode !=
> S5P_FIMV_CODEC_HEVC_ENC) { @@ -230,7
> > +269,11 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct
> s5p_mfc_ctx *ctx)
> >  			DEC_VP9_STATIC_BUFFER_SIZE;
> >  		break;
> >  	case S5P_MFC_CODEC_H264_ENC:
> > -		if (IS_MFCV10_PLUS(dev)) {
> > +		if (IS_MFCV12(dev)) {
> > +			mfc_debug(2, "Use min scratch buffer size\n");
> > +			ctx->me_buffer_size =
> > +				ENC_V120_H264_ME_SIZE(mb_width,
> mb_height);
> > +		} else if (IS_MFCV10_PLUS(dev)) {
> >  			mfc_debug(2, "Use min scratch buffer size\n");
> >  			ctx->me_buffer_size =
> >  			ALIGN(ENC_V100_H264_ME_SIZE(mb_width,
> mb_height), 16); @@ -254,7
> > +297,11 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct
> s5p_mfc_ctx *ctx)
> >  		break;
> >  	case S5P_MFC_CODEC_MPEG4_ENC:
> >  	case S5P_MFC_CODEC_H263_ENC:
> > -		if (IS_MFCV10_PLUS(dev)) {
> > +		if (IS_MFCV12(dev)) {
> > +			mfc_debug(2, "Use min scratch buffer size\n");
> > +			ctx->me_buffer_size =
> > +				ENC_V120_MPEG4_ME_SIZE(mb_width,
> mb_height);
> > +		} else if (IS_MFCV10_PLUS(dev)) {
> >  			mfc_debug(2, "Use min scratch buffer size\n");
> >  			ctx->me_buffer_size =
> >
> 	ALIGN(ENC_V100_MPEG4_ME_SIZE(mb_width,
> > @@ -273,7 +320,11 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct
> s5p_mfc_ctx *ctx)
> >  		ctx->bank2.size = 0;
> >  		break;
> >  	case S5P_MFC_CODEC_VP8_ENC:
> > -		if (IS_MFCV10_PLUS(dev)) {
> > +		if (IS_MFCV12(dev)) {
> > +			mfc_debug(2, "Use min scratch buffer size\n");
> > +			ctx->me_buffer_size =
> > +				ENC_V120_VP8_ME_SIZE(mb_width,
> mb_height);
> > +		} else if (IS_MFCV10_PLUS(dev)) {
> >  			mfc_debug(2, "Use min scratch buffer size\n");
> >  			ctx->me_buffer_size =
> >  				ALIGN(ENC_V100_VP8_ME_SIZE(mb_width,
> mb_height), @@ -297,9
> > +348,14 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct
> s5p_mfc_ctx *ctx)
> >  		ctx->bank2.size = 0;
> >  		break;
> >  	case S5P_MFC_CODEC_HEVC_ENC:
> > +		if (IS_MFCV12(dev))
> > +			ctx->me_buffer_size =
> > +				ENC_V120_HEVC_ME_SIZE(lcu_width,
> lcu_height);
> > +		else
> > +			ctx->me_buffer_size =
> > +				ALIGN(ENC_V100_HEVC_ME_SIZE(lcu_width,
> > +							lcu_height), 16);
> >  		mfc_debug(2, "Use min scratch buffer size\n");
> > -		ctx->me_buffer_size =
> > -			ALIGN(ENC_V100_HEVC_ME_SIZE(lcu_width,
> lcu_height), 16);
> >  		ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, 256);
> >  		ctx->bank1.size =
> >  			ctx->scratch_buf_size + ctx->tmv_buffer_size + @@
> -452,12 +508,15
> > @@ static void s5p_mfc_dec_calc_dpb_size_v6(struct s5p_mfc_ctx *ctx)
> >
> >  	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
> >  			ctx->codec_mode ==
> S5P_MFC_CODEC_H264_MVC_DEC) {
> > -		if (IS_MFCV10_PLUS(dev)) {
> > -			ctx->mv_size = S5P_MFC_DEC_MV_SIZE_V10(ctx-
> >img_width,
> > -					ctx->img_height);
> > +		if (IS_MFCV12(dev)) {
> > +			ctx->mv_size = S5P_MFC_DEC_MV_SIZE(ctx-
> >img_width,
> > +					ctx->img_height, 1024);
> > +		} else if (IS_MFCV10_PLUS(dev)) {
> > +			ctx->mv_size = S5P_MFC_DEC_MV_SIZE(ctx-
> >img_width,
> > +					ctx->img_height, 512);
> >  		} else {
> > -			ctx->mv_size = S5P_MFC_DEC_MV_SIZE_V6(ctx-
> >img_width,
> > -					ctx->img_height);
> > +			ctx->mv_size = S5P_MFC_DEC_MV_SIZE(ctx-
> >img_width,
> > +					ctx->img_height, 128);
> >  		}
> >  	} else if (ctx->codec_mode == S5P_MFC_CODEC_HEVC_DEC) {
> >  		ctx->mv_size = s5p_mfc_dec_hevc_mv_size(ctx-
> >img_width,
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
> > index e4dd03c5454c..30269f3e68e8 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
> > @@ -19,10 +19,8 @@
> >
> >  #define MB_WIDTH(x_size)		DIV_ROUND_UP(x_size, 16)
> >  #define MB_HEIGHT(y_size)		DIV_ROUND_UP(y_size, 16)
> > -#define S5P_MFC_DEC_MV_SIZE_V6(x, y)	(MB_WIDTH(x) * \
> > -					(((MB_HEIGHT(y)+1)/2)*2) * 64 +
> 128)
> > -#define S5P_MFC_DEC_MV_SIZE_V10(x, y)	(MB_WIDTH(x) * \
> > -					(((MB_HEIGHT(y)+1)/2)*2) * 64 +
> 512)
> > +#define S5P_MFC_DEC_MV_SIZE(x, y, offset)	(MB_WIDTH(x) * \
> > +					(((MB_HEIGHT(y)+1)/2)*2) * 64 +
> offset)
> >  #define S5P_MFC_LCU_WIDTH(x_size)	DIV_ROUND_UP(x_size, 32)
> >  #define S5P_MFC_LCU_HEIGHT(y_size)	DIV_ROUND_UP(y_size, 32)
> >



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

* RE: [Patch v4 03/11] media: s5p-mfc: Add initial support for MFCv12
@ 2023-11-27  6:44           ` Aakarsh Jain
  0 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-11-27  6:44 UTC (permalink / raw)
  To: 'Hans Verkuil',
	linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, krzysztof.kozlowski+dt,
	dillon.minfei, david.plowman, mark.rutland, robh+dt, conor+dt,
	linux-samsung-soc, andi, gost.dev, alim.akhtar, aswani.reddy,
	pankaj.dubey, ajaykumar.rs, linux-fsd, 'Smitha T Murthy'

Hi Hans,

> -----Original Message-----
> From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
> Sent: 22 November 2023 21:04
> To: Aakarsh Jain <aakarsh.jain@samsung.com>; linux-arm-
> kernel@lists.infradead.org; linux-media@vger.kernel.org; linux-
> kernel@vger.kernel.org; devicetree@vger.kernel.org
> Cc: m.szyprowski@samsung.com; andrzej.hajda@intel.com;
> mchehab@kernel.org; krzysztof.kozlowski+dt@linaro.org;
> dillon.minfei@gmail.com; david.plowman@raspberrypi.com;
> mark.rutland@arm.com; robh+dt@kernel.org; conor+dt@kernel.org; linux-
> samsung-soc@vger.kernel.org; andi@etezian.org; gost.dev@samsung.com;
> alim.akhtar@samsung.com; aswani.reddy@samsung.com;
> pankaj.dubey@samsung.com; ajaykumar.rs@samsung.com; linux-
> fsd@tesla.com; Smitha T Murthy <smithatmurthy@gmail.com>
> Subject: Re: [Patch v4 03/11] media: s5p-mfc: Add initial support for MFCv12
> 
> On 25/10/2023 12:22, Aakarsh Jain wrote:
> > Add support for MFCv12, with a new register file and necessary hw
> > control, decoder, encoder and structural changes. Add luma dbp, chroma
> > dpb and mv sizes for each codec as per the UM for MFCv12, along with
> > appropriate alignment.
> >
> > Cc: linux-fsd@tesla.com
> > Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
> > Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
> > ---
> >  .../platform/samsung/s5p-mfc/regs-mfc-v12.h   | 50 +++++++++++
> >  .../media/platform/samsung/s5p-mfc/s5p_mfc.c  | 30 +++++++
> > .../platform/samsung/s5p-mfc/s5p_mfc_common.h | 15 +++-
> >  .../platform/samsung/s5p-mfc/s5p_mfc_ctrl.c   |  2 +-
> >  .../platform/samsung/s5p-mfc/s5p_mfc_dec.c    |  6 +-
> >  .../platform/samsung/s5p-mfc/s5p_mfc_enc.c    |  5 +-
> >  .../platform/samsung/s5p-mfc/s5p_mfc_opr.h    |  8 +-
> >  .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 83
> > ++++++++++++++++---  .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
> |
> > 6 +-
> >  9 files changed, 175 insertions(+), 30 deletions(-)  create mode
> > 100644 drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> >
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> > b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> > new file mode 100644
> > index 000000000000..6c68a45082d0
> > --- /dev/null
> > +++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> > @@ -0,0 +1,50 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +/*
> > + * Register definition file for Samsung MFC V12.x Interface (FIMV)
> > +driver
> > + *
> > + * Copyright (c) 2020 Samsung Electronics Co., Ltd.
> > + *     http://www.samsung.com/
> > + */
> > +
> > +#ifndef _REGS_MFC_V12_H
> > +#define _REGS_MFC_V12_H
> > +
> > +#include <linux/sizes.h>
> > +#include "regs-mfc-v10.h"
> > +
> > +/* MFCv12 Context buffer sizes */
> > +#define MFC_CTX_BUF_SIZE_V12		(30 * SZ_1K)
> > +#define MFC_H264_DEC_CTX_BUF_SIZE_V12	(2 * SZ_1M)
> > +#define MFC_OTHER_DEC_CTX_BUF_SIZE_V12	(30 * SZ_1K)
> > +#define MFC_H264_ENC_CTX_BUF_SIZE_V12	(100 * SZ_1K)
> > +#define MFC_HEVC_ENC_CTX_BUF_SIZE_V12	(40 * SZ_1K)
> > +#define MFC_OTHER_ENC_CTX_BUF_SIZE_V12	(25 * SZ_1K)
> > +
> > +/* MFCv12 variant defines */
> > +#define MAX_FW_SIZE_V12			(SZ_1M)
> > +#define MAX_CPB_SIZE_V12		(7 * SZ_1M)
> > +#define MFC_VERSION_V12			0xC0
> > +#define MFC_NUM_PORTS_V12		1
> > +#define S5P_FIMV_CODEC_VP9_ENC		27
> > +
> > +/* Encoder buffer size for MFCv12 */
> > +#define ENC_V120_BASE_SIZE(x, y) \
> > +	(((x + 3) * (y + 3) * 8) \
> > +	+ (((y * 64) + 2304) * (x + 7) / 8))
> > +
> > +#define ENC_V120_H264_ME_SIZE(x, y) \
> > +	ALIGN((ENC_V120_BASE_SIZE(x, y) \
> > +	+ (DIV_ROUND_UP(x * y, 64) * 32)), 256)
> > +
> > +#define ENC_V120_MPEG4_ME_SIZE(x, y) \
> > +	ALIGN((ENC_V120_BASE_SIZE(x, y) \
> > +	+ (DIV_ROUND_UP(x * y, 128) * 16)), 256)
> > +
> > +#define ENC_V120_VP8_ME_SIZE(x, y) \
> > +	ALIGN(ENC_V120_BASE_SIZE(x, y), 256)
> > +
> > +#define ENC_V120_HEVC_ME_SIZE(x, y)     \
> > +	ALIGN((((x + 3) * (y + 3) * 32)       \
> > +	+ (((y * 128) + 2304) * (x + 3) / 4)), 256)
> > +
> > +#endif /*_REGS_MFC_V12_H*/
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
> > index e30e54935d79..dee9ef017997 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
> > @@ -790,6 +790,8 @@ static int s5p_mfc_open(struct file *file)
> >  	INIT_LIST_HEAD(&ctx->dst_queue);
> >  	ctx->src_queue_cnt = 0;
> >  	ctx->dst_queue_cnt = 0;
> > +	ctx->is_422 = 0;
> > +	ctx->is_10bit = 0;
> >  	/* Get context number */
> >  	ctx->num = 0;
> >  	while (dev->ctx[ctx->num]) {
> > @@ -1660,6 +1662,31 @@ static struct s5p_mfc_variant mfc_drvdata_v10 =
> {
> >  	.fw_name[0]     = "s5p-mfc-v10.fw",
> >  };
> >
> > +static struct s5p_mfc_buf_size_v6 mfc_buf_size_v12 = {
> > +	.dev_ctx        = MFC_CTX_BUF_SIZE_V12,
> > +	.h264_dec_ctx   = MFC_H264_DEC_CTX_BUF_SIZE_V12,
> > +	.other_dec_ctx  = MFC_OTHER_DEC_CTX_BUF_SIZE_V12,
> > +	.h264_enc_ctx   = MFC_H264_ENC_CTX_BUF_SIZE_V12,
> > +	.hevc_enc_ctx   = MFC_HEVC_ENC_CTX_BUF_SIZE_V12,
> > +	.other_enc_ctx  = MFC_OTHER_ENC_CTX_BUF_SIZE_V12, };
> > +
> > +static struct s5p_mfc_buf_size buf_size_v12 = {
> > +	.fw     = MAX_FW_SIZE_V12,
> > +	.cpb    = MAX_CPB_SIZE_V12,
> > +	.priv   = &mfc_buf_size_v12,
> > +};
> > +
> > +static struct s5p_mfc_variant mfc_drvdata_v12 = {
> > +	.version        = MFC_VERSION_V12,
> > +	.version_bit    = MFC_V12_BIT,
> > +	.port_num       = MFC_NUM_PORTS_V12,
> > +	.buf_size       = &buf_size_v12,
> > +	.fw_name[0]     = "s5p-mfc-v12.fw",
> 
> Is this fw in the process of being added to linux-firmware? (Or perhaps it is
> already there).
> 
> Regards,
> 
> 	Hans
> 
Yes, we are in a process of upstreaming MFC v12 firmware bin to linux-firmware.

Thanks for the review.

> > +	.clk_names	= {"mfc"},
> > +	.num_clocks	= 1,
> > +};
> > +
> >  static const struct of_device_id exynos_mfc_match[] = {
> >  	{
> >  		.compatible = "samsung,mfc-v5",
> > @@ -1682,6 +1709,9 @@ static const struct of_device_id
> exynos_mfc_match[] = {
> >  	}, {
> >  		.compatible = "samsung,mfc-v10",
> >  		.data = &mfc_drvdata_v10,
> > +	}, {
> > +		.compatible = "tesla,fsd-mfc",
> > +		.data = &mfc_drvdata_v12,
> >  	},
> >  	{},
> >  };
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> > index e6ec4a43b290..dd2e9f7704ab 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> > @@ -19,7 +19,7 @@
> >  #include <media/v4l2-ioctl.h>
> >  #include <media/videobuf2-v4l2.h>
> >  #include "regs-mfc.h"
> > -#include "regs-mfc-v10.h"
> > +#include "regs-mfc-v12.h"
> >
> >  #define S5P_MFC_NAME		"s5p-mfc"
> >
> > @@ -720,6 +720,8 @@ struct s5p_mfc_ctx {
> >  	struct v4l2_ctrl *ctrls[MFC_MAX_CTRLS];
> >  	struct v4l2_ctrl_handler ctrl_handler;
> >  	size_t scratch_buf_size;
> > +	int is_10bit;
> > +	int is_422;
> >  };
> >
> >  /*
> > @@ -775,6 +777,7 @@ void s5p_mfc_cleanup_queue(struct list_head *lh,
> struct vb2_queue *vq);
> >  #define IS_MFCV7_PLUS(dev)	(dev->variant->version >= 0x70)
> >  #define IS_MFCV8_PLUS(dev)	(dev->variant->version >= 0x80)
> >  #define IS_MFCV10_PLUS(dev)	(dev->variant->version >= 0xA0)
> > +#define IS_MFCV12(dev)		(dev->variant->version >= 0xC0)
> >  #define FW_HAS_E_MIN_SCRATCH_BUF(dev) (IS_MFCV10_PLUS(dev))
> >
> >  #define MFC_V5_BIT	BIT(0)
> > @@ -782,11 +785,15 @@ void s5p_mfc_cleanup_queue(struct list_head
> *lh, struct vb2_queue *vq);
> >  #define MFC_V7_BIT	BIT(2)
> >  #define MFC_V8_BIT	BIT(3)
> >  #define MFC_V10_BIT	BIT(5)
> > +#define MFC_V12_BIT	BIT(7)
> >
> >  #define MFC_V5PLUS_BITS		(MFC_V5_BIT | MFC_V6_BIT |
> MFC_V7_BIT | \
> > -					MFC_V8_BIT | MFC_V10_BIT)
> > +					MFC_V8_BIT | MFC_V10_BIT |
> MFC_V12_BIT)
> >  #define MFC_V6PLUS_BITS		(MFC_V6_BIT | MFC_V7_BIT |
> MFC_V8_BIT | \
> > -					MFC_V10_BIT)
> > -#define MFC_V7PLUS_BITS		(MFC_V7_BIT | MFC_V8_BIT |
> MFC_V10_BIT)
> > +					MFC_V10_BIT | MFC_V12_BIT)
> > +#define MFC_V7PLUS_BITS		(MFC_V7_BIT | MFC_V8_BIT |
> MFC_V10_BIT | \
> > +					MFC_V12_BIT)
> > +
> > +#define MFC_V10PLUS_BITS	(MFC_V10_BIT | MFC_V12_BIT)
> >
> >  #endif /* S5P_MFC_COMMON_H_ */
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> > index 54b54b2fa9b1..b49159142c53 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> > @@ -130,7 +130,7 @@ int s5p_mfc_reset(struct s5p_mfc_dev *dev)
> >  			mfc_write(dev, 0, S5P_FIMV_REG_CLEAR_BEGIN_V6
> + (i*4));
> >
> >  		/* check bus reset control before reset */
> > -		if (dev->risc_on)
> > +		if (dev->risc_on && !IS_MFCV12(dev))
> >  			if (s5p_mfc_bus_reset(dev))
> >  				return -EIO;
> >  		/* Reset
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> > index 268ffe4da53c..e219cbcd86d5 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> > @@ -146,7 +146,7 @@ static struct s5p_mfc_fmt formats[] = {
> >  		.codec_mode	= S5P_FIMV_CODEC_HEVC_DEC,
> >  		.type		= MFC_FMT_DEC,
> >  		.num_planes	= 1,
> > -		.versions	= MFC_V10_BIT,
> > +		.versions	= MFC_V10PLUS_BITS,
> >  		.flags		= V4L2_FMT_FLAG_DYN_RESOLUTION |
> >
> V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM,
> >  	},
> > @@ -155,7 +155,7 @@ static struct s5p_mfc_fmt formats[] = {
> >  		.codec_mode	= S5P_FIMV_CODEC_VP9_DEC,
> >  		.type		= MFC_FMT_DEC,
> >  		.num_planes	= 1,
> > -		.versions	= MFC_V10_BIT,
> > +		.versions	= MFC_V10PLUS_BITS,
> >  		.flags		= V4L2_FMT_FLAG_DYN_RESOLUTION,
> >  	},
> >  };
> > @@ -355,7 +355,7 @@ static int vidioc_g_fmt(struct file *file, void *priv,
> struct v4l2_format *f)
> >  		pix_mp->width = ctx->buf_width;
> >  		pix_mp->height = ctx->buf_height;
> >  		pix_mp->field = V4L2_FIELD_NONE;
> > -		pix_mp->num_planes = 2;
> > +		pix_mp->num_planes = ctx->dst_fmt->num_planes;
> >  		/* Set pixelformat to the format in which MFC
> >  		   outputs the decoded frame */
> >  		pix_mp->pixelformat = ctx->dst_fmt->fourcc; diff --git
> > a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> > index f62703cebb77..e4d6e7c117b5 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> > @@ -92,7 +92,7 @@ static struct s5p_mfc_fmt formats[] = {
> >  		.codec_mode	= S5P_FIMV_CODEC_HEVC_ENC,
> >  		.type		= MFC_FMT_ENC,
> >  		.num_planes	= 1,
> > -		.versions	= MFC_V10_BIT,
> > +		.versions	= MFC_V10PLUS_BITS,
> >  	},
> >  };
> >
> > @@ -1179,7 +1179,8 @@ static int enc_post_seq_start(struct s5p_mfc_ctx
> *ctx)
> >  		if (FW_HAS_E_MIN_SCRATCH_BUF(dev)) {
> >  			ctx->scratch_buf_size = s5p_mfc_hw_call(dev-
> >mfc_ops,
> >  					get_e_min_scratch_buf_size, dev);
> > -			ctx->bank1.size += ctx->scratch_buf_size;
> > +			if (!IS_MFCV12(dev))
> > +				ctx->bank1.size += ctx->scratch_buf_size;
> >  		}
> >  		ctx->state = MFCINST_HEAD_PRODUCED;
> >  	}
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> > index b9831275f3ab..87ac56756a16 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> > @@ -166,9 +166,9 @@ struct s5p_mfc_regs {
> >  	void __iomem *d_decoded_third_addr;/* only v7 */
> >  	void __iomem *d_used_dpb_flag_upper;/* v7 and v8 */
> >  	void __iomem *d_used_dpb_flag_lower;/* v7 and v8 */
> > -	void __iomem *d_min_scratch_buffer_size; /* v10 */
> > -	void __iomem *d_static_buffer_addr; /* v10 */
> > -	void __iomem *d_static_buffer_size; /* v10 */
> > +	void __iomem *d_min_scratch_buffer_size; /* v10 and v12 */
> > +	void __iomem *d_static_buffer_addr; /* v10 and v12 */
> > +	void __iomem *d_static_buffer_size; /* v10 and v12 */
> >
> >  	/* encoder registers */
> >  	void __iomem *e_frame_width;
> > @@ -268,7 +268,7 @@ struct s5p_mfc_regs {
> >  	void __iomem *e_vp8_hierarchical_qp_layer0;/* v7 and v8 */
> >  	void __iomem *e_vp8_hierarchical_qp_layer1;/* v7 and v8 */
> >  	void __iomem *e_vp8_hierarchical_qp_layer2;/* v7 and v8 */
> > -	void __iomem *e_min_scratch_buffer_size; /* v10 */
> > +	void __iomem *e_min_scratch_buffer_size; /* v10 and v12 */
> >  	void __iomem *e_num_t_layer; /* v10 */
> >  	void __iomem *e_hier_qp_layer0; /* v10 */
> >  	void __iomem *e_hier_bit_rate_layer0; /* v10 */ diff --git
> > a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> > index 882166e4ac50..fb3f0718821d 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> > @@ -60,12 +60,14 @@ static void
> > s5p_mfc_release_dec_desc_buffer_v6(struct s5p_mfc_ctx *ctx)  static
> > int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)  {
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> > -	unsigned int mb_width, mb_height;
> > +	unsigned int mb_width, mb_height, width64, height32;
> >  	unsigned int lcu_width = 0, lcu_height = 0;
> >  	int ret;
> >
> >  	mb_width = MB_WIDTH(ctx->img_width);
> >  	mb_height = MB_HEIGHT(ctx->img_height);
> > +	width64 = ALIGN(ctx->img_width, 64);
> > +	height32 = ALIGN(ctx->img_height, 32);
> >
> >  	if (ctx->type == MFCINST_DECODER) {
> >  		mfc_debug(2, "Luma size:%d Chroma size:%d MV
> size:%d\n", @@ -82,7
> > +84,44 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx
> *ctx)
> >  			ctx->tmv_buffer_size =
> S5P_FIMV_NUM_TMV_BUFFERS_V6 *
> >
> 	ALIGN(S5P_FIMV_TMV_BUFFER_SIZE_V6(mb_width, mb_height),
> >  			S5P_FIMV_TMV_BUFFER_ALIGN_V6);
> > -		if (IS_MFCV10_PLUS(dev)) {
> > +		if (IS_MFCV12(dev)) {
> > +			lcu_width = S5P_MFC_LCU_WIDTH(ctx->img_width);
> > +			lcu_height = S5P_MFC_LCU_HEIGHT(ctx-
> >img_height);
> > +			if (ctx->codec_mode ==
> S5P_FIMV_CODEC_HEVC_ENC &&
> > +								ctx->is_10bit)
> {
> > +				ctx->luma_dpb_size =
> > +					width64 * height32 +
> > +					ALIGN(DIV_ROUND_UP(lcu_width *
> 32, 4),
> > +							16) * height32 + 128;
> > +				if (ctx->is_422)
> > +					ctx->chroma_dpb_size =
> > +						ctx->luma_dpb_size;
> > +				else
> > +					ctx->chroma_dpb_size =
> > +						width64 * height32 / 2 +
> > +
> 	ALIGN(DIV_ROUND_UP(lcu_width *
> > +						32, 4), 16) * height32 / 2 +
> 128;
> > +			} else if (ctx->codec_mode ==
> S5P_FIMV_CODEC_VP9_ENC &&
> > +					ctx->is_10bit) {
> > +				ctx->luma_dpb_size =
> > +					ALIGN(ctx->img_width * 2, 128) *
> > +					height32 + 64;
> > +				ctx->chroma_dpb_size =
> > +					ALIGN(ctx->img_width * 2, 128) *
> > +					height32 / 2 + 64;
> > +			} else {
> > +				ctx->luma_dpb_size =
> > +					width64 * height32 + 64;
> > +				if (ctx->is_422)
> > +					ctx->chroma_dpb_size =
> > +						ctx->luma_dpb_size;
> > +				else
> > +					ctx->chroma_dpb_size =
> > +						width64 * height32 / 2 + 64;
> > +			}
> > +			ctx->luma_dpb_size = ALIGN(ctx->luma_dpb_size +
> 256, SZ_2K);
> > +			ctx->chroma_dpb_size = ALIGN(ctx-
> >chroma_dpb_size + 256, SZ_2K);
> > +		} else if (IS_MFCV10_PLUS(dev)) {
> >  			lcu_width = S5P_MFC_LCU_WIDTH(ctx->img_width);
> >  			lcu_height = S5P_MFC_LCU_HEIGHT(ctx-
> >img_height);
> >  			if (ctx->codec_mode !=
> S5P_FIMV_CODEC_HEVC_ENC) { @@ -230,7
> > +269,11 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct
> s5p_mfc_ctx *ctx)
> >  			DEC_VP9_STATIC_BUFFER_SIZE;
> >  		break;
> >  	case S5P_MFC_CODEC_H264_ENC:
> > -		if (IS_MFCV10_PLUS(dev)) {
> > +		if (IS_MFCV12(dev)) {
> > +			mfc_debug(2, "Use min scratch buffer size\n");
> > +			ctx->me_buffer_size =
> > +				ENC_V120_H264_ME_SIZE(mb_width,
> mb_height);
> > +		} else if (IS_MFCV10_PLUS(dev)) {
> >  			mfc_debug(2, "Use min scratch buffer size\n");
> >  			ctx->me_buffer_size =
> >  			ALIGN(ENC_V100_H264_ME_SIZE(mb_width,
> mb_height), 16); @@ -254,7
> > +297,11 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct
> s5p_mfc_ctx *ctx)
> >  		break;
> >  	case S5P_MFC_CODEC_MPEG4_ENC:
> >  	case S5P_MFC_CODEC_H263_ENC:
> > -		if (IS_MFCV10_PLUS(dev)) {
> > +		if (IS_MFCV12(dev)) {
> > +			mfc_debug(2, "Use min scratch buffer size\n");
> > +			ctx->me_buffer_size =
> > +				ENC_V120_MPEG4_ME_SIZE(mb_width,
> mb_height);
> > +		} else if (IS_MFCV10_PLUS(dev)) {
> >  			mfc_debug(2, "Use min scratch buffer size\n");
> >  			ctx->me_buffer_size =
> >
> 	ALIGN(ENC_V100_MPEG4_ME_SIZE(mb_width,
> > @@ -273,7 +320,11 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct
> s5p_mfc_ctx *ctx)
> >  		ctx->bank2.size = 0;
> >  		break;
> >  	case S5P_MFC_CODEC_VP8_ENC:
> > -		if (IS_MFCV10_PLUS(dev)) {
> > +		if (IS_MFCV12(dev)) {
> > +			mfc_debug(2, "Use min scratch buffer size\n");
> > +			ctx->me_buffer_size =
> > +				ENC_V120_VP8_ME_SIZE(mb_width,
> mb_height);
> > +		} else if (IS_MFCV10_PLUS(dev)) {
> >  			mfc_debug(2, "Use min scratch buffer size\n");
> >  			ctx->me_buffer_size =
> >  				ALIGN(ENC_V100_VP8_ME_SIZE(mb_width,
> mb_height), @@ -297,9
> > +348,14 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct
> s5p_mfc_ctx *ctx)
> >  		ctx->bank2.size = 0;
> >  		break;
> >  	case S5P_MFC_CODEC_HEVC_ENC:
> > +		if (IS_MFCV12(dev))
> > +			ctx->me_buffer_size =
> > +				ENC_V120_HEVC_ME_SIZE(lcu_width,
> lcu_height);
> > +		else
> > +			ctx->me_buffer_size =
> > +				ALIGN(ENC_V100_HEVC_ME_SIZE(lcu_width,
> > +							lcu_height), 16);
> >  		mfc_debug(2, "Use min scratch buffer size\n");
> > -		ctx->me_buffer_size =
> > -			ALIGN(ENC_V100_HEVC_ME_SIZE(lcu_width,
> lcu_height), 16);
> >  		ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, 256);
> >  		ctx->bank1.size =
> >  			ctx->scratch_buf_size + ctx->tmv_buffer_size + @@
> -452,12 +508,15
> > @@ static void s5p_mfc_dec_calc_dpb_size_v6(struct s5p_mfc_ctx *ctx)
> >
> >  	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
> >  			ctx->codec_mode ==
> S5P_MFC_CODEC_H264_MVC_DEC) {
> > -		if (IS_MFCV10_PLUS(dev)) {
> > -			ctx->mv_size = S5P_MFC_DEC_MV_SIZE_V10(ctx-
> >img_width,
> > -					ctx->img_height);
> > +		if (IS_MFCV12(dev)) {
> > +			ctx->mv_size = S5P_MFC_DEC_MV_SIZE(ctx-
> >img_width,
> > +					ctx->img_height, 1024);
> > +		} else if (IS_MFCV10_PLUS(dev)) {
> > +			ctx->mv_size = S5P_MFC_DEC_MV_SIZE(ctx-
> >img_width,
> > +					ctx->img_height, 512);
> >  		} else {
> > -			ctx->mv_size = S5P_MFC_DEC_MV_SIZE_V6(ctx-
> >img_width,
> > -					ctx->img_height);
> > +			ctx->mv_size = S5P_MFC_DEC_MV_SIZE(ctx-
> >img_width,
> > +					ctx->img_height, 128);
> >  		}
> >  	} else if (ctx->codec_mode == S5P_MFC_CODEC_HEVC_DEC) {
> >  		ctx->mv_size = s5p_mfc_dec_hevc_mv_size(ctx-
> >img_width,
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
> > index e4dd03c5454c..30269f3e68e8 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
> > @@ -19,10 +19,8 @@
> >
> >  #define MB_WIDTH(x_size)		DIV_ROUND_UP(x_size, 16)
> >  #define MB_HEIGHT(y_size)		DIV_ROUND_UP(y_size, 16)
> > -#define S5P_MFC_DEC_MV_SIZE_V6(x, y)	(MB_WIDTH(x) * \
> > -					(((MB_HEIGHT(y)+1)/2)*2) * 64 +
> 128)
> > -#define S5P_MFC_DEC_MV_SIZE_V10(x, y)	(MB_WIDTH(x) * \
> > -					(((MB_HEIGHT(y)+1)/2)*2) * 64 +
> 512)
> > +#define S5P_MFC_DEC_MV_SIZE(x, y, offset)	(MB_WIDTH(x) * \
> > +					(((MB_HEIGHT(y)+1)/2)*2) * 64 +
> offset)
> >  #define S5P_MFC_LCU_WIDTH(x_size)	DIV_ROUND_UP(x_size, 32)
> >  #define S5P_MFC_LCU_HEIGHT(y_size)	DIV_ROUND_UP(y_size, 32)
> >



_______________________________________________
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] 54+ messages in thread

* RE: [Patch v4 04/11] media: s5p-mfc: Add YV12 and I420 multiplanar format support
  2023-11-23 17:25         ` Nicolas Dufresne
@ 2023-11-27  7:00           ` Aakarsh Jain
  -1 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-11-27  7:00 UTC (permalink / raw)
  To: 'Nicolas Dufresne',
	linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	linux-fsd, 'Smitha T Murthy'

Hi Nicolas,

> -----Original Message-----
> From: Nicolas Dufresne <nicolas@ndufresne.ca>
> Sent: 23 November 2023 22:56
> To: Aakarsh Jain <aakarsh.jain@samsung.com>; linux-arm-
> kernel@lists.infradead.org; linux-media@vger.kernel.org; linux-
> kernel@vger.kernel.org; devicetree@vger.kernel.org
> Cc: m.szyprowski@samsung.com; andrzej.hajda@intel.com;
> mchehab@kernel.org; hverkuil-cisco@xs4all.nl;
> krzysztof.kozlowski+dt@linaro.org; dillon.minfei@gmail.com;
> david.plowman@raspberrypi.com; mark.rutland@arm.com;
> robh+dt@kernel.org; conor+dt@kernel.org; linux-samsung-
> soc@vger.kernel.org; andi@etezian.org; gost.dev@samsung.com;
> alim.akhtar@samsung.com; aswani.reddy@samsung.com;
> pankaj.dubey@samsung.com; ajaykumar.rs@samsung.com; linux-
> fsd@tesla.com; Smitha T Murthy <smithatmurthy@gmail.com>
> Subject: Re: [Patch v4 04/11] media: s5p-mfc: Add YV12 and I420 multiplanar
> format support
> 
> Le mercredi 25 octobre 2023 à 15:52 +0530, Aakarsh Jain a écrit :
> > YV12 and I420 format (3-plane) support is added. Stride information is
> > added to all formats and planes since it is necessary for YV12/I420
> > which are different from width.
> >
> > Cc: linux-fsd@tesla.com
> > Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
> > Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
> > ---
> >  .../platform/samsung/s5p-mfc/regs-mfc-v12.h   |   2 +
> >  .../platform/samsung/s5p-mfc/regs-mfc-v7.h    |   1 +
> >  .../platform/samsung/s5p-mfc/regs-mfc-v8.h    |   3 +
> >  .../platform/samsung/s5p-mfc/s5p_mfc_common.h |   4 +
> >  .../platform/samsung/s5p-mfc/s5p_mfc_dec.c    |  45 ++++-
> >  .../platform/samsung/s5p-mfc/s5p_mfc_enc.c    |  86 +++++++--
> >  .../platform/samsung/s5p-mfc/s5p_mfc_opr.h    |   6 +-
> >  .../platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c |  12 +-
> > .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 168
> +++++++++++++++---
> >  9 files changed, 281 insertions(+), 46 deletions(-)
> >
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> > b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> > index 6c68a45082d0..70464f47c1f9 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> > +++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> > @@ -26,6 +26,8 @@
> >  #define MFC_VERSION_V12			0xC0
> >  #define MFC_NUM_PORTS_V12		1
> >  #define S5P_FIMV_CODEC_VP9_ENC		27
> > +#define MFC_CHROMA_PAD_BYTES_V12        256
> > +#define S5P_FIMV_D_ALIGN_PLANE_SIZE_V12 256
> >
> >  /* Encoder buffer size for MFCv12 */
> >  #define ENC_V120_BASE_SIZE(x, y) \
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
> > b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
> > index 4a7adfdaa359..50f9bf0603c1 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
> > +++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
> > @@ -24,6 +24,7 @@
> >
> >  #define S5P_FIMV_E_ENCODED_SOURCE_FIRST_ADDR_V7
> 	0xfa70
> >  #define S5P_FIMV_E_ENCODED_SOURCE_SECOND_ADDR_V7
> 	0xfa74
> > +#define S5P_FIMV_E_ENCODED_SOURCE_THIRD_ADDR_V7
> 	0xfa78
> >
> >  #define S5P_FIMV_E_VP8_OPTIONS_V7			0xfdb0
> >  #define S5P_FIMV_E_VP8_FILTER_OPTIONS_V7		0xfdb4
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
> > b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
> > index 162e3c7e920f..0ef9eb2dff22 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
> > +++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
> > @@ -17,13 +17,16 @@
> >  #define S5P_FIMV_D_MIN_SCRATCH_BUFFER_SIZE_V8	0xf108
> >  #define S5P_FIMV_D_FIRST_PLANE_DPB_SIZE_V8	0xf144
> >  #define S5P_FIMV_D_SECOND_PLANE_DPB_SIZE_V8	0xf148
> > +#define S5P_FIMV_D_THIRD_PLANE_DPB_SIZE_V8	0xf14C
> >  #define S5P_FIMV_D_MV_BUFFER_SIZE_V8		0xf150
> >
> >  #define S5P_FIMV_D_FIRST_PLANE_DPB_STRIDE_SIZE_V8	0xf138
> >  #define S5P_FIMV_D_SECOND_PLANE_DPB_STRIDE_SIZE_V8
> 	0xf13c
> > +#define S5P_FIMV_D_THIRD_PLANE_DPB_STRIDE_SIZE_V8
> 	0xf140
> >
> >  #define S5P_FIMV_D_FIRST_PLANE_DPB_V8		0xf160
> >  #define S5P_FIMV_D_SECOND_PLANE_DPB_V8		0xf260
> > +#define S5P_FIMV_D_THIRD_PLANE_DPB_V8		0xf360
> >  #define S5P_FIMV_D_MV_BUFFER_V8			0xf460
> >
> >  #define S5P_FIMV_D_NUM_MV_V8			0xf134
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> > index dd2e9f7704ab..9a39cccfe002 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> > @@ -56,6 +56,7 @@
> >  #define MFC_NO_INSTANCE_SET	-1
> >  #define MFC_ENC_CAP_PLANE_COUNT	1
> >  #define MFC_ENC_OUT_PLANE_COUNT	2
> > +#define VB2_MAX_PLANE_COUNT	3
> >  #define STUFF_BYTE		4
> >  #define MFC_MAX_CTRLS		128
> >
> > @@ -181,6 +182,7 @@ struct s5p_mfc_buf {
> >  		struct {
> >  			size_t luma;
> >  			size_t chroma;
> > +			size_t chroma_1;
> >  		} raw;
> >  		size_t stream;
> >  	} cookie;
> > @@ -657,6 +659,7 @@ struct s5p_mfc_ctx {
> >
> >  	int luma_size;
> >  	int chroma_size;
> > +	int chroma_size_1;
> >  	int mv_size;
> >
> >  	unsigned long consumed_stream;
> > @@ -722,6 +725,7 @@ struct s5p_mfc_ctx {
> >  	size_t scratch_buf_size;
> >  	int is_10bit;
> >  	int is_422;
> > +	int stride[VB2_MAX_PLANE_COUNT];
> >  };
> >
> >  /*
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> > index e219cbcd86d5..317f796fffa1 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> > @@ -56,6 +56,20 @@ static struct s5p_mfc_fmt formats[] = {
> >  		.num_planes	= 2,
> >  		.versions	= MFC_V6PLUS_BITS,
> >  	},
> > +	{
> > +		.fourcc         = V4L2_PIX_FMT_YUV420M,
> > +		.codec_mode     = S5P_MFC_CODEC_NONE,
> > +		.type           = MFC_FMT_RAW,
> > +		.num_planes     = 3,
> > +		.versions       = MFC_V12_BIT,
> > +	},
> > +	{
> > +		.fourcc         = V4L2_PIX_FMT_YVU420M,
> > +		.codec_mode     = S5P_MFC_CODEC_NONE,
> > +		.type           = MFC_FMT_RAW,
> > +		.num_planes     = 3,
> > +		.versions       = MFC_V12_BIT
> > +	},
> >  	{
> >  		.fourcc		= V4L2_PIX_FMT_H264,
> >  		.codec_mode	= S5P_MFC_CODEC_H264_DEC,
> > @@ -359,10 +373,15 @@ static int vidioc_g_fmt(struct file *file, void *priv,
> struct v4l2_format *f)
> >  		/* Set pixelformat to the format in which MFC
> >  		   outputs the decoded frame */
> >  		pix_mp->pixelformat = ctx->dst_fmt->fourcc;
> > -		pix_mp->plane_fmt[0].bytesperline = ctx->buf_width;
> > +		pix_mp->plane_fmt[0].bytesperline = ctx->stride[0];
> >  		pix_mp->plane_fmt[0].sizeimage = ctx->luma_size;
> > -		pix_mp->plane_fmt[1].bytesperline = ctx->buf_width;
> > +		pix_mp->plane_fmt[1].bytesperline = ctx->stride[1];
> >  		pix_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M) {
> > +			pix_mp->plane_fmt[2].bytesperline = ctx->stride[2];
> > +			pix_mp->plane_fmt[2].sizeimage = ctx-
> >chroma_size_1;
> > +		}
> >  	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
> >  		/* This is run on OUTPUT
> >  		   The buffer contains compressed image @@ -937,6 +956,9
> @@ static
> > int s5p_mfc_queue_setup(struct vb2_queue *vq,
> >  		   vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
> >  		/* Output plane count is 2 - one for Y and one for CbCr */
> >  		*plane_count = 2;
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +			*plane_count = 3;
> 
> I don't usually interfere, this is your driver to maintain, but this becomes
> horribly messy. Have you consider de-hardcoding a little and encapsulate per
> HW format details into a C structure ? Drivers these days try to make sure of
> v4l2- common library, which as a matter of fact knows that YUV420M and
> YVU420M have 3 places, so that you don't have to duplicate it in your driver.
> 
> regards,
> Nicolas

Thanks for pointing out.
We could have done it in this way ' *plane_count = ctx->dst_fmt->num_planes' also.
Anyway, will make use of ' v4l2- common library ' for getting the planes count here in next series.

Thanks for the review.
> 
> >  		/* Setup buffer count */
> >  		if (*buf_count < ctx->pb_count)
> >  			*buf_count = ctx->pb_count;
> > @@ -955,12 +977,17 @@ static int s5p_mfc_queue_setup(struct
> vb2_queue *vq,
> >  	    vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
> >  		psize[0] = ctx->luma_size;
> >  		psize[1] = ctx->chroma_size;
> > -
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +			psize[2] = ctx->chroma_size_1;
> >  		if (IS_MFCV6_PLUS(dev))
> >  			alloc_devs[0] = ctx->dev->mem_dev[BANK_L_CTX];
> >  		else
> >  			alloc_devs[0] = ctx->dev->mem_dev[BANK_R_CTX];
> >  		alloc_devs[1] = ctx->dev->mem_dev[BANK_L_CTX];
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +			alloc_devs[2] = ctx->dev->mem_dev[BANK_L_CTX];
> >  	} else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
> >  		   ctx->state == MFCINST_INIT) {
> >  		psize[0] = ctx->dec_src_buf_size;
> > @@ -994,12 +1021,24 @@ static int s5p_mfc_buf_init(struct vb2_buffer
> *vb)
> >  			mfc_err("Plane buffer (CAPTURE) is too small\n");
> >  			return -EINVAL;
> >  		}
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M) {
> > +			if (vb2_plane_size(vb, 2) < ctx->chroma_size_1) {
> > +				mfc_err("Plane buffer (CAPTURE) is too
> small\n");
> > +				return -EINVAL;
> > +			}
> > +		}
> >  		i = vb->index;
> >  		ctx->dst_bufs[i].b = vbuf;
> >  		ctx->dst_bufs[i].cookie.raw.luma =
> >
> 	vb2_dma_contig_plane_dma_addr(vb, 0);
> >  		ctx->dst_bufs[i].cookie.raw.chroma =
> >
> 	vb2_dma_contig_plane_dma_addr(vb, 1);
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M) {
> > +			ctx->dst_bufs[i].cookie.raw.chroma_1 =
> > +
> 	vb2_dma_contig_plane_dma_addr(vb, 2);
> > +		}
> >  		ctx->dst_bufs_cnt++;
> >  	} else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
> >  		if (IS_ERR_OR_NULL(ERR_PTR(
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> > index e4d6e7c117b5..0eec04eb3ef3 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> > @@ -59,6 +59,20 @@ static struct s5p_mfc_fmt formats[] = {
> >  		.num_planes	= 2,
> >  		.versions	= MFC_V6PLUS_BITS,
> >  	},
> > +	{
> > +		.fourcc         = V4L2_PIX_FMT_YUV420M,
> > +		.codec_mode     = S5P_MFC_CODEC_NONE,
> > +		.type           = MFC_FMT_RAW,
> > +		.num_planes     = 3,
> > +		.versions       = MFC_V12_BIT,
> > +	},
> > +	{
> > +		.fourcc         = V4L2_PIX_FMT_YVU420M,
> > +		.codec_mode     = S5P_MFC_CODEC_NONE,
> > +		.type           = MFC_FMT_RAW,
> > +		.num_planes     = 3,
> > +		.versions       = MFC_V12_BIT,
> > +	},
> >  	{
> >  		.fourcc		= V4L2_PIX_FMT_H264,
> >  		.codec_mode	= S5P_MFC_CODEC_H264_ENC,
> > @@ -1193,14 +1207,20 @@ static int enc_pre_frame_start(struct
> s5p_mfc_ctx *ctx)
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >  	struct s5p_mfc_buf *dst_mb;
> >  	struct s5p_mfc_buf *src_mb;
> > -	unsigned long src_y_addr, src_c_addr, dst_addr;
> > +	unsigned long src_y_addr, src_c_addr, src_c_1_addr, dst_addr;
> >  	unsigned int dst_size;
> >
> >  	src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
> >  	src_y_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b-
> >vb2_buf, 0);
> >  	src_c_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b-
> >vb2_buf, 1);
> > +	if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +			ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> > +		src_c_1_addr =
> > +			vb2_dma_contig_plane_dma_addr(&src_mb->b-
> >vb2_buf, 2);
> > +	else
> > +		src_c_1_addr = 0;
> >  	s5p_mfc_hw_call(dev->mfc_ops, set_enc_frame_buffer, ctx,
> > -							src_y_addr,
> src_c_addr);
> > +					src_y_addr, src_c_addr,
> src_c_1_addr);
> >
> >  	dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
> >  	dst_addr = vb2_dma_contig_plane_dma_addr(&dst_mb->b-
> >vb2_buf, 0); @@
> > -1215,8 +1235,8 @@ static int enc_post_frame_start(struct s5p_mfc_ctx
> > *ctx)  {
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >  	struct s5p_mfc_buf *mb_entry;
> > -	unsigned long enc_y_addr = 0, enc_c_addr = 0;
> > -	unsigned long mb_y_addr, mb_c_addr;
> > +	unsigned long enc_y_addr = 0, enc_c_addr = 0, enc_c_1_addr = 0;
> > +	unsigned long mb_y_addr, mb_c_addr, mb_c_1_addr;
> >  	int slice_type;
> >  	unsigned int strm_size;
> >  	bool src_ready;
> > @@ -1229,14 +1249,21 @@ static int enc_post_frame_start(struct
> s5p_mfc_ctx *ctx)
> >  		  mfc_read(dev, S5P_FIMV_ENC_SI_PIC_CNT));
> >  	if (slice_type >= 0) {
> >  		s5p_mfc_hw_call(dev->mfc_ops, get_enc_frame_buffer,
> ctx,
> > -				&enc_y_addr, &enc_c_addr);
> > +				&enc_y_addr, &enc_c_addr,
> &enc_c_1_addr);
> >  		list_for_each_entry(mb_entry, &ctx->src_queue, list) {
> >  			mb_y_addr = vb2_dma_contig_plane_dma_addr(
> >  					&mb_entry->b->vb2_buf, 0);
> >  			mb_c_addr = vb2_dma_contig_plane_dma_addr(
> >  					&mb_entry->b->vb2_buf, 1);
> > -			if ((enc_y_addr == mb_y_addr) &&
> > -						(enc_c_addr == mb_c_addr))
> {
> > +			if (ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +				mb_c_1_addr =
> vb2_dma_contig_plane_dma_addr
> > +						(&mb_entry->b->vb2_buf,
> 2);
> > +			else
> > +				mb_c_1_addr = 0;
> > +			if ((enc_y_addr == mb_y_addr)
> > +					&& (enc_c_addr == mb_c_addr)
> > +					&& (enc_c_1_addr ==
> mb_c_1_addr)) {
> >  				list_del(&mb_entry->list);
> >  				ctx->src_queue_cnt--;
> >  				vb2_buffer_done(&mb_entry->b->vb2_buf,
> > @@ -1249,8 +1276,15 @@ static int enc_post_frame_start(struct
> s5p_mfc_ctx *ctx)
> >  					&mb_entry->b->vb2_buf, 0);
> >  			mb_c_addr = vb2_dma_contig_plane_dma_addr(
> >  					&mb_entry->b->vb2_buf, 1);
> > -			if ((enc_y_addr == mb_y_addr) &&
> > -						(enc_c_addr == mb_c_addr))
> {
> > +			if (ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +				mb_c_1_addr =
> vb2_dma_contig_plane_dma_addr(
> > +						&mb_entry->b->vb2_buf, 2);
> > +			else
> > +				mb_c_1_addr = 0;
> > +			if ((enc_y_addr == mb_y_addr)
> > +					&& (enc_c_addr == mb_c_addr)
> > +					&& (enc_c_1_addr ==
> mb_c_1_addr)) {
> >  				list_del(&mb_entry->list);
> >  				ctx->ref_queue_cnt--;
> >  				vb2_buffer_done(&mb_entry->b->vb2_buf,
> > @@ -1381,10 +1415,15 @@ static int vidioc_g_fmt(struct file *file, void
> *priv, struct v4l2_format *f)
> >  		pix_fmt_mp->pixelformat = ctx->src_fmt->fourcc;
> >  		pix_fmt_mp->num_planes = ctx->src_fmt->num_planes;
> >
> > -		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
> > +		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->stride[0];
> >  		pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
> > -		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
> > +		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->stride[1];
> >  		pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
> > +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M) {
> > +			pix_fmt_mp->plane_fmt[2].bytesperline = ctx-
> >stride[2];
> > +			pix_fmt_mp->plane_fmt[2].sizeimage = ctx-
> >chroma_size_1;
> > +		}
> >  	} else {
> >  		mfc_err("invalid buf type\n");
> >  		return -EINVAL;
> > @@ -1468,9 +1507,14 @@ static int vidioc_s_fmt(struct file *file, void
> > *priv, struct v4l2_format *f)
> >
> >  		s5p_mfc_hw_call(dev->mfc_ops, enc_calc_src_size, ctx);
> >  		pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
> > -		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
> > +		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->stride[0];
> >  		pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
> > -		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
> > +		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->stride[1];
> > +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M) {
> > +			pix_fmt_mp->plane_fmt[2].bytesperline = ctx-
> >stride[2];
> > +			pix_fmt_mp->plane_fmt[2].sizeimage = ctx-
> >chroma_size_1;
> > +		}
> >
> >  		ctx->src_bufs_cnt = 0;
> >  		ctx->output_state = QUEUE_FREE;
> > @@ -2414,10 +2458,16 @@ static int s5p_mfc_queue_setup(struct
> > vb2_queue *vq,
> >
> >  		psize[0] = ctx->luma_size;
> >  		psize[1] = ctx->chroma_size;
> > +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +			psize[2] = ctx->chroma_size_1;
> >
> >  		if (IS_MFCV6_PLUS(dev)) {
> >  			alloc_devs[0] = ctx->dev->mem_dev[BANK_L_CTX];
> >  			alloc_devs[1] = ctx->dev->mem_dev[BANK_L_CTX];
> > +			if (ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +				alloc_devs[2] = ctx->dev-
> >mem_dev[BANK_L_CTX];
> >  		} else {
> >  			alloc_devs[0] = ctx->dev->mem_dev[BANK_R_CTX];
> >  			alloc_devs[1] = ctx->dev->mem_dev[BANK_R_CTX];
> @@ -2456,6 +2506,10
> > @@ static int s5p_mfc_buf_init(struct vb2_buffer *vb)
> >
> 	vb2_dma_contig_plane_dma_addr(vb, 0);
> >  		ctx->src_bufs[i].cookie.raw.chroma =
> >
> 	vb2_dma_contig_plane_dma_addr(vb, 1);
> > +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +			ctx->src_bufs[i].cookie.raw.chroma_1 =
> > +
> 	vb2_dma_contig_plane_dma_addr(vb, 2);
> >  		ctx->src_bufs_cnt++;
> >  	} else {
> >  		mfc_err("invalid queue type: %d\n", vq->type); @@ -2493,6
> +2547,12
> > @@ static int s5p_mfc_buf_prepare(struct vb2_buffer *vb)
> >  			mfc_err("plane size is too small for output\n");
> >  			return -EINVAL;
> >  		}
> > +		if ((ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +		     ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) &&
> > +		    (vb2_plane_size(vb, 2) < ctx->chroma_size_1)) {
> > +			mfc_err("plane size is too small for output\n");
> > +			return -EINVAL;
> > +		}
> >  	} else {
> >  		mfc_err("invalid queue type: %d\n", vq->type);
> >  		return -EINVAL;
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> > index 87ac56756a16..7c5e851c8191 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> > @@ -293,9 +293,11 @@ struct s5p_mfc_hw_ops {
> >  	int (*set_enc_stream_buffer)(struct s5p_mfc_ctx *ctx,
> >  			unsigned long addr, unsigned int size);
> >  	void (*set_enc_frame_buffer)(struct s5p_mfc_ctx *ctx,
> > -			unsigned long y_addr, unsigned long c_addr);
> > +			unsigned long y_addr, unsigned long c_addr,
> > +			unsigned long c_1_addr);
> >  	void (*get_enc_frame_buffer)(struct s5p_mfc_ctx *ctx,
> > -			unsigned long *y_addr, unsigned long *c_addr);
> > +			unsigned long *y_addr, unsigned long *c_addr,
> > +			unsigned long *c_1_addr);
> >  	void (*try_run)(struct s5p_mfc_dev *dev);
> >  	void (*clear_int_flags)(struct s5p_mfc_dev *dev);
> >  	int (*get_dspl_y_adr)(struct s5p_mfc_dev *dev); diff --git
> > a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
> > index 28a06dc343fd..fcfaf125a5a1 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
> > @@ -516,7 +516,8 @@ static int
> s5p_mfc_set_enc_stream_buffer_v5(struct
> > s5p_mfc_ctx *ctx,  }
> >
> >  static void s5p_mfc_set_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,
> > -		unsigned long y_addr, unsigned long c_addr)
> > +		unsigned long y_addr, unsigned long c_addr,
> > +		unsigned long c_1_addr)
> >  {
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >
> > @@ -525,7 +526,8 @@ static void
> s5p_mfc_set_enc_frame_buffer_v5(struct
> > s5p_mfc_ctx *ctx,  }
> >
> >  static void s5p_mfc_get_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,
> > -		unsigned long *y_addr, unsigned long *c_addr)
> > +		unsigned long *y_addr, unsigned long *c_addr,
> > +		unsigned long *c_1_addr)
> >  {
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >
> > @@ -1210,7 +1212,7 @@ static int s5p_mfc_run_enc_frame(struct
> s5p_mfc_ctx *ctx)
> >  	if (list_empty(&ctx->src_queue)) {
> >  		/* send null frame */
> >  		s5p_mfc_set_enc_frame_buffer_v5(ctx, dev-
> >dma_base[BANK_R_CTX],
> > -						dev-
> >dma_base[BANK_R_CTX]);
> > +						dev-
> >dma_base[BANK_R_CTX], 0);
> >  		src_mb = NULL;
> >  	} else {
> >  		src_mb = list_entry(ctx->src_queue.next, struct
> s5p_mfc_buf, @@
> > -1220,7 +1222,7 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx
> *ctx)
> >  			/* send null frame */
> >  			s5p_mfc_set_enc_frame_buffer_v5(ctx,
> >  						dev-
> >dma_base[BANK_R_CTX],
> > -						dev-
> >dma_base[BANK_R_CTX]);
> > +						dev-
> >dma_base[BANK_R_CTX], 0);
> >  			ctx->state = MFCINST_FINISHING;
> >  		} else {
> >  			src_y_addr = vb2_dma_contig_plane_dma_addr(
> @@ -1228,7 +1230,7 @@
> > static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
> >  			src_c_addr = vb2_dma_contig_plane_dma_addr(
> >  					&src_mb->b->vb2_buf, 1);
> >  			s5p_mfc_set_enc_frame_buffer_v5(ctx, src_y_addr,
> > -								src_c_addr);
> > +								src_c_addr,
> 0);
> >  			if (src_mb->flags & MFC_BUF_FLAG_EOS)
> >  				ctx->state = MFCINST_FINISHING;
> >  		}
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> > index fb3f0718821d..e579c765e902 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> > @@ -494,16 +494,43 @@ static void s5p_mfc_dec_calc_dpb_size_v6(struct
> s5p_mfc_ctx *ctx)
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >  	ctx->buf_width = ALIGN(ctx->img_width,
> S5P_FIMV_NV12MT_HALIGN_V6);
> >  	ctx->buf_height = ALIGN(ctx->img_height,
> S5P_FIMV_NV12MT_VALIGN_V6);
> > +	ctx->chroma_size_1 = 0;
> >  	mfc_debug(2, "SEQ Done: Movie dimensions %dx%d,\n"
> >  			"buffer dimensions: %dx%d\n", ctx->img_width,
> >  			ctx->img_height, ctx->buf_width, ctx->buf_height);
> >
> > -	ctx->luma_size = calc_plane(ctx->img_width, ctx->img_height);
> > -	ctx->chroma_size = calc_plane(ctx->img_width, (ctx->img_height >>
> 1));
> > +	switch (ctx->dst_fmt->fourcc) {
> > +	case V4L2_PIX_FMT_NV12M:
> > +	case V4L2_PIX_FMT_NV21M:
> > +		ctx->stride[0] = ALIGN(ctx->img_width,
> > +					S5P_FIMV_NV12MT_HALIGN_V6);
> > +		ctx->stride[1] = ALIGN(ctx->img_width,
> > +					S5P_FIMV_NV12MT_HALIGN_V6);
> > +		ctx->luma_size = calc_plane(ctx->stride[0], ctx->img_height);
> > +		ctx->chroma_size = calc_plane(ctx->stride[1],
> > +					(ctx->img_height / 2));
> > +		break;
> > +	case V4L2_PIX_FMT_YUV420M:
> > +	case V4L2_PIX_FMT_YVU420M:
> > +		ctx->stride[0] = ALIGN(ctx->img_width,
> > +					S5P_FIMV_NV12MT_HALIGN_V6);
> > +		ctx->stride[1] = ALIGN(ctx->img_width / 2,
> > +					S5P_FIMV_NV12MT_HALIGN_V6);
> > +		ctx->stride[2] = ALIGN(ctx->img_width / 2,
> > +					S5P_FIMV_NV12MT_HALIGN_V6);
> > +		ctx->luma_size = calc_plane(ctx->stride[0], ctx->img_height);
> > +		ctx->chroma_size = calc_plane(ctx->stride[1],
> > +					(ctx->img_height / 2));
> > +		ctx->chroma_size_1 = calc_plane(ctx->stride[2],
> > +					(ctx->img_height / 2));
> > +		break;
> > +	}
> > +
> >  	if (IS_MFCV8_PLUS(ctx->dev)) {
> >  		/* MFCv8 needs additional 64 bytes for luma,chroma dpb*/
> >  		ctx->luma_size += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8;
> >  		ctx->chroma_size += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8;
> > +		ctx->chroma_size_1 +=
> S5P_FIMV_D_ALIGN_PLANE_SIZE_V8;
> >  	}
> >
> >  	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC || @@ -534,15
> +561,53
> > @@ static void s5p_mfc_enc_calc_src_size_v6(struct s5p_mfc_ctx *ctx)
> >  	mb_width = MB_WIDTH(ctx->img_width);
> >  	mb_height = MB_HEIGHT(ctx->img_height);
> >
> > -	ctx->buf_width = ALIGN(ctx->img_width,
> S5P_FIMV_NV12M_HALIGN_V6);
> > -	ctx->luma_size = ALIGN((mb_width * mb_height) * 256, 256);
> > -	ctx->chroma_size = ALIGN((mb_width * mb_height) * 128, 256);
> > -
> > -	/* MFCv7 needs pad bytes for Luma and Chroma */
> > -	if (IS_MFCV7_PLUS(ctx->dev)) {
> > +	if (IS_MFCV12(ctx->dev)) {
> > +		switch (ctx->src_fmt->fourcc) {
> > +		case V4L2_PIX_FMT_NV12M:
> > +		case V4L2_PIX_FMT_NV21M:
> > +			ctx->stride[0] = ALIGN(ctx->img_width,
> > +
> 	S5P_FIMV_NV12M_HALIGN_V6);
> > +			ctx->stride[1] = ALIGN(ctx->img_width,
> > +
> 	S5P_FIMV_NV12M_HALIGN_V6);
> > +			ctx->luma_size = ctx->stride[0] *
> > +						ALIGN(ctx->img_height, 16);
> > +			ctx->chroma_size =  ctx->stride[0] *
> > +						ALIGN(ctx->img_height / 2,
> 16);
> > +			break;
> > +		case V4L2_PIX_FMT_YUV420M:
> > +		case V4L2_PIX_FMT_YVU420M:
> > +			ctx->stride[0] = ALIGN(ctx->img_width,
> > +
> 	S5P_FIMV_NV12M_HALIGN_V6);
> > +			ctx->stride[1] = ALIGN(ctx->img_width / 2,
> > +
> 	S5P_FIMV_NV12M_HALIGN_V6);
> > +			ctx->stride[2] = ALIGN(ctx->img_width / 2,
> > +
> 	S5P_FIMV_NV12M_HALIGN_V6);
> > +			ctx->luma_size = ctx->stride[0] *
> > +						ALIGN(ctx->img_height, 16);
> > +			ctx->chroma_size =  ctx->stride[1] *
> > +						ALIGN(ctx->img_height / 2,
> 16);
> > +			ctx->chroma_size_1 =  ctx->stride[2] *
> > +						ALIGN(ctx->img_height / 2,
> 16);
> > +			break;
> > +		}
> >  		ctx->luma_size += MFC_LUMA_PAD_BYTES_V7;
> > -		ctx->chroma_size += MFC_CHROMA_PAD_BYTES_V7;
> > +		ctx->chroma_size += MFC_CHROMA_PAD_BYTES_V12;
> > +		ctx->chroma_size_1 += MFC_CHROMA_PAD_BYTES_V12;
> > +	} else {
> > +		ctx->buf_width = ALIGN(ctx->img_width,
> > +					S5P_FIMV_NV12M_HALIGN_V6);
> > +		ctx->stride[0] = ctx->buf_width;
> > +		ctx->stride[1] = ctx->buf_width;
> > +		ctx->luma_size = ALIGN((mb_width * mb_height) * 256,
> 256);
> > +		ctx->chroma_size = ALIGN((mb_width * mb_height) * 128,
> 256);
> > +		ctx->chroma_size_1 = 0;
> > +		/* MFCv7 needs pad bytes for Luma and Chroma */
> > +		if (IS_MFCV7_PLUS(ctx->dev)) {
> > +			ctx->luma_size += MFC_LUMA_PAD_BYTES_V7;
> > +			ctx->chroma_size += MFC_LUMA_PAD_BYTES_V7;
> > +		}
> >  	}
> > +
> >  }
> >
> >  /* Set registers for decoding stream buffer */ @@ -588,15 +653,21 @@
> > static int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx)
> >  	writel(ctx->total_dpb_count, mfc_regs->d_num_dpb);
> >  	writel(ctx->luma_size, mfc_regs->d_first_plane_dpb_size);
> >  	writel(ctx->chroma_size, mfc_regs->d_second_plane_dpb_size);
> > -
> > +	if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +			ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> > +		writel(ctx->chroma_size_1, mfc_regs-
> >d_third_plane_dpb_size);
> >  	writel(buf_addr1, mfc_regs->d_scratch_buffer_addr);
> >  	writel(ctx->scratch_buf_size, mfc_regs->d_scratch_buffer_size);
> >
> >  	if (IS_MFCV8_PLUS(dev)) {
> > -		writel(ctx->img_width,
> > +		writel(ctx->stride[0],
> >  			mfc_regs->d_first_plane_dpb_stride_size);
> > -		writel(ctx->img_width,
> > +		writel(ctx->stride[1],
> >  			mfc_regs->d_second_plane_dpb_stride_size);
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +			writel(ctx->stride[2],
> > +				mfc_regs->d_third_plane_dpb_stride_size);
> >  	}
> >
> >  	buf_addr1 += ctx->scratch_buf_size;
> > @@ -625,6 +696,13 @@ static int
> s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx)
> >  					ctx->dst_bufs[i].cookie.raw.chroma);
> >  		writel(ctx->dst_bufs[i].cookie.raw.chroma,
> >  				mfc_regs->d_second_plane_dpb + i * 4);
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M) {
> > +			mfc_debug(2, "\tChroma_1 %d: %zx\n", i,
> > +					ctx-
> >dst_bufs[i].cookie.raw.chroma_1);
> > +			writel(ctx->dst_bufs[i].cookie.raw.chroma_1,
> > +					mfc_regs->d_third_plane_dpb + i *
> 4);
> > +		}
> >  	}
> >  	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
> >  			ctx->codec_mode ==
> S5P_MFC_CODEC_H264_MVC_DEC || @@ -683,20
> > +761,24 @@ static int s5p_mfc_set_enc_stream_buffer_v6(struct
> > s5p_mfc_ctx *ctx,  }
> >
> >  static void s5p_mfc_set_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
> > -		unsigned long y_addr, unsigned long c_addr)
> > +		unsigned long y_addr, unsigned long c_addr,
> > +		unsigned long c_1_addr)
> >  {
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >  	const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs;
> >
> >  	writel(y_addr, mfc_regs->e_source_first_plane_addr);
> >  	writel(c_addr, mfc_regs->e_source_second_plane_addr);
> > +	writel(c_1_addr, mfc_regs->e_source_third_plane_addr);
> >
> >  	mfc_debug(2, "enc src y buf addr: 0x%08lx\n", y_addr);
> >  	mfc_debug(2, "enc src c buf addr: 0x%08lx\n", c_addr);
> > +	mfc_debug(2, "enc src cr buf addr: 0x%08lx\n", c_1_addr);
> >  }
> >
> >  static void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
> > -		unsigned long *y_addr, unsigned long *c_addr)
> > +		unsigned long *y_addr, unsigned long *c_addr,
> > +		unsigned long *c_1_addr)
> >  {
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >  	const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; @@ -704,12
> > +786,17 @@ static void s5p_mfc_get_enc_frame_buffer_v6(struct
> > s5p_mfc_ctx *ctx,
> >
> >  	*y_addr = readl(mfc_regs->e_encoded_source_first_plane_addr);
> >  	*c_addr = readl(mfc_regs-
> >e_encoded_source_second_plane_addr);
> > +	if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +			ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> > +		*c_1_addr = readl(mfc_regs-
> >e_encoded_source_third_plane_addr);
> > +	else
> > +		*c_1_addr = 0;
> >
> >  	enc_recon_y_addr = readl(mfc_regs->e_recon_luma_dpb_addr);
> >  	enc_recon_c_addr = readl(mfc_regs->e_recon_chroma_dpb_addr);
> >
> >  	mfc_debug(2, "recon y addr: 0x%08lx y_addr: 0x%08lx\n",
> enc_recon_y_addr, *y_addr);
> > -	mfc_debug(2, "recon c addr: 0x%08lx\n", enc_recon_c_addr);
> > +	mfc_debug(2, "recon c addr: 0x%08lx c_addr: 0x%08lx\n",
> > +enc_recon_c_addr, *c_addr);
> >  }
> >
> >  /* Set encoding ref & codec buffer */ @@ -886,6 +973,20 @@ static int
> > s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
> >  		writel(reg, mfc_regs->e_enc_options);
> >  		/* 0: NV12(CbCr), 1: NV21(CrCb) */
> >  		writel(0x0, mfc_regs->pixel_format);
> > +	} else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> > +		/* 0: Linear, 1: 2D tiled*/
> > +		reg = readl(mfc_regs->e_enc_options);
> > +		reg &= ~(0x1 << 7);
> > +		writel(reg, mfc_regs->e_enc_options);
> > +		/* 2: YV12(CrCb), 3: I420(CrCb) */
> > +		writel(0x2, mfc_regs->pixel_format);
> > +	} else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M) {
> > +		/* 0: Linear, 1: 2D tiled*/
> > +		reg = readl(mfc_regs->e_enc_options);
> > +		reg &= ~(0x1 << 7);
> > +		writel(reg, mfc_regs->e_enc_options);
> > +		/* 2: YV12(CrCb), 3: I420(CrCb) */
> > +		writel(0x3, mfc_regs->pixel_format);
> >  	}
> >
> >  	/* memory structure recon. frame */
> > @@ -1696,8 +1797,12 @@ static int s5p_mfc_init_decode_v6(struct
> s5p_mfc_ctx *ctx)
> >  	else
> >  		writel(reg, mfc_regs->d_dec_options);
> >
> > -	/* 0: NV12(CbCr), 1: NV21(CrCb) */
> > -	if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV21M)
> > +	/* 0: NV12(CbCr), 1: NV21(CrCb), 2: YV12(CrCb), 3: I420(CbCr) */
> > +	if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M)
> > +		writel(0x3, mfc_regs->pixel_format);
> > +	else if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> > +		writel(0x2, mfc_regs->pixel_format);
> > +	else if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV21M)
> >  		writel(0x1, mfc_regs->pixel_format);
> >  	else
> >  		writel(0x0, mfc_regs->pixel_format); @@ -1781,8 +1886,12
> @@ static
> > int s5p_mfc_init_encode_v6(struct s5p_mfc_ctx *ctx)
> >
> >  	/* Set stride lengths for v7 & above */
> >  	if (IS_MFCV7_PLUS(dev)) {
> > -		writel(ctx->img_width, mfc_regs-
> >e_source_first_plane_stride);
> > -		writel(ctx->img_width, mfc_regs-
> >e_source_second_plane_stride);
> > +		writel(ctx->stride[0], mfc_regs-
> >e_source_first_plane_stride);
> > +		writel(ctx->stride[1], mfc_regs-
> >e_source_second_plane_stride);
> > +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +			writel(ctx->stride[2],
> > +					mfc_regs-
> >e_source_third_plane_stride);
> >  	}
> >
> >  	writel(ctx->inst_no, mfc_regs->instance_id); @@ -1891,7 +2000,7
> @@
> > static inline int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >  	struct s5p_mfc_buf *dst_mb;
> >  	struct s5p_mfc_buf *src_mb;
> > -	unsigned long src_y_addr, src_c_addr, dst_addr;
> > +	unsigned long src_y_addr, src_c_addr, src_c_1_addr, dst_addr;
> >  	/*
> >  	unsigned int src_y_size, src_c_size;
> >  	*/
> > @@ -1909,22 +2018,29 @@ static inline int s5p_mfc_run_enc_frame(struct
> > s5p_mfc_ctx *ctx)
> >
> >  	if (list_empty(&ctx->src_queue)) {
> >  		/* send null frame */
> > -		s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0);
> > +		s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0, 0);
> >  		src_mb = NULL;
> >  	} else {
> >  		src_mb = list_entry(ctx->src_queue.next, struct
> s5p_mfc_buf, list);
> >  		src_mb->flags |= MFC_BUF_FLAG_USED;
> >  		if (src_mb->b->vb2_buf.planes[0].bytesused == 0) {
> > -			s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0);
> > +			s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0, 0);
> >  			ctx->state = MFCINST_FINISHING;
> >  		} else {
> >  			src_y_addr =
> vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 0);
> >  			src_c_addr =
> vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf,
> > 1);
> > +			if (ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +				src_c_1_addr =
> vb2_dma_contig_plane_dma_addr
> > +						(&src_mb->b->vb2_buf, 2);
> > +			else
> > +				src_c_1_addr = 0;
> >
> >  			mfc_debug(2, "enc src y addr: 0x%08lx\n",
> src_y_addr);
> >  			mfc_debug(2, "enc src c addr: 0x%08lx\n",
> src_c_addr);
> >
> > -			s5p_mfc_set_enc_frame_buffer_v6(ctx, src_y_addr,
> src_c_addr);
> > +			s5p_mfc_set_enc_frame_buffer_v6(ctx, src_y_addr,
> > +						src_c_addr, src_c_1_addr);
> >  			if (src_mb->flags & MFC_BUF_FLAG_EOS)
> >  				ctx->state = MFCINST_FINISHING;
> >  		}
> > @@ -2450,6 +2566,8 @@ const struct s5p_mfc_regs
> *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev)
> >  			S5P_FIMV_E_ENCODED_SOURCE_FIRST_ADDR_V7);
> >  	R(e_encoded_source_second_plane_addr,
> >
> 	S5P_FIMV_E_ENCODED_SOURCE_SECOND_ADDR_V7);
> > +	R(e_encoded_source_third_plane_addr,
> > +			S5P_FIMV_E_ENCODED_SOURCE_THIRD_ADDR_V7);
> >  	R(e_vp8_options, S5P_FIMV_E_VP8_OPTIONS_V7);
> >
> >  	if (!IS_MFCV8_PLUS(dev))
> > @@ -2464,16 +2582,20 @@ const struct s5p_mfc_regs
> *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev)
> >  	R(d_cpb_buffer_offset, S5P_FIMV_D_CPB_BUFFER_OFFSET_V8);
> >  	R(d_first_plane_dpb_size,
> S5P_FIMV_D_FIRST_PLANE_DPB_SIZE_V8);
> >  	R(d_second_plane_dpb_size,
> S5P_FIMV_D_SECOND_PLANE_DPB_SIZE_V8);
> > +	R(d_third_plane_dpb_size,
> S5P_FIMV_D_THIRD_PLANE_DPB_SIZE_V8);
> >  	R(d_scratch_buffer_addr,
> S5P_FIMV_D_SCRATCH_BUFFER_ADDR_V8);
> >  	R(d_scratch_buffer_size, S5P_FIMV_D_SCRATCH_BUFFER_SIZE_V8);
> >  	R(d_first_plane_dpb_stride_size,
> >  			S5P_FIMV_D_FIRST_PLANE_DPB_STRIDE_SIZE_V8);
> >  	R(d_second_plane_dpb_stride_size,
> >
> 	S5P_FIMV_D_SECOND_PLANE_DPB_STRIDE_SIZE_V8);
> > +	R(d_third_plane_dpb_stride_size,
> > +			S5P_FIMV_D_THIRD_PLANE_DPB_STRIDE_SIZE_V8);
> >  	R(d_mv_buffer_size, S5P_FIMV_D_MV_BUFFER_SIZE_V8);
> >  	R(d_num_mv, S5P_FIMV_D_NUM_MV_V8);
> >  	R(d_first_plane_dpb, S5P_FIMV_D_FIRST_PLANE_DPB_V8);
> >  	R(d_second_plane_dpb, S5P_FIMV_D_SECOND_PLANE_DPB_V8);
> > +	R(d_third_plane_dpb, S5P_FIMV_D_THIRD_PLANE_DPB_V8);
> >  	R(d_mv_buffer, S5P_FIMV_D_MV_BUFFER_V8);
> >  	R(d_init_buffer_options, S5P_FIMV_D_INIT_BUFFER_OPTIONS_V8);
> >  	R(d_available_dpb_flag_lower,
> > S5P_FIMV_D_AVAILABLE_DPB_FLAG_LOWER_V8);




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

* RE: [Patch v4 04/11] media: s5p-mfc: Add YV12 and I420 multiplanar format support
@ 2023-11-27  7:00           ` Aakarsh Jain
  0 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-11-27  7:00 UTC (permalink / raw)
  To: 'Nicolas Dufresne',
	linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, hverkuil-cisco,
	krzysztof.kozlowski+dt, dillon.minfei, david.plowman,
	mark.rutland, robh+dt, conor+dt, linux-samsung-soc, andi,
	gost.dev, alim.akhtar, aswani.reddy, pankaj.dubey, ajaykumar.rs,
	linux-fsd, 'Smitha T Murthy'

Hi Nicolas,

> -----Original Message-----
> From: Nicolas Dufresne <nicolas@ndufresne.ca>
> Sent: 23 November 2023 22:56
> To: Aakarsh Jain <aakarsh.jain@samsung.com>; linux-arm-
> kernel@lists.infradead.org; linux-media@vger.kernel.org; linux-
> kernel@vger.kernel.org; devicetree@vger.kernel.org
> Cc: m.szyprowski@samsung.com; andrzej.hajda@intel.com;
> mchehab@kernel.org; hverkuil-cisco@xs4all.nl;
> krzysztof.kozlowski+dt@linaro.org; dillon.minfei@gmail.com;
> david.plowman@raspberrypi.com; mark.rutland@arm.com;
> robh+dt@kernel.org; conor+dt@kernel.org; linux-samsung-
> soc@vger.kernel.org; andi@etezian.org; gost.dev@samsung.com;
> alim.akhtar@samsung.com; aswani.reddy@samsung.com;
> pankaj.dubey@samsung.com; ajaykumar.rs@samsung.com; linux-
> fsd@tesla.com; Smitha T Murthy <smithatmurthy@gmail.com>
> Subject: Re: [Patch v4 04/11] media: s5p-mfc: Add YV12 and I420 multiplanar
> format support
> 
> Le mercredi 25 octobre 2023 à 15:52 +0530, Aakarsh Jain a écrit :
> > YV12 and I420 format (3-plane) support is added. Stride information is
> > added to all formats and planes since it is necessary for YV12/I420
> > which are different from width.
> >
> > Cc: linux-fsd@tesla.com
> > Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
> > Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
> > ---
> >  .../platform/samsung/s5p-mfc/regs-mfc-v12.h   |   2 +
> >  .../platform/samsung/s5p-mfc/regs-mfc-v7.h    |   1 +
> >  .../platform/samsung/s5p-mfc/regs-mfc-v8.h    |   3 +
> >  .../platform/samsung/s5p-mfc/s5p_mfc_common.h |   4 +
> >  .../platform/samsung/s5p-mfc/s5p_mfc_dec.c    |  45 ++++-
> >  .../platform/samsung/s5p-mfc/s5p_mfc_enc.c    |  86 +++++++--
> >  .../platform/samsung/s5p-mfc/s5p_mfc_opr.h    |   6 +-
> >  .../platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c |  12 +-
> > .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 168
> +++++++++++++++---
> >  9 files changed, 281 insertions(+), 46 deletions(-)
> >
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> > b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> > index 6c68a45082d0..70464f47c1f9 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> > +++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> > @@ -26,6 +26,8 @@
> >  #define MFC_VERSION_V12			0xC0
> >  #define MFC_NUM_PORTS_V12		1
> >  #define S5P_FIMV_CODEC_VP9_ENC		27
> > +#define MFC_CHROMA_PAD_BYTES_V12        256
> > +#define S5P_FIMV_D_ALIGN_PLANE_SIZE_V12 256
> >
> >  /* Encoder buffer size for MFCv12 */
> >  #define ENC_V120_BASE_SIZE(x, y) \
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
> > b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
> > index 4a7adfdaa359..50f9bf0603c1 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
> > +++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
> > @@ -24,6 +24,7 @@
> >
> >  #define S5P_FIMV_E_ENCODED_SOURCE_FIRST_ADDR_V7
> 	0xfa70
> >  #define S5P_FIMV_E_ENCODED_SOURCE_SECOND_ADDR_V7
> 	0xfa74
> > +#define S5P_FIMV_E_ENCODED_SOURCE_THIRD_ADDR_V7
> 	0xfa78
> >
> >  #define S5P_FIMV_E_VP8_OPTIONS_V7			0xfdb0
> >  #define S5P_FIMV_E_VP8_FILTER_OPTIONS_V7		0xfdb4
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
> > b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
> > index 162e3c7e920f..0ef9eb2dff22 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
> > +++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
> > @@ -17,13 +17,16 @@
> >  #define S5P_FIMV_D_MIN_SCRATCH_BUFFER_SIZE_V8	0xf108
> >  #define S5P_FIMV_D_FIRST_PLANE_DPB_SIZE_V8	0xf144
> >  #define S5P_FIMV_D_SECOND_PLANE_DPB_SIZE_V8	0xf148
> > +#define S5P_FIMV_D_THIRD_PLANE_DPB_SIZE_V8	0xf14C
> >  #define S5P_FIMV_D_MV_BUFFER_SIZE_V8		0xf150
> >
> >  #define S5P_FIMV_D_FIRST_PLANE_DPB_STRIDE_SIZE_V8	0xf138
> >  #define S5P_FIMV_D_SECOND_PLANE_DPB_STRIDE_SIZE_V8
> 	0xf13c
> > +#define S5P_FIMV_D_THIRD_PLANE_DPB_STRIDE_SIZE_V8
> 	0xf140
> >
> >  #define S5P_FIMV_D_FIRST_PLANE_DPB_V8		0xf160
> >  #define S5P_FIMV_D_SECOND_PLANE_DPB_V8		0xf260
> > +#define S5P_FIMV_D_THIRD_PLANE_DPB_V8		0xf360
> >  #define S5P_FIMV_D_MV_BUFFER_V8			0xf460
> >
> >  #define S5P_FIMV_D_NUM_MV_V8			0xf134
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> > index dd2e9f7704ab..9a39cccfe002 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> > @@ -56,6 +56,7 @@
> >  #define MFC_NO_INSTANCE_SET	-1
> >  #define MFC_ENC_CAP_PLANE_COUNT	1
> >  #define MFC_ENC_OUT_PLANE_COUNT	2
> > +#define VB2_MAX_PLANE_COUNT	3
> >  #define STUFF_BYTE		4
> >  #define MFC_MAX_CTRLS		128
> >
> > @@ -181,6 +182,7 @@ struct s5p_mfc_buf {
> >  		struct {
> >  			size_t luma;
> >  			size_t chroma;
> > +			size_t chroma_1;
> >  		} raw;
> >  		size_t stream;
> >  	} cookie;
> > @@ -657,6 +659,7 @@ struct s5p_mfc_ctx {
> >
> >  	int luma_size;
> >  	int chroma_size;
> > +	int chroma_size_1;
> >  	int mv_size;
> >
> >  	unsigned long consumed_stream;
> > @@ -722,6 +725,7 @@ struct s5p_mfc_ctx {
> >  	size_t scratch_buf_size;
> >  	int is_10bit;
> >  	int is_422;
> > +	int stride[VB2_MAX_PLANE_COUNT];
> >  };
> >
> >  /*
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> > index e219cbcd86d5..317f796fffa1 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> > @@ -56,6 +56,20 @@ static struct s5p_mfc_fmt formats[] = {
> >  		.num_planes	= 2,
> >  		.versions	= MFC_V6PLUS_BITS,
> >  	},
> > +	{
> > +		.fourcc         = V4L2_PIX_FMT_YUV420M,
> > +		.codec_mode     = S5P_MFC_CODEC_NONE,
> > +		.type           = MFC_FMT_RAW,
> > +		.num_planes     = 3,
> > +		.versions       = MFC_V12_BIT,
> > +	},
> > +	{
> > +		.fourcc         = V4L2_PIX_FMT_YVU420M,
> > +		.codec_mode     = S5P_MFC_CODEC_NONE,
> > +		.type           = MFC_FMT_RAW,
> > +		.num_planes     = 3,
> > +		.versions       = MFC_V12_BIT
> > +	},
> >  	{
> >  		.fourcc		= V4L2_PIX_FMT_H264,
> >  		.codec_mode	= S5P_MFC_CODEC_H264_DEC,
> > @@ -359,10 +373,15 @@ static int vidioc_g_fmt(struct file *file, void *priv,
> struct v4l2_format *f)
> >  		/* Set pixelformat to the format in which MFC
> >  		   outputs the decoded frame */
> >  		pix_mp->pixelformat = ctx->dst_fmt->fourcc;
> > -		pix_mp->plane_fmt[0].bytesperline = ctx->buf_width;
> > +		pix_mp->plane_fmt[0].bytesperline = ctx->stride[0];
> >  		pix_mp->plane_fmt[0].sizeimage = ctx->luma_size;
> > -		pix_mp->plane_fmt[1].bytesperline = ctx->buf_width;
> > +		pix_mp->plane_fmt[1].bytesperline = ctx->stride[1];
> >  		pix_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M) {
> > +			pix_mp->plane_fmt[2].bytesperline = ctx->stride[2];
> > +			pix_mp->plane_fmt[2].sizeimage = ctx-
> >chroma_size_1;
> > +		}
> >  	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
> >  		/* This is run on OUTPUT
> >  		   The buffer contains compressed image @@ -937,6 +956,9
> @@ static
> > int s5p_mfc_queue_setup(struct vb2_queue *vq,
> >  		   vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
> >  		/* Output plane count is 2 - one for Y and one for CbCr */
> >  		*plane_count = 2;
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +			*plane_count = 3;
> 
> I don't usually interfere, this is your driver to maintain, but this becomes
> horribly messy. Have you consider de-hardcoding a little and encapsulate per
> HW format details into a C structure ? Drivers these days try to make sure of
> v4l2- common library, which as a matter of fact knows that YUV420M and
> YVU420M have 3 places, so that you don't have to duplicate it in your driver.
> 
> regards,
> Nicolas

Thanks for pointing out.
We could have done it in this way ' *plane_count = ctx->dst_fmt->num_planes' also.
Anyway, will make use of ' v4l2- common library ' for getting the planes count here in next series.

Thanks for the review.
> 
> >  		/* Setup buffer count */
> >  		if (*buf_count < ctx->pb_count)
> >  			*buf_count = ctx->pb_count;
> > @@ -955,12 +977,17 @@ static int s5p_mfc_queue_setup(struct
> vb2_queue *vq,
> >  	    vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
> >  		psize[0] = ctx->luma_size;
> >  		psize[1] = ctx->chroma_size;
> > -
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +			psize[2] = ctx->chroma_size_1;
> >  		if (IS_MFCV6_PLUS(dev))
> >  			alloc_devs[0] = ctx->dev->mem_dev[BANK_L_CTX];
> >  		else
> >  			alloc_devs[0] = ctx->dev->mem_dev[BANK_R_CTX];
> >  		alloc_devs[1] = ctx->dev->mem_dev[BANK_L_CTX];
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +			alloc_devs[2] = ctx->dev->mem_dev[BANK_L_CTX];
> >  	} else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
> >  		   ctx->state == MFCINST_INIT) {
> >  		psize[0] = ctx->dec_src_buf_size;
> > @@ -994,12 +1021,24 @@ static int s5p_mfc_buf_init(struct vb2_buffer
> *vb)
> >  			mfc_err("Plane buffer (CAPTURE) is too small\n");
> >  			return -EINVAL;
> >  		}
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M) {
> > +			if (vb2_plane_size(vb, 2) < ctx->chroma_size_1) {
> > +				mfc_err("Plane buffer (CAPTURE) is too
> small\n");
> > +				return -EINVAL;
> > +			}
> > +		}
> >  		i = vb->index;
> >  		ctx->dst_bufs[i].b = vbuf;
> >  		ctx->dst_bufs[i].cookie.raw.luma =
> >
> 	vb2_dma_contig_plane_dma_addr(vb, 0);
> >  		ctx->dst_bufs[i].cookie.raw.chroma =
> >
> 	vb2_dma_contig_plane_dma_addr(vb, 1);
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M) {
> > +			ctx->dst_bufs[i].cookie.raw.chroma_1 =
> > +
> 	vb2_dma_contig_plane_dma_addr(vb, 2);
> > +		}
> >  		ctx->dst_bufs_cnt++;
> >  	} else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
> >  		if (IS_ERR_OR_NULL(ERR_PTR(
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> > index e4d6e7c117b5..0eec04eb3ef3 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> > @@ -59,6 +59,20 @@ static struct s5p_mfc_fmt formats[] = {
> >  		.num_planes	= 2,
> >  		.versions	= MFC_V6PLUS_BITS,
> >  	},
> > +	{
> > +		.fourcc         = V4L2_PIX_FMT_YUV420M,
> > +		.codec_mode     = S5P_MFC_CODEC_NONE,
> > +		.type           = MFC_FMT_RAW,
> > +		.num_planes     = 3,
> > +		.versions       = MFC_V12_BIT,
> > +	},
> > +	{
> > +		.fourcc         = V4L2_PIX_FMT_YVU420M,
> > +		.codec_mode     = S5P_MFC_CODEC_NONE,
> > +		.type           = MFC_FMT_RAW,
> > +		.num_planes     = 3,
> > +		.versions       = MFC_V12_BIT,
> > +	},
> >  	{
> >  		.fourcc		= V4L2_PIX_FMT_H264,
> >  		.codec_mode	= S5P_MFC_CODEC_H264_ENC,
> > @@ -1193,14 +1207,20 @@ static int enc_pre_frame_start(struct
> s5p_mfc_ctx *ctx)
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >  	struct s5p_mfc_buf *dst_mb;
> >  	struct s5p_mfc_buf *src_mb;
> > -	unsigned long src_y_addr, src_c_addr, dst_addr;
> > +	unsigned long src_y_addr, src_c_addr, src_c_1_addr, dst_addr;
> >  	unsigned int dst_size;
> >
> >  	src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
> >  	src_y_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b-
> >vb2_buf, 0);
> >  	src_c_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b-
> >vb2_buf, 1);
> > +	if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +			ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> > +		src_c_1_addr =
> > +			vb2_dma_contig_plane_dma_addr(&src_mb->b-
> >vb2_buf, 2);
> > +	else
> > +		src_c_1_addr = 0;
> >  	s5p_mfc_hw_call(dev->mfc_ops, set_enc_frame_buffer, ctx,
> > -							src_y_addr,
> src_c_addr);
> > +					src_y_addr, src_c_addr,
> src_c_1_addr);
> >
> >  	dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
> >  	dst_addr = vb2_dma_contig_plane_dma_addr(&dst_mb->b-
> >vb2_buf, 0); @@
> > -1215,8 +1235,8 @@ static int enc_post_frame_start(struct s5p_mfc_ctx
> > *ctx)  {
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >  	struct s5p_mfc_buf *mb_entry;
> > -	unsigned long enc_y_addr = 0, enc_c_addr = 0;
> > -	unsigned long mb_y_addr, mb_c_addr;
> > +	unsigned long enc_y_addr = 0, enc_c_addr = 0, enc_c_1_addr = 0;
> > +	unsigned long mb_y_addr, mb_c_addr, mb_c_1_addr;
> >  	int slice_type;
> >  	unsigned int strm_size;
> >  	bool src_ready;
> > @@ -1229,14 +1249,21 @@ static int enc_post_frame_start(struct
> s5p_mfc_ctx *ctx)
> >  		  mfc_read(dev, S5P_FIMV_ENC_SI_PIC_CNT));
> >  	if (slice_type >= 0) {
> >  		s5p_mfc_hw_call(dev->mfc_ops, get_enc_frame_buffer,
> ctx,
> > -				&enc_y_addr, &enc_c_addr);
> > +				&enc_y_addr, &enc_c_addr,
> &enc_c_1_addr);
> >  		list_for_each_entry(mb_entry, &ctx->src_queue, list) {
> >  			mb_y_addr = vb2_dma_contig_plane_dma_addr(
> >  					&mb_entry->b->vb2_buf, 0);
> >  			mb_c_addr = vb2_dma_contig_plane_dma_addr(
> >  					&mb_entry->b->vb2_buf, 1);
> > -			if ((enc_y_addr == mb_y_addr) &&
> > -						(enc_c_addr == mb_c_addr))
> {
> > +			if (ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +				mb_c_1_addr =
> vb2_dma_contig_plane_dma_addr
> > +						(&mb_entry->b->vb2_buf,
> 2);
> > +			else
> > +				mb_c_1_addr = 0;
> > +			if ((enc_y_addr == mb_y_addr)
> > +					&& (enc_c_addr == mb_c_addr)
> > +					&& (enc_c_1_addr ==
> mb_c_1_addr)) {
> >  				list_del(&mb_entry->list);
> >  				ctx->src_queue_cnt--;
> >  				vb2_buffer_done(&mb_entry->b->vb2_buf,
> > @@ -1249,8 +1276,15 @@ static int enc_post_frame_start(struct
> s5p_mfc_ctx *ctx)
> >  					&mb_entry->b->vb2_buf, 0);
> >  			mb_c_addr = vb2_dma_contig_plane_dma_addr(
> >  					&mb_entry->b->vb2_buf, 1);
> > -			if ((enc_y_addr == mb_y_addr) &&
> > -						(enc_c_addr == mb_c_addr))
> {
> > +			if (ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +				mb_c_1_addr =
> vb2_dma_contig_plane_dma_addr(
> > +						&mb_entry->b->vb2_buf, 2);
> > +			else
> > +				mb_c_1_addr = 0;
> > +			if ((enc_y_addr == mb_y_addr)
> > +					&& (enc_c_addr == mb_c_addr)
> > +					&& (enc_c_1_addr ==
> mb_c_1_addr)) {
> >  				list_del(&mb_entry->list);
> >  				ctx->ref_queue_cnt--;
> >  				vb2_buffer_done(&mb_entry->b->vb2_buf,
> > @@ -1381,10 +1415,15 @@ static int vidioc_g_fmt(struct file *file, void
> *priv, struct v4l2_format *f)
> >  		pix_fmt_mp->pixelformat = ctx->src_fmt->fourcc;
> >  		pix_fmt_mp->num_planes = ctx->src_fmt->num_planes;
> >
> > -		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
> > +		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->stride[0];
> >  		pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
> > -		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
> > +		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->stride[1];
> >  		pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
> > +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M) {
> > +			pix_fmt_mp->plane_fmt[2].bytesperline = ctx-
> >stride[2];
> > +			pix_fmt_mp->plane_fmt[2].sizeimage = ctx-
> >chroma_size_1;
> > +		}
> >  	} else {
> >  		mfc_err("invalid buf type\n");
> >  		return -EINVAL;
> > @@ -1468,9 +1507,14 @@ static int vidioc_s_fmt(struct file *file, void
> > *priv, struct v4l2_format *f)
> >
> >  		s5p_mfc_hw_call(dev->mfc_ops, enc_calc_src_size, ctx);
> >  		pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
> > -		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
> > +		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->stride[0];
> >  		pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
> > -		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
> > +		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->stride[1];
> > +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M) {
> > +			pix_fmt_mp->plane_fmt[2].bytesperline = ctx-
> >stride[2];
> > +			pix_fmt_mp->plane_fmt[2].sizeimage = ctx-
> >chroma_size_1;
> > +		}
> >
> >  		ctx->src_bufs_cnt = 0;
> >  		ctx->output_state = QUEUE_FREE;
> > @@ -2414,10 +2458,16 @@ static int s5p_mfc_queue_setup(struct
> > vb2_queue *vq,
> >
> >  		psize[0] = ctx->luma_size;
> >  		psize[1] = ctx->chroma_size;
> > +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +			psize[2] = ctx->chroma_size_1;
> >
> >  		if (IS_MFCV6_PLUS(dev)) {
> >  			alloc_devs[0] = ctx->dev->mem_dev[BANK_L_CTX];
> >  			alloc_devs[1] = ctx->dev->mem_dev[BANK_L_CTX];
> > +			if (ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +				alloc_devs[2] = ctx->dev-
> >mem_dev[BANK_L_CTX];
> >  		} else {
> >  			alloc_devs[0] = ctx->dev->mem_dev[BANK_R_CTX];
> >  			alloc_devs[1] = ctx->dev->mem_dev[BANK_R_CTX];
> @@ -2456,6 +2506,10
> > @@ static int s5p_mfc_buf_init(struct vb2_buffer *vb)
> >
> 	vb2_dma_contig_plane_dma_addr(vb, 0);
> >  		ctx->src_bufs[i].cookie.raw.chroma =
> >
> 	vb2_dma_contig_plane_dma_addr(vb, 1);
> > +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +			ctx->src_bufs[i].cookie.raw.chroma_1 =
> > +
> 	vb2_dma_contig_plane_dma_addr(vb, 2);
> >  		ctx->src_bufs_cnt++;
> >  	} else {
> >  		mfc_err("invalid queue type: %d\n", vq->type); @@ -2493,6
> +2547,12
> > @@ static int s5p_mfc_buf_prepare(struct vb2_buffer *vb)
> >  			mfc_err("plane size is too small for output\n");
> >  			return -EINVAL;
> >  		}
> > +		if ((ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +		     ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) &&
> > +		    (vb2_plane_size(vb, 2) < ctx->chroma_size_1)) {
> > +			mfc_err("plane size is too small for output\n");
> > +			return -EINVAL;
> > +		}
> >  	} else {
> >  		mfc_err("invalid queue type: %d\n", vq->type);
> >  		return -EINVAL;
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> > index 87ac56756a16..7c5e851c8191 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> > @@ -293,9 +293,11 @@ struct s5p_mfc_hw_ops {
> >  	int (*set_enc_stream_buffer)(struct s5p_mfc_ctx *ctx,
> >  			unsigned long addr, unsigned int size);
> >  	void (*set_enc_frame_buffer)(struct s5p_mfc_ctx *ctx,
> > -			unsigned long y_addr, unsigned long c_addr);
> > +			unsigned long y_addr, unsigned long c_addr,
> > +			unsigned long c_1_addr);
> >  	void (*get_enc_frame_buffer)(struct s5p_mfc_ctx *ctx,
> > -			unsigned long *y_addr, unsigned long *c_addr);
> > +			unsigned long *y_addr, unsigned long *c_addr,
> > +			unsigned long *c_1_addr);
> >  	void (*try_run)(struct s5p_mfc_dev *dev);
> >  	void (*clear_int_flags)(struct s5p_mfc_dev *dev);
> >  	int (*get_dspl_y_adr)(struct s5p_mfc_dev *dev); diff --git
> > a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
> > index 28a06dc343fd..fcfaf125a5a1 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
> > @@ -516,7 +516,8 @@ static int
> s5p_mfc_set_enc_stream_buffer_v5(struct
> > s5p_mfc_ctx *ctx,  }
> >
> >  static void s5p_mfc_set_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,
> > -		unsigned long y_addr, unsigned long c_addr)
> > +		unsigned long y_addr, unsigned long c_addr,
> > +		unsigned long c_1_addr)
> >  {
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >
> > @@ -525,7 +526,8 @@ static void
> s5p_mfc_set_enc_frame_buffer_v5(struct
> > s5p_mfc_ctx *ctx,  }
> >
> >  static void s5p_mfc_get_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,
> > -		unsigned long *y_addr, unsigned long *c_addr)
> > +		unsigned long *y_addr, unsigned long *c_addr,
> > +		unsigned long *c_1_addr)
> >  {
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >
> > @@ -1210,7 +1212,7 @@ static int s5p_mfc_run_enc_frame(struct
> s5p_mfc_ctx *ctx)
> >  	if (list_empty(&ctx->src_queue)) {
> >  		/* send null frame */
> >  		s5p_mfc_set_enc_frame_buffer_v5(ctx, dev-
> >dma_base[BANK_R_CTX],
> > -						dev-
> >dma_base[BANK_R_CTX]);
> > +						dev-
> >dma_base[BANK_R_CTX], 0);
> >  		src_mb = NULL;
> >  	} else {
> >  		src_mb = list_entry(ctx->src_queue.next, struct
> s5p_mfc_buf, @@
> > -1220,7 +1222,7 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx
> *ctx)
> >  			/* send null frame */
> >  			s5p_mfc_set_enc_frame_buffer_v5(ctx,
> >  						dev-
> >dma_base[BANK_R_CTX],
> > -						dev-
> >dma_base[BANK_R_CTX]);
> > +						dev-
> >dma_base[BANK_R_CTX], 0);
> >  			ctx->state = MFCINST_FINISHING;
> >  		} else {
> >  			src_y_addr = vb2_dma_contig_plane_dma_addr(
> @@ -1228,7 +1230,7 @@
> > static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
> >  			src_c_addr = vb2_dma_contig_plane_dma_addr(
> >  					&src_mb->b->vb2_buf, 1);
> >  			s5p_mfc_set_enc_frame_buffer_v5(ctx, src_y_addr,
> > -								src_c_addr);
> > +								src_c_addr,
> 0);
> >  			if (src_mb->flags & MFC_BUF_FLAG_EOS)
> >  				ctx->state = MFCINST_FINISHING;
> >  		}
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> > index fb3f0718821d..e579c765e902 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> > @@ -494,16 +494,43 @@ static void s5p_mfc_dec_calc_dpb_size_v6(struct
> s5p_mfc_ctx *ctx)
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >  	ctx->buf_width = ALIGN(ctx->img_width,
> S5P_FIMV_NV12MT_HALIGN_V6);
> >  	ctx->buf_height = ALIGN(ctx->img_height,
> S5P_FIMV_NV12MT_VALIGN_V6);
> > +	ctx->chroma_size_1 = 0;
> >  	mfc_debug(2, "SEQ Done: Movie dimensions %dx%d,\n"
> >  			"buffer dimensions: %dx%d\n", ctx->img_width,
> >  			ctx->img_height, ctx->buf_width, ctx->buf_height);
> >
> > -	ctx->luma_size = calc_plane(ctx->img_width, ctx->img_height);
> > -	ctx->chroma_size = calc_plane(ctx->img_width, (ctx->img_height >>
> 1));
> > +	switch (ctx->dst_fmt->fourcc) {
> > +	case V4L2_PIX_FMT_NV12M:
> > +	case V4L2_PIX_FMT_NV21M:
> > +		ctx->stride[0] = ALIGN(ctx->img_width,
> > +					S5P_FIMV_NV12MT_HALIGN_V6);
> > +		ctx->stride[1] = ALIGN(ctx->img_width,
> > +					S5P_FIMV_NV12MT_HALIGN_V6);
> > +		ctx->luma_size = calc_plane(ctx->stride[0], ctx->img_height);
> > +		ctx->chroma_size = calc_plane(ctx->stride[1],
> > +					(ctx->img_height / 2));
> > +		break;
> > +	case V4L2_PIX_FMT_YUV420M:
> > +	case V4L2_PIX_FMT_YVU420M:
> > +		ctx->stride[0] = ALIGN(ctx->img_width,
> > +					S5P_FIMV_NV12MT_HALIGN_V6);
> > +		ctx->stride[1] = ALIGN(ctx->img_width / 2,
> > +					S5P_FIMV_NV12MT_HALIGN_V6);
> > +		ctx->stride[2] = ALIGN(ctx->img_width / 2,
> > +					S5P_FIMV_NV12MT_HALIGN_V6);
> > +		ctx->luma_size = calc_plane(ctx->stride[0], ctx->img_height);
> > +		ctx->chroma_size = calc_plane(ctx->stride[1],
> > +					(ctx->img_height / 2));
> > +		ctx->chroma_size_1 = calc_plane(ctx->stride[2],
> > +					(ctx->img_height / 2));
> > +		break;
> > +	}
> > +
> >  	if (IS_MFCV8_PLUS(ctx->dev)) {
> >  		/* MFCv8 needs additional 64 bytes for luma,chroma dpb*/
> >  		ctx->luma_size += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8;
> >  		ctx->chroma_size += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8;
> > +		ctx->chroma_size_1 +=
> S5P_FIMV_D_ALIGN_PLANE_SIZE_V8;
> >  	}
> >
> >  	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC || @@ -534,15
> +561,53
> > @@ static void s5p_mfc_enc_calc_src_size_v6(struct s5p_mfc_ctx *ctx)
> >  	mb_width = MB_WIDTH(ctx->img_width);
> >  	mb_height = MB_HEIGHT(ctx->img_height);
> >
> > -	ctx->buf_width = ALIGN(ctx->img_width,
> S5P_FIMV_NV12M_HALIGN_V6);
> > -	ctx->luma_size = ALIGN((mb_width * mb_height) * 256, 256);
> > -	ctx->chroma_size = ALIGN((mb_width * mb_height) * 128, 256);
> > -
> > -	/* MFCv7 needs pad bytes for Luma and Chroma */
> > -	if (IS_MFCV7_PLUS(ctx->dev)) {
> > +	if (IS_MFCV12(ctx->dev)) {
> > +		switch (ctx->src_fmt->fourcc) {
> > +		case V4L2_PIX_FMT_NV12M:
> > +		case V4L2_PIX_FMT_NV21M:
> > +			ctx->stride[0] = ALIGN(ctx->img_width,
> > +
> 	S5P_FIMV_NV12M_HALIGN_V6);
> > +			ctx->stride[1] = ALIGN(ctx->img_width,
> > +
> 	S5P_FIMV_NV12M_HALIGN_V6);
> > +			ctx->luma_size = ctx->stride[0] *
> > +						ALIGN(ctx->img_height, 16);
> > +			ctx->chroma_size =  ctx->stride[0] *
> > +						ALIGN(ctx->img_height / 2,
> 16);
> > +			break;
> > +		case V4L2_PIX_FMT_YUV420M:
> > +		case V4L2_PIX_FMT_YVU420M:
> > +			ctx->stride[0] = ALIGN(ctx->img_width,
> > +
> 	S5P_FIMV_NV12M_HALIGN_V6);
> > +			ctx->stride[1] = ALIGN(ctx->img_width / 2,
> > +
> 	S5P_FIMV_NV12M_HALIGN_V6);
> > +			ctx->stride[2] = ALIGN(ctx->img_width / 2,
> > +
> 	S5P_FIMV_NV12M_HALIGN_V6);
> > +			ctx->luma_size = ctx->stride[0] *
> > +						ALIGN(ctx->img_height, 16);
> > +			ctx->chroma_size =  ctx->stride[1] *
> > +						ALIGN(ctx->img_height / 2,
> 16);
> > +			ctx->chroma_size_1 =  ctx->stride[2] *
> > +						ALIGN(ctx->img_height / 2,
> 16);
> > +			break;
> > +		}
> >  		ctx->luma_size += MFC_LUMA_PAD_BYTES_V7;
> > -		ctx->chroma_size += MFC_CHROMA_PAD_BYTES_V7;
> > +		ctx->chroma_size += MFC_CHROMA_PAD_BYTES_V12;
> > +		ctx->chroma_size_1 += MFC_CHROMA_PAD_BYTES_V12;
> > +	} else {
> > +		ctx->buf_width = ALIGN(ctx->img_width,
> > +					S5P_FIMV_NV12M_HALIGN_V6);
> > +		ctx->stride[0] = ctx->buf_width;
> > +		ctx->stride[1] = ctx->buf_width;
> > +		ctx->luma_size = ALIGN((mb_width * mb_height) * 256,
> 256);
> > +		ctx->chroma_size = ALIGN((mb_width * mb_height) * 128,
> 256);
> > +		ctx->chroma_size_1 = 0;
> > +		/* MFCv7 needs pad bytes for Luma and Chroma */
> > +		if (IS_MFCV7_PLUS(ctx->dev)) {
> > +			ctx->luma_size += MFC_LUMA_PAD_BYTES_V7;
> > +			ctx->chroma_size += MFC_LUMA_PAD_BYTES_V7;
> > +		}
> >  	}
> > +
> >  }
> >
> >  /* Set registers for decoding stream buffer */ @@ -588,15 +653,21 @@
> > static int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx)
> >  	writel(ctx->total_dpb_count, mfc_regs->d_num_dpb);
> >  	writel(ctx->luma_size, mfc_regs->d_first_plane_dpb_size);
> >  	writel(ctx->chroma_size, mfc_regs->d_second_plane_dpb_size);
> > -
> > +	if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +			ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> > +		writel(ctx->chroma_size_1, mfc_regs-
> >d_third_plane_dpb_size);
> >  	writel(buf_addr1, mfc_regs->d_scratch_buffer_addr);
> >  	writel(ctx->scratch_buf_size, mfc_regs->d_scratch_buffer_size);
> >
> >  	if (IS_MFCV8_PLUS(dev)) {
> > -		writel(ctx->img_width,
> > +		writel(ctx->stride[0],
> >  			mfc_regs->d_first_plane_dpb_stride_size);
> > -		writel(ctx->img_width,
> > +		writel(ctx->stride[1],
> >  			mfc_regs->d_second_plane_dpb_stride_size);
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +			writel(ctx->stride[2],
> > +				mfc_regs->d_third_plane_dpb_stride_size);
> >  	}
> >
> >  	buf_addr1 += ctx->scratch_buf_size;
> > @@ -625,6 +696,13 @@ static int
> s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx)
> >  					ctx->dst_bufs[i].cookie.raw.chroma);
> >  		writel(ctx->dst_bufs[i].cookie.raw.chroma,
> >  				mfc_regs->d_second_plane_dpb + i * 4);
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M) {
> > +			mfc_debug(2, "\tChroma_1 %d: %zx\n", i,
> > +					ctx-
> >dst_bufs[i].cookie.raw.chroma_1);
> > +			writel(ctx->dst_bufs[i].cookie.raw.chroma_1,
> > +					mfc_regs->d_third_plane_dpb + i *
> 4);
> > +		}
> >  	}
> >  	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
> >  			ctx->codec_mode ==
> S5P_MFC_CODEC_H264_MVC_DEC || @@ -683,20
> > +761,24 @@ static int s5p_mfc_set_enc_stream_buffer_v6(struct
> > s5p_mfc_ctx *ctx,  }
> >
> >  static void s5p_mfc_set_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
> > -		unsigned long y_addr, unsigned long c_addr)
> > +		unsigned long y_addr, unsigned long c_addr,
> > +		unsigned long c_1_addr)
> >  {
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >  	const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs;
> >
> >  	writel(y_addr, mfc_regs->e_source_first_plane_addr);
> >  	writel(c_addr, mfc_regs->e_source_second_plane_addr);
> > +	writel(c_1_addr, mfc_regs->e_source_third_plane_addr);
> >
> >  	mfc_debug(2, "enc src y buf addr: 0x%08lx\n", y_addr);
> >  	mfc_debug(2, "enc src c buf addr: 0x%08lx\n", c_addr);
> > +	mfc_debug(2, "enc src cr buf addr: 0x%08lx\n", c_1_addr);
> >  }
> >
> >  static void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
> > -		unsigned long *y_addr, unsigned long *c_addr)
> > +		unsigned long *y_addr, unsigned long *c_addr,
> > +		unsigned long *c_1_addr)
> >  {
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >  	const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; @@ -704,12
> > +786,17 @@ static void s5p_mfc_get_enc_frame_buffer_v6(struct
> > s5p_mfc_ctx *ctx,
> >
> >  	*y_addr = readl(mfc_regs->e_encoded_source_first_plane_addr);
> >  	*c_addr = readl(mfc_regs-
> >e_encoded_source_second_plane_addr);
> > +	if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +			ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> > +		*c_1_addr = readl(mfc_regs-
> >e_encoded_source_third_plane_addr);
> > +	else
> > +		*c_1_addr = 0;
> >
> >  	enc_recon_y_addr = readl(mfc_regs->e_recon_luma_dpb_addr);
> >  	enc_recon_c_addr = readl(mfc_regs->e_recon_chroma_dpb_addr);
> >
> >  	mfc_debug(2, "recon y addr: 0x%08lx y_addr: 0x%08lx\n",
> enc_recon_y_addr, *y_addr);
> > -	mfc_debug(2, "recon c addr: 0x%08lx\n", enc_recon_c_addr);
> > +	mfc_debug(2, "recon c addr: 0x%08lx c_addr: 0x%08lx\n",
> > +enc_recon_c_addr, *c_addr);
> >  }
> >
> >  /* Set encoding ref & codec buffer */ @@ -886,6 +973,20 @@ static int
> > s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
> >  		writel(reg, mfc_regs->e_enc_options);
> >  		/* 0: NV12(CbCr), 1: NV21(CrCb) */
> >  		writel(0x0, mfc_regs->pixel_format);
> > +	} else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> > +		/* 0: Linear, 1: 2D tiled*/
> > +		reg = readl(mfc_regs->e_enc_options);
> > +		reg &= ~(0x1 << 7);
> > +		writel(reg, mfc_regs->e_enc_options);
> > +		/* 2: YV12(CrCb), 3: I420(CrCb) */
> > +		writel(0x2, mfc_regs->pixel_format);
> > +	} else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M) {
> > +		/* 0: Linear, 1: 2D tiled*/
> > +		reg = readl(mfc_regs->e_enc_options);
> > +		reg &= ~(0x1 << 7);
> > +		writel(reg, mfc_regs->e_enc_options);
> > +		/* 2: YV12(CrCb), 3: I420(CrCb) */
> > +		writel(0x3, mfc_regs->pixel_format);
> >  	}
> >
> >  	/* memory structure recon. frame */
> > @@ -1696,8 +1797,12 @@ static int s5p_mfc_init_decode_v6(struct
> s5p_mfc_ctx *ctx)
> >  	else
> >  		writel(reg, mfc_regs->d_dec_options);
> >
> > -	/* 0: NV12(CbCr), 1: NV21(CrCb) */
> > -	if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV21M)
> > +	/* 0: NV12(CbCr), 1: NV21(CrCb), 2: YV12(CrCb), 3: I420(CbCr) */
> > +	if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M)
> > +		writel(0x3, mfc_regs->pixel_format);
> > +	else if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> > +		writel(0x2, mfc_regs->pixel_format);
> > +	else if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV21M)
> >  		writel(0x1, mfc_regs->pixel_format);
> >  	else
> >  		writel(0x0, mfc_regs->pixel_format); @@ -1781,8 +1886,12
> @@ static
> > int s5p_mfc_init_encode_v6(struct s5p_mfc_ctx *ctx)
> >
> >  	/* Set stride lengths for v7 & above */
> >  	if (IS_MFCV7_PLUS(dev)) {
> > -		writel(ctx->img_width, mfc_regs-
> >e_source_first_plane_stride);
> > -		writel(ctx->img_width, mfc_regs-
> >e_source_second_plane_stride);
> > +		writel(ctx->stride[0], mfc_regs-
> >e_source_first_plane_stride);
> > +		writel(ctx->stride[1], mfc_regs-
> >e_source_second_plane_stride);
> > +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +			writel(ctx->stride[2],
> > +					mfc_regs-
> >e_source_third_plane_stride);
> >  	}
> >
> >  	writel(ctx->inst_no, mfc_regs->instance_id); @@ -1891,7 +2000,7
> @@
> > static inline int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >  	struct s5p_mfc_buf *dst_mb;
> >  	struct s5p_mfc_buf *src_mb;
> > -	unsigned long src_y_addr, src_c_addr, dst_addr;
> > +	unsigned long src_y_addr, src_c_addr, src_c_1_addr, dst_addr;
> >  	/*
> >  	unsigned int src_y_size, src_c_size;
> >  	*/
> > @@ -1909,22 +2018,29 @@ static inline int s5p_mfc_run_enc_frame(struct
> > s5p_mfc_ctx *ctx)
> >
> >  	if (list_empty(&ctx->src_queue)) {
> >  		/* send null frame */
> > -		s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0);
> > +		s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0, 0);
> >  		src_mb = NULL;
> >  	} else {
> >  		src_mb = list_entry(ctx->src_queue.next, struct
> s5p_mfc_buf, list);
> >  		src_mb->flags |= MFC_BUF_FLAG_USED;
> >  		if (src_mb->b->vb2_buf.planes[0].bytesused == 0) {
> > -			s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0);
> > +			s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0, 0);
> >  			ctx->state = MFCINST_FINISHING;
> >  		} else {
> >  			src_y_addr =
> vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 0);
> >  			src_c_addr =
> vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf,
> > 1);
> > +			if (ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +				src_c_1_addr =
> vb2_dma_contig_plane_dma_addr
> > +						(&src_mb->b->vb2_buf, 2);
> > +			else
> > +				src_c_1_addr = 0;
> >
> >  			mfc_debug(2, "enc src y addr: 0x%08lx\n",
> src_y_addr);
> >  			mfc_debug(2, "enc src c addr: 0x%08lx\n",
> src_c_addr);
> >
> > -			s5p_mfc_set_enc_frame_buffer_v6(ctx, src_y_addr,
> src_c_addr);
> > +			s5p_mfc_set_enc_frame_buffer_v6(ctx, src_y_addr,
> > +						src_c_addr, src_c_1_addr);
> >  			if (src_mb->flags & MFC_BUF_FLAG_EOS)
> >  				ctx->state = MFCINST_FINISHING;
> >  		}
> > @@ -2450,6 +2566,8 @@ const struct s5p_mfc_regs
> *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev)
> >  			S5P_FIMV_E_ENCODED_SOURCE_FIRST_ADDR_V7);
> >  	R(e_encoded_source_second_plane_addr,
> >
> 	S5P_FIMV_E_ENCODED_SOURCE_SECOND_ADDR_V7);
> > +	R(e_encoded_source_third_plane_addr,
> > +			S5P_FIMV_E_ENCODED_SOURCE_THIRD_ADDR_V7);
> >  	R(e_vp8_options, S5P_FIMV_E_VP8_OPTIONS_V7);
> >
> >  	if (!IS_MFCV8_PLUS(dev))
> > @@ -2464,16 +2582,20 @@ const struct s5p_mfc_regs
> *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev)
> >  	R(d_cpb_buffer_offset, S5P_FIMV_D_CPB_BUFFER_OFFSET_V8);
> >  	R(d_first_plane_dpb_size,
> S5P_FIMV_D_FIRST_PLANE_DPB_SIZE_V8);
> >  	R(d_second_plane_dpb_size,
> S5P_FIMV_D_SECOND_PLANE_DPB_SIZE_V8);
> > +	R(d_third_plane_dpb_size,
> S5P_FIMV_D_THIRD_PLANE_DPB_SIZE_V8);
> >  	R(d_scratch_buffer_addr,
> S5P_FIMV_D_SCRATCH_BUFFER_ADDR_V8);
> >  	R(d_scratch_buffer_size, S5P_FIMV_D_SCRATCH_BUFFER_SIZE_V8);
> >  	R(d_first_plane_dpb_stride_size,
> >  			S5P_FIMV_D_FIRST_PLANE_DPB_STRIDE_SIZE_V8);
> >  	R(d_second_plane_dpb_stride_size,
> >
> 	S5P_FIMV_D_SECOND_PLANE_DPB_STRIDE_SIZE_V8);
> > +	R(d_third_plane_dpb_stride_size,
> > +			S5P_FIMV_D_THIRD_PLANE_DPB_STRIDE_SIZE_V8);
> >  	R(d_mv_buffer_size, S5P_FIMV_D_MV_BUFFER_SIZE_V8);
> >  	R(d_num_mv, S5P_FIMV_D_NUM_MV_V8);
> >  	R(d_first_plane_dpb, S5P_FIMV_D_FIRST_PLANE_DPB_V8);
> >  	R(d_second_plane_dpb, S5P_FIMV_D_SECOND_PLANE_DPB_V8);
> > +	R(d_third_plane_dpb, S5P_FIMV_D_THIRD_PLANE_DPB_V8);
> >  	R(d_mv_buffer, S5P_FIMV_D_MV_BUFFER_V8);
> >  	R(d_init_buffer_options, S5P_FIMV_D_INIT_BUFFER_OPTIONS_V8);
> >  	R(d_available_dpb_flag_lower,
> > S5P_FIMV_D_AVAILABLE_DPB_FLAG_LOWER_V8);




_______________________________________________
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] 54+ messages in thread

* RE: [Patch v4 04/11] media: s5p-mfc: Add YV12 and I420 multiplanar format support
  2023-11-22 15:40         ` Hans Verkuil
@ 2023-11-27  7:01           ` Aakarsh Jain
  -1 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-11-27  7:01 UTC (permalink / raw)
  To: 'Hans Verkuil',
	linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, krzysztof.kozlowski+dt,
	dillon.minfei, david.plowman, mark.rutland, robh+dt, conor+dt,
	linux-samsung-soc, andi, gost.dev, alim.akhtar, aswani.reddy,
	pankaj.dubey, ajaykumar.rs, linux-fsd, 'Smitha T Murthy'

Hi Hans,

> -----Original Message-----
> From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
> Sent: 22 November 2023 21:11
> To: Aakarsh Jain <aakarsh.jain@samsung.com>; linux-arm-
> kernel@lists.infradead.org; linux-media@vger.kernel.org; linux-
> kernel@vger.kernel.org; devicetree@vger.kernel.org
> Cc: m.szyprowski@samsung.com; andrzej.hajda@intel.com;
> mchehab@kernel.org; krzysztof.kozlowski+dt@linaro.org;
> dillon.minfei@gmail.com; david.plowman@raspberrypi.com;
> mark.rutland@arm.com; robh+dt@kernel.org; conor+dt@kernel.org; linux-
> samsung-soc@vger.kernel.org; andi@etezian.org; gost.dev@samsung.com;
> alim.akhtar@samsung.com; aswani.reddy@samsung.com;
> pankaj.dubey@samsung.com; ajaykumar.rs@samsung.com; linux-
> fsd@tesla.com; Smitha T Murthy <smithatmurthy@gmail.com>
> Subject: Re: [Patch v4 04/11] media: s5p-mfc: Add YV12 and I420 multiplanar
> format support
> 
> On 25/10/2023 12:22, Aakarsh Jain wrote:
> > YV12 and I420 format (3-plane) support is added. Stride information is
> > added to all formats and planes since it is necessary for YV12/I420
> > which are different from width.
> >
> > Cc: linux-fsd@tesla.com
> > Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
> > Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
> > ---
> >  .../platform/samsung/s5p-mfc/regs-mfc-v12.h   |   2 +
> >  .../platform/samsung/s5p-mfc/regs-mfc-v7.h    |   1 +
> >  .../platform/samsung/s5p-mfc/regs-mfc-v8.h    |   3 +
> >  .../platform/samsung/s5p-mfc/s5p_mfc_common.h |   4 +
> >  .../platform/samsung/s5p-mfc/s5p_mfc_dec.c    |  45 ++++-
> >  .../platform/samsung/s5p-mfc/s5p_mfc_enc.c    |  86 +++++++--
> >  .../platform/samsung/s5p-mfc/s5p_mfc_opr.h    |   6 +-
> >  .../platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c |  12 +-
> > .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 168
> +++++++++++++++---
> >  9 files changed, 281 insertions(+), 46 deletions(-)
> >
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> > b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> > index 6c68a45082d0..70464f47c1f9 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> > +++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> > @@ -26,6 +26,8 @@
> >  #define MFC_VERSION_V12			0xC0
> >  #define MFC_NUM_PORTS_V12		1
> >  #define S5P_FIMV_CODEC_VP9_ENC		27
> > +#define MFC_CHROMA_PAD_BYTES_V12        256
> > +#define S5P_FIMV_D_ALIGN_PLANE_SIZE_V12 256
> >
> >  /* Encoder buffer size for MFCv12 */
> >  #define ENC_V120_BASE_SIZE(x, y) \
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
> > b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
> > index 4a7adfdaa359..50f9bf0603c1 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
> > +++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
> > @@ -24,6 +24,7 @@
> >
> >  #define S5P_FIMV_E_ENCODED_SOURCE_FIRST_ADDR_V7
> 	0xfa70
> >  #define S5P_FIMV_E_ENCODED_SOURCE_SECOND_ADDR_V7
> 	0xfa74
> > +#define S5P_FIMV_E_ENCODED_SOURCE_THIRD_ADDR_V7
> 	0xfa78
> >
> >  #define S5P_FIMV_E_VP8_OPTIONS_V7			0xfdb0
> >  #define S5P_FIMV_E_VP8_FILTER_OPTIONS_V7		0xfdb4
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
> > b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
> > index 162e3c7e920f..0ef9eb2dff22 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
> > +++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
> > @@ -17,13 +17,16 @@
> >  #define S5P_FIMV_D_MIN_SCRATCH_BUFFER_SIZE_V8	0xf108
> >  #define S5P_FIMV_D_FIRST_PLANE_DPB_SIZE_V8	0xf144
> >  #define S5P_FIMV_D_SECOND_PLANE_DPB_SIZE_V8	0xf148
> > +#define S5P_FIMV_D_THIRD_PLANE_DPB_SIZE_V8	0xf14C
> >  #define S5P_FIMV_D_MV_BUFFER_SIZE_V8		0xf150
> >
> >  #define S5P_FIMV_D_FIRST_PLANE_DPB_STRIDE_SIZE_V8	0xf138
> >  #define S5P_FIMV_D_SECOND_PLANE_DPB_STRIDE_SIZE_V8
> 	0xf13c
> > +#define S5P_FIMV_D_THIRD_PLANE_DPB_STRIDE_SIZE_V8
> 	0xf140
> >
> >  #define S5P_FIMV_D_FIRST_PLANE_DPB_V8		0xf160
> >  #define S5P_FIMV_D_SECOND_PLANE_DPB_V8		0xf260
> > +#define S5P_FIMV_D_THIRD_PLANE_DPB_V8		0xf360
> >  #define S5P_FIMV_D_MV_BUFFER_V8			0xf460
> >
> >  #define S5P_FIMV_D_NUM_MV_V8			0xf134
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> > index dd2e9f7704ab..9a39cccfe002 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> > @@ -56,6 +56,7 @@
> >  #define MFC_NO_INSTANCE_SET	-1
> >  #define MFC_ENC_CAP_PLANE_COUNT	1
> >  #define MFC_ENC_OUT_PLANE_COUNT	2
> > +#define VB2_MAX_PLANE_COUNT	3
> >  #define STUFF_BYTE		4
> >  #define MFC_MAX_CTRLS		128
> >
> > @@ -181,6 +182,7 @@ struct s5p_mfc_buf {
> >  		struct {
> >  			size_t luma;
> >  			size_t chroma;
> > +			size_t chroma_1;
> >  		} raw;
> >  		size_t stream;
> >  	} cookie;
> > @@ -657,6 +659,7 @@ struct s5p_mfc_ctx {
> >
> >  	int luma_size;
> >  	int chroma_size;
> > +	int chroma_size_1;
> >  	int mv_size;
> >
> >  	unsigned long consumed_stream;
> > @@ -722,6 +725,7 @@ struct s5p_mfc_ctx {
> >  	size_t scratch_buf_size;
> >  	int is_10bit;
> >  	int is_422;
> > +	int stride[VB2_MAX_PLANE_COUNT];
> >  };
> >
> >  /*
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> > index e219cbcd86d5..317f796fffa1 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> > @@ -56,6 +56,20 @@ static struct s5p_mfc_fmt formats[] = {
> >  		.num_planes	= 2,
> >  		.versions	= MFC_V6PLUS_BITS,
> >  	},
> > +	{
> > +		.fourcc         = V4L2_PIX_FMT_YUV420M,
> > +		.codec_mode     = S5P_MFC_CODEC_NONE,
> > +		.type           = MFC_FMT_RAW,
> > +		.num_planes     = 3,
> > +		.versions       = MFC_V12_BIT,
> > +	},
> > +	{
> > +		.fourcc         = V4L2_PIX_FMT_YVU420M,
> > +		.codec_mode     = S5P_MFC_CODEC_NONE,
> > +		.type           = MFC_FMT_RAW,
> > +		.num_planes     = 3,
> > +		.versions       = MFC_V12_BIT
> > +	},
> >  	{
> >  		.fourcc		= V4L2_PIX_FMT_H264,
> >  		.codec_mode	= S5P_MFC_CODEC_H264_DEC,
> > @@ -359,10 +373,15 @@ static int vidioc_g_fmt(struct file *file, void *priv,
> struct v4l2_format *f)
> >  		/* Set pixelformat to the format in which MFC
> >  		   outputs the decoded frame */
> >  		pix_mp->pixelformat = ctx->dst_fmt->fourcc;
> > -		pix_mp->plane_fmt[0].bytesperline = ctx->buf_width;
> > +		pix_mp->plane_fmt[0].bytesperline = ctx->stride[0];
> >  		pix_mp->plane_fmt[0].sizeimage = ctx->luma_size;
> > -		pix_mp->plane_fmt[1].bytesperline = ctx->buf_width;
> > +		pix_mp->plane_fmt[1].bytesperline = ctx->stride[1];
> >  		pix_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M) {
> > +			pix_mp->plane_fmt[2].bytesperline = ctx->stride[2];
> > +			pix_mp->plane_fmt[2].sizeimage = ctx-
> >chroma_size_1;
> > +		}
> >  	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
> >  		/* This is run on OUTPUT
> >  		   The buffer contains compressed image @@ -937,6 +956,9
> @@ static
> > int s5p_mfc_queue_setup(struct vb2_queue *vq,
> >  		   vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
> >  		/* Output plane count is 2 - one for Y and one for CbCr */
> >  		*plane_count = 2;
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> 
> These misalignments produce a lot of checkpatch warnings.
> 
> Make sure you run your patch series through 'checkpatch.pl --strict'!
> 
> Regards,
> 
> 	Hans
> 
Thanks for pointing out. Will fix it in next series.

Thanks for the review.
> > +			*plane_count = 3;
> >  		/* Setup buffer count */
> >  		if (*buf_count < ctx->pb_count)
> >  			*buf_count = ctx->pb_count;
> > @@ -955,12 +977,17 @@ static int s5p_mfc_queue_setup(struct
> vb2_queue *vq,
> >  	    vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
> >  		psize[0] = ctx->luma_size;
> >  		psize[1] = ctx->chroma_size;
> > -
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +			psize[2] = ctx->chroma_size_1;
> >  		if (IS_MFCV6_PLUS(dev))
> >  			alloc_devs[0] = ctx->dev->mem_dev[BANK_L_CTX];
> >  		else
> >  			alloc_devs[0] = ctx->dev->mem_dev[BANK_R_CTX];
> >  		alloc_devs[1] = ctx->dev->mem_dev[BANK_L_CTX];
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +			alloc_devs[2] = ctx->dev->mem_dev[BANK_L_CTX];
> >  	} else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
> >  		   ctx->state == MFCINST_INIT) {
> >  		psize[0] = ctx->dec_src_buf_size;
> > @@ -994,12 +1021,24 @@ static int s5p_mfc_buf_init(struct vb2_buffer
> *vb)
> >  			mfc_err("Plane buffer (CAPTURE) is too small\n");
> >  			return -EINVAL;
> >  		}
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M) {
> > +			if (vb2_plane_size(vb, 2) < ctx->chroma_size_1) {
> > +				mfc_err("Plane buffer (CAPTURE) is too
> small\n");
> > +				return -EINVAL;
> > +			}
> > +		}
> >  		i = vb->index;
> >  		ctx->dst_bufs[i].b = vbuf;
> >  		ctx->dst_bufs[i].cookie.raw.luma =
> >
> 	vb2_dma_contig_plane_dma_addr(vb, 0);
> >  		ctx->dst_bufs[i].cookie.raw.chroma =
> >
> 	vb2_dma_contig_plane_dma_addr(vb, 1);
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M) {
> > +			ctx->dst_bufs[i].cookie.raw.chroma_1 =
> > +
> 	vb2_dma_contig_plane_dma_addr(vb, 2);
> > +		}
> >  		ctx->dst_bufs_cnt++;
> >  	} else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
> >  		if (IS_ERR_OR_NULL(ERR_PTR(
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> > index e4d6e7c117b5..0eec04eb3ef3 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> > @@ -59,6 +59,20 @@ static struct s5p_mfc_fmt formats[] = {
> >  		.num_planes	= 2,
> >  		.versions	= MFC_V6PLUS_BITS,
> >  	},
> > +	{
> > +		.fourcc         = V4L2_PIX_FMT_YUV420M,
> > +		.codec_mode     = S5P_MFC_CODEC_NONE,
> > +		.type           = MFC_FMT_RAW,
> > +		.num_planes     = 3,
> > +		.versions       = MFC_V12_BIT,
> > +	},
> > +	{
> > +		.fourcc         = V4L2_PIX_FMT_YVU420M,
> > +		.codec_mode     = S5P_MFC_CODEC_NONE,
> > +		.type           = MFC_FMT_RAW,
> > +		.num_planes     = 3,
> > +		.versions       = MFC_V12_BIT,
> > +	},
> >  	{
> >  		.fourcc		= V4L2_PIX_FMT_H264,
> >  		.codec_mode	= S5P_MFC_CODEC_H264_ENC,
> > @@ -1193,14 +1207,20 @@ static int enc_pre_frame_start(struct
> s5p_mfc_ctx *ctx)
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >  	struct s5p_mfc_buf *dst_mb;
> >  	struct s5p_mfc_buf *src_mb;
> > -	unsigned long src_y_addr, src_c_addr, dst_addr;
> > +	unsigned long src_y_addr, src_c_addr, src_c_1_addr, dst_addr;
> >  	unsigned int dst_size;
> >
> >  	src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
> >  	src_y_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b-
> >vb2_buf, 0);
> >  	src_c_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b-
> >vb2_buf, 1);
> > +	if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +			ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> > +		src_c_1_addr =
> > +			vb2_dma_contig_plane_dma_addr(&src_mb->b-
> >vb2_buf, 2);
> > +	else
> > +		src_c_1_addr = 0;
> >  	s5p_mfc_hw_call(dev->mfc_ops, set_enc_frame_buffer, ctx,
> > -							src_y_addr,
> src_c_addr);
> > +					src_y_addr, src_c_addr,
> src_c_1_addr);
> >
> >  	dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
> >  	dst_addr = vb2_dma_contig_plane_dma_addr(&dst_mb->b-
> >vb2_buf, 0); @@
> > -1215,8 +1235,8 @@ static int enc_post_frame_start(struct s5p_mfc_ctx
> > *ctx)  {
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >  	struct s5p_mfc_buf *mb_entry;
> > -	unsigned long enc_y_addr = 0, enc_c_addr = 0;
> > -	unsigned long mb_y_addr, mb_c_addr;
> > +	unsigned long enc_y_addr = 0, enc_c_addr = 0, enc_c_1_addr = 0;
> > +	unsigned long mb_y_addr, mb_c_addr, mb_c_1_addr;
> >  	int slice_type;
> >  	unsigned int strm_size;
> >  	bool src_ready;
> > @@ -1229,14 +1249,21 @@ static int enc_post_frame_start(struct
> s5p_mfc_ctx *ctx)
> >  		  mfc_read(dev, S5P_FIMV_ENC_SI_PIC_CNT));
> >  	if (slice_type >= 0) {
> >  		s5p_mfc_hw_call(dev->mfc_ops, get_enc_frame_buffer,
> ctx,
> > -				&enc_y_addr, &enc_c_addr);
> > +				&enc_y_addr, &enc_c_addr,
> &enc_c_1_addr);
> >  		list_for_each_entry(mb_entry, &ctx->src_queue, list) {
> >  			mb_y_addr = vb2_dma_contig_plane_dma_addr(
> >  					&mb_entry->b->vb2_buf, 0);
> >  			mb_c_addr = vb2_dma_contig_plane_dma_addr(
> >  					&mb_entry->b->vb2_buf, 1);
> > -			if ((enc_y_addr == mb_y_addr) &&
> > -						(enc_c_addr == mb_c_addr))
> {
> > +			if (ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +				mb_c_1_addr =
> vb2_dma_contig_plane_dma_addr
> > +						(&mb_entry->b->vb2_buf,
> 2);
> > +			else
> > +				mb_c_1_addr = 0;
> > +			if ((enc_y_addr == mb_y_addr)
> > +					&& (enc_c_addr == mb_c_addr)
> > +					&& (enc_c_1_addr ==
> mb_c_1_addr)) {
> >  				list_del(&mb_entry->list);
> >  				ctx->src_queue_cnt--;
> >  				vb2_buffer_done(&mb_entry->b->vb2_buf,
> > @@ -1249,8 +1276,15 @@ static int enc_post_frame_start(struct
> s5p_mfc_ctx *ctx)
> >  					&mb_entry->b->vb2_buf, 0);
> >  			mb_c_addr = vb2_dma_contig_plane_dma_addr(
> >  					&mb_entry->b->vb2_buf, 1);
> > -			if ((enc_y_addr == mb_y_addr) &&
> > -						(enc_c_addr == mb_c_addr))
> {
> > +			if (ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +				mb_c_1_addr =
> vb2_dma_contig_plane_dma_addr(
> > +						&mb_entry->b->vb2_buf, 2);
> > +			else
> > +				mb_c_1_addr = 0;
> > +			if ((enc_y_addr == mb_y_addr)
> > +					&& (enc_c_addr == mb_c_addr)
> > +					&& (enc_c_1_addr ==
> mb_c_1_addr)) {
> >  				list_del(&mb_entry->list);
> >  				ctx->ref_queue_cnt--;
> >  				vb2_buffer_done(&mb_entry->b->vb2_buf,
> > @@ -1381,10 +1415,15 @@ static int vidioc_g_fmt(struct file *file, void
> *priv, struct v4l2_format *f)
> >  		pix_fmt_mp->pixelformat = ctx->src_fmt->fourcc;
> >  		pix_fmt_mp->num_planes = ctx->src_fmt->num_planes;
> >
> > -		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
> > +		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->stride[0];
> >  		pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
> > -		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
> > +		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->stride[1];
> >  		pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
> > +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M) {
> > +			pix_fmt_mp->plane_fmt[2].bytesperline = ctx-
> >stride[2];
> > +			pix_fmt_mp->plane_fmt[2].sizeimage = ctx-
> >chroma_size_1;
> > +		}
> >  	} else {
> >  		mfc_err("invalid buf type\n");
> >  		return -EINVAL;
> > @@ -1468,9 +1507,14 @@ static int vidioc_s_fmt(struct file *file, void
> > *priv, struct v4l2_format *f)
> >
> >  		s5p_mfc_hw_call(dev->mfc_ops, enc_calc_src_size, ctx);
> >  		pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
> > -		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
> > +		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->stride[0];
> >  		pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
> > -		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
> > +		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->stride[1];
> > +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M) {
> > +			pix_fmt_mp->plane_fmt[2].bytesperline = ctx-
> >stride[2];
> > +			pix_fmt_mp->plane_fmt[2].sizeimage = ctx-
> >chroma_size_1;
> > +		}
> >
> >  		ctx->src_bufs_cnt = 0;
> >  		ctx->output_state = QUEUE_FREE;
> > @@ -2414,10 +2458,16 @@ static int s5p_mfc_queue_setup(struct
> > vb2_queue *vq,
> >
> >  		psize[0] = ctx->luma_size;
> >  		psize[1] = ctx->chroma_size;
> > +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +			psize[2] = ctx->chroma_size_1;
> >
> >  		if (IS_MFCV6_PLUS(dev)) {
> >  			alloc_devs[0] = ctx->dev->mem_dev[BANK_L_CTX];
> >  			alloc_devs[1] = ctx->dev->mem_dev[BANK_L_CTX];
> > +			if (ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +				alloc_devs[2] = ctx->dev-
> >mem_dev[BANK_L_CTX];
> >  		} else {
> >  			alloc_devs[0] = ctx->dev->mem_dev[BANK_R_CTX];
> >  			alloc_devs[1] = ctx->dev->mem_dev[BANK_R_CTX];
> @@ -2456,6 +2506,10
> > @@ static int s5p_mfc_buf_init(struct vb2_buffer *vb)
> >
> 	vb2_dma_contig_plane_dma_addr(vb, 0);
> >  		ctx->src_bufs[i].cookie.raw.chroma =
> >
> 	vb2_dma_contig_plane_dma_addr(vb, 1);
> > +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +			ctx->src_bufs[i].cookie.raw.chroma_1 =
> > +
> 	vb2_dma_contig_plane_dma_addr(vb, 2);
> >  		ctx->src_bufs_cnt++;
> >  	} else {
> >  		mfc_err("invalid queue type: %d\n", vq->type); @@ -2493,6
> +2547,12
> > @@ static int s5p_mfc_buf_prepare(struct vb2_buffer *vb)
> >  			mfc_err("plane size is too small for output\n");
> >  			return -EINVAL;
> >  		}
> > +		if ((ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +		     ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) &&
> > +		    (vb2_plane_size(vb, 2) < ctx->chroma_size_1)) {
> > +			mfc_err("plane size is too small for output\n");
> > +			return -EINVAL;
> > +		}
> >  	} else {
> >  		mfc_err("invalid queue type: %d\n", vq->type);
> >  		return -EINVAL;
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> > index 87ac56756a16..7c5e851c8191 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> > @@ -293,9 +293,11 @@ struct s5p_mfc_hw_ops {
> >  	int (*set_enc_stream_buffer)(struct s5p_mfc_ctx *ctx,
> >  			unsigned long addr, unsigned int size);
> >  	void (*set_enc_frame_buffer)(struct s5p_mfc_ctx *ctx,
> > -			unsigned long y_addr, unsigned long c_addr);
> > +			unsigned long y_addr, unsigned long c_addr,
> > +			unsigned long c_1_addr);
> >  	void (*get_enc_frame_buffer)(struct s5p_mfc_ctx *ctx,
> > -			unsigned long *y_addr, unsigned long *c_addr);
> > +			unsigned long *y_addr, unsigned long *c_addr,
> > +			unsigned long *c_1_addr);
> >  	void (*try_run)(struct s5p_mfc_dev *dev);
> >  	void (*clear_int_flags)(struct s5p_mfc_dev *dev);
> >  	int (*get_dspl_y_adr)(struct s5p_mfc_dev *dev); diff --git
> > a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
> > index 28a06dc343fd..fcfaf125a5a1 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
> > @@ -516,7 +516,8 @@ static int
> s5p_mfc_set_enc_stream_buffer_v5(struct
> > s5p_mfc_ctx *ctx,  }
> >
> >  static void s5p_mfc_set_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,
> > -		unsigned long y_addr, unsigned long c_addr)
> > +		unsigned long y_addr, unsigned long c_addr,
> > +		unsigned long c_1_addr)
> >  {
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >
> > @@ -525,7 +526,8 @@ static void
> s5p_mfc_set_enc_frame_buffer_v5(struct
> > s5p_mfc_ctx *ctx,  }
> >
> >  static void s5p_mfc_get_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,
> > -		unsigned long *y_addr, unsigned long *c_addr)
> > +		unsigned long *y_addr, unsigned long *c_addr,
> > +		unsigned long *c_1_addr)
> >  {
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >
> > @@ -1210,7 +1212,7 @@ static int s5p_mfc_run_enc_frame(struct
> s5p_mfc_ctx *ctx)
> >  	if (list_empty(&ctx->src_queue)) {
> >  		/* send null frame */
> >  		s5p_mfc_set_enc_frame_buffer_v5(ctx, dev-
> >dma_base[BANK_R_CTX],
> > -						dev-
> >dma_base[BANK_R_CTX]);
> > +						dev-
> >dma_base[BANK_R_CTX], 0);
> >  		src_mb = NULL;
> >  	} else {
> >  		src_mb = list_entry(ctx->src_queue.next, struct
> s5p_mfc_buf, @@
> > -1220,7 +1222,7 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx
> *ctx)
> >  			/* send null frame */
> >  			s5p_mfc_set_enc_frame_buffer_v5(ctx,
> >  						dev-
> >dma_base[BANK_R_CTX],
> > -						dev-
> >dma_base[BANK_R_CTX]);
> > +						dev-
> >dma_base[BANK_R_CTX], 0);
> >  			ctx->state = MFCINST_FINISHING;
> >  		} else {
> >  			src_y_addr = vb2_dma_contig_plane_dma_addr(
> @@ -1228,7 +1230,7 @@
> > static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
> >  			src_c_addr = vb2_dma_contig_plane_dma_addr(
> >  					&src_mb->b->vb2_buf, 1);
> >  			s5p_mfc_set_enc_frame_buffer_v5(ctx, src_y_addr,
> > -								src_c_addr);
> > +								src_c_addr,
> 0);
> >  			if (src_mb->flags & MFC_BUF_FLAG_EOS)
> >  				ctx->state = MFCINST_FINISHING;
> >  		}
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> > index fb3f0718821d..e579c765e902 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> > @@ -494,16 +494,43 @@ static void s5p_mfc_dec_calc_dpb_size_v6(struct
> s5p_mfc_ctx *ctx)
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >  	ctx->buf_width = ALIGN(ctx->img_width,
> S5P_FIMV_NV12MT_HALIGN_V6);
> >  	ctx->buf_height = ALIGN(ctx->img_height,
> S5P_FIMV_NV12MT_VALIGN_V6);
> > +	ctx->chroma_size_1 = 0;
> >  	mfc_debug(2, "SEQ Done: Movie dimensions %dx%d,\n"
> >  			"buffer dimensions: %dx%d\n", ctx->img_width,
> >  			ctx->img_height, ctx->buf_width, ctx->buf_height);
> >
> > -	ctx->luma_size = calc_plane(ctx->img_width, ctx->img_height);
> > -	ctx->chroma_size = calc_plane(ctx->img_width, (ctx->img_height >>
> 1));
> > +	switch (ctx->dst_fmt->fourcc) {
> > +	case V4L2_PIX_FMT_NV12M:
> > +	case V4L2_PIX_FMT_NV21M:
> > +		ctx->stride[0] = ALIGN(ctx->img_width,
> > +					S5P_FIMV_NV12MT_HALIGN_V6);
> > +		ctx->stride[1] = ALIGN(ctx->img_width,
> > +					S5P_FIMV_NV12MT_HALIGN_V6);
> > +		ctx->luma_size = calc_plane(ctx->stride[0], ctx->img_height);
> > +		ctx->chroma_size = calc_plane(ctx->stride[1],
> > +					(ctx->img_height / 2));
> > +		break;
> > +	case V4L2_PIX_FMT_YUV420M:
> > +	case V4L2_PIX_FMT_YVU420M:
> > +		ctx->stride[0] = ALIGN(ctx->img_width,
> > +					S5P_FIMV_NV12MT_HALIGN_V6);
> > +		ctx->stride[1] = ALIGN(ctx->img_width / 2,
> > +					S5P_FIMV_NV12MT_HALIGN_V6);
> > +		ctx->stride[2] = ALIGN(ctx->img_width / 2,
> > +					S5P_FIMV_NV12MT_HALIGN_V6);
> > +		ctx->luma_size = calc_plane(ctx->stride[0], ctx->img_height);
> > +		ctx->chroma_size = calc_plane(ctx->stride[1],
> > +					(ctx->img_height / 2));
> > +		ctx->chroma_size_1 = calc_plane(ctx->stride[2],
> > +					(ctx->img_height / 2));
> > +		break;
> > +	}
> > +
> >  	if (IS_MFCV8_PLUS(ctx->dev)) {
> >  		/* MFCv8 needs additional 64 bytes for luma,chroma dpb*/
> >  		ctx->luma_size += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8;
> >  		ctx->chroma_size += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8;
> > +		ctx->chroma_size_1 +=
> S5P_FIMV_D_ALIGN_PLANE_SIZE_V8;
> >  	}
> >
> >  	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC || @@ -534,15
> +561,53
> > @@ static void s5p_mfc_enc_calc_src_size_v6(struct s5p_mfc_ctx *ctx)
> >  	mb_width = MB_WIDTH(ctx->img_width);
> >  	mb_height = MB_HEIGHT(ctx->img_height);
> >
> > -	ctx->buf_width = ALIGN(ctx->img_width,
> S5P_FIMV_NV12M_HALIGN_V6);
> > -	ctx->luma_size = ALIGN((mb_width * mb_height) * 256, 256);
> > -	ctx->chroma_size = ALIGN((mb_width * mb_height) * 128, 256);
> > -
> > -	/* MFCv7 needs pad bytes for Luma and Chroma */
> > -	if (IS_MFCV7_PLUS(ctx->dev)) {
> > +	if (IS_MFCV12(ctx->dev)) {
> > +		switch (ctx->src_fmt->fourcc) {
> > +		case V4L2_PIX_FMT_NV12M:
> > +		case V4L2_PIX_FMT_NV21M:
> > +			ctx->stride[0] = ALIGN(ctx->img_width,
> > +
> 	S5P_FIMV_NV12M_HALIGN_V6);
> > +			ctx->stride[1] = ALIGN(ctx->img_width,
> > +
> 	S5P_FIMV_NV12M_HALIGN_V6);
> > +			ctx->luma_size = ctx->stride[0] *
> > +						ALIGN(ctx->img_height, 16);
> > +			ctx->chroma_size =  ctx->stride[0] *
> > +						ALIGN(ctx->img_height / 2,
> 16);
> > +			break;
> > +		case V4L2_PIX_FMT_YUV420M:
> > +		case V4L2_PIX_FMT_YVU420M:
> > +			ctx->stride[0] = ALIGN(ctx->img_width,
> > +
> 	S5P_FIMV_NV12M_HALIGN_V6);
> > +			ctx->stride[1] = ALIGN(ctx->img_width / 2,
> > +
> 	S5P_FIMV_NV12M_HALIGN_V6);
> > +			ctx->stride[2] = ALIGN(ctx->img_width / 2,
> > +
> 	S5P_FIMV_NV12M_HALIGN_V6);
> > +			ctx->luma_size = ctx->stride[0] *
> > +						ALIGN(ctx->img_height, 16);
> > +			ctx->chroma_size =  ctx->stride[1] *
> > +						ALIGN(ctx->img_height / 2,
> 16);
> > +			ctx->chroma_size_1 =  ctx->stride[2] *
> > +						ALIGN(ctx->img_height / 2,
> 16);
> > +			break;
> > +		}
> >  		ctx->luma_size += MFC_LUMA_PAD_BYTES_V7;
> > -		ctx->chroma_size += MFC_CHROMA_PAD_BYTES_V7;
> > +		ctx->chroma_size += MFC_CHROMA_PAD_BYTES_V12;
> > +		ctx->chroma_size_1 += MFC_CHROMA_PAD_BYTES_V12;
> > +	} else {
> > +		ctx->buf_width = ALIGN(ctx->img_width,
> > +					S5P_FIMV_NV12M_HALIGN_V6);
> > +		ctx->stride[0] = ctx->buf_width;
> > +		ctx->stride[1] = ctx->buf_width;
> > +		ctx->luma_size = ALIGN((mb_width * mb_height) * 256,
> 256);
> > +		ctx->chroma_size = ALIGN((mb_width * mb_height) * 128,
> 256);
> > +		ctx->chroma_size_1 = 0;
> > +		/* MFCv7 needs pad bytes for Luma and Chroma */
> > +		if (IS_MFCV7_PLUS(ctx->dev)) {
> > +			ctx->luma_size += MFC_LUMA_PAD_BYTES_V7;
> > +			ctx->chroma_size += MFC_LUMA_PAD_BYTES_V7;
> > +		}
> >  	}
> > +
> >  }
> >
> >  /* Set registers for decoding stream buffer */ @@ -588,15 +653,21 @@
> > static int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx)
> >  	writel(ctx->total_dpb_count, mfc_regs->d_num_dpb);
> >  	writel(ctx->luma_size, mfc_regs->d_first_plane_dpb_size);
> >  	writel(ctx->chroma_size, mfc_regs->d_second_plane_dpb_size);
> > -
> > +	if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +			ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> > +		writel(ctx->chroma_size_1, mfc_regs-
> >d_third_plane_dpb_size);
> >  	writel(buf_addr1, mfc_regs->d_scratch_buffer_addr);
> >  	writel(ctx->scratch_buf_size, mfc_regs->d_scratch_buffer_size);
> >
> >  	if (IS_MFCV8_PLUS(dev)) {
> > -		writel(ctx->img_width,
> > +		writel(ctx->stride[0],
> >  			mfc_regs->d_first_plane_dpb_stride_size);
> > -		writel(ctx->img_width,
> > +		writel(ctx->stride[1],
> >  			mfc_regs->d_second_plane_dpb_stride_size);
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +			writel(ctx->stride[2],
> > +				mfc_regs->d_third_plane_dpb_stride_size);
> >  	}
> >
> >  	buf_addr1 += ctx->scratch_buf_size;
> > @@ -625,6 +696,13 @@ static int
> s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx)
> >  					ctx->dst_bufs[i].cookie.raw.chroma);
> >  		writel(ctx->dst_bufs[i].cookie.raw.chroma,
> >  				mfc_regs->d_second_plane_dpb + i * 4);
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M) {
> > +			mfc_debug(2, "\tChroma_1 %d: %zx\n", i,
> > +					ctx-
> >dst_bufs[i].cookie.raw.chroma_1);
> > +			writel(ctx->dst_bufs[i].cookie.raw.chroma_1,
> > +					mfc_regs->d_third_plane_dpb + i *
> 4);
> > +		}
> >  	}
> >  	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
> >  			ctx->codec_mode ==
> S5P_MFC_CODEC_H264_MVC_DEC || @@ -683,20
> > +761,24 @@ static int s5p_mfc_set_enc_stream_buffer_v6(struct
> > s5p_mfc_ctx *ctx,  }
> >
> >  static void s5p_mfc_set_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
> > -		unsigned long y_addr, unsigned long c_addr)
> > +		unsigned long y_addr, unsigned long c_addr,
> > +		unsigned long c_1_addr)
> >  {
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >  	const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs;
> >
> >  	writel(y_addr, mfc_regs->e_source_first_plane_addr);
> >  	writel(c_addr, mfc_regs->e_source_second_plane_addr);
> > +	writel(c_1_addr, mfc_regs->e_source_third_plane_addr);
> >
> >  	mfc_debug(2, "enc src y buf addr: 0x%08lx\n", y_addr);
> >  	mfc_debug(2, "enc src c buf addr: 0x%08lx\n", c_addr);
> > +	mfc_debug(2, "enc src cr buf addr: 0x%08lx\n", c_1_addr);
> >  }
> >
> >  static void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
> > -		unsigned long *y_addr, unsigned long *c_addr)
> > +		unsigned long *y_addr, unsigned long *c_addr,
> > +		unsigned long *c_1_addr)
> >  {
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >  	const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; @@ -704,12
> > +786,17 @@ static void s5p_mfc_get_enc_frame_buffer_v6(struct
> > s5p_mfc_ctx *ctx,
> >
> >  	*y_addr = readl(mfc_regs->e_encoded_source_first_plane_addr);
> >  	*c_addr = readl(mfc_regs-
> >e_encoded_source_second_plane_addr);
> > +	if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +			ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> > +		*c_1_addr = readl(mfc_regs-
> >e_encoded_source_third_plane_addr);
> > +	else
> > +		*c_1_addr = 0;
> >
> >  	enc_recon_y_addr = readl(mfc_regs->e_recon_luma_dpb_addr);
> >  	enc_recon_c_addr = readl(mfc_regs->e_recon_chroma_dpb_addr);
> >
> >  	mfc_debug(2, "recon y addr: 0x%08lx y_addr: 0x%08lx\n",
> enc_recon_y_addr, *y_addr);
> > -	mfc_debug(2, "recon c addr: 0x%08lx\n", enc_recon_c_addr);
> > +	mfc_debug(2, "recon c addr: 0x%08lx c_addr: 0x%08lx\n",
> > +enc_recon_c_addr, *c_addr);
> >  }
> >
> >  /* Set encoding ref & codec buffer */ @@ -886,6 +973,20 @@ static int
> > s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
> >  		writel(reg, mfc_regs->e_enc_options);
> >  		/* 0: NV12(CbCr), 1: NV21(CrCb) */
> >  		writel(0x0, mfc_regs->pixel_format);
> > +	} else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> > +		/* 0: Linear, 1: 2D tiled*/
> > +		reg = readl(mfc_regs->e_enc_options);
> > +		reg &= ~(0x1 << 7);
> > +		writel(reg, mfc_regs->e_enc_options);
> > +		/* 2: YV12(CrCb), 3: I420(CrCb) */
> > +		writel(0x2, mfc_regs->pixel_format);
> > +	} else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M) {
> > +		/* 0: Linear, 1: 2D tiled*/
> > +		reg = readl(mfc_regs->e_enc_options);
> > +		reg &= ~(0x1 << 7);
> > +		writel(reg, mfc_regs->e_enc_options);
> > +		/* 2: YV12(CrCb), 3: I420(CrCb) */
> > +		writel(0x3, mfc_regs->pixel_format);
> >  	}
> >
> >  	/* memory structure recon. frame */
> > @@ -1696,8 +1797,12 @@ static int s5p_mfc_init_decode_v6(struct
> s5p_mfc_ctx *ctx)
> >  	else
> >  		writel(reg, mfc_regs->d_dec_options);
> >
> > -	/* 0: NV12(CbCr), 1: NV21(CrCb) */
> > -	if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV21M)
> > +	/* 0: NV12(CbCr), 1: NV21(CrCb), 2: YV12(CrCb), 3: I420(CbCr) */
> > +	if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M)
> > +		writel(0x3, mfc_regs->pixel_format);
> > +	else if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> > +		writel(0x2, mfc_regs->pixel_format);
> > +	else if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV21M)
> >  		writel(0x1, mfc_regs->pixel_format);
> >  	else
> >  		writel(0x0, mfc_regs->pixel_format); @@ -1781,8 +1886,12
> @@ static
> > int s5p_mfc_init_encode_v6(struct s5p_mfc_ctx *ctx)
> >
> >  	/* Set stride lengths for v7 & above */
> >  	if (IS_MFCV7_PLUS(dev)) {
> > -		writel(ctx->img_width, mfc_regs-
> >e_source_first_plane_stride);
> > -		writel(ctx->img_width, mfc_regs-
> >e_source_second_plane_stride);
> > +		writel(ctx->stride[0], mfc_regs-
> >e_source_first_plane_stride);
> > +		writel(ctx->stride[1], mfc_regs-
> >e_source_second_plane_stride);
> > +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +			writel(ctx->stride[2],
> > +					mfc_regs-
> >e_source_third_plane_stride);
> >  	}
> >
> >  	writel(ctx->inst_no, mfc_regs->instance_id); @@ -1891,7 +2000,7
> @@
> > static inline int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >  	struct s5p_mfc_buf *dst_mb;
> >  	struct s5p_mfc_buf *src_mb;
> > -	unsigned long src_y_addr, src_c_addr, dst_addr;
> > +	unsigned long src_y_addr, src_c_addr, src_c_1_addr, dst_addr;
> >  	/*
> >  	unsigned int src_y_size, src_c_size;
> >  	*/
> > @@ -1909,22 +2018,29 @@ static inline int s5p_mfc_run_enc_frame(struct
> > s5p_mfc_ctx *ctx)
> >
> >  	if (list_empty(&ctx->src_queue)) {
> >  		/* send null frame */
> > -		s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0);
> > +		s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0, 0);
> >  		src_mb = NULL;
> >  	} else {
> >  		src_mb = list_entry(ctx->src_queue.next, struct
> s5p_mfc_buf, list);
> >  		src_mb->flags |= MFC_BUF_FLAG_USED;
> >  		if (src_mb->b->vb2_buf.planes[0].bytesused == 0) {
> > -			s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0);
> > +			s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0, 0);
> >  			ctx->state = MFCINST_FINISHING;
> >  		} else {
> >  			src_y_addr =
> vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 0);
> >  			src_c_addr =
> vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf,
> > 1);
> > +			if (ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +				src_c_1_addr =
> vb2_dma_contig_plane_dma_addr
> > +						(&src_mb->b->vb2_buf, 2);
> > +			else
> > +				src_c_1_addr = 0;
> >
> >  			mfc_debug(2, "enc src y addr: 0x%08lx\n",
> src_y_addr);
> >  			mfc_debug(2, "enc src c addr: 0x%08lx\n",
> src_c_addr);
> >
> > -			s5p_mfc_set_enc_frame_buffer_v6(ctx, src_y_addr,
> src_c_addr);
> > +			s5p_mfc_set_enc_frame_buffer_v6(ctx, src_y_addr,
> > +						src_c_addr, src_c_1_addr);
> >  			if (src_mb->flags & MFC_BUF_FLAG_EOS)
> >  				ctx->state = MFCINST_FINISHING;
> >  		}
> > @@ -2450,6 +2566,8 @@ const struct s5p_mfc_regs
> *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev)
> >  			S5P_FIMV_E_ENCODED_SOURCE_FIRST_ADDR_V7);
> >  	R(e_encoded_source_second_plane_addr,
> >
> 	S5P_FIMV_E_ENCODED_SOURCE_SECOND_ADDR_V7);
> > +	R(e_encoded_source_third_plane_addr,
> > +			S5P_FIMV_E_ENCODED_SOURCE_THIRD_ADDR_V7);
> >  	R(e_vp8_options, S5P_FIMV_E_VP8_OPTIONS_V7);
> >
> >  	if (!IS_MFCV8_PLUS(dev))
> > @@ -2464,16 +2582,20 @@ const struct s5p_mfc_regs
> *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev)
> >  	R(d_cpb_buffer_offset, S5P_FIMV_D_CPB_BUFFER_OFFSET_V8);
> >  	R(d_first_plane_dpb_size,
> S5P_FIMV_D_FIRST_PLANE_DPB_SIZE_V8);
> >  	R(d_second_plane_dpb_size,
> S5P_FIMV_D_SECOND_PLANE_DPB_SIZE_V8);
> > +	R(d_third_plane_dpb_size,
> S5P_FIMV_D_THIRD_PLANE_DPB_SIZE_V8);
> >  	R(d_scratch_buffer_addr,
> S5P_FIMV_D_SCRATCH_BUFFER_ADDR_V8);
> >  	R(d_scratch_buffer_size, S5P_FIMV_D_SCRATCH_BUFFER_SIZE_V8);
> >  	R(d_first_plane_dpb_stride_size,
> >  			S5P_FIMV_D_FIRST_PLANE_DPB_STRIDE_SIZE_V8);
> >  	R(d_second_plane_dpb_stride_size,
> >
> 	S5P_FIMV_D_SECOND_PLANE_DPB_STRIDE_SIZE_V8);
> > +	R(d_third_plane_dpb_stride_size,
> > +			S5P_FIMV_D_THIRD_PLANE_DPB_STRIDE_SIZE_V8);
> >  	R(d_mv_buffer_size, S5P_FIMV_D_MV_BUFFER_SIZE_V8);
> >  	R(d_num_mv, S5P_FIMV_D_NUM_MV_V8);
> >  	R(d_first_plane_dpb, S5P_FIMV_D_FIRST_PLANE_DPB_V8);
> >  	R(d_second_plane_dpb, S5P_FIMV_D_SECOND_PLANE_DPB_V8);
> > +	R(d_third_plane_dpb, S5P_FIMV_D_THIRD_PLANE_DPB_V8);
> >  	R(d_mv_buffer, S5P_FIMV_D_MV_BUFFER_V8);
> >  	R(d_init_buffer_options, S5P_FIMV_D_INIT_BUFFER_OPTIONS_V8);
> >  	R(d_available_dpb_flag_lower,
> > S5P_FIMV_D_AVAILABLE_DPB_FLAG_LOWER_V8);



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

* RE: [Patch v4 04/11] media: s5p-mfc: Add YV12 and I420 multiplanar format support
@ 2023-11-27  7:01           ` Aakarsh Jain
  0 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-11-27  7:01 UTC (permalink / raw)
  To: 'Hans Verkuil',
	linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, krzysztof.kozlowski+dt,
	dillon.minfei, david.plowman, mark.rutland, robh+dt, conor+dt,
	linux-samsung-soc, andi, gost.dev, alim.akhtar, aswani.reddy,
	pankaj.dubey, ajaykumar.rs, linux-fsd, 'Smitha T Murthy'

Hi Hans,

> -----Original Message-----
> From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
> Sent: 22 November 2023 21:11
> To: Aakarsh Jain <aakarsh.jain@samsung.com>; linux-arm-
> kernel@lists.infradead.org; linux-media@vger.kernel.org; linux-
> kernel@vger.kernel.org; devicetree@vger.kernel.org
> Cc: m.szyprowski@samsung.com; andrzej.hajda@intel.com;
> mchehab@kernel.org; krzysztof.kozlowski+dt@linaro.org;
> dillon.minfei@gmail.com; david.plowman@raspberrypi.com;
> mark.rutland@arm.com; robh+dt@kernel.org; conor+dt@kernel.org; linux-
> samsung-soc@vger.kernel.org; andi@etezian.org; gost.dev@samsung.com;
> alim.akhtar@samsung.com; aswani.reddy@samsung.com;
> pankaj.dubey@samsung.com; ajaykumar.rs@samsung.com; linux-
> fsd@tesla.com; Smitha T Murthy <smithatmurthy@gmail.com>
> Subject: Re: [Patch v4 04/11] media: s5p-mfc: Add YV12 and I420 multiplanar
> format support
> 
> On 25/10/2023 12:22, Aakarsh Jain wrote:
> > YV12 and I420 format (3-plane) support is added. Stride information is
> > added to all formats and planes since it is necessary for YV12/I420
> > which are different from width.
> >
> > Cc: linux-fsd@tesla.com
> > Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
> > Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
> > ---
> >  .../platform/samsung/s5p-mfc/regs-mfc-v12.h   |   2 +
> >  .../platform/samsung/s5p-mfc/regs-mfc-v7.h    |   1 +
> >  .../platform/samsung/s5p-mfc/regs-mfc-v8.h    |   3 +
> >  .../platform/samsung/s5p-mfc/s5p_mfc_common.h |   4 +
> >  .../platform/samsung/s5p-mfc/s5p_mfc_dec.c    |  45 ++++-
> >  .../platform/samsung/s5p-mfc/s5p_mfc_enc.c    |  86 +++++++--
> >  .../platform/samsung/s5p-mfc/s5p_mfc_opr.h    |   6 +-
> >  .../platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c |  12 +-
> > .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 168
> +++++++++++++++---
> >  9 files changed, 281 insertions(+), 46 deletions(-)
> >
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> > b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> > index 6c68a45082d0..70464f47c1f9 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> > +++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v12.h
> > @@ -26,6 +26,8 @@
> >  #define MFC_VERSION_V12			0xC0
> >  #define MFC_NUM_PORTS_V12		1
> >  #define S5P_FIMV_CODEC_VP9_ENC		27
> > +#define MFC_CHROMA_PAD_BYTES_V12        256
> > +#define S5P_FIMV_D_ALIGN_PLANE_SIZE_V12 256
> >
> >  /* Encoder buffer size for MFCv12 */
> >  #define ENC_V120_BASE_SIZE(x, y) \
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
> > b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
> > index 4a7adfdaa359..50f9bf0603c1 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
> > +++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h
> > @@ -24,6 +24,7 @@
> >
> >  #define S5P_FIMV_E_ENCODED_SOURCE_FIRST_ADDR_V7
> 	0xfa70
> >  #define S5P_FIMV_E_ENCODED_SOURCE_SECOND_ADDR_V7
> 	0xfa74
> > +#define S5P_FIMV_E_ENCODED_SOURCE_THIRD_ADDR_V7
> 	0xfa78
> >
> >  #define S5P_FIMV_E_VP8_OPTIONS_V7			0xfdb0
> >  #define S5P_FIMV_E_VP8_FILTER_OPTIONS_V7		0xfdb4
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
> > b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
> > index 162e3c7e920f..0ef9eb2dff22 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
> > +++ b/drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h
> > @@ -17,13 +17,16 @@
> >  #define S5P_FIMV_D_MIN_SCRATCH_BUFFER_SIZE_V8	0xf108
> >  #define S5P_FIMV_D_FIRST_PLANE_DPB_SIZE_V8	0xf144
> >  #define S5P_FIMV_D_SECOND_PLANE_DPB_SIZE_V8	0xf148
> > +#define S5P_FIMV_D_THIRD_PLANE_DPB_SIZE_V8	0xf14C
> >  #define S5P_FIMV_D_MV_BUFFER_SIZE_V8		0xf150
> >
> >  #define S5P_FIMV_D_FIRST_PLANE_DPB_STRIDE_SIZE_V8	0xf138
> >  #define S5P_FIMV_D_SECOND_PLANE_DPB_STRIDE_SIZE_V8
> 	0xf13c
> > +#define S5P_FIMV_D_THIRD_PLANE_DPB_STRIDE_SIZE_V8
> 	0xf140
> >
> >  #define S5P_FIMV_D_FIRST_PLANE_DPB_V8		0xf160
> >  #define S5P_FIMV_D_SECOND_PLANE_DPB_V8		0xf260
> > +#define S5P_FIMV_D_THIRD_PLANE_DPB_V8		0xf360
> >  #define S5P_FIMV_D_MV_BUFFER_V8			0xf460
> >
> >  #define S5P_FIMV_D_NUM_MV_V8			0xf134
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> > index dd2e9f7704ab..9a39cccfe002 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
> > @@ -56,6 +56,7 @@
> >  #define MFC_NO_INSTANCE_SET	-1
> >  #define MFC_ENC_CAP_PLANE_COUNT	1
> >  #define MFC_ENC_OUT_PLANE_COUNT	2
> > +#define VB2_MAX_PLANE_COUNT	3
> >  #define STUFF_BYTE		4
> >  #define MFC_MAX_CTRLS		128
> >
> > @@ -181,6 +182,7 @@ struct s5p_mfc_buf {
> >  		struct {
> >  			size_t luma;
> >  			size_t chroma;
> > +			size_t chroma_1;
> >  		} raw;
> >  		size_t stream;
> >  	} cookie;
> > @@ -657,6 +659,7 @@ struct s5p_mfc_ctx {
> >
> >  	int luma_size;
> >  	int chroma_size;
> > +	int chroma_size_1;
> >  	int mv_size;
> >
> >  	unsigned long consumed_stream;
> > @@ -722,6 +725,7 @@ struct s5p_mfc_ctx {
> >  	size_t scratch_buf_size;
> >  	int is_10bit;
> >  	int is_422;
> > +	int stride[VB2_MAX_PLANE_COUNT];
> >  };
> >
> >  /*
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> > index e219cbcd86d5..317f796fffa1 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
> > @@ -56,6 +56,20 @@ static struct s5p_mfc_fmt formats[] = {
> >  		.num_planes	= 2,
> >  		.versions	= MFC_V6PLUS_BITS,
> >  	},
> > +	{
> > +		.fourcc         = V4L2_PIX_FMT_YUV420M,
> > +		.codec_mode     = S5P_MFC_CODEC_NONE,
> > +		.type           = MFC_FMT_RAW,
> > +		.num_planes     = 3,
> > +		.versions       = MFC_V12_BIT,
> > +	},
> > +	{
> > +		.fourcc         = V4L2_PIX_FMT_YVU420M,
> > +		.codec_mode     = S5P_MFC_CODEC_NONE,
> > +		.type           = MFC_FMT_RAW,
> > +		.num_planes     = 3,
> > +		.versions       = MFC_V12_BIT
> > +	},
> >  	{
> >  		.fourcc		= V4L2_PIX_FMT_H264,
> >  		.codec_mode	= S5P_MFC_CODEC_H264_DEC,
> > @@ -359,10 +373,15 @@ static int vidioc_g_fmt(struct file *file, void *priv,
> struct v4l2_format *f)
> >  		/* Set pixelformat to the format in which MFC
> >  		   outputs the decoded frame */
> >  		pix_mp->pixelformat = ctx->dst_fmt->fourcc;
> > -		pix_mp->plane_fmt[0].bytesperline = ctx->buf_width;
> > +		pix_mp->plane_fmt[0].bytesperline = ctx->stride[0];
> >  		pix_mp->plane_fmt[0].sizeimage = ctx->luma_size;
> > -		pix_mp->plane_fmt[1].bytesperline = ctx->buf_width;
> > +		pix_mp->plane_fmt[1].bytesperline = ctx->stride[1];
> >  		pix_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M) {
> > +			pix_mp->plane_fmt[2].bytesperline = ctx->stride[2];
> > +			pix_mp->plane_fmt[2].sizeimage = ctx-
> >chroma_size_1;
> > +		}
> >  	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
> >  		/* This is run on OUTPUT
> >  		   The buffer contains compressed image @@ -937,6 +956,9
> @@ static
> > int s5p_mfc_queue_setup(struct vb2_queue *vq,
> >  		   vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
> >  		/* Output plane count is 2 - one for Y and one for CbCr */
> >  		*plane_count = 2;
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> 
> These misalignments produce a lot of checkpatch warnings.
> 
> Make sure you run your patch series through 'checkpatch.pl --strict'!
> 
> Regards,
> 
> 	Hans
> 
Thanks for pointing out. Will fix it in next series.

Thanks for the review.
> > +			*plane_count = 3;
> >  		/* Setup buffer count */
> >  		if (*buf_count < ctx->pb_count)
> >  			*buf_count = ctx->pb_count;
> > @@ -955,12 +977,17 @@ static int s5p_mfc_queue_setup(struct
> vb2_queue *vq,
> >  	    vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
> >  		psize[0] = ctx->luma_size;
> >  		psize[1] = ctx->chroma_size;
> > -
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +			psize[2] = ctx->chroma_size_1;
> >  		if (IS_MFCV6_PLUS(dev))
> >  			alloc_devs[0] = ctx->dev->mem_dev[BANK_L_CTX];
> >  		else
> >  			alloc_devs[0] = ctx->dev->mem_dev[BANK_R_CTX];
> >  		alloc_devs[1] = ctx->dev->mem_dev[BANK_L_CTX];
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +			alloc_devs[2] = ctx->dev->mem_dev[BANK_L_CTX];
> >  	} else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
> >  		   ctx->state == MFCINST_INIT) {
> >  		psize[0] = ctx->dec_src_buf_size;
> > @@ -994,12 +1021,24 @@ static int s5p_mfc_buf_init(struct vb2_buffer
> *vb)
> >  			mfc_err("Plane buffer (CAPTURE) is too small\n");
> >  			return -EINVAL;
> >  		}
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M) {
> > +			if (vb2_plane_size(vb, 2) < ctx->chroma_size_1) {
> > +				mfc_err("Plane buffer (CAPTURE) is too
> small\n");
> > +				return -EINVAL;
> > +			}
> > +		}
> >  		i = vb->index;
> >  		ctx->dst_bufs[i].b = vbuf;
> >  		ctx->dst_bufs[i].cookie.raw.luma =
> >
> 	vb2_dma_contig_plane_dma_addr(vb, 0);
> >  		ctx->dst_bufs[i].cookie.raw.chroma =
> >
> 	vb2_dma_contig_plane_dma_addr(vb, 1);
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M) {
> > +			ctx->dst_bufs[i].cookie.raw.chroma_1 =
> > +
> 	vb2_dma_contig_plane_dma_addr(vb, 2);
> > +		}
> >  		ctx->dst_bufs_cnt++;
> >  	} else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
> >  		if (IS_ERR_OR_NULL(ERR_PTR(
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> > index e4d6e7c117b5..0eec04eb3ef3 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
> > @@ -59,6 +59,20 @@ static struct s5p_mfc_fmt formats[] = {
> >  		.num_planes	= 2,
> >  		.versions	= MFC_V6PLUS_BITS,
> >  	},
> > +	{
> > +		.fourcc         = V4L2_PIX_FMT_YUV420M,
> > +		.codec_mode     = S5P_MFC_CODEC_NONE,
> > +		.type           = MFC_FMT_RAW,
> > +		.num_planes     = 3,
> > +		.versions       = MFC_V12_BIT,
> > +	},
> > +	{
> > +		.fourcc         = V4L2_PIX_FMT_YVU420M,
> > +		.codec_mode     = S5P_MFC_CODEC_NONE,
> > +		.type           = MFC_FMT_RAW,
> > +		.num_planes     = 3,
> > +		.versions       = MFC_V12_BIT,
> > +	},
> >  	{
> >  		.fourcc		= V4L2_PIX_FMT_H264,
> >  		.codec_mode	= S5P_MFC_CODEC_H264_ENC,
> > @@ -1193,14 +1207,20 @@ static int enc_pre_frame_start(struct
> s5p_mfc_ctx *ctx)
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >  	struct s5p_mfc_buf *dst_mb;
> >  	struct s5p_mfc_buf *src_mb;
> > -	unsigned long src_y_addr, src_c_addr, dst_addr;
> > +	unsigned long src_y_addr, src_c_addr, src_c_1_addr, dst_addr;
> >  	unsigned int dst_size;
> >
> >  	src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
> >  	src_y_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b-
> >vb2_buf, 0);
> >  	src_c_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b-
> >vb2_buf, 1);
> > +	if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +			ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> > +		src_c_1_addr =
> > +			vb2_dma_contig_plane_dma_addr(&src_mb->b-
> >vb2_buf, 2);
> > +	else
> > +		src_c_1_addr = 0;
> >  	s5p_mfc_hw_call(dev->mfc_ops, set_enc_frame_buffer, ctx,
> > -							src_y_addr,
> src_c_addr);
> > +					src_y_addr, src_c_addr,
> src_c_1_addr);
> >
> >  	dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
> >  	dst_addr = vb2_dma_contig_plane_dma_addr(&dst_mb->b-
> >vb2_buf, 0); @@
> > -1215,8 +1235,8 @@ static int enc_post_frame_start(struct s5p_mfc_ctx
> > *ctx)  {
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >  	struct s5p_mfc_buf *mb_entry;
> > -	unsigned long enc_y_addr = 0, enc_c_addr = 0;
> > -	unsigned long mb_y_addr, mb_c_addr;
> > +	unsigned long enc_y_addr = 0, enc_c_addr = 0, enc_c_1_addr = 0;
> > +	unsigned long mb_y_addr, mb_c_addr, mb_c_1_addr;
> >  	int slice_type;
> >  	unsigned int strm_size;
> >  	bool src_ready;
> > @@ -1229,14 +1249,21 @@ static int enc_post_frame_start(struct
> s5p_mfc_ctx *ctx)
> >  		  mfc_read(dev, S5P_FIMV_ENC_SI_PIC_CNT));
> >  	if (slice_type >= 0) {
> >  		s5p_mfc_hw_call(dev->mfc_ops, get_enc_frame_buffer,
> ctx,
> > -				&enc_y_addr, &enc_c_addr);
> > +				&enc_y_addr, &enc_c_addr,
> &enc_c_1_addr);
> >  		list_for_each_entry(mb_entry, &ctx->src_queue, list) {
> >  			mb_y_addr = vb2_dma_contig_plane_dma_addr(
> >  					&mb_entry->b->vb2_buf, 0);
> >  			mb_c_addr = vb2_dma_contig_plane_dma_addr(
> >  					&mb_entry->b->vb2_buf, 1);
> > -			if ((enc_y_addr == mb_y_addr) &&
> > -						(enc_c_addr == mb_c_addr))
> {
> > +			if (ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +				mb_c_1_addr =
> vb2_dma_contig_plane_dma_addr
> > +						(&mb_entry->b->vb2_buf,
> 2);
> > +			else
> > +				mb_c_1_addr = 0;
> > +			if ((enc_y_addr == mb_y_addr)
> > +					&& (enc_c_addr == mb_c_addr)
> > +					&& (enc_c_1_addr ==
> mb_c_1_addr)) {
> >  				list_del(&mb_entry->list);
> >  				ctx->src_queue_cnt--;
> >  				vb2_buffer_done(&mb_entry->b->vb2_buf,
> > @@ -1249,8 +1276,15 @@ static int enc_post_frame_start(struct
> s5p_mfc_ctx *ctx)
> >  					&mb_entry->b->vb2_buf, 0);
> >  			mb_c_addr = vb2_dma_contig_plane_dma_addr(
> >  					&mb_entry->b->vb2_buf, 1);
> > -			if ((enc_y_addr == mb_y_addr) &&
> > -						(enc_c_addr == mb_c_addr))
> {
> > +			if (ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +				mb_c_1_addr =
> vb2_dma_contig_plane_dma_addr(
> > +						&mb_entry->b->vb2_buf, 2);
> > +			else
> > +				mb_c_1_addr = 0;
> > +			if ((enc_y_addr == mb_y_addr)
> > +					&& (enc_c_addr == mb_c_addr)
> > +					&& (enc_c_1_addr ==
> mb_c_1_addr)) {
> >  				list_del(&mb_entry->list);
> >  				ctx->ref_queue_cnt--;
> >  				vb2_buffer_done(&mb_entry->b->vb2_buf,
> > @@ -1381,10 +1415,15 @@ static int vidioc_g_fmt(struct file *file, void
> *priv, struct v4l2_format *f)
> >  		pix_fmt_mp->pixelformat = ctx->src_fmt->fourcc;
> >  		pix_fmt_mp->num_planes = ctx->src_fmt->num_planes;
> >
> > -		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
> > +		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->stride[0];
> >  		pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
> > -		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
> > +		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->stride[1];
> >  		pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
> > +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M) {
> > +			pix_fmt_mp->plane_fmt[2].bytesperline = ctx-
> >stride[2];
> > +			pix_fmt_mp->plane_fmt[2].sizeimage = ctx-
> >chroma_size_1;
> > +		}
> >  	} else {
> >  		mfc_err("invalid buf type\n");
> >  		return -EINVAL;
> > @@ -1468,9 +1507,14 @@ static int vidioc_s_fmt(struct file *file, void
> > *priv, struct v4l2_format *f)
> >
> >  		s5p_mfc_hw_call(dev->mfc_ops, enc_calc_src_size, ctx);
> >  		pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
> > -		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
> > +		pix_fmt_mp->plane_fmt[0].bytesperline = ctx->stride[0];
> >  		pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
> > -		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
> > +		pix_fmt_mp->plane_fmt[1].bytesperline = ctx->stride[1];
> > +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M) {
> > +			pix_fmt_mp->plane_fmt[2].bytesperline = ctx-
> >stride[2];
> > +			pix_fmt_mp->plane_fmt[2].sizeimage = ctx-
> >chroma_size_1;
> > +		}
> >
> >  		ctx->src_bufs_cnt = 0;
> >  		ctx->output_state = QUEUE_FREE;
> > @@ -2414,10 +2458,16 @@ static int s5p_mfc_queue_setup(struct
> > vb2_queue *vq,
> >
> >  		psize[0] = ctx->luma_size;
> >  		psize[1] = ctx->chroma_size;
> > +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +			psize[2] = ctx->chroma_size_1;
> >
> >  		if (IS_MFCV6_PLUS(dev)) {
> >  			alloc_devs[0] = ctx->dev->mem_dev[BANK_L_CTX];
> >  			alloc_devs[1] = ctx->dev->mem_dev[BANK_L_CTX];
> > +			if (ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +				alloc_devs[2] = ctx->dev-
> >mem_dev[BANK_L_CTX];
> >  		} else {
> >  			alloc_devs[0] = ctx->dev->mem_dev[BANK_R_CTX];
> >  			alloc_devs[1] = ctx->dev->mem_dev[BANK_R_CTX];
> @@ -2456,6 +2506,10
> > @@ static int s5p_mfc_buf_init(struct vb2_buffer *vb)
> >
> 	vb2_dma_contig_plane_dma_addr(vb, 0);
> >  		ctx->src_bufs[i].cookie.raw.chroma =
> >
> 	vb2_dma_contig_plane_dma_addr(vb, 1);
> > +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +			ctx->src_bufs[i].cookie.raw.chroma_1 =
> > +
> 	vb2_dma_contig_plane_dma_addr(vb, 2);
> >  		ctx->src_bufs_cnt++;
> >  	} else {
> >  		mfc_err("invalid queue type: %d\n", vq->type); @@ -2493,6
> +2547,12
> > @@ static int s5p_mfc_buf_prepare(struct vb2_buffer *vb)
> >  			mfc_err("plane size is too small for output\n");
> >  			return -EINVAL;
> >  		}
> > +		if ((ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +		     ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) &&
> > +		    (vb2_plane_size(vb, 2) < ctx->chroma_size_1)) {
> > +			mfc_err("plane size is too small for output\n");
> > +			return -EINVAL;
> > +		}
> >  	} else {
> >  		mfc_err("invalid queue type: %d\n", vq->type);
> >  		return -EINVAL;
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> > index 87ac56756a16..7c5e851c8191 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h
> > @@ -293,9 +293,11 @@ struct s5p_mfc_hw_ops {
> >  	int (*set_enc_stream_buffer)(struct s5p_mfc_ctx *ctx,
> >  			unsigned long addr, unsigned int size);
> >  	void (*set_enc_frame_buffer)(struct s5p_mfc_ctx *ctx,
> > -			unsigned long y_addr, unsigned long c_addr);
> > +			unsigned long y_addr, unsigned long c_addr,
> > +			unsigned long c_1_addr);
> >  	void (*get_enc_frame_buffer)(struct s5p_mfc_ctx *ctx,
> > -			unsigned long *y_addr, unsigned long *c_addr);
> > +			unsigned long *y_addr, unsigned long *c_addr,
> > +			unsigned long *c_1_addr);
> >  	void (*try_run)(struct s5p_mfc_dev *dev);
> >  	void (*clear_int_flags)(struct s5p_mfc_dev *dev);
> >  	int (*get_dspl_y_adr)(struct s5p_mfc_dev *dev); diff --git
> > a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
> > index 28a06dc343fd..fcfaf125a5a1 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
> > @@ -516,7 +516,8 @@ static int
> s5p_mfc_set_enc_stream_buffer_v5(struct
> > s5p_mfc_ctx *ctx,  }
> >
> >  static void s5p_mfc_set_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,
> > -		unsigned long y_addr, unsigned long c_addr)
> > +		unsigned long y_addr, unsigned long c_addr,
> > +		unsigned long c_1_addr)
> >  {
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >
> > @@ -525,7 +526,8 @@ static void
> s5p_mfc_set_enc_frame_buffer_v5(struct
> > s5p_mfc_ctx *ctx,  }
> >
> >  static void s5p_mfc_get_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,
> > -		unsigned long *y_addr, unsigned long *c_addr)
> > +		unsigned long *y_addr, unsigned long *c_addr,
> > +		unsigned long *c_1_addr)
> >  {
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >
> > @@ -1210,7 +1212,7 @@ static int s5p_mfc_run_enc_frame(struct
> s5p_mfc_ctx *ctx)
> >  	if (list_empty(&ctx->src_queue)) {
> >  		/* send null frame */
> >  		s5p_mfc_set_enc_frame_buffer_v5(ctx, dev-
> >dma_base[BANK_R_CTX],
> > -						dev-
> >dma_base[BANK_R_CTX]);
> > +						dev-
> >dma_base[BANK_R_CTX], 0);
> >  		src_mb = NULL;
> >  	} else {
> >  		src_mb = list_entry(ctx->src_queue.next, struct
> s5p_mfc_buf, @@
> > -1220,7 +1222,7 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx
> *ctx)
> >  			/* send null frame */
> >  			s5p_mfc_set_enc_frame_buffer_v5(ctx,
> >  						dev-
> >dma_base[BANK_R_CTX],
> > -						dev-
> >dma_base[BANK_R_CTX]);
> > +						dev-
> >dma_base[BANK_R_CTX], 0);
> >  			ctx->state = MFCINST_FINISHING;
> >  		} else {
> >  			src_y_addr = vb2_dma_contig_plane_dma_addr(
> @@ -1228,7 +1230,7 @@
> > static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
> >  			src_c_addr = vb2_dma_contig_plane_dma_addr(
> >  					&src_mb->b->vb2_buf, 1);
> >  			s5p_mfc_set_enc_frame_buffer_v5(ctx, src_y_addr,
> > -								src_c_addr);
> > +								src_c_addr,
> 0);
> >  			if (src_mb->flags & MFC_BUF_FLAG_EOS)
> >  				ctx->state = MFCINST_FINISHING;
> >  		}
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> > index fb3f0718821d..e579c765e902 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
> > @@ -494,16 +494,43 @@ static void s5p_mfc_dec_calc_dpb_size_v6(struct
> s5p_mfc_ctx *ctx)
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >  	ctx->buf_width = ALIGN(ctx->img_width,
> S5P_FIMV_NV12MT_HALIGN_V6);
> >  	ctx->buf_height = ALIGN(ctx->img_height,
> S5P_FIMV_NV12MT_VALIGN_V6);
> > +	ctx->chroma_size_1 = 0;
> >  	mfc_debug(2, "SEQ Done: Movie dimensions %dx%d,\n"
> >  			"buffer dimensions: %dx%d\n", ctx->img_width,
> >  			ctx->img_height, ctx->buf_width, ctx->buf_height);
> >
> > -	ctx->luma_size = calc_plane(ctx->img_width, ctx->img_height);
> > -	ctx->chroma_size = calc_plane(ctx->img_width, (ctx->img_height >>
> 1));
> > +	switch (ctx->dst_fmt->fourcc) {
> > +	case V4L2_PIX_FMT_NV12M:
> > +	case V4L2_PIX_FMT_NV21M:
> > +		ctx->stride[0] = ALIGN(ctx->img_width,
> > +					S5P_FIMV_NV12MT_HALIGN_V6);
> > +		ctx->stride[1] = ALIGN(ctx->img_width,
> > +					S5P_FIMV_NV12MT_HALIGN_V6);
> > +		ctx->luma_size = calc_plane(ctx->stride[0], ctx->img_height);
> > +		ctx->chroma_size = calc_plane(ctx->stride[1],
> > +					(ctx->img_height / 2));
> > +		break;
> > +	case V4L2_PIX_FMT_YUV420M:
> > +	case V4L2_PIX_FMT_YVU420M:
> > +		ctx->stride[0] = ALIGN(ctx->img_width,
> > +					S5P_FIMV_NV12MT_HALIGN_V6);
> > +		ctx->stride[1] = ALIGN(ctx->img_width / 2,
> > +					S5P_FIMV_NV12MT_HALIGN_V6);
> > +		ctx->stride[2] = ALIGN(ctx->img_width / 2,
> > +					S5P_FIMV_NV12MT_HALIGN_V6);
> > +		ctx->luma_size = calc_plane(ctx->stride[0], ctx->img_height);
> > +		ctx->chroma_size = calc_plane(ctx->stride[1],
> > +					(ctx->img_height / 2));
> > +		ctx->chroma_size_1 = calc_plane(ctx->stride[2],
> > +					(ctx->img_height / 2));
> > +		break;
> > +	}
> > +
> >  	if (IS_MFCV8_PLUS(ctx->dev)) {
> >  		/* MFCv8 needs additional 64 bytes for luma,chroma dpb*/
> >  		ctx->luma_size += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8;
> >  		ctx->chroma_size += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8;
> > +		ctx->chroma_size_1 +=
> S5P_FIMV_D_ALIGN_PLANE_SIZE_V8;
> >  	}
> >
> >  	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC || @@ -534,15
> +561,53
> > @@ static void s5p_mfc_enc_calc_src_size_v6(struct s5p_mfc_ctx *ctx)
> >  	mb_width = MB_WIDTH(ctx->img_width);
> >  	mb_height = MB_HEIGHT(ctx->img_height);
> >
> > -	ctx->buf_width = ALIGN(ctx->img_width,
> S5P_FIMV_NV12M_HALIGN_V6);
> > -	ctx->luma_size = ALIGN((mb_width * mb_height) * 256, 256);
> > -	ctx->chroma_size = ALIGN((mb_width * mb_height) * 128, 256);
> > -
> > -	/* MFCv7 needs pad bytes for Luma and Chroma */
> > -	if (IS_MFCV7_PLUS(ctx->dev)) {
> > +	if (IS_MFCV12(ctx->dev)) {
> > +		switch (ctx->src_fmt->fourcc) {
> > +		case V4L2_PIX_FMT_NV12M:
> > +		case V4L2_PIX_FMT_NV21M:
> > +			ctx->stride[0] = ALIGN(ctx->img_width,
> > +
> 	S5P_FIMV_NV12M_HALIGN_V6);
> > +			ctx->stride[1] = ALIGN(ctx->img_width,
> > +
> 	S5P_FIMV_NV12M_HALIGN_V6);
> > +			ctx->luma_size = ctx->stride[0] *
> > +						ALIGN(ctx->img_height, 16);
> > +			ctx->chroma_size =  ctx->stride[0] *
> > +						ALIGN(ctx->img_height / 2,
> 16);
> > +			break;
> > +		case V4L2_PIX_FMT_YUV420M:
> > +		case V4L2_PIX_FMT_YVU420M:
> > +			ctx->stride[0] = ALIGN(ctx->img_width,
> > +
> 	S5P_FIMV_NV12M_HALIGN_V6);
> > +			ctx->stride[1] = ALIGN(ctx->img_width / 2,
> > +
> 	S5P_FIMV_NV12M_HALIGN_V6);
> > +			ctx->stride[2] = ALIGN(ctx->img_width / 2,
> > +
> 	S5P_FIMV_NV12M_HALIGN_V6);
> > +			ctx->luma_size = ctx->stride[0] *
> > +						ALIGN(ctx->img_height, 16);
> > +			ctx->chroma_size =  ctx->stride[1] *
> > +						ALIGN(ctx->img_height / 2,
> 16);
> > +			ctx->chroma_size_1 =  ctx->stride[2] *
> > +						ALIGN(ctx->img_height / 2,
> 16);
> > +			break;
> > +		}
> >  		ctx->luma_size += MFC_LUMA_PAD_BYTES_V7;
> > -		ctx->chroma_size += MFC_CHROMA_PAD_BYTES_V7;
> > +		ctx->chroma_size += MFC_CHROMA_PAD_BYTES_V12;
> > +		ctx->chroma_size_1 += MFC_CHROMA_PAD_BYTES_V12;
> > +	} else {
> > +		ctx->buf_width = ALIGN(ctx->img_width,
> > +					S5P_FIMV_NV12M_HALIGN_V6);
> > +		ctx->stride[0] = ctx->buf_width;
> > +		ctx->stride[1] = ctx->buf_width;
> > +		ctx->luma_size = ALIGN((mb_width * mb_height) * 256,
> 256);
> > +		ctx->chroma_size = ALIGN((mb_width * mb_height) * 128,
> 256);
> > +		ctx->chroma_size_1 = 0;
> > +		/* MFCv7 needs pad bytes for Luma and Chroma */
> > +		if (IS_MFCV7_PLUS(ctx->dev)) {
> > +			ctx->luma_size += MFC_LUMA_PAD_BYTES_V7;
> > +			ctx->chroma_size += MFC_LUMA_PAD_BYTES_V7;
> > +		}
> >  	}
> > +
> >  }
> >
> >  /* Set registers for decoding stream buffer */ @@ -588,15 +653,21 @@
> > static int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx)
> >  	writel(ctx->total_dpb_count, mfc_regs->d_num_dpb);
> >  	writel(ctx->luma_size, mfc_regs->d_first_plane_dpb_size);
> >  	writel(ctx->chroma_size, mfc_regs->d_second_plane_dpb_size);
> > -
> > +	if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +			ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> > +		writel(ctx->chroma_size_1, mfc_regs-
> >d_third_plane_dpb_size);
> >  	writel(buf_addr1, mfc_regs->d_scratch_buffer_addr);
> >  	writel(ctx->scratch_buf_size, mfc_regs->d_scratch_buffer_size);
> >
> >  	if (IS_MFCV8_PLUS(dev)) {
> > -		writel(ctx->img_width,
> > +		writel(ctx->stride[0],
> >  			mfc_regs->d_first_plane_dpb_stride_size);
> > -		writel(ctx->img_width,
> > +		writel(ctx->stride[1],
> >  			mfc_regs->d_second_plane_dpb_stride_size);
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +			writel(ctx->stride[2],
> > +				mfc_regs->d_third_plane_dpb_stride_size);
> >  	}
> >
> >  	buf_addr1 += ctx->scratch_buf_size;
> > @@ -625,6 +696,13 @@ static int
> s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx)
> >  					ctx->dst_bufs[i].cookie.raw.chroma);
> >  		writel(ctx->dst_bufs[i].cookie.raw.chroma,
> >  				mfc_regs->d_second_plane_dpb + i * 4);
> > +		if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->dst_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M) {
> > +			mfc_debug(2, "\tChroma_1 %d: %zx\n", i,
> > +					ctx-
> >dst_bufs[i].cookie.raw.chroma_1);
> > +			writel(ctx->dst_bufs[i].cookie.raw.chroma_1,
> > +					mfc_regs->d_third_plane_dpb + i *
> 4);
> > +		}
> >  	}
> >  	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
> >  			ctx->codec_mode ==
> S5P_MFC_CODEC_H264_MVC_DEC || @@ -683,20
> > +761,24 @@ static int s5p_mfc_set_enc_stream_buffer_v6(struct
> > s5p_mfc_ctx *ctx,  }
> >
> >  static void s5p_mfc_set_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
> > -		unsigned long y_addr, unsigned long c_addr)
> > +		unsigned long y_addr, unsigned long c_addr,
> > +		unsigned long c_1_addr)
> >  {
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >  	const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs;
> >
> >  	writel(y_addr, mfc_regs->e_source_first_plane_addr);
> >  	writel(c_addr, mfc_regs->e_source_second_plane_addr);
> > +	writel(c_1_addr, mfc_regs->e_source_third_plane_addr);
> >
> >  	mfc_debug(2, "enc src y buf addr: 0x%08lx\n", y_addr);
> >  	mfc_debug(2, "enc src c buf addr: 0x%08lx\n", c_addr);
> > +	mfc_debug(2, "enc src cr buf addr: 0x%08lx\n", c_1_addr);
> >  }
> >
> >  static void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
> > -		unsigned long *y_addr, unsigned long *c_addr)
> > +		unsigned long *y_addr, unsigned long *c_addr,
> > +		unsigned long *c_1_addr)
> >  {
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >  	const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; @@ -704,12
> > +786,17 @@ static void s5p_mfc_get_enc_frame_buffer_v6(struct
> > s5p_mfc_ctx *ctx,
> >
> >  	*y_addr = readl(mfc_regs->e_encoded_source_first_plane_addr);
> >  	*c_addr = readl(mfc_regs-
> >e_encoded_source_second_plane_addr);
> > +	if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +			ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> > +		*c_1_addr = readl(mfc_regs-
> >e_encoded_source_third_plane_addr);
> > +	else
> > +		*c_1_addr = 0;
> >
> >  	enc_recon_y_addr = readl(mfc_regs->e_recon_luma_dpb_addr);
> >  	enc_recon_c_addr = readl(mfc_regs->e_recon_chroma_dpb_addr);
> >
> >  	mfc_debug(2, "recon y addr: 0x%08lx y_addr: 0x%08lx\n",
> enc_recon_y_addr, *y_addr);
> > -	mfc_debug(2, "recon c addr: 0x%08lx\n", enc_recon_c_addr);
> > +	mfc_debug(2, "recon c addr: 0x%08lx c_addr: 0x%08lx\n",
> > +enc_recon_c_addr, *c_addr);
> >  }
> >
> >  /* Set encoding ref & codec buffer */ @@ -886,6 +973,20 @@ static int
> > s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
> >  		writel(reg, mfc_regs->e_enc_options);
> >  		/* 0: NV12(CbCr), 1: NV21(CrCb) */
> >  		writel(0x0, mfc_regs->pixel_format);
> > +	} else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) {
> > +		/* 0: Linear, 1: 2D tiled*/
> > +		reg = readl(mfc_regs->e_enc_options);
> > +		reg &= ~(0x1 << 7);
> > +		writel(reg, mfc_regs->e_enc_options);
> > +		/* 2: YV12(CrCb), 3: I420(CrCb) */
> > +		writel(0x2, mfc_regs->pixel_format);
> > +	} else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M) {
> > +		/* 0: Linear, 1: 2D tiled*/
> > +		reg = readl(mfc_regs->e_enc_options);
> > +		reg &= ~(0x1 << 7);
> > +		writel(reg, mfc_regs->e_enc_options);
> > +		/* 2: YV12(CrCb), 3: I420(CrCb) */
> > +		writel(0x3, mfc_regs->pixel_format);
> >  	}
> >
> >  	/* memory structure recon. frame */
> > @@ -1696,8 +1797,12 @@ static int s5p_mfc_init_decode_v6(struct
> s5p_mfc_ctx *ctx)
> >  	else
> >  		writel(reg, mfc_regs->d_dec_options);
> >
> > -	/* 0: NV12(CbCr), 1: NV21(CrCb) */
> > -	if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV21M)
> > +	/* 0: NV12(CbCr), 1: NV21(CrCb), 2: YV12(CrCb), 3: I420(CbCr) */
> > +	if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YUV420M)
> > +		writel(0x3, mfc_regs->pixel_format);
> > +	else if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_YVU420M)
> > +		writel(0x2, mfc_regs->pixel_format);
> > +	else if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV21M)
> >  		writel(0x1, mfc_regs->pixel_format);
> >  	else
> >  		writel(0x0, mfc_regs->pixel_format); @@ -1781,8 +1886,12
> @@ static
> > int s5p_mfc_init_encode_v6(struct s5p_mfc_ctx *ctx)
> >
> >  	/* Set stride lengths for v7 & above */
> >  	if (IS_MFCV7_PLUS(dev)) {
> > -		writel(ctx->img_width, mfc_regs-
> >e_source_first_plane_stride);
> > -		writel(ctx->img_width, mfc_regs-
> >e_source_second_plane_stride);
> > +		writel(ctx->stride[0], mfc_regs-
> >e_source_first_plane_stride);
> > +		writel(ctx->stride[1], mfc_regs-
> >e_source_second_plane_stride);
> > +		if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +			writel(ctx->stride[2],
> > +					mfc_regs-
> >e_source_third_plane_stride);
> >  	}
> >
> >  	writel(ctx->inst_no, mfc_regs->instance_id); @@ -1891,7 +2000,7
> @@
> > static inline int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
> >  	struct s5p_mfc_dev *dev = ctx->dev;
> >  	struct s5p_mfc_buf *dst_mb;
> >  	struct s5p_mfc_buf *src_mb;
> > -	unsigned long src_y_addr, src_c_addr, dst_addr;
> > +	unsigned long src_y_addr, src_c_addr, src_c_1_addr, dst_addr;
> >  	/*
> >  	unsigned int src_y_size, src_c_size;
> >  	*/
> > @@ -1909,22 +2018,29 @@ static inline int s5p_mfc_run_enc_frame(struct
> > s5p_mfc_ctx *ctx)
> >
> >  	if (list_empty(&ctx->src_queue)) {
> >  		/* send null frame */
> > -		s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0);
> > +		s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0, 0);
> >  		src_mb = NULL;
> >  	} else {
> >  		src_mb = list_entry(ctx->src_queue.next, struct
> s5p_mfc_buf, list);
> >  		src_mb->flags |= MFC_BUF_FLAG_USED;
> >  		if (src_mb->b->vb2_buf.planes[0].bytesused == 0) {
> > -			s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0);
> > +			s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0, 0);
> >  			ctx->state = MFCINST_FINISHING;
> >  		} else {
> >  			src_y_addr =
> vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 0);
> >  			src_c_addr =
> vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf,
> > 1);
> > +			if (ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YUV420M ||
> > +				ctx->src_fmt->fourcc ==
> V4L2_PIX_FMT_YVU420M)
> > +				src_c_1_addr =
> vb2_dma_contig_plane_dma_addr
> > +						(&src_mb->b->vb2_buf, 2);
> > +			else
> > +				src_c_1_addr = 0;
> >
> >  			mfc_debug(2, "enc src y addr: 0x%08lx\n",
> src_y_addr);
> >  			mfc_debug(2, "enc src c addr: 0x%08lx\n",
> src_c_addr);
> >
> > -			s5p_mfc_set_enc_frame_buffer_v6(ctx, src_y_addr,
> src_c_addr);
> > +			s5p_mfc_set_enc_frame_buffer_v6(ctx, src_y_addr,
> > +						src_c_addr, src_c_1_addr);
> >  			if (src_mb->flags & MFC_BUF_FLAG_EOS)
> >  				ctx->state = MFCINST_FINISHING;
> >  		}
> > @@ -2450,6 +2566,8 @@ const struct s5p_mfc_regs
> *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev)
> >  			S5P_FIMV_E_ENCODED_SOURCE_FIRST_ADDR_V7);
> >  	R(e_encoded_source_second_plane_addr,
> >
> 	S5P_FIMV_E_ENCODED_SOURCE_SECOND_ADDR_V7);
> > +	R(e_encoded_source_third_plane_addr,
> > +			S5P_FIMV_E_ENCODED_SOURCE_THIRD_ADDR_V7);
> >  	R(e_vp8_options, S5P_FIMV_E_VP8_OPTIONS_V7);
> >
> >  	if (!IS_MFCV8_PLUS(dev))
> > @@ -2464,16 +2582,20 @@ const struct s5p_mfc_regs
> *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev)
> >  	R(d_cpb_buffer_offset, S5P_FIMV_D_CPB_BUFFER_OFFSET_V8);
> >  	R(d_first_plane_dpb_size,
> S5P_FIMV_D_FIRST_PLANE_DPB_SIZE_V8);
> >  	R(d_second_plane_dpb_size,
> S5P_FIMV_D_SECOND_PLANE_DPB_SIZE_V8);
> > +	R(d_third_plane_dpb_size,
> S5P_FIMV_D_THIRD_PLANE_DPB_SIZE_V8);
> >  	R(d_scratch_buffer_addr,
> S5P_FIMV_D_SCRATCH_BUFFER_ADDR_V8);
> >  	R(d_scratch_buffer_size, S5P_FIMV_D_SCRATCH_BUFFER_SIZE_V8);
> >  	R(d_first_plane_dpb_stride_size,
> >  			S5P_FIMV_D_FIRST_PLANE_DPB_STRIDE_SIZE_V8);
> >  	R(d_second_plane_dpb_stride_size,
> >
> 	S5P_FIMV_D_SECOND_PLANE_DPB_STRIDE_SIZE_V8);
> > +	R(d_third_plane_dpb_stride_size,
> > +			S5P_FIMV_D_THIRD_PLANE_DPB_STRIDE_SIZE_V8);
> >  	R(d_mv_buffer_size, S5P_FIMV_D_MV_BUFFER_SIZE_V8);
> >  	R(d_num_mv, S5P_FIMV_D_NUM_MV_V8);
> >  	R(d_first_plane_dpb, S5P_FIMV_D_FIRST_PLANE_DPB_V8);
> >  	R(d_second_plane_dpb, S5P_FIMV_D_SECOND_PLANE_DPB_V8);
> > +	R(d_third_plane_dpb, S5P_FIMV_D_THIRD_PLANE_DPB_V8);
> >  	R(d_mv_buffer, S5P_FIMV_D_MV_BUFFER_V8);
> >  	R(d_init_buffer_options, S5P_FIMV_D_INIT_BUFFER_OPTIONS_V8);
> >  	R(d_available_dpb_flag_lower,
> > S5P_FIMV_D_AVAILABLE_DPB_FLAG_LOWER_V8);



_______________________________________________
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] 54+ messages in thread

* RE: [Patch v4 09/11] media: s5p-mfc: Load firmware for each run in MFCv12.
  2023-11-22 15:44         ` Hans Verkuil
@ 2023-11-28 10:31           ` Aakarsh Jain
  -1 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-11-28 10:31 UTC (permalink / raw)
  To: 'Hans Verkuil',
	linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, krzysztof.kozlowski+dt,
	dillon.minfei, david.plowman, mark.rutland, robh+dt, conor+dt,
	linux-samsung-soc, andi, gost.dev, alim.akhtar, aswani.reddy,
	pankaj.dubey, ajaykumar.rs, linux-fsd, 'Smitha T Murthy'

Hi Hans,

> -----Original Message-----
> From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
> Sent: 22 November 2023 21:14
> To: Aakarsh Jain <aakarsh.jain@samsung.com>; linux-arm-
> kernel@lists.infradead.org; linux-media@vger.kernel.org; linux-
> kernel@vger.kernel.org; devicetree@vger.kernel.org
> Cc: m.szyprowski@samsung.com; andrzej.hajda@intel.com;
> mchehab@kernel.org; krzysztof.kozlowski+dt@linaro.org;
> dillon.minfei@gmail.com; david.plowman@raspberrypi.com;
> mark.rutland@arm.com; robh+dt@kernel.org; conor+dt@kernel.org; linux-
> samsung-soc@vger.kernel.org; andi@etezian.org; gost.dev@samsung.com;
> alim.akhtar@samsung.com; aswani.reddy@samsung.com;
> pankaj.dubey@samsung.com; ajaykumar.rs@samsung.com; linux-
> fsd@tesla.com; Smitha T Murthy <smithatmurthy@gmail.com>
> Subject: Re: [Patch v4 09/11] media: s5p-mfc: Load firmware for each run in
> MFCv12.
> 
> On 25/10/2023 12:22, Aakarsh Jain wrote:
> > In MFCv12, some section of firmware gets updated at each MFC run.
> > Hence we need to reload original firmware for each run at the start.
> 
> Huh? This is very weird. This definitely deserves a comment in the actual
> code rather than just the commit log.
> 
> Do you know what is going on? What part is updated? Are you sure it isn't a
> driver bug somehow?
> 
> Regards,
> 
> 	Hans
> 
During SYS_INIT command sent to MFC sequentially, firmware is not able to initialize the hardware due to incorrect firmware transfer and in current scenario the firmware is not loaded again in the Reserved memory area.
In this case RET_SYS_INIT response from hardware is failing. So we need to load firmware every time we open the device node.
I will add comment in the code why this change is needed.

Thanks for the review.
> >
> > Cc: linux-fsd@tesla.com
> > Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
> > Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
> > ---
> >  drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c | 5 +++--
> >  1 file changed, 3 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> > index b49159142c53..057088b9d327 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> > @@ -51,8 +51,9 @@ int s5p_mfc_load_firmware(struct s5p_mfc_dev
> *dev)
> >  	 * into kernel. */
> >  	mfc_debug_enter();
> >
> > -	if (dev->fw_get_done)
> > -		return 0;
> > +	if (!IS_MFCV12(dev))
> > +		if (dev->fw_get_done)
> > +			return 0;
> >
> >  	for (i = MFC_FW_MAX_VERSIONS - 1; i >= 0; i--) {
> >  		if (!dev->variant->fw_name[i])



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

* RE: [Patch v4 09/11] media: s5p-mfc: Load firmware for each run in MFCv12.
@ 2023-11-28 10:31           ` Aakarsh Jain
  0 siblings, 0 replies; 54+ messages in thread
From: Aakarsh Jain @ 2023-11-28 10:31 UTC (permalink / raw)
  To: 'Hans Verkuil',
	linux-arm-kernel, linux-media, linux-kernel, devicetree
  Cc: m.szyprowski, andrzej.hajda, mchehab, krzysztof.kozlowski+dt,
	dillon.minfei, david.plowman, mark.rutland, robh+dt, conor+dt,
	linux-samsung-soc, andi, gost.dev, alim.akhtar, aswani.reddy,
	pankaj.dubey, ajaykumar.rs, linux-fsd, 'Smitha T Murthy'

Hi Hans,

> -----Original Message-----
> From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
> Sent: 22 November 2023 21:14
> To: Aakarsh Jain <aakarsh.jain@samsung.com>; linux-arm-
> kernel@lists.infradead.org; linux-media@vger.kernel.org; linux-
> kernel@vger.kernel.org; devicetree@vger.kernel.org
> Cc: m.szyprowski@samsung.com; andrzej.hajda@intel.com;
> mchehab@kernel.org; krzysztof.kozlowski+dt@linaro.org;
> dillon.minfei@gmail.com; david.plowman@raspberrypi.com;
> mark.rutland@arm.com; robh+dt@kernel.org; conor+dt@kernel.org; linux-
> samsung-soc@vger.kernel.org; andi@etezian.org; gost.dev@samsung.com;
> alim.akhtar@samsung.com; aswani.reddy@samsung.com;
> pankaj.dubey@samsung.com; ajaykumar.rs@samsung.com; linux-
> fsd@tesla.com; Smitha T Murthy <smithatmurthy@gmail.com>
> Subject: Re: [Patch v4 09/11] media: s5p-mfc: Load firmware for each run in
> MFCv12.
> 
> On 25/10/2023 12:22, Aakarsh Jain wrote:
> > In MFCv12, some section of firmware gets updated at each MFC run.
> > Hence we need to reload original firmware for each run at the start.
> 
> Huh? This is very weird. This definitely deserves a comment in the actual
> code rather than just the commit log.
> 
> Do you know what is going on? What part is updated? Are you sure it isn't a
> driver bug somehow?
> 
> Regards,
> 
> 	Hans
> 
During SYS_INIT command sent to MFC sequentially, firmware is not able to initialize the hardware due to incorrect firmware transfer and in current scenario the firmware is not loaded again in the Reserved memory area.
In this case RET_SYS_INIT response from hardware is failing. So we need to load firmware every time we open the device node.
I will add comment in the code why this change is needed.

Thanks for the review.
> >
> > Cc: linux-fsd@tesla.com
> > Signed-off-by: Smitha T Murthy <smithatmurthy@gmail.com>
> > Signed-off-by: Aakarsh Jain <aakarsh.jain@samsung.com>
> > ---
> >  drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c | 5 +++--
> >  1 file changed, 3 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> > b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> > index b49159142c53..057088b9d327 100644
> > --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> > +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
> > @@ -51,8 +51,9 @@ int s5p_mfc_load_firmware(struct s5p_mfc_dev
> *dev)
> >  	 * into kernel. */
> >  	mfc_debug_enter();
> >
> > -	if (dev->fw_get_done)
> > -		return 0;
> > +	if (!IS_MFCV12(dev))
> > +		if (dev->fw_get_done)
> > +			return 0;
> >
> >  	for (i = MFC_FW_MAX_VERSIONS - 1; i >= 0; i--) {
> >  		if (!dev->variant->fw_name[i])



_______________________________________________
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] 54+ messages in thread

end of thread, other threads:[~2023-11-29  6:41 UTC | newest]

Thread overview: 54+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CGME20231025102230epcas5p1558641a18fbf4f841c82b0ef4cf5a91f@epcas5p1.samsung.com>
2023-10-25 10:22 ` [Patch v4 00/11] Add MFC V12 support Aakarsh Jain
2023-10-25 10:22   ` Aakarsh Jain
     [not found]   ` <CGME20231025102233epcas5p16b716d5b650bbc5af0d759ea4f58f44d@epcas5p1.samsung.com>
2023-10-25 10:22     ` [Patch v4 01/11] dt-bindings: media: s5p-mfc: Add mfcv12 variant Aakarsh Jain
2023-10-25 10:22       ` Aakarsh Jain
2023-10-25 13:00       ` Krzysztof Kozlowski
2023-10-25 13:00         ` Krzysztof Kozlowski
2023-10-26 13:31         ` Aakarsh Jain
2023-10-26 13:31           ` Aakarsh Jain
2023-11-01  8:24           ` Krzysztof Kozlowski
2023-11-01  8:24             ` Krzysztof Kozlowski
2023-11-08 17:24             ` Alim Akhtar
2023-11-08 17:24               ` Alim Akhtar
     [not found]   ` <CGME20231025102237epcas5p28a5ad9db8d7dea072a6986d530810dde@epcas5p2.samsung.com>
2023-10-25 10:22     ` [Patch v4 02/11] media: s5p-mfc: Rename IS_MFCV10 macro Aakarsh Jain
2023-10-25 10:22       ` Aakarsh Jain
2023-11-16  5:00       ` Alim Akhtar
2023-11-16  5:00         ` Alim Akhtar
     [not found]   ` <CGME20231025102240epcas5p1551ac81bc2cd45f6c84e2eebc11571c4@epcas5p1.samsung.com>
2023-10-25 10:22     ` [Patch v4 03/11] media: s5p-mfc: Add initial support for MFCv12 Aakarsh Jain
2023-10-25 10:22       ` Aakarsh Jain
2023-11-16  5:44       ` Alim Akhtar
2023-11-16  5:44         ` Alim Akhtar
2023-11-22 15:34       ` Hans Verkuil
2023-11-22 15:34         ` Hans Verkuil
2023-11-27  6:44         ` Aakarsh Jain
2023-11-27  6:44           ` Aakarsh Jain
     [not found]   ` <CGME20231025102243epcas5p1cdd0eb385d2381943d6d194eec3a569d@epcas5p1.samsung.com>
2023-10-25 10:22     ` [Patch v4 04/11] media: s5p-mfc: Add YV12 and I420 multiplanar format support Aakarsh Jain
2023-10-25 10:22       ` Aakarsh Jain
2023-11-22 15:40       ` Hans Verkuil
2023-11-22 15:40         ` Hans Verkuil
2023-11-27  7:01         ` Aakarsh Jain
2023-11-27  7:01           ` Aakarsh Jain
2023-11-23 17:25       ` Nicolas Dufresne
2023-11-23 17:25         ` Nicolas Dufresne
2023-11-27  7:00         ` Aakarsh Jain
2023-11-27  7:00           ` Aakarsh Jain
     [not found]   ` <CGME20231025102247epcas5p1103ae6d3194f2ffc354984e263ab7b4a@epcas5p1.samsung.com>
2023-10-25 10:22     ` [Patch v4 05/11] media: s5p-mfc: Add support for rate controls in MFCv12 Aakarsh Jain
2023-10-25 10:22       ` Aakarsh Jain
     [not found]   ` <CGME20231025102250epcas5p375603c0f150fd508f0c0aa3ec6305517@epcas5p3.samsung.com>
2023-10-25 10:22     ` [Patch v4 06/11] media: s5p-mfc: Add support for UHD encoding Aakarsh Jain
2023-10-25 10:22       ` Aakarsh Jain
     [not found]   ` <CGME20231025102253epcas5p4e57ce0924392b879d8d296f66613a798@epcas5p4.samsung.com>
2023-10-25 10:22     ` [Patch v4 07/11] media: s5p-mfc: Add support for DMABUF for encoder Aakarsh Jain
2023-10-25 10:22       ` Aakarsh Jain
     [not found]   ` <CGME20231025102257epcas5p4bf00a54078bf640dfb2e2e03e671453c@epcas5p4.samsung.com>
2023-10-25 10:22     ` [Patch v4 08/11] media: s5p-mfc: Set context for valid case before calling try_run Aakarsh Jain
2023-10-25 10:22       ` Aakarsh Jain
     [not found]   ` <CGME20231025102300epcas5p2c266a078b70614dc948b0e47cd5cf788@epcas5p2.samsung.com>
2023-10-25 10:22     ` [Patch v4 09/11] media: s5p-mfc: Load firmware for each run in MFCv12 Aakarsh Jain
2023-10-25 10:22       ` Aakarsh Jain
2023-11-22 15:44       ` Hans Verkuil
2023-11-22 15:44         ` Hans Verkuil
2023-11-28 10:31         ` Aakarsh Jain
2023-11-28 10:31           ` Aakarsh Jain
     [not found]   ` <CGME20231025102304epcas5p2065f908cb77558ef5573fbaab82352bd@epcas5p2.samsung.com>
2023-10-25 10:22     ` [Patch v4 10/11] media: s5p-mfc: DPB Count Independent of VIDIOC_REQBUF Aakarsh Jain
2023-10-25 10:22       ` Aakarsh Jain
     [not found]   ` <CGME20231025102307epcas5p1fde3d5b0095477a8a565ce9f913e71e5@epcas5p1.samsung.com>
2023-10-25 10:22     ` [Patch v4 11/11] arm64: dts: fsd: Add MFC related DT enteries Aakarsh Jain
2023-10-25 10:22       ` Aakarsh Jain
2023-11-20 12:48   ` [Patch v4 00/11] Add MFC V12 support Aakarsh Jain
2023-11-20 12:48     ` Aakarsh Jain

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.