Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save EmbeddedAndroid/4aadc7a54fb808040e41dca5440ef5ed to your computer and use it in GitHub Desktop.

Select an option

Save EmbeddedAndroid/4aadc7a54fb808040e41dca5440ef5ed to your computer and use it in GitHub Desktop.
Linux patches for the X1E80100 (Hamoa) IoT EVK on the open boot stack
From 627f09fc3f9fbfb6c41952f582ae3cdbe0bbd102 Mon Sep 17 00:00:00 2001
From: Tyler Baker <tyler.baker@oss.qualcomm.com>
Date: Thu, 8 Oct 2026 22:35:15 -0400
Subject: [PATCH 1/6] WIP: arm64: dts: qcom: sm8750: add the EL2 overlay
---
arch/arm64/boot/dts/qcom/Makefile | 4 +++
arch/arm64/boot/dts/qcom/sm8750-el2.dtso | 33 ++++++++++++++++++++++++
2 files changed, 37 insertions(+)
create mode 100644 arch/arm64/boot/dts/qcom/sm8750-el2.dtso
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 88230c4e00ea9..6675d2d1db90b 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -454,6 +454,10 @@ dtb-$(CONFIG_ARCH_QCOM) += sm8650-mtp.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8650-qrd.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8650-valve-deckard.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8750-mtp.dtb
+
+sm8750-mtp-el2-dtbs := sm8750-mtp.dtb sm8750-el2.dtbo
+
+dtb-$(CONFIG_ARCH_QCOM) += sm8750-mtp-el2.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8750-qrd.dtb
dtb-$(CONFIG_ARCH_QCOM) += talos-evk.dtb
diff --git a/arch/arm64/boot/dts/qcom/sm8750-el2.dtso b/arch/arm64/boot/dts/qcom/sm8750-el2.dtso
new file mode 100644
index 0000000000000..0ca26a95e45f4
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sm8750-el2.dtso
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ *
+ * SM8750 specific modifications required to boot in EL2.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/* We can't and don't need to use zap shader in EL2 as linux can zap the gpu on it's own. */
+&gpu_zap_shader {
+ status = "disabled";
+};
+
+&iris {
+ /* TODO: Add video-firmware iommus to start IRIS from EL2 */
+ status = "disabled";
+};
+
+/*
+ * Linux at EL2 with VHE uses the EL2 virtual timer, PPI 12 (INTID 28), which
+ * Gunyah owns when Linux runs at EL1.
+ */
+&{/timer} {
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>;
+};
--
2.47.3
From 3aa27db08ada1635691b271d708c9b836176d4f3 Mon Sep 17 00:00:00 2001
From: Tyler Baker <tyler.baker@oss.qualcomm.com>
Date: Fri, 9 Oct 2026 07:22:49 -0400
Subject: [PATCH 2/6] WIP: sm8750-el2: DSP SMMU streams, DARE tag reservations
The ADSP and CDSP boot streams (0x1000, 0x0c00) come from the
stock firmware IORT; the DARE tag regions from the XBL memory map. early
memtest without them: SError at 0x81400000.
Signed-off-by: Tyler Baker <tyler.baker@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/sm8750-el2.dtso | 25 ++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/sm8750-el2.dtso b/arch/arm64/boot/dts/qcom/sm8750-el2.dtso
index 0ca26a95e45f4..455d3b5e9d9d3 100644
--- a/arch/arm64/boot/dts/qcom/sm8750-el2.dtso
+++ b/arch/arm64/boot/dts/qcom/sm8750-el2.dtso
@@ -15,6 +15,31 @@ &gpu_zap_shader {
status = "disabled";
};
+&remoteproc_adsp {
+ iommus = <&apps_smmu 0x1000 0x0>;
+};
+
+&remoteproc_cdsp {
+ iommus = <&apps_smmu 0x0c00 0x0>;
+};
+
+/*
+ * DARE tag storage that the firmware protects and that Gunyah keeps out of
+ * the HLOS VM: the hypervisor tags after the Gunyah carve-outs and the TZ
+ * tags after tz-merged. A Linux access takes an SError.
+ */
+&{/reserved-memory} {
+ dare-hyp-tags@81400000 {
+ reg = <0x0 0x81400000 0x0 0x560000>;
+ no-map;
+ };
+
+ dare-tz-tags@d8600000 {
+ reg = <0x0 0xd8600000 0x0 0xb340000>;
+ no-map;
+ };
+};
+
&iris {
/* TODO: Add video-firmware iommus to start IRIS from EL2 */
status = "disabled";
--
2.47.3
From 60a770323e93522cfb43900b33cf65d11655f7ab Mon Sep 17 00:00:00 2001
From: Tyler Baker <tyler.baker@oss.qualcomm.com>
Date: Fri, 9 Oct 2026 14:16:50 -0400
Subject: [PATCH 3/6] remoteproc: qcom: pas: pass no input table when the
firmware has none
qcom_pas_parse_firmware() hands rproc->table_ptr and rproc->table_sz to
the PAS service as the firmware's own resource table even when
rproc_elf_load_rsc_table() found none. After a failed start the core
clears table_ptr but leaves table_sz, so the next start copies
table_sz bytes from NULL:
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
pc : __pi_memcpy_generic+0x110/0x22c
lr : qcom_pas_tee_get_rsc_table+0xf4/0x25c
Call trace:
__pi_memcpy_generic+0x110/0x22c (P)
qcom_pas_get_rsc_table+0x38/0x60
qcom_pas_parse_firmware+0xa0/0x100
rproc_boot+0x2d4/0x380
Pass a NULL table of size zero when the firmware carries none, as the
comment below the call describes.
Signed-off-by: Tyler Baker <tyler.baker@oss.qualcomm.com>
---
drivers/remoteproc/qcom_q6v5_pas.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
index 2e1e39826ffa0..2f6865c82654a 100644
--- a/drivers/remoteproc/qcom_q6v5_pas.c
+++ b/drivers/remoteproc/qcom_q6v5_pas.c
@@ -504,11 +504,13 @@ static int qcom_pas_parse_firmware(struct rproc *rproc, const struct firmware *f
return 0;
ret = rproc_elf_load_rsc_table(rproc, fw);
- if (ret)
+ if (ret) {
dev_dbg(&rproc->dev, "Failed to load resource table from firmware\n");
-
- table = rproc->table_ptr;
- table_sz = rproc->table_sz;
+ table_sz = 0;
+ } else {
+ table = rproc->table_ptr;
+ table_sz = rproc->table_sz;
+ }
/*
* The resources consumed by Qualcomm remote processors fall into two categories:
--
2.47.3
From d0946b3e3886fec16c5b38056a5ecb5493e9801c Mon Sep 17 00:00:00 2001
From: Tyler Baker <tyler.baker@oss.qualcomm.com>
Date: Fri, 16 Oct 2026 03:04:47 -0400
Subject: [PATCH 4/6] iommu/arm-smmu-qcom: keep firmware stream mappings on the
Adreno SMMU-500
On X1E80100 running Linux at EL2, the CP fetches the zap shader, its
trusted microcode, through stream ID 0x3 of the Adreno SMMU. The stream
is non-secure and nothing in Linux maps it, so the SMMU blocks the fetch
and the CP stops on an illegal instruction:
arm-smmu 3da0000.iommu: Blocked unknown Stream ID 0x3
adreno 3d00000.gpu: CP illegal instruction error
Under the Qualcomm hypervisor that stream is handled by the hypervisor.
At EL2 the boot firmware leaves a bypass stream mapping for it instead,
but unlike the other Qualcomm SMMU-500 implementations the Adreno one
does not keep stream mappings found at probe, and resets it away.
Use qcom_smmu_cfg_probe() for the Adreno SMMU-500 as well, so valid
stream mappings left by the firmware are kept as bypass.
Change-Id: Ibfeaa95c735af398e1dd4a04dc893c0b68b6ad2c
Signed-off-by: Tyler Baker <tyler.baker@oss.qualcomm.com>
---
drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index 795e8ec7e8faf..59d8a7d510eef 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -654,6 +654,7 @@ static const struct arm_smmu_impl qcom_adreno_smmu_v2_impl = {
static const struct arm_smmu_impl qcom_adreno_smmu_500_impl = {
.init_context = qcom_adreno_smmu_init_context,
+ .cfg_probe = qcom_smmu_cfg_probe,
.def_domain_type = qcom_smmu_def_domain_type,
.reset = arm_mmu500_reset,
.alloc_context_bank = qcom_adreno_smmu_alloc_context_bank,
--
2.47.3
From 748180037aef73beeff36fce6673569a49a220c2 Mon Sep 17 00:00:00 2001
From: Tyler Baker <tyler.baker@oss.qualcomm.com>
Date: Fri, 16 Oct 2026 12:02:34 -0400
Subject: [PATCH 5/6] clk: qcom: gpucc-x1e80100: do not gate the GX PLL as
unused
gpu_cc_pll0 is the GX PLL. It feeds the GX_GFX3D RCG, which Linux does
not model, and is turned on and off by the GMU together with the GX
domain; nothing in Linux takes a reference on it. When
clk_disable_unused() runs while the GMU holds GX on, it finds the PLL
enabled and unused and turns it off under the running GX, and the SoC
hangs:
[ 5.528873] GPUDIAG shutdown after oob
[ 5.846658] clk: Disabling unused clocks
[ 5.847149] CLKDIAG disable gpu_cc_pll0
(no further output, watchdog reset)
The window is normally short, as the GMU collapses GX within about
100 ms of the first idle, but it is open for the whole idle timeout when
the GMU does not reach IFPC, and clk_disable_unused() lands in it when
the GPU binds early in boot. Keeping gpu_cc_pll0 enabled in the same
boots avoids the hang.
Mark gpu_cc_pll0 CLK_IGNORE_UNUSED. It cannot be CLK_IS_CRITICAL, which
would keep GX clocked across power collapse.
Fixes: acddef6e1744 ("clk: qcom: Add GPU clock driver for x1e80100")
Change-Id: Ib8016de00c4051748e3a12302e22a7c791e8ad61
Signed-off-by: Tyler Baker <tyler.baker@oss.qualcomm.com>
---
drivers/clk/qcom/gpucc-x1e80100.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/clk/qcom/gpucc-x1e80100.c b/drivers/clk/qcom/gpucc-x1e80100.c
index 10a0b11927e38..cdb77985b9675 100644
--- a/drivers/clk/qcom/gpucc-x1e80100.c
+++ b/drivers/clk/qcom/gpucc-x1e80100.c
@@ -65,6 +65,11 @@ static struct clk_alpha_pll gpu_cc_pll0 = {
.index = DT_BI_TCXO,
},
.num_parents = 1,
+ /*
+ * The GX PLL is turned on and off by the GMU together
+ * with the GX domain and has no consumer in Linux.
+ */
+ .flags = CLK_IGNORE_UNUSED,
.ops = &clk_alpha_pll_zonda_ole_ops,
},
},
--
2.47.3

Linux patches for the X1E80100 (Hamoa) IoT EVK on the open boot stack

Linux at EL2 on TF-A + OP-TEE + U-Boot. Base: linux-next next-20261008 (aac26bee2287 "Add linux-next specific files for 20261008"), branch hamoa-dp-offlink (5a4563a23948).

Apply with git am *.patch on that base. Test run: https://lava.infra.foundries.io/scheduler/job/493314

The first two (sm8750) patches are shared with the Pakala branch this tree was built on. WIP patches are marked WIP and are not intended for upstream as is.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment