From: Jelly Jia <Jelly.Jia@cixtech.com>
To: vkoul@kernel.org, robh@kernel.org, krzk+dt@kernel.org,
conor+dt@kernel.org, robin.murphy@arm.com
Cc: devicetree@vger.kernel.org, Frank.Li@kernel.org,
cix-kernel-upstream@cixtech.com, dmaengine@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, Jelly.Jia@cixtech.com
Subject: [PATCH v2 5/6] dmaengine: arm-dma350: Add CIX Sky1 integration support
Date: Fri, 9 Oct 2026 13:18:45 +0800 [thread overview]
Message-ID: <20261009051846.1115962-6-Jelly.Jia@cixtech.com> (raw)
In-Reply-To: <20261009051846.1115962-1-Jelly.Jia@cixtech.com>
The CIX Sky1 SoC integrates DMA-350 controllers whose DMA masters see
peripheral resources at different addresses than the CPU, and whose
channel interrupts are gated by a subsystem register block before they
reach the AP interrupt controller.
Add match data for the "cix,sky1-dma350" compatible, describing the
interrupt routing register, and use it to bring the controller up:
enable the clock, reset the controller, and route the channel
interrupts through the register block. Routing is redone after system
resume because that block may lose its state.
The address translation is described in the device tree, not in the
driver: a bus node wrapping the controller carries the dma-ranges of
the integration, the OF core builds dev->dma_range_map from them, and
the DMA API applies the translation to both buffers and resources, so
slave resources are mapped with dma_map_resource() like on any other
device. Integrations without such a bus node keep the identity mapping.
The controller may also be attached to a reserved memory region, for
integrations whose DMA master cannot reach all of system memory.
Assisted-by: LLM checkpatch sparse dt_binding_check dtbs_check
Signed-off-by: Jelly Jia <Jelly.Jia@cixtech.com>
---
v1 -> v2:
- Merged the Sky1 integration into arm-dma350.c: the SoC resources are
managed by the DMA-350 driver itself, matched through the
"cix,sky1-dma350" compatible.
- Slave resources are mapped with dma_map_resource() and translated by
the standard DMA API through the dma-ranges of the parent bus node.
- Dropped drivers/dma/cix-sky1-dma350.c and its MAINTAINERS entry.
- ARM_DMA350 now selects MFD_SYSCON for the interrupt router syscon.
drivers/dma/Kconfig | 4 ++
drivers/dma/arm-dma350.c | 92 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 96 insertions(+)
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index ae6a682c9f76..efa6d280bb36 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -97,9 +97,13 @@ config ARM_DMA350
depends on ARM || ARM64 || COMPILE_TEST
select DMA_ENGINE
select DMA_VIRTUAL_CHANNELS
+ select MFD_SYSCON
help
Enable support for the Arm DMA-350 controller.
+ Some integrations need to poke a syscon to route the channel
+ interrupts, so MFD_SYSCON is selected here.
+
config AT_HDMAC
tristate "Atmel AHB DMA support"
depends on ARCH_AT91 || COMPILE_TEST
diff --git a/drivers/dma/arm-dma350.c b/drivers/dma/arm-dma350.c
index e3fbfcce66e8..e443a9c3189b 100644
--- a/drivers/dma/arm-dma350.c
+++ b/drivers/dma/arm-dma350.c
@@ -4,14 +4,21 @@
#include <linux/bitfield.h>
#include <linux/bitops.h>
+#include <linux/clk.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
+#include <linux/mfd/syscon.h>
#include <linux/of.h>
#include <linux/of_dma.h>
+#include <linux/of_reserved_mem.h>
#include <linux/module.h>
#include <linux/overflow.h>
#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>
@@ -158,6 +165,9 @@
#define D350_SLAVE_CMD_WORDS 14
+#define SKY1_DMA350_CRU_DMAC_AP_IRQ 0x54
+#define SKY1_DMA350_IRQ_ROUTE_MASK 0xff
+
enum ch_ctrl_donetype {
CH_CTRL_DONETYPE_NONE = 0,
CH_CTRL_DONETYPE_CMD = 1,
@@ -222,6 +232,13 @@ struct d350_chan_map {
bool needs_unmap;
};
+struct d350;
+
+struct d350_data {
+ u32 irq_route_reg;
+ u32 irq_route_mask;
+};
+
struct d350_chan {
struct virt_dma_chan vc;
struct d350_desc *desc;
@@ -241,6 +258,8 @@ struct d350_chan {
struct d350 {
struct dma_device dma;
+ const struct d350_data *data;
+ struct regmap *irq_router;
int nchan;
int nreq;
struct d350_chan channels[] __counted_by(nchan);
@@ -256,6 +275,16 @@ static inline struct d350_desc *to_d350_desc(struct virt_dma_desc *vd)
return container_of(vd, struct d350_desc, vd);
}
+static int d350_route_irqs(struct d350 *dmac)
+{
+ if (!dmac->irq_router)
+ return 0;
+
+ return regmap_update_bits(dmac->irq_router, dmac->data->irq_route_reg,
+ dmac->data->irq_route_mask,
+ dmac->data->irq_route_mask);
+}
+
static void d350_free_cmds(struct device *dev, struct d350_desc *desc)
{
if (desc->cmds) {
@@ -1089,12 +1118,40 @@ static void d350_free_chan_resources(struct dma_chan *chan)
static int d350_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
+ const struct d350_data *data = device_get_match_data(dev);
+ struct reset_control *reset;
+ struct regmap *irq_router = NULL;
+ struct clk *clk;
struct d350 *dmac;
void __iomem *base;
u32 reg;
int ret, nchan, dw, aw, r, p;
bool coherent, memset;
+ clk = devm_clk_get_optional_enabled(dev, NULL);
+ if (IS_ERR(clk))
+ return dev_err_probe(dev, PTR_ERR(clk),
+ "failed to enable clock\n");
+
+ reset = devm_reset_control_get_optional_exclusive(dev, NULL);
+ if (IS_ERR(reset))
+ return dev_err_probe(dev, PTR_ERR(reset),
+ "failed to get reset\n");
+
+ if (data && data->irq_route_mask &&
+ of_property_present(dev->of_node, "cix,irq-router")) {
+ irq_router =
+ syscon_regmap_lookup_by_phandle(dev->of_node,
+ "cix,irq-router");
+ if (IS_ERR(irq_router))
+ return dev_err_probe(dev, PTR_ERR(irq_router),
+ "failed to get IRQ router\n");
+ }
+
+ ret = reset_control_reset(reset);
+ if (ret)
+ return ret;
+
base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
return PTR_ERR(base);
@@ -1118,8 +1175,14 @@ static int d350_probe(struct platform_device *pdev)
if (!dmac)
return -ENOMEM;
+ dmac->data = data;
+ dmac->irq_router = irq_router;
dmac->nchan = nchan;
+ ret = d350_route_irqs(dmac);
+ if (ret)
+ return ret;
+
reg = readl_relaxed(base + DMAINFO + DMA_BUILDCFG1);
dmac->nreq = FIELD_GET(DMA_CFG_NUM_TRIGGER_IN, reg);
@@ -1201,6 +1264,13 @@ static int d350_probe(struct platform_device *pdev)
dmac->dma.device_prep_dma_memset = d350_prep_memset;
}
+ if (of_property_present(dev->of_node, "memory-region")) {
+ ret = of_reserved_mem_device_init(dev);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "failed to attach reserved memory\n");
+ }
+
platform_set_drvdata(pdev, dmac);
ret = dma_async_device_register(&dmac->dma);
@@ -1223,9 +1293,30 @@ static void d350_remove(struct platform_device *pdev)
of_dma_controller_free(pdev->dev.of_node);
dma_async_device_unregister(&dmac->dma);
+ of_reserved_mem_device_release(&pdev->dev);
+}
+
+static int __maybe_unused d350_resume_noirq(struct device *dev)
+{
+ struct d350 *dmac = dev_get_drvdata(dev);
+
+ if (!dmac)
+ return 0;
+
+ return d350_route_irqs(dmac);
}
+static const struct dev_pm_ops d350_pm = {
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(NULL, d350_resume_noirq)
+};
+
+static const struct d350_data d350_sky1_data = {
+ .irq_route_reg = SKY1_DMA350_CRU_DMAC_AP_IRQ,
+ .irq_route_mask = SKY1_DMA350_IRQ_ROUTE_MASK,
+};
+
static const struct of_device_id d350_of_match[] __maybe_unused = {
+ { .compatible = "cix,sky1-dma350", .data = &d350_sky1_data },
{ .compatible = "arm,dma-350" },
{}
};
@@ -1235,6 +1326,7 @@ static struct platform_driver d350_driver = {
.driver = {
.name = "arm-dma350",
.of_match_table = of_match_ptr(d350_of_match),
+ .pm = pm_sleep_ptr(&d350_pm),
},
.probe = d350_probe,
.remove = d350_remove,
--
2.54.0
next prev parent reply other threads:[~2026-10-09 5:19 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-07 3:33 [PATCH v1 0/5] dmaengine: arm-dma350: Add slave support and CIX Sky1 integration Jelly Jia
2026-09-07 3:34 ` [PATCH v1 1/5] dmaengine: arm-dma350: Fix source trigger bit Jelly Jia
2026-09-07 3:41 ` sashiko-bot
2026-09-07 3:34 ` [PATCH v1 2/5] dmaengine: arm-dma350: Add slave transfer support Jelly Jia
2026-09-07 3:49 ` sashiko-bot
2026-09-07 3:34 ` [PATCH v1 3/5] dt-bindings: dma: Add CIX Sky1 DMA-350 integration Jelly Jia
2026-09-07 17:15 ` Conor Dooley
2026-09-09 6:05 ` Jelly Jia
2026-09-09 10:45 ` Conor Dooley
2026-09-20 5:15 ` Jelly Jia
2026-09-22 17:04 ` Conor Dooley
2026-09-23 8:34 ` Krzysztof Kozlowski
2026-09-07 3:34 ` [PATCH v1 4/5] dmaengine: cix-sky1-dma350: Add Sky1 integration driver Jelly Jia
2026-09-07 3:44 ` sashiko-bot
2026-09-07 3:34 ` [PATCH v1 5/5] arm64: dts: cix: Add Sky1 DMA-350 nodes Jelly Jia
2026-10-09 5:18 ` [PATCH v2 0/6] dmaengine: arm-dma350: Add slave support and CIX Sky1 integration Jelly Jia
2026-10-09 5:18 ` [PATCH v2 1/6] dmaengine: arm-dma350: Fix source trigger bit Jelly Jia
2026-10-09 5:18 ` [PATCH v2 2/6] dmaengine: arm-dma350: Add slave and cyclic transfer support Jelly Jia
2026-10-09 5:30 ` sashiko-bot
2026-10-09 5:18 ` [PATCH v2 3/6] dmaengine: arm-dma350: Sync the slave command list before starting Jelly Jia
2026-10-09 5:27 ` sashiko-bot
2026-10-09 5:18 ` [PATCH v2 4/6] dt-bindings: dma: arm,dma-350: Document the CIX Sky1 integration Jelly Jia
2026-10-09 5:29 ` sashiko-bot
2026-10-09 5:18 ` Jelly Jia [this message]
2026-10-09 5:33 ` [PATCH v2 5/6] dmaengine: arm-dma350: Add CIX Sky1 integration support sashiko-bot
2026-10-09 5:18 ` [PATCH v2 6/6] arm64: dts: cix: Describe the Sky1 DMA-350 bus integration Jelly Jia
2026-10-09 5:28 ` sashiko-bot
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=20261009051846.1115962-6-Jelly.Jia@cixtech.com \
--to=jelly.jia@cixtech.com \
--cc=Frank.Li@kernel.org \
--cc=cix-kernel-upstream@cixtech.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dmaengine@vger.kernel.org \
--cc=krzk+dt@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=robh@kernel.org \
--cc=robin.murphy@arm.com \
--cc=vkoul@kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox