* [PATCH v3 1/4] arm64: dts: socfpga: agilex5: add FPGA manager and region nodes
2026-09-07 8:20 [PATCH v3 0/4] Add Agilex5 support in SVC driver and FPGA configuration and partial reconfiguration support for Agilex5 Adrian Ng Ho Yin
@ 2026-09-07 8:20 ` Adrian Ng Ho Yin
2026-09-07 8:20 ` [PATCH v3 2/4] firmware: stratix10-svc: warn on unmatched free in stratix10_svc_free_memory Adrian Ng Ho Yin
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Adrian Ng Ho Yin @ 2026-09-07 8:20 UTC (permalink / raw)
To: dinguyen, robh, krzk+dt, conor+dt, devicetree, linux-kernel
Cc: Adrian Ng Ho Yin
Add the fpga-mgr child node under the svc firmware node and a fpga-region
node to enable FPGA configuration and partial reconfiguration on Agilex5.
The SMMU is already enabled upstream; it remains a hard requirement for
the svc driver to allocate DMA buffers within the SDM-accessible address
range.
Signed-off-by: Adrian Ng Ho Yin <adrian.ho.yin.ng@altera.com>
---
arch/arm64/boot/dts/intel/socfpga_agilex5.dtsi | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/arch/arm64/boot/dts/intel/socfpga_agilex5.dtsi b/arch/arm64/boot/dts/intel/socfpga_agilex5.dtsi
index f54767d1526e..2e9844ce1ed4 100644
--- a/arch/arm64/boot/dts/intel/socfpga_agilex5.dtsi
+++ b/arch/arm64/boot/dts/intel/socfpga_agilex5.dtsi
@@ -85,9 +85,20 @@ svc {
method = "smc";
memory-region = <&service_reserved>;
iommus = <&smmu 10>;
+
+ fpga_mgr: fpga-mgr {
+ compatible = "intel,agilex-soc-fpga-mgr";
+ };
};
};
+ fpga-region {
+ compatible = "fpga-region";
+ #address-cells = <0x2>;
+ #size-cells = <0x2>;
+ fpga-mgr = <&fpga_mgr>;
+ };
+
psci {
compatible = "arm,psci-0.2";
method = "smc";
--
2.49.GIT
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH v3 2/4] firmware: stratix10-svc: warn on unmatched free in stratix10_svc_free_memory
2026-09-07 8:20 [PATCH v3 0/4] Add Agilex5 support in SVC driver and FPGA configuration and partial reconfiguration support for Agilex5 Adrian Ng Ho Yin
2026-09-07 8:20 ` [PATCH v3 1/4] arm64: dts: socfpga: agilex5: add FPGA manager and region nodes Adrian Ng Ho Yin
@ 2026-09-07 8:20 ` Adrian Ng Ho Yin
2026-09-07 8:20 ` [PATCH v3 3/4] firmware: stratix10-svc: add DMA coherent memory allocation for SMMU-enabled platforms Adrian Ng Ho Yin
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Adrian Ng Ho Yin @ 2026-09-07 8:20 UTC (permalink / raw)
To: dinguyen, robh, krzk+dt, conor+dt, devicetree, linux-kernel
Cc: Adrian Ng Ho Yin
After commit 9119ceb76e98 ("firmware: stratix10-svc: fix memory leaks and
list corruption bugs") removed the erroneous list_del(&svc_data_mem) that
corrupted the list head on failed lookups, an unmatched free still
silently returned. Report the spurious address with dev_warn().
While here, refactor the loop to use an inverted condition with continue
to reduce nesting. Add braces in svc_pa_to_va() for consistency, and fix
a stale "physical address" comment to "address" since paddr is not
strictly a physical address.
Signed-off-by: Adrian Ng Ho Yin <adrian.ho.yin.ng@altera.com>
---
drivers/firmware/stratix10-svc.c | 27 ++++++++++++++++-----------
1 file changed, 16 insertions(+), 11 deletions(-)
diff --git a/drivers/firmware/stratix10-svc.c b/drivers/firmware/stratix10-svc.c
index 34c591d7fd58..643cc008808e 100644
--- a/drivers/firmware/stratix10-svc.c
+++ b/drivers/firmware/stratix10-svc.c
@@ -338,11 +338,12 @@ static void *svc_pa_to_va(unsigned long addr)
pr_debug("claim back P-addr=0x%016x\n", (unsigned int)addr);
guard(mutex)(&svc_mem_lock);
- list_for_each_entry(pmem, &svc_data_mem, node)
+ list_for_each_entry(pmem, &svc_data_mem, node) {
if (pmem->paddr == addr)
return pmem->vaddr;
+ }
- /* physical address is not found */
+ /* address is not found */
return NULL;
}
@@ -1997,19 +1998,23 @@ EXPORT_SYMBOL_GPL(stratix10_svc_allocate_memory);
*/
void stratix10_svc_free_memory(struct stratix10_svc_chan *chan, void *kaddr)
{
+ struct stratix10_svc_controller *ctrl = chan->ctrl;
struct stratix10_svc_data_mem *pmem;
guard(mutex)(&svc_mem_lock);
- list_for_each_entry(pmem, &svc_data_mem, node)
- if (pmem->vaddr == kaddr) {
- gen_pool_free(chan->ctrl->genpool,
- (unsigned long)kaddr, pmem->size);
- pmem->vaddr = NULL;
- list_del(&pmem->node);
- kfree(pmem);
- return;
- }
+ list_for_each_entry(pmem, &svc_data_mem, node) {
+ if (pmem->vaddr != kaddr)
+ continue;
+
+ gen_pool_free(ctrl->genpool, (unsigned long)kaddr, pmem->size);
+ pmem->vaddr = NULL;
+ list_del(&pmem->node);
+ kfree(pmem);
+ return;
+ }
+
+ dev_warn(ctrl->dev, "free of unknown buffer %p\n", kaddr);
}
EXPORT_SYMBOL_GPL(stratix10_svc_free_memory);
--
2.49.GIT
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH v3 3/4] firmware: stratix10-svc: add DMA coherent memory allocation for SMMU-enabled platforms
2026-09-07 8:20 [PATCH v3 0/4] Add Agilex5 support in SVC driver and FPGA configuration and partial reconfiguration support for Agilex5 Adrian Ng Ho Yin
2026-09-07 8:20 ` [PATCH v3 1/4] arm64: dts: socfpga: agilex5: add FPGA manager and region nodes Adrian Ng Ho Yin
2026-09-07 8:20 ` [PATCH v3 2/4] firmware: stratix10-svc: warn on unmatched free in stratix10_svc_free_memory Adrian Ng Ho Yin
@ 2026-09-07 8:20 ` Adrian Ng Ho Yin
2026-09-07 8:20 ` [PATCH v3 4/4] firmware: stratix10-svc: enable Agilex5 SMMU support in probe Adrian Ng Ho Yin
2026-09-09 16:40 ` [PATCH v3 0/4] Add Agilex5 support in SVC driver and FPGA configuration and partial reconfiguration support for Agilex5 Dinh Nguyen
4 siblings, 0 replies; 6+ messages in thread
From: Adrian Ng Ho Yin @ 2026-09-07 8:20 UTC (permalink / raw)
To: dinguyen, robh, krzk+dt, conor+dt, devicetree, linux-kernel
Cc: Adrian Ng Ho Yin
On Agilex5, DDR starts at 0x8000_0000 which is outside the SDM's
addressable range. When SMMU is active, the driver must allocate
DMA-coherent buffers and pass IOVAs (not physical addresses) to ATF.
Add SVC_SDM_DMA_ADDR_BITS (29) and SVC_SDM_DMA_ADDR_OFFSET
(0x8000_0000) to constrain IOVAs to the 0-512 MB window the SDM can
reach and to satisfy ATF's address range check respectively.
Extend struct stratix10_svc_data_mem with dma_addr to hold the raw
IOVA for teardown, and struct stratix10_svc_controller with use_dma_mem
and dma_addr_offset to select the DMA path at runtime.
Add svc_setup_dma_memory() to set the 29-bit DMA mask. Update
stratix10_svc_allocate_memory() and stratix10_svc_free_memory() with a
dma_alloc_coherent()/dma_free_coherent() branch, and adjust
svc_thread_cmd_data_claim() to reapply dma_addr_offset when resolving
ATF completion addresses back to virtual addresses.
Both new controller fields default to zero so existing gen_pool
platforms are unaffected.
Signed-off-by: Adrian Ng Ho Yin <adrian.ho.yin.ng@altera.com>
---
drivers/firmware/stratix10-svc.c | 146 +++++++++++++++++++++++++------
1 file changed, 121 insertions(+), 25 deletions(-)
diff --git a/drivers/firmware/stratix10-svc.c b/drivers/firmware/stratix10-svc.c
index 643cc008808e..d790ae239cf4 100644
--- a/drivers/firmware/stratix10-svc.c
+++ b/drivers/firmware/stratix10-svc.c
@@ -7,10 +7,12 @@
#include <linux/atomic.h>
#include <linux/completion.h>
#include <linux/delay.h>
+#include <linux/dma-mapping.h>
#include <linux/genalloc.h>
#include <linux/hashtable.h>
#include <linux/idr.h>
#include <linux/io.h>
+#include <linux/iommu.h>
#include <linux/kfifo.h>
#include <linux/kthread.h>
#include <linux/module.h>
@@ -48,6 +50,23 @@
#define FPGA_CONFIG_STATUS_TIMEOUT_SEC 30
#define BYTE_TO_WORD_SIZE 4
+/*
+ * SVC_SDM_DMA_ADDR_BITS - constrains the IOVA allocated by
+ * dma_alloc_coherent() to 29 bits (0x0000_0000 - 0x1FFF_FFFF)
+ * when SMMU is active on Agilex5. The SDM accesses these buffers
+ * via the SMMU using IOVAs, so the 29-bit limit keeps IOVAs within
+ * the SDM's addressable window.
+ *
+ * SVC_SDM_DMA_ADDR_OFFSET - ATF on Agilex5 distinguishes
+ * SMMU-mapped buffers from direct physical addresses by the
+ * presence of this offset. The driver adds it to the IOVA before
+ * passing the address to ATF via SMC; ATF strips it, translates
+ * the remaining IOVA through the SMMU, and the SDM accesses the
+ * underlying physical memory.
+ */
+#define SVC_SDM_DMA_ADDR_BITS 29
+#define SVC_SDM_DMA_ADDR_OFFSET 0x80000000UL
+
/* stratix10 service layer clients */
#define STRATIX10_RSU "stratix10-rsu"
#define SOCFPGA_HWMON "socfpga-hwmon"
@@ -149,18 +168,25 @@ struct stratix10_svc_sh_memory {
/**
* struct stratix10_svc_data_mem - service memory structure
* @vaddr: virtual address
- * @paddr: physical address
+ * @paddr: address passed to ATF via SMC and echoed back in completion
+ * notifications; used as the lookup key in svc_pa_to_va().
+ * On the SMMU path this is (IOVA + %SVC_SDM_DMA_ADDR_OFFSET);
+ * on the gen_pool path this equals the raw physical address.
* @size: size of memory
+ * @dma_addr: IOVA returned by dma_alloc_coherent(); used to free the
+ * mapping via dma_free_coherent() on the SMMU path.
* @node: link list head node
*
* This struct is used in a list that keeps track of buffers which have
* been allocated or freed from the memory pool. Service layer driver also
- * uses this struct to transfer physical address to virtual address.
+ * uses this struct to map the address returned by ATF back to a virtual
+ * address.
*/
struct stratix10_svc_data_mem {
void *vaddr;
phys_addr_t paddr;
size_t size;
+ dma_addr_t dma_addr;
struct list_head node;
};
@@ -296,6 +322,15 @@ struct stratix10_svc_chan {
* @sdm_lock: only allows a single command single response to SDM
* @actrl: async control structure
* @psci_reboot_nb: reboot notifier for PSCI secondary CPU offlining
+ * @use_dma_mem: when true, buffers are allocated via dma_alloc_coherent()
+ * instead of the ATF reserved-memory gen_pool.
+ * @dma_addr_offset: value added to the DMA address (IOVA) before passing it
+ * to ATF via SMC. ATF uses this offset to distinguish
+ * SMMU-mapped buffers from direct physical addresses; it
+ * strips the offset, translates the remaining IOVA through
+ * the SMMU, and the SDM accesses the underlying memory.
+ * Set to %SVC_SDM_DMA_ADDR_OFFSET on Agilex5 when SMMU is
+ * active; zero otherwise.
* @chans: array of service channels
*
* This struct is used to create communication channels for service clients, to
@@ -313,6 +348,8 @@ struct stratix10_svc_controller {
struct mutex sdm_lock;
struct stratix10_async_ctrl actrl;
struct notifier_block psci_reboot_nb;
+ bool use_dma_mem;
+ unsigned long dma_addr_offset;
struct stratix10_svc_chan chans[] __counted_by(num_chans);
};
@@ -377,11 +414,17 @@ static void svc_thread_cmd_data_claim(struct stratix10_svc_controller *ctrl,
break;
}
cb_data->status = BIT(SVC_STATUS_BUFFER_DONE);
- cb_data->kaddr1 = svc_pa_to_va(res.a1);
+ /*
+ * The firmware COMPLETED_WRITE response returns the
+ * raw IOVA (without dma_addr_offset). Add it back to
+ * match the key stored in pmem->paddr at allocation
+ * time. dma_addr_offset is zero on non-SMMU paths.
+ */
+ cb_data->kaddr1 = svc_pa_to_va(res.a1 + ctrl->dma_addr_offset);
cb_data->kaddr2 = (res.a2) ?
- svc_pa_to_va(res.a2) : NULL;
+ svc_pa_to_va(res.a2 + ctrl->dma_addr_offset) : NULL;
cb_data->kaddr3 = (res.a3) ?
- svc_pa_to_va(res.a3) : NULL;
+ svc_pa_to_va(res.a3 + ctrl->dma_addr_offset) : NULL;
p_data->chan->scl->receive_cb(p_data->chan->scl,
cb_data);
} else {
@@ -1052,6 +1095,38 @@ svc_create_memory_pool(struct platform_device *pdev,
return genpool;
}
+/**
+ * svc_setup_dma_memory() - configure the device for dynamic DMA allocation
+ * @pdev: pointer to service layer device
+ *
+ * Called instead of svc_get_sh_memory() + svc_create_memory_pool() when
+ * the device is behind an SMMU. Sets a 29-bit coherent DMA mask so that
+ * every subsequent dma_alloc_coherent() call yields an IOVA within the
+ * first 512MB (0x0000_0000 - 0x1FFF_FFFF). The driver then adds
+ * %SVC_SDM_DMA_ADDR_OFFSET to the IOVA before passing it to ATF; ATF
+ * strips the offset and uses the SMMU to translate the IOVA to the
+ * underlying physical memory for SDM access.
+ *
+ * Return: 0 on success, or a negative error code on failure.
+ */
+static int svc_setup_dma_memory(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ int ret;
+
+ ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(SVC_SDM_DMA_ADDR_BITS));
+ if (ret) {
+ dev_err(dev,
+ "failed to set %u-bit DMA mask: %d\n",
+ SVC_SDM_DMA_ADDR_BITS, ret);
+ return ret;
+ }
+
+ dev_info(dev,
+ "SMMU enabled: using dynamic DMA allocation (IOVA range 0-512MB)\n");
+ return 0;
+}
+
/**
* svc_smccc_smc() - secure monitor call between normal and secure world
* @a0: argument passed in registers 0
@@ -1958,34 +2033,50 @@ EXPORT_SYMBOL_GPL(stratix10_svc_done);
void *stratix10_svc_allocate_memory(struct stratix10_svc_chan *chan,
size_t size)
{
+ struct stratix10_svc_controller *ctrl = chan->ctrl;
struct stratix10_svc_data_mem *pmem;
- unsigned long va;
- phys_addr_t pa;
- struct gen_pool *genpool = chan->ctrl->genpool;
- size_t s = roundup(size, 1 << genpool->min_alloc_order);
+ struct gen_pool *genpool;
+ dma_addr_t dma_addr;
+ size_t s;
+ void *va;
pmem = kzalloc_obj(*pmem);
if (!pmem)
return ERR_PTR(-ENOMEM);
- guard(mutex)(&svc_mem_lock);
- va = gen_pool_alloc(genpool, s);
- if (!va) {
- kfree(pmem);
- return ERR_PTR(-ENOMEM);
- }
+ if (ctrl->use_dma_mem) {
+ va = dma_alloc_coherent(ctrl->dev, size, &dma_addr, GFP_KERNEL);
+ if (!va) {
+ kfree(pmem);
+ return ERR_PTR(-ENOMEM);
+ }
- memset((void *)va, 0, s);
- pa = gen_pool_virt_to_phys(genpool, va);
+ pmem->vaddr = va;
+ pmem->paddr = dma_addr + ctrl->dma_addr_offset;
+ pmem->dma_addr = dma_addr;
+ pmem->size = size;
+ } else {
+ genpool = ctrl->genpool;
+ s = roundup(size, 1 << genpool->min_alloc_order);
- pmem->vaddr = (void *)va;
- pmem->paddr = pa;
- pmem->size = s;
+ va = (void *)gen_pool_alloc(genpool, s);
+ if (!va) {
+ kfree(pmem);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ memset(va, 0, s);
+ pmem->vaddr = va;
+ pmem->paddr = gen_pool_virt_to_phys(genpool, (unsigned long)va);
+ pmem->size = s;
+ }
+
+ guard(mutex)(&svc_mem_lock);
list_add_tail(&pmem->node, &svc_data_mem);
- pr_debug("%s: %s: va=%p, pa=0x%016x\n", __func__,
- chan->name, pmem->vaddr, (unsigned int)pmem->paddr);
+ pr_debug("%s: %s: va=%p, addr=0x%016llx\n", __func__,
+ chan->name, pmem->vaddr, (unsigned long long)pmem->paddr);
- return (void *)va;
+ return va;
}
EXPORT_SYMBOL_GPL(stratix10_svc_allocate_memory);
@@ -2007,8 +2098,13 @@ void stratix10_svc_free_memory(struct stratix10_svc_chan *chan, void *kaddr)
if (pmem->vaddr != kaddr)
continue;
- gen_pool_free(ctrl->genpool, (unsigned long)kaddr, pmem->size);
- pmem->vaddr = NULL;
+ if (ctrl->use_dma_mem) {
+ dma_free_coherent(ctrl->dev, pmem->size,
+ pmem->vaddr, pmem->dma_addr);
+ } else {
+ gen_pool_free(ctrl->genpool,
+ (unsigned long)kaddr, pmem->size);
+ }
list_del(&pmem->node);
kfree(pmem);
return;
--
2.49.GIT
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH v3 4/4] firmware: stratix10-svc: enable Agilex5 SMMU support in probe
2026-09-07 8:20 [PATCH v3 0/4] Add Agilex5 support in SVC driver and FPGA configuration and partial reconfiguration support for Agilex5 Adrian Ng Ho Yin
` (2 preceding siblings ...)
2026-09-07 8:20 ` [PATCH v3 3/4] firmware: stratix10-svc: add DMA coherent memory allocation for SMMU-enabled platforms Adrian Ng Ho Yin
@ 2026-09-07 8:20 ` Adrian Ng Ho Yin
2026-09-09 16:40 ` [PATCH v3 0/4] Add Agilex5 support in SVC driver and FPGA configuration and partial reconfiguration support for Agilex5 Dinh Nguyen
4 siblings, 0 replies; 6+ messages in thread
From: Adrian Ng Ho Yin @ 2026-09-07 8:20 UTC (permalink / raw)
To: dinguyen, robh, krzk+dt, conor+dt, devicetree, linux-kernel
Cc: Adrian Ng Ho Yin
Wire up the Agilex5-specific path in stratix10_svc_drv_probe().
Add INTEL_SIP_SMC_SDM_REMAPPER_CONFIG to stratix10-smc.h and issue
INTEL_SIP_SMC_SDM_REMAPPER_BYPASS from probe. On Agilex5 REV B the
hardware SDM address remapper must be bypassed when the SMMU is active
so no extra offset is applied on top of the IOVA translation.
Extend stratix10_svc_pdata with use_dma_mem and add intel,agilex5-svc to
the of_device_id match table with that flag set. Probe reads the flag via
of_device_get_match_data() so it shares the same pdata mechanism used for
needs_psci_cpu_off.
On Agilex5, DDR starts at 0x8000_0000 which is outside the SDM's
addressable range, making the SMMU mandatory. Fail probe with -ENODEV
if no IOMMU domain is attached to the device.
Register svc_data_mem_cleanup() as a devm action on the DMA path to
free any buffers leaked by service clients on driver unbind. Guard
err_destroy_pool against NULL genpool for the early-exit DMA path.
Signed-off-by: Adrian Ng Ho Yin <adrian.ho.yin.ng@altera.com>
---
drivers/firmware/stratix10-svc.c | 83 +++++++++++++++++---
include/linux/firmware/intel/stratix10-smc.h | 23 ++++++
2 files changed, 94 insertions(+), 12 deletions(-)
diff --git a/drivers/firmware/stratix10-svc.c b/drivers/firmware/stratix10-svc.c
index d790ae239cf4..fa2335378536 100644
--- a/drivers/firmware/stratix10-svc.c
+++ b/drivers/firmware/stratix10-svc.c
@@ -122,12 +122,17 @@
struct stratix10_svc_pdata {
bool needs_psci_cpu_off;
+ bool use_dma_mem;
};
static const struct stratix10_svc_pdata psci_cpu_off_pdata = {
.needs_psci_cpu_off = true,
};
+static const struct stratix10_svc_pdata agilex5_pdata = {
+ .use_dma_mem = true,
+};
+
typedef void (svc_invoke_fn)(unsigned long, unsigned long, unsigned long,
unsigned long, unsigned long, unsigned long,
unsigned long, unsigned long,
@@ -2169,6 +2174,7 @@ static void psci_cpu_off_teardown(struct stratix10_svc_controller *ctrl)
static const struct of_device_id stratix10_svc_drv_match[] = {
{ .compatible = "intel,stratix10-svc", .data = &psci_cpu_off_pdata },
{ .compatible = "intel,agilex-svc", .data = &psci_cpu_off_pdata },
+ { .compatible = "intel,agilex5-svc", .data = &agilex5_pdata },
{},
};
@@ -2179,14 +2185,38 @@ static const char * const chan_names[SVC_NUM_CHANNEL] = {
SVC_CLIENT_HWMON
};
+static void svc_data_mem_cleanup(void *data)
+{
+ struct stratix10_svc_controller *ctrl = data;
+ struct stratix10_svc_data_mem *pmem, *tmp;
+
+ guard(mutex)(&svc_mem_lock);
+
+ list_for_each_entry_safe(pmem, tmp, &svc_data_mem, node) {
+ dev_warn(ctrl->dev, "leaked svc buffer %p, freeing on unbind\n",
+ pmem->vaddr);
+ if (ctrl->use_dma_mem) {
+ dma_free_coherent(ctrl->dev, pmem->size,
+ pmem->vaddr, pmem->dma_addr);
+ } else {
+ gen_pool_free(ctrl->genpool,
+ (unsigned long)pmem->vaddr, pmem->size);
+ }
+ list_del(&pmem->node);
+ kfree(pmem);
+ }
+}
+
static int stratix10_svc_drv_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct stratix10_svc_controller *controller;
- struct gen_pool *genpool;
+ struct gen_pool *genpool = NULL;
struct stratix10_svc_sh_memory *sh_memory;
struct stratix10_svc *svc = NULL;
const struct stratix10_svc_pdata *pdata = of_device_get_match_data(dev);
+ struct arm_smccc_res res;
+ bool use_dma_mem = false;
svc_invoke_fn *invoke_fn;
size_t fifo_size;
@@ -2197,18 +2227,38 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev)
if (IS_ERR(invoke_fn))
return -EINVAL;
- sh_memory = devm_kzalloc(dev, sizeof(*sh_memory), GFP_KERNEL);
- if (!sh_memory)
- return -ENOMEM;
+ use_dma_mem = pdata && pdata->use_dma_mem;
- sh_memory->invoke_fn = invoke_fn;
- ret = svc_get_sh_memory(pdev, sh_memory);
- if (ret)
- return ret;
+ if (use_dma_mem) {
+ if (!iommu_get_domain_for_dev(dev)) {
+ dev_err(dev,
+ "SMMU is required for agilex5-svc but no IOMMU domain found\n");
+ dev_err(dev,
+ "Ensure the SMMU node is enabled in the device tree and 'iommus' is set for this node\n");
+ return -ENODEV;
+ }
+
+ invoke_fn(INTEL_SIP_SMC_SDM_REMAPPER_CONFIG,
+ INTEL_SIP_SMC_SDM_REMAPPER_BYPASS,
+ 0, 0, 0, 0, 0, 0, &res);
+
+ ret = svc_setup_dma_memory(pdev);
+ if (ret)
+ return ret;
+ } else {
+ sh_memory = devm_kzalloc(dev, sizeof(*sh_memory), GFP_KERNEL);
+ if (!sh_memory)
+ return -ENOMEM;
- genpool = svc_create_memory_pool(pdev, sh_memory);
- if (IS_ERR(genpool))
- return PTR_ERR(genpool);
+ sh_memory->invoke_fn = invoke_fn;
+ ret = svc_get_sh_memory(pdev, sh_memory);
+ if (ret)
+ return ret;
+
+ genpool = svc_create_memory_pool(pdev, sh_memory);
+ if (IS_ERR(genpool))
+ return PTR_ERR(genpool);
+ }
/* allocate service controller and supporting channel */
controller = devm_kzalloc(dev, struct_size(controller, chans, SVC_NUM_CHANNEL),
@@ -2223,9 +2273,17 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev)
controller->num_active_client = 0;
controller->genpool = genpool;
controller->invoke_fn = invoke_fn;
+ controller->use_dma_mem = use_dma_mem;
+ controller->dma_addr_offset = use_dma_mem ? SVC_SDM_DMA_ADDR_OFFSET : 0;
INIT_LIST_HEAD(&controller->node);
init_completion(&controller->complete_status);
+ if (use_dma_mem) {
+ ret = devm_add_action_or_reset(dev, svc_data_mem_cleanup, controller);
+ if (ret)
+ goto err_destroy_pool;
+ }
+
if (pdata && pdata->needs_psci_cpu_off) {
controller->psci_reboot_nb.notifier_call =
psci_cpu_off_reboot_notifier;
@@ -2333,7 +2391,8 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev)
err_free_notifier:
psci_cpu_off_teardown(controller);
err_destroy_pool:
- gen_pool_destroy(genpool);
+ if (genpool)
+ gen_pool_destroy(genpool);
return ret;
}
diff --git a/include/linux/firmware/intel/stratix10-smc.h b/include/linux/firmware/intel/stratix10-smc.h
index 366309260121..b0d42d585a75 100644
--- a/include/linux/firmware/intel/stratix10-smc.h
+++ b/include/linux/firmware/intel/stratix10-smc.h
@@ -813,4 +813,27 @@ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_COMPLETED_WRITE)
#define INTEL_SIP_SMC_ASYNC_FUNC_ID_RSU_NOTIFY (0xEC)
#define INTEL_SIP_SMC_ASYNC_RSU_NOTIFY \
INTEL_SIP_SMC_ASYNC_VAL(INTEL_SIP_SMC_ASYNC_FUNC_ID_RSU_NOTIFY)
+
+/**
+ * Request INTEL_SIP_SMC_SDM_REMAPPER_CONFIG
+ *
+ * Sync call to configure the SDM address remapper. On Agilex5, the remapper
+ * must be bypassed when the SMMU is active to avoid conflicts with IOMMU
+ * address translation.
+ *
+ * Call register usage:
+ * a0: INTEL_SIP_SMC_SDM_REMAPPER_CONFIG
+ * a1: INTEL_SIP_SMC_SDM_REMAPPER_ENABLE or INTEL_SIP_SMC_SDM_REMAPPER_BYPASS
+ * a2-7: not used
+ *
+ * Return status:
+ * a0: INTEL_SIP_SMC_STATUS_OK
+ * a1-3: not used
+ */
+#define INTEL_SIP_SMC_FUNCID_SDM_REMAPPER_CONFIG 513
+#define INTEL_SIP_SMC_SDM_REMAPPER_CONFIG \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_SDM_REMAPPER_CONFIG)
+#define INTEL_SIP_SMC_SDM_REMAPPER_ENABLE 0
+#define INTEL_SIP_SMC_SDM_REMAPPER_BYPASS 1
+
#endif
--
2.49.GIT
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH v3 0/4] Add Agilex5 support in SVC driver and FPGA configuration and partial reconfiguration support for Agilex5
2026-09-07 8:20 [PATCH v3 0/4] Add Agilex5 support in SVC driver and FPGA configuration and partial reconfiguration support for Agilex5 Adrian Ng Ho Yin
` (3 preceding siblings ...)
2026-09-07 8:20 ` [PATCH v3 4/4] firmware: stratix10-svc: enable Agilex5 SMMU support in probe Adrian Ng Ho Yin
@ 2026-09-09 16:40 ` Dinh Nguyen
4 siblings, 0 replies; 6+ messages in thread
From: Dinh Nguyen @ 2026-09-09 16:40 UTC (permalink / raw)
To: Adrian Ng Ho Yin, robh, krzk+dt, conor+dt, devicetree, linux-kernel
On 9/7/26 03:20, Adrian Ng Ho Yin wrote:
> This series adds support for Agilex5 in the SVC driver and enables FPGA
> configuration and partial reconfiguration on Altera Agilex5 SoC.
>
> On Agilex5 the DDR base address starts at 0x8000_0000, which is
> outside the addressable range of the SDM. The SMMU is used to remap
> DDR-allocated buffers to an IOVA within the SDM-accessible 0-512MB
> window. Agilex5 REV B introduced a hardware SDM address remapper,
> but it must be bypassed so no additional offset is applied to the
> IOVA, keeping the implementation consistent across all Agilex5
> revisions.
>
> Patch 1 adds the fpga-mgr child node and fpga-region to the Agilex5 DTSI.
> The SMMU is already enabled upstream.
>
> Patch 2 reports unmatched frees in stratix10_svc_free_memory() with
> dev_warn() and cleans up related coding style in svc_pa_to_va(). The
> list-head corruption from list_del(&svc_data_mem) was already fixed by
> commit 9119ceb76e98 ("firmware: stratix10-svc: fix memory leaks and list
> corruption bugs").
>
> Patch 3 adds all data-structure fields, macros, includes, helper function,
> and allocation/free paths required for the DMA coherent mode. This covers
> both the foundational types (dma_addr, use_dma_mem, dma_addr_offset,
> SVC_SDM_DMA_ADDR_BITS/OFFSET) and the functional DMA allocation/free code,
> keeping the structural and functional changes together so each intermediate
> commit is bisect-safe.
>
> Patch 4 adds INTEL_SIP_SMC_SDM_REMAPPER_CONFIG and integrates the Agilex5
> path into probe: enforces SMMU presence for intel,agilex5-svc, issues the
> remapper-bypass SMC, selects the DMA path via stratix10_svc_pdata.use_dma_mem,
> initialises the controller fields, registers a devm cleanup action for
> leaked buffers, and guards the error path against a NULL genpool.
>
> ---
> changelog:
> v2 -> v3:
> - Squash former patch 2 (SMC remapper defines) into the probe enablement
> patch so the defines land with their first usage.
> - Rebase on socfpga_firmware_for_v7.4.
> - Drop SMMU status="disabled" removal from the DTS patch (already upstream
> in 10cf797f3f8a).
> - Drop the list_del(&svc_data_mem) fix already present in 9119ceb76e98;
> keep the unmatched-free warning and style cleanup.
> - Adapt of_device_id.data usage to extend stratix10_svc_pdata (shared with
> needs_psci_cpu_off) instead of casting BIT flags into .data.
> - Keep kzalloc_obj()/kfree() lifetime for pmem on both gen_pool and DMA
> paths after 9119ceb76e98.
>
> v1 -> v2:
> - split original patch into smaller patches for easier review and backporting.
> - Fixed the Fixes: tag in patch 3 referencing 5a0793ac66ac
> - Replaced of_device_is_compatible() with of_device_id.data + of_device_get_match_data()
> - Various commit message improvements
> ---
>
> Adrian Ng Ho Yin (4):
> arm64: dts: socfpga: agilex5: add FPGA manager and region nodes
> firmware: stratix10-svc: warn on unmatched free in
> stratix10_svc_free_memory
> firmware: stratix10-svc: add DMA coherent memory allocation for
> SMMU-enabled platforms
> firmware: stratix10-svc: enable Agilex5 SMMU support in probe
>
> .../arm64/boot/dts/intel/socfpga_agilex5.dtsi | 11 +
> drivers/firmware/stratix10-svc.c | 250 +++++++++++++++++---
> include/linux/firmware/intel/stratix10-smc.h | 23 ++
> 3 files changed, 239 insertions(+), 45 deletions(-)
>
All patches applied!
Thanks,
Dinh
^ permalink raw reply [flat|nested] 6+ messages in thread