qualcommax: ipq807x/ipq60xx: use secure WCSS driver

Use the WCSS secure driver for Q6 remoteproc on IPQ807x and IPQ6018.

This allows dropping a bunch of patches for the current overloaded driver.

Link: https://github.com/openwrt/openwrt/pull/25223
Signed-off-by: Robert Marko <robimarko@gmail.com>
This commit is contained in:
Robert Marko committed 2026-09-16 20:20:56 +02:00
1 parent 73e1cc119e
commit d7502b4694
22 files changed
+219 -770

No files matched your search

+2 -2
View File
@@ -449,8 +449,8 @@ CONFIG_QCOM_Q6V5_COMMON=y
# CONFIG_QCOM_Q6V5_MPD is not set
# CONFIG_QCOM_Q6V5_MSS is not set
# CONFIG_QCOM_Q6V5_PAS is not set
CONFIG_QCOM_Q6V5_WCSS=y
# CONFIG_QCOM_Q6V5_WCSS_SEC is not set
# CONFIG_QCOM_Q6V5_WCSS is not set
CONFIG_QCOM_Q6V5_WCSS_SEC=y
# CONFIG_QCOM_QSEECOM is not set
# CONFIG_QCOM_RAMP_CTRL is not set
# CONFIG_QCOM_RMTFS_MEM is not set
@@ -1,155 +0,0 @@
From 125681433c8e526356947acf572fe8ca8ad32291 Mon Sep 17 00:00:00 2001
From: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Date: Sat, 30 Jan 2021 10:50:05 +0530
Subject: [PATCH] remoteproc: qcom: Add PRNG proxy clock
PRNG clock is needed by the secure PIL, support for the same
is added in subsequent patches.
Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
Signed-off-by: Nikhil Prakash V <nprakash@codeaurora.org>
---
drivers/remoteproc/qcom_q6v5_wcss.c | 65 +++++++++++++++++++++--------
1 file changed, 47 insertions(+), 18 deletions(-)
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -91,19 +91,6 @@ enum {
WCSS_QCS404,
};
-struct wcss_data {
- const char *firmware_name;
- unsigned int crash_reason_smem;
- u32 version;
- bool aon_reset_required;
- bool wcss_q6_reset_required;
- const char *ssr_name;
- const char *sysmon_name;
- int ssctl_id;
- const struct rproc_ops *ops;
- bool requires_force_stop;
-};
-
struct q6v5_wcss {
struct device *dev;
@@ -128,6 +115,7 @@ struct q6v5_wcss {
struct clk *qdsp6ss_xo_cbcr;
struct clk *qdsp6ss_core_gfmux;
struct clk *lcc_bcr_sleep;
+ struct clk *prng_clk;
struct regulator *cx_supply;
struct qcom_sysmon *sysmon;
@@ -152,6 +140,21 @@ struct q6v5_wcss {
struct qcom_rproc_ssr ssr_subdev;
};
+struct wcss_data {
+ int (*init_clock)(struct q6v5_wcss *wcss);
+ int (*init_regulator)(struct q6v5_wcss *wcss);
+ const char *firmware_name;
+ unsigned int crash_reason_smem;
+ u32 version;
+ bool aon_reset_required;
+ bool wcss_q6_reset_required;
+ const char *ssr_name;
+ const char *sysmon_name;
+ int ssctl_id;
+ const struct rproc_ops *ops;
+ bool requires_force_stop;
+};
+
static int q6v5_wcss_reset(struct q6v5_wcss *wcss)
{
int ret;
@@ -241,6 +244,12 @@ static int q6v5_wcss_start(struct rproc
struct q6v5_wcss *wcss = rproc->priv;
int ret;
+ ret = clk_prepare_enable(wcss->prng_clk);
+ if (ret) {
+ dev_err(wcss->dev, "prng clock enable failed\n");
+ return ret;
+ }
+
qcom_q6v5_prepare(&wcss->q6v5);
/* Release Q6 and WCSS reset */
@@ -734,6 +743,7 @@ static int q6v5_wcss_stop(struct rproc *
return ret;
}
+ clk_disable_unprepare(wcss->prng_clk);
qcom_q6v5_unprepare(&wcss->q6v5);
return 0;
@@ -900,7 +910,21 @@ static int q6v5_alloc_memory_region(stru
return 0;
}
-static int q6v5_wcss_init_clock(struct q6v5_wcss *wcss)
+static int ipq8074_init_clock(struct q6v5_wcss *wcss)
+{
+ int ret;
+
+ wcss->prng_clk = devm_clk_get(wcss->dev, "prng");
+ if (IS_ERR(wcss->prng_clk)) {
+ ret = PTR_ERR(wcss->prng_clk);
+ if (ret != -EPROBE_DEFER)
+ dev_err(wcss->dev, "Failed to get prng clock\n");
+ return ret;
+ }
+ return 0;
+}
+
+static int qcs404_init_clock(struct q6v5_wcss *wcss)
{
wcss->xo = devm_clk_get(wcss->dev, "xo");
if (IS_ERR(wcss->xo))
@@ -958,7 +982,7 @@ static int q6v5_wcss_init_clock(struct q
return 0;
}
-static int q6v5_wcss_init_regulator(struct q6v5_wcss *wcss)
+static int qcs404_init_regulator(struct q6v5_wcss *wcss)
{
wcss->cx_supply = devm_regulator_get(wcss->dev, "cx");
if (IS_ERR(wcss->cx_supply))
@@ -1001,12 +1025,14 @@ static int q6v5_wcss_probe(struct platfo
if (ret)
return ret;
- if (wcss->version == WCSS_QCS404) {
- ret = q6v5_wcss_init_clock(wcss);
+ if (desc->init_clock) {
+ ret = desc->init_clock(wcss);
if (ret)
return ret;
+ }
- ret = q6v5_wcss_init_regulator(wcss);
+ if (desc->init_regulator) {
+ ret = desc->init_regulator(wcss);
if (ret)
return ret;
}
@@ -1063,6 +1089,7 @@ static void q6v5_wcss_remove(struct plat
}
static const struct wcss_data wcss_ipq8074_res_init = {
+ .init_clock = ipq8074_init_clock,
.firmware_name = "IPQ8074/q6_fw.mdt",
.crash_reason_smem = WCSS_CRASH_REASON,
.aon_reset_required = true,
@@ -1072,6 +1099,8 @@ static const struct wcss_data wcss_ipq80
};
static const struct wcss_data wcss_qcs404_res_init = {
+ .init_clock = qcs404_init_clock,
+ .init_regulator = qcs404_init_regulator,
.crash_reason_smem = WCSS_CRASH_REASON,
.firmware_name = "wcnss.mdt",
.version = WCSS_QCS404,
@@ -1,143 +0,0 @@
From 7358d42dfbdfdb5d4f1d0d4c2e5c2bb4143a29b0 Mon Sep 17 00:00:00 2001
From: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Date: Sat, 30 Jan 2021 10:50:06 +0530
Subject: [PATCH] remoteproc: qcom: Add secure PIL support
IPQ8074 uses secure PIL. Hence, adding the support for the same.
Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
Signed-off-by: Nikhil Prakash V <nprakash@codeaurora.org>
---
drivers/remoteproc/qcom_q6v5_wcss.c | 43 +++++++++++++++++++++++++++--
1 file changed, 40 insertions(+), 3 deletions(-)
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -18,6 +18,7 @@
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
#include <linux/soc/qcom/mdt_loader.h>
+#include <linux/firmware/qcom/qcom_scm.h>
#include "qcom_common.h"
#include "qcom_pil_info.h"
#include "qcom_q6v5.h"
@@ -86,6 +87,9 @@
#define TCSR_WCSS_CLK_ENABLE 0x14
#define MAX_HALT_REG 4
+
+#define WCNSS_PAS_ID 6
+
enum {
WCSS_IPQ8074,
WCSS_QCS404,
@@ -134,6 +138,7 @@ struct q6v5_wcss {
unsigned int crash_reason_smem;
u32 version;
bool requires_force_stop;
+ bool need_mem_protection;
struct qcom_rproc_glink glink_subdev;
struct qcom_rproc_pdm pdm_subdev;
@@ -153,6 +158,7 @@ struct wcss_data {
int ssctl_id;
const struct rproc_ops *ops;
bool requires_force_stop;
+ bool need_mem_protection;
};
static int q6v5_wcss_reset(struct q6v5_wcss *wcss)
@@ -252,6 +258,15 @@ static int q6v5_wcss_start(struct rproc
qcom_q6v5_prepare(&wcss->q6v5);
+ if (wcss->need_mem_protection) {
+ ret = qcom_scm_pas_auth_and_reset(WCNSS_PAS_ID);
+ if (ret) {
+ dev_err(wcss->dev, "wcss_reset failed\n");
+ return ret;
+ }
+ goto wait_for_reset;
+ }
+
/* Release Q6 and WCSS reset */
ret = reset_control_deassert(wcss->wcss_reset);
if (ret) {
@@ -286,6 +301,7 @@ static int q6v5_wcss_start(struct rproc
if (ret)
goto wcss_q6_reset;
+wait_for_reset:
ret = qcom_q6v5_wait_for_start(&wcss->q6v5, 5 * HZ);
if (ret == -ETIMEDOUT)
dev_err(wcss->dev, "start timed out\n");
@@ -719,6 +735,15 @@ static int q6v5_wcss_stop(struct rproc *
struct q6v5_wcss *wcss = rproc->priv;
int ret;
+ if (wcss->need_mem_protection) {
+ ret = qcom_scm_pas_shutdown(WCNSS_PAS_ID);
+ if (ret) {
+ dev_err(wcss->dev, "not able to shutdown\n");
+ return ret;
+ }
+ goto pas_done;
+ }
+
/* WCSS powerdown */
if (wcss->requires_force_stop) {
ret = qcom_q6v5_request_stop(&wcss->q6v5, NULL);
@@ -743,6 +768,7 @@ static int q6v5_wcss_stop(struct rproc *
return ret;
}
+pas_done:
clk_disable_unprepare(wcss->prng_clk);
qcom_q6v5_unprepare(&wcss->q6v5);
@@ -766,9 +792,15 @@ static int q6v5_wcss_load(struct rproc *
struct q6v5_wcss *wcss = rproc->priv;
int ret;
- ret = qcom_mdt_load_no_init(wcss->dev, fw, rproc->firmware,
- wcss->mem_region, wcss->mem_phys,
- wcss->mem_size, &wcss->mem_reloc);
+ if (wcss->need_mem_protection)
+ ret = qcom_mdt_load(wcss->dev, fw, rproc->firmware,
+ WCNSS_PAS_ID, wcss->mem_region,
+ wcss->mem_phys, wcss->mem_size,
+ &wcss->mem_reloc);
+ else
+ ret = qcom_mdt_load_no_init(wcss->dev, fw, rproc->firmware,
+ wcss->mem_region, wcss->mem_phys,
+ wcss->mem_size, &wcss->mem_reloc);
if (ret)
return ret;
@@ -1004,6 +1036,9 @@ static int q6v5_wcss_probe(struct platfo
if (!desc)
return -EINVAL;
+ if (desc->need_mem_protection && !qcom_scm_is_available())
+ return -EPROBE_DEFER;
+
rproc = devm_rproc_alloc(&pdev->dev, pdev->name, desc->ops,
desc->firmware_name, sizeof(*wcss));
if (!rproc) {
@@ -1016,6 +1051,7 @@ static int q6v5_wcss_probe(struct platfo
wcss->version = desc->version;
wcss->requires_force_stop = desc->requires_force_stop;
+ wcss->need_mem_protection = desc->need_mem_protection;
ret = q6v5_wcss_init_mmio(wcss, pdev);
if (ret)
@@ -1096,6 +1132,7 @@ static const struct wcss_data wcss_ipq80
.wcss_q6_reset_required = true,
.ops = &q6v5_wcss_ipq8074_ops,
.requires_force_stop = true,
+ .need_mem_protection = true,
};
static const struct wcss_data wcss_qcs404_res_init = {
@@ -1,103 +0,0 @@
From b422c9d4f048b086ce83f44a7cfcddcce162897f Mon Sep 17 00:00:00 2001
From: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Date: Sat, 30 Jan 2021 10:50:07 +0530
Subject: [PATCH] remoteproc: qcom: Add support for split q6 + m3 wlan firmware
IPQ8074 supports split firmware for q6 and m3 as well.
So add support for loading the m3 firmware before q6.
Now the drivers works fine for both split and unified
firmwares.
Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
Signed-off-by: Nikhil Prakash V <nprakash@codeaurora.org>
---
drivers/remoteproc/qcom_q6v5_wcss.c | 33 +++++++++++++++++++++++++----
1 file changed, 29 insertions(+), 4 deletions(-)
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -139,6 +139,7 @@ struct q6v5_wcss {
u32 version;
bool requires_force_stop;
bool need_mem_protection;
+ const char *m3_firmware_name;
struct qcom_rproc_glink glink_subdev;
struct qcom_rproc_pdm pdm_subdev;
@@ -148,7 +149,8 @@ struct q6v5_wcss {
struct wcss_data {
int (*init_clock)(struct q6v5_wcss *wcss);
int (*init_regulator)(struct q6v5_wcss *wcss);
- const char *firmware_name;
+ const char *q6_firmware_name;
+ const char *m3_firmware_name;
unsigned int crash_reason_smem;
u32 version;
bool aon_reset_required;
@@ -790,8 +792,29 @@ static void *q6v5_wcss_da_to_va(struct r
static int q6v5_wcss_load(struct rproc *rproc, const struct firmware *fw)
{
struct q6v5_wcss *wcss = rproc->priv;
+ const struct firmware *m3_fw;
int ret;
+ if (wcss->m3_firmware_name) {
+ ret = request_firmware(&m3_fw, wcss->m3_firmware_name,
+ wcss->dev);
+ if (ret)
+ goto skip_m3;
+
+ ret = qcom_mdt_load_no_init(wcss->dev, m3_fw,
+ wcss->m3_firmware_name,
+ wcss->mem_region, wcss->mem_phys,
+ wcss->mem_size, &wcss->mem_reloc);
+
+ release_firmware(m3_fw);
+
+ if (ret) {
+ dev_err(wcss->dev, "can't load m3_fw.bXX\n");
+ return ret;
+ }
+ }
+
+skip_m3:
if (wcss->need_mem_protection)
ret = qcom_mdt_load(wcss->dev, fw, rproc->firmware,
WCNSS_PAS_ID, wcss->mem_region,
@@ -1040,7 +1063,7 @@ static int q6v5_wcss_probe(struct platfo
return -EPROBE_DEFER;
rproc = devm_rproc_alloc(&pdev->dev, pdev->name, desc->ops,
- desc->firmware_name, sizeof(*wcss));
+ desc->q6_firmware_name, sizeof(*wcss));
if (!rproc) {
dev_err(&pdev->dev, "failed to allocate rproc\n");
return -ENOMEM;
@@ -1052,6 +1075,7 @@ static int q6v5_wcss_probe(struct platfo
wcss->version = desc->version;
wcss->requires_force_stop = desc->requires_force_stop;
wcss->need_mem_protection = desc->need_mem_protection;
+ wcss->m3_firmware_name = desc->m3_firmware_name;
ret = q6v5_wcss_init_mmio(wcss, pdev);
if (ret)
@@ -1126,7 +1150,8 @@ static void q6v5_wcss_remove(struct plat
static const struct wcss_data wcss_ipq8074_res_init = {
.init_clock = ipq8074_init_clock,
- .firmware_name = "IPQ8074/q6_fw.mdt",
+ .q6_firmware_name = "IPQ8074/q6_fw.mdt",
+ .m3_firmware_name = "IPQ8074/m3_fw.mdt",
.crash_reason_smem = WCSS_CRASH_REASON,
.aon_reset_required = true,
.wcss_q6_reset_required = true,
@@ -1139,7 +1164,7 @@ static const struct wcss_data wcss_qcs40
.init_clock = qcs404_init_clock,
.init_regulator = qcs404_init_regulator,
.crash_reason_smem = WCSS_CRASH_REASON,
- .firmware_name = "wcnss.mdt",
+ .q6_firmware_name = "wcnss.mdt",
.version = WCSS_QCS404,
.aon_reset_required = false,
.wcss_q6_reset_required = false,
@@ -1,24 +0,0 @@
From 3a8f67b4770c817b04794c9a02e3f88f85d86280 Mon Sep 17 00:00:00 2001
From: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Date: Sat, 30 Jan 2021 10:50:08 +0530
Subject: [PATCH] remoteproc: qcom: Add ssr subdevice identifier
Add name for ssr subdevice on IPQ8074 SoC.
Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
Signed-off-by: Nikhil Prakash V <nprakash@codeaurora.org>
---
drivers/remoteproc/qcom_q6v5_wcss.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -1155,6 +1155,7 @@ static const struct wcss_data wcss_ipq80
.crash_reason_smem = WCSS_CRASH_REASON,
.aon_reset_required = true,
.wcss_q6_reset_required = true,
+ .ssr_name = "q6wcss",
.ops = &q6v5_wcss_ipq8074_ops,
.requires_force_stop = true,
.need_mem_protection = true,
@@ -1,29 +0,0 @@
From 641092c1bc1bbc3be059d9d723b1cec10a368617 Mon Sep 17 00:00:00 2001
From: Alexandru Gagniuc <mr.nuke.me@gmail.com>
Date: Fri, 28 Nov 2025 19:32:06 -0600
Subject: [PATCH] remoteproc: qcom_q6v5_wcss: use optional reset for
wcss_q6_bcr_reset
The "wcss_q6_bcr_reset" is not used on IPQ8074, and IPQ6018. Use
devm_reset_control_get_optional_exclusive() for this reset so that
probe() does not fail on platforms where it is not used.
Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
Link: https://lore.kernel.org/r/20251129013207.3981517-2-mr.nuke.me@gmail.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
---
drivers/remoteproc/qcom_q6v5_wcss.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -876,7 +876,8 @@ static int q6v5_wcss_init_reset(struct q
}
}
- wcss->wcss_q6_bcr_reset = devm_reset_control_get_exclusive(dev, "wcss_q6_bcr_reset");
+ wcss->wcss_q6_bcr_reset = devm_reset_control_get_optional_exclusive(dev,
+ "wcss_q6_bcr_reset");
if (IS_ERR(wcss->wcss_q6_bcr_reset)) {
dev_err(wcss->dev, "unable to acquire wcss_q6_bcr_reset\n");
return PTR_ERR(wcss->wcss_q6_bcr_reset);
@@ -1,48 +0,0 @@
From 406a332fd1bcc4e18d73cce390f56272fe9111d7 Mon Sep 17 00:00:00 2001
From: Sivaprakash Murugesan <sivaprak@codeaurora.org>
Date: Fri, 17 Apr 2020 16:37:10 +0530
Subject: [PATCH] remoteproc: wcss: disable auto boot for IPQ8074
There is no need for remoteproc to boot automatically, ath11k will trigger
booting when its probing.
Signed-off-by: Sivaprakash Murugesan <sivaprak@codeaurora.org>
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
drivers/remoteproc/qcom_q6v5_wcss.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -161,6 +161,7 @@ struct wcss_data {
const struct rproc_ops *ops;
bool requires_force_stop;
bool need_mem_protection;
+ bool need_auto_boot;
};
static int q6v5_wcss_reset(struct q6v5_wcss *wcss)
@@ -1120,6 +1121,7 @@ static int q6v5_wcss_probe(struct platfo
}
}
+ rproc->auto_boot = desc->need_auto_boot;
ret = rproc_add(rproc);
if (ret)
goto remove_sysmon_subdev;
@@ -1160,6 +1162,7 @@ static const struct wcss_data wcss_ipq80
.ops = &q6v5_wcss_ipq8074_ops,
.requires_force_stop = true,
.need_mem_protection = true,
+ .need_auto_boot = false,
};
static const struct wcss_data wcss_qcs404_res_init = {
@@ -1175,6 +1178,7 @@ static const struct wcss_data wcss_qcs40
.ssctl_id = 0x12,
.ops = &q6v5_wcss_qcs404_ops,
.requires_force_stop = false,
+ .need_auto_boot = true,
};
static const struct of_device_id q6v5_wcss_of_match[] = {
@@ -1,18 +1,17 @@
From 7388400b8bd42f71d040dbf2fdbdcb834fcc0ede Mon Sep 17 00:00:00 2001
From: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Date: Sat, 30 Jan 2021 10:50:13 +0530
Subject: [PATCH] arm64: dts: qcom: Enable Q6v5 WCSS for ipq8074 SoC
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Wed, 16 Sep 2026 14:20:44 +0200
Subject: [PATCH] arm64: dts: qcom: ipq8074: add secure WCSS remoteproc
Enable remoteproc WCSS PIL driver with glink and ssr subdevices.
Also enables smp2p and mailboxes required for IPC.
Describe the IPQ8074 WCSS remote processor using the secure PIL
compatible. Add the SMP2P state and interrupt channels needed for
startup, shutdown and crash handling, and the GLINK edge used by the
firmware.
Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
Signed-off-by: Nikhil Prakash V <nprakash@codeaurora.org>
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
arch/arm64/boot/dts/qcom/ipq8074.dtsi | 81 +++++++++++++++++++++++++++
1 file changed, 81 insertions(+)
arch/arm64/boot/dts/qcom/ipq8074.dtsi | 72 ++++++++++++++++++++++++++++
1 file changed, 72 insertions(+)
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -25,7 +24,7 @@ Signed-off-by: Robert Marko <robimarko@gmail.com>
+ qcom,smem = <435>, <428>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <0 322 1>;
+ interrupts = <GIC_SPI 322 IRQ_TYPE_EDGE_RISING>;
+
+ mboxes = <&apcs_glb 9>;
+
@@ -49,36 +48,22 @@ Signed-off-by: Robert Marko <robimarko@gmail.com>
soc: soc@0 {
#address-cells = <1>;
#size-cells = <1>;
@@ -415,6 +441,11 @@
reg = <0x01937000 0x21000>;
};
+ tcsr_q6: syscon@1945000 {
+ compatible = "syscon";
+ reg = <0x01945000 0xe000>;
+ };
+
spmi_bus: spmi@200f000 {
compatible = "qcom,spmi-pmic-arb";
reg = <0x0200f000 0x001000>,
@@ -1028,6 +1059,56 @@
@@ -1028,6 +1054,52 @@
ranges;
};
};
+
+ q6v5_wcss: q6v5_wcss@cd00000 {
+ compatible = "qcom,ipq8074-wcss-pil";
+ reg = <0x0cd00000 0x4040>,
+ <0x004ab000 0x20>;
+ reg-names = "qdsp6",
+ "rmb";
+ qca,auto-restart;
+ qca,extended-intc;
+ interrupts-extended = <&intc 0 325 1>,
+ <&wcss_smp2p_in 0 0>,
+ <&wcss_smp2p_in 1 0>,
+ <&wcss_smp2p_in 2 0>,
+ <&wcss_smp2p_in 3 0>;
+ q6v5_wcss: remoteproc@cd00000 {
+ compatible = "qcom,ipq8074-wcss-sec-pil";
+ reg = <0x0cd00000 0x4040>, <0x004ab000 0x20>;
+ reg-names = "qdsp6", "rmb";
+ firmware-name = "IPQ8074/q6_fw.mdt";
+
+ interrupts-extended = <&intc GIC_SPI 325 IRQ_TYPE_EDGE_RISING>,
+ <&wcss_smp2p_in 0 IRQ_TYPE_NONE>,
+ <&wcss_smp2p_in 1 IRQ_TYPE_NONE>,
+ <&wcss_smp2p_in 2 IRQ_TYPE_NONE>,
+ <&wcss_smp2p_in 3 IRQ_TYPE_NONE>;
+ interrupt-names = "wdog",
+ "fatal",
+ "ready",
@@ -96,8 +81,6 @@ Signed-off-by: Robert Marko <robimarko@gmail.com>
+ clocks = <&gcc GCC_PRNG_AHB_CLK>;
+ clock-names = "prng";
+
+ qcom,halt-regs = <&tcsr_q6 0xa000 0xd000 0x0>;
+
+ qcom,smem-states = <&wcss_smp2p_out 0>,
+ <&wcss_smp2p_out 1>;
+ qcom,smem-state-names = "shutdown",
@@ -15,7 +15,7 @@ Signed-off-by: Robert Marko <robimarko@gmail.com>
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -1109,6 +1109,117 @@
@@ -1100,6 +1100,117 @@
};
};
};
@@ -1,60 +0,0 @@
From 9dd19a9ae36bc60d58287d0c52e53024d484e64d Mon Sep 17 00:00:00 2001
From: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Date: Fri, 29 Jan 2021 22:41:59 +0530
Subject: [PATCH 2/3] remoteproc: qcom: wcss: populate driver data for IPQ6018
Populate hardcoded param using driver data for IPQ6018 SoCs.
Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
---
drivers/remoteproc/qcom_q6v5_wcss.c | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -967,7 +967,7 @@ static int q6v5_alloc_memory_region(stru
return 0;
}
-static int ipq8074_init_clock(struct q6v5_wcss *wcss)
+static int ipq_init_clock(struct q6v5_wcss *wcss)
{
int ret;
@@ -1152,7 +1152,7 @@ static void q6v5_wcss_remove(struct plat
}
static const struct wcss_data wcss_ipq8074_res_init = {
- .init_clock = ipq8074_init_clock,
+ .init_clock = ipq_init_clock,
.q6_firmware_name = "IPQ8074/q6_fw.mdt",
.m3_firmware_name = "IPQ8074/m3_fw.mdt",
.crash_reason_smem = WCSS_CRASH_REASON,
@@ -1165,6 +1165,19 @@ static const struct wcss_data wcss_ipq80
.need_auto_boot = false,
};
+static const struct wcss_data wcss_ipq6018_res_init = {
+ .init_clock = ipq_init_clock,
+ .q6_firmware_name = "IPQ6018/q6_fw.mdt",
+ .m3_firmware_name = "IPQ6018/m3_fw.mdt",
+ .crash_reason_smem = WCSS_CRASH_REASON,
+ .aon_reset_required = true,
+ .wcss_q6_reset_required = true,
+ .ssr_name = "q6wcss",
+ .ops = &q6v5_wcss_ipq8074_ops,
+ .requires_force_stop = true,
+ .need_mem_protection = true,
+};
+
static const struct wcss_data wcss_qcs404_res_init = {
.init_clock = qcs404_init_clock,
.init_regulator = qcs404_init_regulator,
@@ -1183,6 +1196,7 @@ static const struct wcss_data wcss_qcs40
static const struct of_device_id q6v5_wcss_of_match[] = {
{ .compatible = "qcom,ipq8074-wcss-pil", .data = &wcss_ipq8074_res_init },
+ { .compatible = "qcom,ipq6018-wcss-pil", .data = &wcss_ipq6018_res_init },
{ .compatible = "qcom,qcs404-wcss-pil", .data = &wcss_qcs404_res_init },
{ },
};
@@ -32,7 +32,7 @@ Signed-off-by: George Moussalem <george.moussalem@outlook.com>
perst-gpios = <&tlmm 61 GPIO_ACTIVE_LOW>;
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -892,7 +892,6 @@
@@ -887,7 +887,6 @@
snps,hird-threshold = /bits/ 8 <0x0>;
snps,dis_u2_susphy_quirk;
snps,dis_u3_susphy_quirk;
@@ -40,7 +40,7 @@ Signed-off-by: George Moussalem <george.moussalem@outlook.com>
};
};
@@ -942,7 +941,6 @@
@@ -937,7 +936,6 @@
snps,hird-threshold = /bits/ 8 <0x0>;
snps,dis_u2_susphy_quirk;
snps,dis_u3_susphy_quirk;
@@ -48,7 +48,7 @@ Signed-off-by: George Moussalem <george.moussalem@outlook.com>
};
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -846,102 +846,94 @@
@@ -841,102 +841,94 @@
status = "disabled";
};
@@ -0,0 +1,37 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Wed, 16 Sep 2026 14:26:38 +0200
Subject: [PATCH] remoteproc: qcom: wcss-sec: enable PRNG clock
The IPQ8074 WCSS secure PIL requires the PRNG clock while the remote
processor is running. Acquire and enable the optional PRNG clock at
probe, using the same managed clock handling as the sleep and
interconnect clocks.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
drivers/remoteproc/qcom_q6v5_wcss_sec.c | 6 ++++++
1 file changed, 6 insertions(+)
--- a/drivers/remoteproc/qcom_q6v5_wcss_sec.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss_sec.c
@@ -316,6 +316,7 @@ static int wcss_sec_probe(struct platfor
struct rproc *rproc;
struct wcss_sec *wcss;
struct clk *sleep_clk;
+ struct clk *prng_clk;
struct clk *int_clk;
const char **firmware = NULL;
const struct wcss_data *desc = of_device_get_match_data(&pdev->dev);
@@ -355,6 +356,11 @@ static int wcss_sec_probe(struct platfor
return dev_err_probe(&pdev->dev, PTR_ERR(int_clk),
"Failed to get interconnect clock\n");
+ prng_clk = devm_clk_get_optional_enabled(&pdev->dev, "prng");
+ if (IS_ERR(prng_clk))
+ return dev_err_probe(&pdev->dev, PTR_ERR(prng_clk),
+ "Failed to get prng clock\n");
+
ret = qcom_q6v5_init(&wcss->q6, pdev, rproc,
WCSS_CRASH_REASON, NULL, NULL);
if (ret)
@@ -0,0 +1,23 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Wed, 16 Sep 2026 14:30:17 +0200
Subject: [PATCH] remoteproc: qcom: wcss-sec: add IPQ8074 compatible
Match the IPQ8074 WCSS secure PIL node and use the same PAS ID and
subsystem name as IPQ9574.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
drivers/remoteproc/qcom_q6v5_wcss_sec.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/remoteproc/qcom_q6v5_wcss_sec.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss_sec.c
@@ -423,6 +423,7 @@ static const struct of_device_id wcss_se
{ .compatible = "qcom,ipq5018-wcss-sec-pil", .data = &wcss_sec_ipq5332_res_init },
{ .compatible = "qcom,ipq5332-wcss-sec-pil", .data = &wcss_sec_ipq5332_res_init },
{ .compatible = "qcom,ipq5424-wcss-sec-pil", .data = &wcss_sec_ipq5424_res_init },
+ { .compatible = "qcom,ipq8074-wcss-sec-pil", .data = &wcss_sec_ipq9574_res_init },
{ .compatible = "qcom,ipq9574-wcss-sec-pil", .data = &wcss_sec_ipq9574_res_init },
{ },
};
@@ -0,0 +1,35 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Wed, 16 Sep 2026 18:15:00 +0200
Subject: [PATCH] remoteproc: qcom: wcss-sec: enable optional QDSS clock
Enable the optional QDSS clock while the secure WCSS remote processor is
running. Some platforms require this clock for WCSS firmware loading.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
drivers/remoteproc/qcom_q6v5_wcss_sec.c | 6 ++++++
1 file changed, 6 insertions(+)
--- a/drivers/remoteproc/qcom_q6v5_wcss_sec.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss_sec.c
@@ -316,6 +316,7 @@ static int wcss_sec_probe(struct platfor
struct rproc *rproc;
struct wcss_sec *wcss;
struct clk *sleep_clk;
+ struct clk *qdss_clk;
struct clk *prng_clk;
struct clk *int_clk;
const char **firmware = NULL;
@@ -361,6 +362,11 @@ static int wcss_sec_probe(struct platfor
return dev_err_probe(&pdev->dev, PTR_ERR(prng_clk),
"Failed to get prng clock\n");
+ qdss_clk = devm_clk_get_optional_enabled(&pdev->dev, "qdss");
+ if (IS_ERR(qdss_clk))
+ return dev_err_probe(&pdev->dev, PTR_ERR(qdss_clk),
+ "Failed to get QDSS clock\n");
+
ret = qcom_q6v5_init(&wcss->q6, pdev, rproc,
WCSS_CRASH_REASON, NULL, NULL);
if (ret)
@@ -0,0 +1,36 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Wed, 16 Sep 2026 18:16:00 +0200
Subject: [PATCH] remoteproc: qcom: wcss-sec: add IPQ6018 support
IPQ6018 uses the secure WCSS PIL remoteproc driver, but its SSR subsystem
name is "wcnss" rather than the "q6wcss" name used by IPQ9574. Add a
dedicated descriptor for IPQ6018 and match its WCSS compatible to it.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
drivers/remoteproc/qcom_q6v5_wcss_sec.c | 6 ++++++
1 file changed, 6 insertions(+)
--- a/drivers/remoteproc/qcom_q6v5_wcss_sec.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss_sec.c
@@ -420,6 +420,11 @@ static const struct wcss_data wcss_sec_i
.use_tmelcom = true,
};
+static const struct wcss_data wcss_sec_ipq6018_res_init = {
+ .pasid = WCSS_PAS_ID,
+ .ss_name = "wcnss",
+};
+
static const struct wcss_data wcss_sec_ipq9574_res_init = {
.pasid = WCSS_PAS_ID,
.ss_name = "q6wcss",
@@ -429,6 +434,7 @@ static const struct of_device_id wcss_se
{ .compatible = "qcom,ipq5018-wcss-sec-pil", .data = &wcss_sec_ipq5332_res_init },
{ .compatible = "qcom,ipq5332-wcss-sec-pil", .data = &wcss_sec_ipq5332_res_init },
{ .compatible = "qcom,ipq5424-wcss-sec-pil", .data = &wcss_sec_ipq5424_res_init },
+ { .compatible = "qcom,ipq6018-wcss-sec-pil", .data = &wcss_sec_ipq6018_res_init },
{ .compatible = "qcom,ipq8074-wcss-sec-pil", .data = &wcss_sec_ipq9574_res_init },
{ .compatible = "qcom,ipq9574-wcss-sec-pil", .data = &wcss_sec_ipq9574_res_init },
{ },
@@ -0,0 +1,58 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Wed, 16 Sep 2026 14:45:00 +0200
Subject: [PATCH] arm64: dts: qcom: ipq6018: use secure WCSS remoteproc
The IPQ6018 WCSS firmware is loaded through the secure PIL remoteproc
driver. Describe the remote processor with its secure PIL compatible and
provide the firmware name used to locate the WCSS firmware. Enable the
QDSS_AT clock required while loading that firmware.
Use IRQ_TYPE_NONE for the SMP2P interrupt specifiers, since these are
mailbox notification channels rather than hardware interrupts with a
configurable trigger type.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
arch/arm64/boot/dts/qcom/ipq6018.dtsi | 29 ++++++++++++++++-------------
1 file changed, 9 insertions(+), 9 deletions(-)
--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
@@ -829,16 +829,18 @@
};
q6v5_wcss: remoteproc@cd00000 {
- compatible = "qcom,ipq6018-wcss-pil";
+ compatible = "qcom,ipq6018-wcss-sec-pil";
reg = <0x0 0x0cd00000 0x0 0x4040>,
<0x0 0x004ab000 0x0 0x20>;
reg-names = "qdsp6",
"rmb";
+ firmware-name = "IPQ6018/q6_fw.mdt";
+
interrupts-extended = <&intc GIC_SPI 325 IRQ_TYPE_EDGE_RISING>,
- <&wcss_smp2p_in 0 0>,
- <&wcss_smp2p_in 1 0>,
- <&wcss_smp2p_in 2 0>,
- <&wcss_smp2p_in 3 0>;
+ <&wcss_smp2p_in 0 IRQ_TYPE_NONE>,
+ <&wcss_smp2p_in 1 IRQ_TYPE_NONE>,
+ <&wcss_smp2p_in 2 IRQ_TYPE_NONE>,
+ <&wcss_smp2p_in 3 IRQ_TYPE_NONE>;
interrupt-names = "wdog",
"fatal",
"ready",
@@ -853,10 +855,8 @@
"wcss_reset",
"wcss_q6_reset";
- clocks = <&gcc GCC_PRNG_AHB_CLK>;
- clock-names = "prng";
-
- qcom,halt-regs = <&tcsr 0x18000 0x1b000 0xe000>;
+ clocks = <&gcc GCC_PRNG_AHB_CLK>, <&gcc GCC_QDSS_AT_CLK>;
+ clock-names = "prng", "qdss" ;
qcom,smem-states = <&wcss_smp2p_out 0>,
<&wcss_smp2p_out 1>;
@@ -1,41 +0,0 @@
From 505f9c8653fc218ca47a153ec58ebc16bef5502f Mon Sep 17 00:00:00 2001
From: Mantas Pucka <mantas@8devices.com>
Date: Tue, 16 Jan 2024 10:42:40 +0200
Subject: [PATCH 16/19] remoteproc: q6v5_wcss: change ssr name for ipq6018 wifi
subsystem
On IPQ6018 this string ends up being sent to RPM when remoteproc stops
(on crash or rmmod ath11k). "q6wcss" is not a valid name (not found by
`strings` in rpm.mbn), so this causes RPM do 'something' (presumably crash)
causing a system reboot followed by hang in XBL, with no WDT running.
Let's change ssr_name to a more sensible 'wcnss', that does not cause such
issues.
Signed-off-by: Mantas Pucka <mantas@8devices.com>
---
drivers/remoteproc/qcom_q6v5_wcss.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -1107,9 +1107,9 @@ static int q6v5_wcss_probe(struct platfo
if (ret)
return ret;
- qcom_add_glink_subdev(rproc, &wcss->glink_subdev, "q6wcss");
+ qcom_add_glink_subdev(rproc, &wcss->glink_subdev, desc->ssr_name);
qcom_add_pdm_subdev(rproc, &wcss->pdm_subdev);
- qcom_add_ssr_subdev(rproc, &wcss->ssr_subdev, "q6wcss");
+ qcom_add_ssr_subdev(rproc, &wcss->ssr_subdev, desc->ssr_name);
if (desc->ssctl_id) {
wcss->sysmon = qcom_add_sysmon_subdev(rproc,
@@ -1158,7 +1158,7 @@ static const struct wcss_data wcss_ipq80
.crash_reason_smem = WCSS_CRASH_REASON,
.aon_reset_required = true,
.wcss_q6_reset_required = true,
- .ssr_name = "q6wcss",
+ .ssr_name = "wcnss",
.ops = &q6v5_wcss_ipq8074_ops,
.requires_force_stop = true,
.need_mem_protection = true,
@@ -116,5 +116,5 @@ Signed-off-by: Mantas Pucka <mantas@8devices.com>
+ };
+
q6v5_wcss: remoteproc@cd00000 {
compatible = "qcom,ipq6018-wcss-pil";
compatible = "qcom,ipq6018-wcss-sec-pil";
reg = <0x0 0x0cd00000 0x0 0x4040>,
@@ -1,55 +0,0 @@
From 87dbcc69a7e3fe6ccddf4fe9bdbf51330f5e4a77 Mon Sep 17 00:00:00 2001
From: Mantas Pucka <mantas@8devices.com>
Date: Tue, 23 Jan 2024 11:04:04 +0200
Subject: [PATCH] remoteproc: qcom_q6v5_wcss: add optional qdss_at clock
IPQ6018 needs QDSS_AT clock enabled when loading wifi. Optionally enable it
when provided by DT.
Signed-off-by: Mantas Pucka <mantas@8devices.com>
---
drivers/remoteproc/qcom_q6v5_wcss.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -120,6 +120,7 @@ struct q6v5_wcss {
struct clk *qdsp6ss_core_gfmux;
struct clk *lcc_bcr_sleep;
struct clk *prng_clk;
+ struct clk *qdss_clk;
struct regulator *cx_supply;
struct qcom_sysmon *sysmon;
@@ -259,6 +260,9 @@ static int q6v5_wcss_start(struct rproc
return ret;
}
+ if (wcss->qdss_clk)
+ clk_prepare_enable(wcss->qdss_clk);
+
qcom_q6v5_prepare(&wcss->q6v5);
if (wcss->need_mem_protection) {
@@ -772,6 +776,8 @@ static int q6v5_wcss_stop(struct rproc *
}
pas_done:
+ if (wcss->qdss_clk)
+ clk_disable_unprepare(wcss->qdss_clk);
clk_disable_unprepare(wcss->prng_clk);
qcom_q6v5_unprepare(&wcss->q6v5);
@@ -978,6 +984,12 @@ static int ipq_init_clock(struct q6v5_wc
dev_err(wcss->dev, "Failed to get prng clock\n");
return ret;
}
+
+ wcss->qdss_clk = devm_clk_get(wcss->dev, "qdss");
+ if (IS_ERR(wcss->qdss_clk)) {
+ wcss->qdss_clk = NULL;
+ }
+
return 0;
}
@@ -1,26 +0,0 @@
From 71f30e25d21ae4981ecef6653a4ba7dfeb80db7b Mon Sep 17 00:00:00 2001
From: Mantas Pucka <mantas@8devices.com>
Date: Tue, 23 Jan 2024 11:04:57 +0200
Subject: [PATCH] arm64: dts: qcom: ipq6018: assign QDSS_AT clock to wifi remoteproc
IPQ6018 needs to enable QDSS_AT clock when loading wifi firmware,
add it to wifi remoteproc clock list.
Signed-off-by: Mantas Pucka <mantas@8devices.com>
---
arch/arm64/boot/dts/qcom/ipq6018.dtsi | 15 ++++++++-------
1 file changed, 9 insertions(+), 8 deletions(-)
--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
@@ -949,8 +949,8 @@
"wcss_reset",
"wcss_q6_reset";
- clocks = <&gcc GCC_PRNG_AHB_CLK>;
- clock-names = "prng";
+ clocks = <&gcc GCC_PRNG_AHB_CLK>, <&gcc GCC_QDSS_AT_CLK>;
+ clock-names = "prng", "qdss" ;
qcom,halt-regs = <&tcsr 0x18000 0x1b000 0xe000>;
@@ -1,39 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Wed, 26 Aug 2026 14:05:00 +0200
Subject: [PATCH] remoteproc: qcom_q6v5_wcss: fix IPQ6018 SSR name
The IPQ6018 SSR-name workaround was refreshed for Linux 6.18 with its
second hunk pointing at the IPQ8074 data instead of IPQ6018. Consequently
IPQ8074 was changed to "wcnss", while IPQ6018 retained the invalid
"q6wcss" name.
Sending that name to RPM while stopping WCSS resets the SoC, after which a
warm boot hangs in SBL1 Pre_DDR_clock_init. Restore the IPQ8074 value and
apply the intended "wcnss" value to IPQ6018.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
drivers/remoteproc/qcom_q6v5_wcss.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -1170,7 +1170,7 @@ static const struct wcss_data wcss_ipq80
.crash_reason_smem = WCSS_CRASH_REASON,
.aon_reset_required = true,
.wcss_q6_reset_required = true,
- .ssr_name = "wcnss",
+ .ssr_name = "q6wcss",
.ops = &q6v5_wcss_ipq8074_ops,
.requires_force_stop = true,
.need_mem_protection = true,
@@ -1184,7 +1184,7 @@ static const struct wcss_data wcss_ipq60
.crash_reason_smem = WCSS_CRASH_REASON,
.aon_reset_required = true,
.wcss_q6_reset_required = true,
- .ssr_name = "q6wcss",
+ .ssr_name = "wcnss",
.ops = &q6v5_wcss_ipq8074_ops,
.requires_force_stop = true,
.need_mem_protection = true,