All of lore.kernel.org
 help / color / mirror / Atom feed
From: Marc Gonzalez <mgonzalez@freebox.fr>
To: Neil Armstrong <neil.armstrong@linaro.org>
Cc: AML <linux-amlogic@lists.infradead.org>,
	Maxime Jourdan <mjourdan@baylibre.com>,
	Kevin Hilman <khilman@baylibre.com>,
	Jerome Brunet <jbrunet@baylibre.com>,
	Martin Blumenstingl <martin.blumenstingl@googlemail.com>,
	Pierre-Hugues Husson <phh@phh.me>
Subject: [RFC WIP PATCH v2] Load VDEC FW from TEE
Date: Tue, 27 Feb 2024 15:25:56 +0100	[thread overview]
Message-ID: <2c244e57-2898-4f30-8823-b3d0bd856c05@freebox.fr> (raw)

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

                 reply	other threads:[~2024-02-27 14:26 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2c244e57-2898-4f30-8823-b3d0bd856c05@freebox.fr \
    --to=mgonzalez@freebox.fr \
    --cc=jbrunet@baylibre.com \
    --cc=khilman@baylibre.com \
    --cc=linux-amlogic@lists.infradead.org \
    --cc=martin.blumenstingl@googlemail.com \
    --cc=mjourdan@baylibre.com \
    --cc=neil.armstrong@linaro.org \
    --cc=phh@phh.me \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.