All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC WIP PATCH v2] Load VDEC FW from TEE
@ 2024-02-27 14:25 Marc Gonzalez
  0 siblings, 0 replies; only message in thread
From: Marc Gonzalez @ 2024-02-27 14:25 UTC (permalink / raw)
  To: Neil Armstrong
  Cc: AML, Maxime Jourdan, Kevin Hilman, Jerome Brunet,
	Martin Blumenstingl, Pierre-Hugues Husson

Preliminary support for loading VDEC FW through TEE.

TODO:
- split the patch in 2 (or more?)
  - DT binding amlogic,tee-loads-vdec-fw
  - driver code
- test how long the delays need to be (after load & after start)
- add the DT prop to arch/arm64/boot/dts/amlogic/meson-g12a-fbx8am.dts


---
 Documentation/devicetree/bindings/media/amlogic,gx-vdec.yaml |  4 ++++
 drivers/staging/media/meson/vdec/Makefile                    |  1 +
 drivers/staging/media/meson/vdec/optee.c                     | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/staging/media/meson/vdec/optee.h                     |  5 +++++
 drivers/staging/media/meson/vdec/vdec.c                      |  3 +++
 drivers/staging/media/meson/vdec/vdec.h                      |  2 ++
 drivers/staging/media/meson/vdec/vdec_1.c                    | 14 +++++++++++++-
 drivers/staging/media/meson/vdec/vdec_hevc.c                 |  9 ++++++++-
 8 files changed, 86 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/amlogic,gx-vdec.yaml b/Documentation/devicetree/bindings/media/amlogic,gx-vdec.yaml
index 55930f6107c9c..543a90e83bfdc 100644
--- a/Documentation/devicetree/bindings/media/amlogic,gx-vdec.yaml
+++ b/Documentation/devicetree/bindings/media/amlogic,gx-vdec.yaml
@@ -82,6 +82,10 @@ properties:
     description: should point to a canvas provider node
     $ref: /schemas/types.yaml#/definitions/phandle
 
+  amlogic,tee-loads-vdec-fw:
+    type: boolean
+    description: Linux must request FW load from TEE
+
 allOf:
   - if:
       properties:
diff --git a/drivers/staging/media/meson/vdec/Makefile b/drivers/staging/media/meson/vdec/Makefile
index 6e726af84ac9b..41e5006fa6294 100644
--- a/drivers/staging/media/meson/vdec/Makefile
+++ b/drivers/staging/media/meson/vdec/Makefile
@@ -4,5 +4,6 @@
 meson-vdec-objs = esparser.o vdec.o vdec_helpers.o vdec_platform.o
 meson-vdec-objs += vdec_1.o vdec_hevc.o
 meson-vdec-objs += codec_mpeg12.o codec_h264.o codec_hevc_common.o codec_vp9.o
+meson-vdec-objs += optee.o
 
 obj-$(CONFIG_VIDEO_MESON_VDEC) += meson-vdec.o
diff --git a/drivers/staging/media/meson/vdec/optee.c b/drivers/staging/media/meson/vdec/optee.c
new file mode 100644
index 0000000000000..00ea935f7656a
--- /dev/null
+++ b/drivers/staging/media/meson/vdec/optee.c
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright (c) 2024 Freebox SAS
+
+#include "optee.h"
+#include <linux/arm-smccc.h>
+
+#define TEE_SMC_FAST_CALL_VAL(func_num) \
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, ARM_SMCCC_OWNER_TRUSTED_OS, func_num)
+
+static void request_fw_from_optee(struct device *dev, int fw_id)
+{
+	struct arm_smccc_res res;
+	arm_smccc_smc(TEE_SMC_FAST_CALL_VAL(15), fw_id, 0, 0, 0, 0, 0, 0, &res);
+	dev_dbg(dev, "VDEC FW ID %d: %lu\n", fw_id, res.a0);
+}
+
+/* VDEC FW IDs */
+#define VDEC_MPEG12	0
+#define VDEC_H264	11
+#define VDEC_HEVC	16
+#define VDEC_HEVC_MMU	17
+#define VDEC_VP9	18
+#define VDEC_VP9_MMU	19
+
+int amvdec_load_firmware_optee(struct amvdec_session *sess)
+{
+	struct device *dev = sess->core->dev_dec;
+	u32 pixfmt = sess->fmt_out->pixfmt;
+	int fw_id = 1;
+
+	// Load wrong firmware to make TEE reset HW component for us
+	request_fw_from_optee(dev, fw_id);
+
+	if (pixfmt == V4L2_PIX_FMT_MPEG1 || pixfmt == V4L2_PIX_FMT_MPEG2)
+		fw_id = VDEC_MPEG12;
+
+	if (pixfmt == V4L2_PIX_FMT_H264)
+		fw_id = VDEC_H264;
+
+	if (pixfmt == V4L2_PIX_FMT_HEVC)
+		fw_id = VDEC_HEVC_MMU;
+
+	if (pixfmt == V4L2_PIX_FMT_VP9)
+		fw_id = VDEC_VP9_MMU;
+
+	request_fw_from_optee(dev, fw_id);
+	msleep(100); /*** REQUIRED??? ***/
+
+	return 0;
+}
diff --git a/drivers/staging/media/meson/vdec/optee.h b/drivers/staging/media/meson/vdec/optee.h
new file mode 100644
index 0000000000000..f4e209850ad8a
--- /dev/null
+++ b/drivers/staging/media/meson/vdec/optee.h
@@ -0,0 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include "vdec.h"
+
+int amvdec_load_firmware_optee(struct amvdec_session *sess);
diff --git a/drivers/staging/media/meson/vdec/vdec.c b/drivers/staging/media/meson/vdec/vdec.c
index de3e0345ab7c6..9acdbb0d53340 100644
--- a/drivers/staging/media/meson/vdec/vdec.c
+++ b/drivers/staging/media/meson/vdec/vdec.c
@@ -1029,6 +1029,9 @@ static int vdec_probe(struct platform_device *pdev)
 	of_id = of_match_node(vdec_dt_match, dev->of_node);
 	core->platform = of_id->data;
 
+	if (of_property_read_bool(dev->of_node, "amlogic,tee-loads-vdec-fw"))
+		core->use_optee = true;
+
 	if (core->platform->revision == VDEC_REVISION_G12A ||
 	    core->platform->revision == VDEC_REVISION_SM1) {
 		core->vdec_hevcf_clk = devm_clk_get(dev, "vdec_hevcf");
diff --git a/drivers/staging/media/meson/vdec/vdec.h b/drivers/staging/media/meson/vdec/vdec.h
index 0906b8fb5cc60..274e8dae8c386 100644
--- a/drivers/staging/media/meson/vdec/vdec.h
+++ b/drivers/staging/media/meson/vdec/vdec.h
@@ -66,6 +66,7 @@ struct amvdec_session;
  * @v4l2_dev: v4l2 device
  * @cur_sess: current decoding session
  * @lock: video device lock
+ * @use_optee: request FW load from Trusted Execution Environment
  */
 struct amvdec_core {
 	void __iomem *dos_base;
@@ -91,6 +92,7 @@ struct amvdec_core {
 
 	struct amvdec_session *cur_sess;
 	struct mutex lock;
+	bool use_optee;
 };
 
 /**
diff --git a/drivers/staging/media/meson/vdec/vdec_1.c b/drivers/staging/media/meson/vdec/vdec_1.c
index 3fe2de0c9331f..0b46d72a5e0aa 100644
--- a/drivers/staging/media/meson/vdec/vdec_1.c
+++ b/drivers/staging/media/meson/vdec/vdec_1.c
@@ -13,6 +13,7 @@
 #include "vdec_1.h"
 #include "vdec_helpers.h"
 #include "dos_regs.h"
+#include "optee.h"
 
 /* AO Registers */
 #define AO_RTI_GEN_PWR_SLEEP0	0xe8
@@ -209,7 +210,11 @@ static int vdec_1_start(struct amvdec_session *sess)
 
 	vdec_1_stbuf_power_up(sess);
 
-	ret = vdec_1_load_firmware(sess, sess->fmt_out->firmware_path);
+	if (core->use_optee)
+		ret = amvdec_load_firmware_optee(sess);
+	else
+		ret = vdec_1_load_firmware(sess, sess->fmt_out->firmware_path);
+
 	if (ret)
 		goto stop;
 
@@ -232,6 +237,13 @@ static int vdec_1_start(struct amvdec_session *sess)
 	/* Let the firmware settle */
 	usleep_range(10, 20);
 
+	/*
+	 * When running secure boot, it looks like the codec needs
+	 * more time to settle (perhaps to authenticate the image?)
+	 */
+	if (core->use_optee)
+		msleep(100); /*** REQUIRED??? ***/
+
 	return 0;
 
 stop:
diff --git a/drivers/staging/media/meson/vdec/vdec_hevc.c b/drivers/staging/media/meson/vdec/vdec_hevc.c
index afced435c9070..6d9141c5f3163 100644
--- a/drivers/staging/media/meson/vdec/vdec_hevc.c
+++ b/drivers/staging/media/meson/vdec/vdec_hevc.c
@@ -14,6 +14,7 @@
 #include "vdec_hevc.h"
 #include "hevc_regs.h"
 #include "dos_regs.h"
+#include "optee.h"
 
 /* AO Registers */
 #define AO_RTI_GEN_PWR_SLEEP0	0xe8
@@ -204,7 +205,10 @@ static int vdec_hevc_start(struct amvdec_session *sess)
 
 	vdec_hevc_stbuf_init(sess);
 
-	ret = vdec_hevc_load_firmware(sess, sess->fmt_out->firmware_path);
+	if (core->use_optee)
+		ret = amvdec_load_firmware_optee(sess);
+	else
+		ret = vdec_hevc_load_firmware(sess, sess->fmt_out->firmware_path);
 	if (ret)
 		goto stop;
 
@@ -220,6 +224,9 @@ static int vdec_hevc_start(struct amvdec_session *sess)
 	/* Let the firmware settle */
 	usleep_range(10, 20);
 
+	if (core->use_optee)
+		msleep(100); /*** REQUIRED??? ***/
+
 	return 0;
 
 stop:
-- 
2.34.1


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

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2024-02-27 14:26 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-27 14:25 [RFC WIP PATCH v2] Load VDEC FW from TEE Marc Gonzalez

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.