2024-01-24 12:43:48

by Siddharth Vadapalli

[permalink] [raw]
Subject: [PATCH v4 0/4] Add APIs to request TX/RX DMA channels for thread ID

The existing APIs for requesting TX and RX DMA channels rely on parsing
a device-tree node to obtain the Channel/Thread IDs from their names.
However, it is possible to know the thread IDs by alternative means such
as being informed by Firmware on a remote core via RPMsg regarding the
allocated TX/RX DMA channel thread IDs. In such cases, the driver can be
probed by non device-tree methods such as RPMsg-bus, due to which it is not
necessary that the device using the DMA has a device-tree node
corresponding to it. Thus, add APIs to enable the driver to make use of
the existing DMA APIs even when there's no device-tree node.

Additionally, since the name of the device for the remote RX channel is
being set purely on the basis of the RX channel ID itself, it can result
in duplicate names when multiple flows are used on the same channel.
Avoid name duplication by including the flow in the name.

Series is based on linux-next tagged next-20240124.

v3:
https://lore.kernel.org/r/[email protected]/
Changes since v3:
- Rebased series on linux-next tagged next-20240124.
- Collected Acked-by tag from Peter Ujfalusi <[email protected]> at:
https://lore.kernel.org/r/[email protected]/
for the series.

v2:
https://lore.kernel.org/r/[email protected]/
Changes since v2:
- Rebased series on linux-next tagged next-20231215.
- Renamed the function "k3_udma_glue_request_tx_chn_by_id()" to
"k3_udma_glue_request_tx_chn_for_thread_id()" as suggested by:
Péter Ujfalusi <[email protected]>
- Similar to the above change, I have also renamed the function
"k3_udma_glue_request_remote_rx_chn_by_id()" to
"k3_udma_glue_request_remote_rx_chn_for_thread_id()".
- Updated the function prototypes in include/linux/dma/k3-udma-glue.h
accordingly.
- Updated the commit messages for patches 3/4 and 4/4 to match the
changes made to the function names.

v1:
https://lore.kernel.org/r/[email protected]/
Changes since v1:
- Rebased series on linux-next tagged next-20231212.
- Updated commit messages with details regarding the use-case for which
the newly added APIs will be required.
- Removed unnecessary return value check within
"of_k3_udma_glue_parse_chn()" function in patch 1, since it will fall
through to "out_put_spec" anyway.
- Removed unnecessary return value check within
"of_k3_udma_glue_parse_chn_by_id()" function in patch 1, since it will
fall through to "out_put_spec" anyway.
- Moved patch 4 of v1 series to patch 2 of current series.

RFC Series:
https://lore.kernel.org/r/[email protected]/
Changes since RFC Series:
- Rebased patches 1, 2 and 3 on linux-next tagged next-20231114.
- Added patch 4 to the series.

Regards,
Siddharth.

Siddharth Vadapalli (4):
dmaengine: ti: k3-udma-glue: Add function to parse channel by ID
dmaengine: ti: k3-udma-glue: Update name for remote RX channel device
dmaengine: ti: k3-udma-glue: Add function to request TX chan for
thread ID
dmaengine: ti: k3-udma-glue: Add function to request RX chan for
thread ID

drivers/dma/ti/k3-udma-glue.c | 306 ++++++++++++++++++++++---------
include/linux/dma/k3-udma-glue.h | 10 +
2 files changed, 229 insertions(+), 87 deletions(-)

--
2.34.1



2024-01-24 12:43:56

by Siddharth Vadapalli

[permalink] [raw]
Subject: [PATCH v4 1/4] dmaengine: ti: k3-udma-glue: Add function to parse channel by ID

The existing helper function of_k3_udma_glue_parse() fetches the DMA
Channel thread ID from the device-tree node. This makes it necessary to
have a device-tree node with the Channel thread IDs populated. However,
in the case where the thread ID is known by alternate methods (an
example being that of Firmware running on remote core sharing details of
the thread IDs), there is no equivalent function to implement the
functionality of the existing of_k3_udma_glue_parse() function. In such
cases, the driver utilizing the DMA APIs might not even have a
device-tree node to begin with, since it could be probed with other
methods (RPMsg-Bus for example).

Add the of_k3_udma_glue_parse_chn_by_id() helper function which accepts
the thread ID as an argument, thereby making it unnecessary to have a
device-tree node for obtaining the thread ID.

Since of_k3_udma_glue_parse() and of_k3_udma_glue_parse_chn_by_id()
share a lot of code in common, create a new function to handle the
common code which is named as of_k3_udma_glue_parse_chn_common().

Signed-off-by: Siddharth Vadapalli <[email protected]>
Acked-by: Peter Ujfalusi <[email protected]>
---
drivers/dma/ti/k3-udma-glue.c | 79 ++++++++++++++++++++++-------------
1 file changed, 51 insertions(+), 28 deletions(-)

diff --git a/drivers/dma/ti/k3-udma-glue.c b/drivers/dma/ti/k3-udma-glue.c
index c278d5facf7d..d8781625034b 100644
--- a/drivers/dma/ti/k3-udma-glue.c
+++ b/drivers/dma/ti/k3-udma-glue.c
@@ -111,6 +111,35 @@ static int of_k3_udma_glue_parse(struct device_node *udmax_np,
return 0;
}

+static int of_k3_udma_glue_parse_chn_common(struct k3_udma_glue_common *common, u32 thread_id,
+ bool tx_chn)
+{
+ if (tx_chn && !(thread_id & K3_PSIL_DST_THREAD_ID_OFFSET))
+ return -EINVAL;
+
+ if (!tx_chn && (thread_id & K3_PSIL_DST_THREAD_ID_OFFSET))
+ return -EINVAL;
+
+ /* get psil endpoint config */
+ common->ep_config = psil_get_ep_config(thread_id);
+ if (IS_ERR(common->ep_config)) {
+ dev_err(common->dev,
+ "No configuration for psi-l thread 0x%04x\n",
+ thread_id);
+ return PTR_ERR(common->ep_config);
+ }
+
+ common->epib = common->ep_config->needs_epib;
+ common->psdata_size = common->ep_config->psd_size;
+
+ if (tx_chn)
+ common->dst_thread = thread_id;
+ else
+ common->src_thread = thread_id;
+
+ return 0;
+}
+
static int of_k3_udma_glue_parse_chn(struct device_node *chn_np,
const char *name, struct k3_udma_glue_common *common,
bool tx_chn)
@@ -153,38 +182,32 @@ static int of_k3_udma_glue_parse_chn(struct device_node *chn_np,
common->atype_asel = dma_spec.args[1];
}

- if (tx_chn && !(thread_id & K3_PSIL_DST_THREAD_ID_OFFSET)) {
- ret = -EINVAL;
- goto out_put_spec;
- }
-
- if (!tx_chn && (thread_id & K3_PSIL_DST_THREAD_ID_OFFSET)) {
- ret = -EINVAL;
- goto out_put_spec;
- }
-
- /* get psil endpoint config */
- common->ep_config = psil_get_ep_config(thread_id);
- if (IS_ERR(common->ep_config)) {
- dev_err(common->dev,
- "No configuration for psi-l thread 0x%04x\n",
- thread_id);
- ret = PTR_ERR(common->ep_config);
- goto out_put_spec;
- }
-
- common->epib = common->ep_config->needs_epib;
- common->psdata_size = common->ep_config->psd_size;
-
- if (tx_chn)
- common->dst_thread = thread_id;
- else
- common->src_thread = thread_id;
+ ret = of_k3_udma_glue_parse_chn_common(common, thread_id, tx_chn);

out_put_spec:
of_node_put(dma_spec.np);
return ret;
-};
+}
+
+static int
+of_k3_udma_glue_parse_chn_by_id(struct device_node *udmax_np, struct k3_udma_glue_common *common,
+ bool tx_chn, u32 thread_id)
+{
+ int ret = 0;
+
+ if (unlikely(!udmax_np))
+ return -EINVAL;
+
+ ret = of_k3_udma_glue_parse(udmax_np, common);
+ if (ret)
+ goto out_put_spec;
+
+ ret = of_k3_udma_glue_parse_chn_common(common, thread_id, tx_chn);
+
+out_put_spec:
+ of_node_put(udmax_np);
+ return ret;
+}

static void k3_udma_glue_dump_tx_chn(struct k3_udma_glue_tx_channel *tx_chn)
{
--
2.34.1


2024-01-24 12:44:10

by Siddharth Vadapalli

[permalink] [raw]
Subject: [PATCH v4 2/4] dmaengine: ti: k3-udma-glue: Update name for remote RX channel device

A single RX Channel can have multiple flows. It is possible that a
single device requests multiple flows on the same RX Channel. In such
cases, the existing implementation of naming the device on the basis of
the RX Channel can result in duplicate names. The existing implementation
only uses the RX Channel source thread when naming, which implies duplicate
names when different flows are being requested on the same RX Channel.

In order to avoid duplicate names, include the RX flow as well in the name.

Signed-off-by: Siddharth Vadapalli <[email protected]>
Acked-by: Peter Ujfalusi <[email protected]>
---
drivers/dma/ti/k3-udma-glue.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/dma/ti/k3-udma-glue.c b/drivers/dma/ti/k3-udma-glue.c
index d8781625034b..eff1ae3d3efe 100644
--- a/drivers/dma/ti/k3-udma-glue.c
+++ b/drivers/dma/ti/k3-udma-glue.c
@@ -1072,8 +1072,8 @@ k3_udma_glue_request_remote_rx_chn(struct device *dev, const char *name,

rx_chn->common.chan_dev.class = &k3_udma_glue_devclass;
rx_chn->common.chan_dev.parent = xudma_get_device(rx_chn->common.udmax);
- dev_set_name(&rx_chn->common.chan_dev, "rchan_remote-0x%04x",
- rx_chn->common.src_thread);
+ dev_set_name(&rx_chn->common.chan_dev, "rchan_remote-0x%04x-0x%02x",
+ rx_chn->common.src_thread, rx_chn->flow_id_base);
ret = device_register(&rx_chn->common.chan_dev);
if (ret) {
dev_err(dev, "Channel Device registration failed %d\n", ret);
--
2.34.1


2024-01-24 12:44:31

by Siddharth Vadapalli

[permalink] [raw]
Subject: [PATCH v4 3/4] dmaengine: ti: k3-udma-glue: Add function to request TX chan for thread ID

The existing function k3_udma_glue_request_tx_chn() supports requesting
a TX DMA channel by its name. Add a new function to request TX DMA channel
for a given thread ID, named k3_udma_glue_request_tx_chn_for_thread_id().
Also, export it for use by drivers which are probed by alternate methods
(non device-tree) but still wish to make use of the existing DMA APIs. Such
drivers could be informed about the thread ID corresponding to the TX DMA
channel by RPMsg for example.

Since the new function k3_udma_glue_request_tx_chn_for_thread_id() reuses
most of the code in k3_udma_glue_request_tx_chn(), create a new function
for the common code, named k3_udma_glue_request_tx_chn_common().

Signed-off-by: Siddharth Vadapalli <[email protected]>
Acked-by: Peter Ujfalusi <[email protected]>
---
drivers/dma/ti/k3-udma-glue.c | 102 +++++++++++++++++++++++--------
include/linux/dma/k3-udma-glue.h | 5 ++
2 files changed, 81 insertions(+), 26 deletions(-)

diff --git a/drivers/dma/ti/k3-udma-glue.c b/drivers/dma/ti/k3-udma-glue.c
index eff1ae3d3efe..a475bbea35ee 100644
--- a/drivers/dma/ti/k3-udma-glue.c
+++ b/drivers/dma/ti/k3-udma-glue.c
@@ -274,29 +274,13 @@ static int k3_udma_glue_cfg_tx_chn(struct k3_udma_glue_tx_channel *tx_chn)
return tisci_rm->tisci_udmap_ops->tx_ch_cfg(tisci_rm->tisci, &req);
}

-struct k3_udma_glue_tx_channel *k3_udma_glue_request_tx_chn(struct device *dev,
- const char *name, struct k3_udma_glue_tx_channel_cfg *cfg)
+static int
+k3_udma_glue_request_tx_chn_common(struct device *dev,
+ struct k3_udma_glue_tx_channel *tx_chn,
+ struct k3_udma_glue_tx_channel_cfg *cfg)
{
- struct k3_udma_glue_tx_channel *tx_chn;
int ret;

- tx_chn = devm_kzalloc(dev, sizeof(*tx_chn), GFP_KERNEL);
- if (!tx_chn)
- return ERR_PTR(-ENOMEM);
-
- tx_chn->common.dev = dev;
- tx_chn->common.swdata_size = cfg->swdata_size;
- tx_chn->tx_pause_on_err = cfg->tx_pause_on_err;
- tx_chn->tx_filt_einfo = cfg->tx_filt_einfo;
- tx_chn->tx_filt_pswords = cfg->tx_filt_pswords;
- tx_chn->tx_supr_tdpkt = cfg->tx_supr_tdpkt;
-
- /* parse of udmap channel */
- ret = of_k3_udma_glue_parse_chn(dev->of_node, name,
- &tx_chn->common, true);
- if (ret)
- goto err;
-
tx_chn->common.hdesc_size = cppi5_hdesc_calc_size(tx_chn->common.epib,
tx_chn->common.psdata_size,
tx_chn->common.swdata_size);
@@ -312,7 +296,7 @@ struct k3_udma_glue_tx_channel *k3_udma_glue_request_tx_chn(struct device *dev,
if (IS_ERR(tx_chn->udma_tchanx)) {
ret = PTR_ERR(tx_chn->udma_tchanx);
dev_err(dev, "UDMAX tchanx get err %d\n", ret);
- goto err;
+ return ret;
}
tx_chn->udma_tchan_id = xudma_tchan_get_id(tx_chn->udma_tchanx);

@@ -325,7 +309,7 @@ struct k3_udma_glue_tx_channel *k3_udma_glue_request_tx_chn(struct device *dev,
dev_err(dev, "Channel Device registration failed %d\n", ret);
put_device(&tx_chn->common.chan_dev);
tx_chn->common.chan_dev.parent = NULL;
- goto err;
+ return ret;
}

if (xudma_is_pktdma(tx_chn->common.udmax)) {
@@ -349,7 +333,7 @@ struct k3_udma_glue_tx_channel *k3_udma_glue_request_tx_chn(struct device *dev,
&tx_chn->ringtxcq);
if (ret) {
dev_err(dev, "Failed to get TX/TXCQ rings %d\n", ret);
- goto err;
+ return ret;
}

/* Set the dma_dev for the rings to be configured */
@@ -365,13 +349,13 @@ struct k3_udma_glue_tx_channel *k3_udma_glue_request_tx_chn(struct device *dev,
ret = k3_ringacc_ring_cfg(tx_chn->ringtx, &cfg->tx_cfg);
if (ret) {
dev_err(dev, "Failed to cfg ringtx %d\n", ret);
- goto err;
+ return ret;
}

ret = k3_ringacc_ring_cfg(tx_chn->ringtxcq, &cfg->txcq_cfg);
if (ret) {
dev_err(dev, "Failed to cfg ringtx %d\n", ret);
- goto err;
+ return ret;
}

/* request and cfg psi-l */
@@ -382,11 +366,42 @@ struct k3_udma_glue_tx_channel *k3_udma_glue_request_tx_chn(struct device *dev,
ret = k3_udma_glue_cfg_tx_chn(tx_chn);
if (ret) {
dev_err(dev, "Failed to cfg tchan %d\n", ret);
- goto err;
+ return ret;
}

k3_udma_glue_dump_tx_chn(tx_chn);

+ return 0;
+}
+
+struct k3_udma_glue_tx_channel *
+k3_udma_glue_request_tx_chn(struct device *dev, const char *name,
+ struct k3_udma_glue_tx_channel_cfg *cfg)
+{
+ struct k3_udma_glue_tx_channel *tx_chn;
+ int ret;
+
+ tx_chn = devm_kzalloc(dev, sizeof(*tx_chn), GFP_KERNEL);
+ if (!tx_chn)
+ return ERR_PTR(-ENOMEM);
+
+ tx_chn->common.dev = dev;
+ tx_chn->common.swdata_size = cfg->swdata_size;
+ tx_chn->tx_pause_on_err = cfg->tx_pause_on_err;
+ tx_chn->tx_filt_einfo = cfg->tx_filt_einfo;
+ tx_chn->tx_filt_pswords = cfg->tx_filt_pswords;
+ tx_chn->tx_supr_tdpkt = cfg->tx_supr_tdpkt;
+
+ /* parse of udmap channel */
+ ret = of_k3_udma_glue_parse_chn(dev->of_node, name,
+ &tx_chn->common, true);
+ if (ret)
+ goto err;
+
+ ret = k3_udma_glue_request_tx_chn_common(dev, tx_chn, cfg);
+ if (ret)
+ goto err;
+
return tx_chn;

err:
@@ -395,6 +410,41 @@ struct k3_udma_glue_tx_channel *k3_udma_glue_request_tx_chn(struct device *dev,
}
EXPORT_SYMBOL_GPL(k3_udma_glue_request_tx_chn);

+struct k3_udma_glue_tx_channel *
+k3_udma_glue_request_tx_chn_for_thread_id(struct device *dev,
+ struct k3_udma_glue_tx_channel_cfg *cfg,
+ struct device_node *udmax_np, u32 thread_id)
+{
+ struct k3_udma_glue_tx_channel *tx_chn;
+ int ret;
+
+ tx_chn = devm_kzalloc(dev, sizeof(*tx_chn), GFP_KERNEL);
+ if (!tx_chn)
+ return ERR_PTR(-ENOMEM);
+
+ tx_chn->common.dev = dev;
+ tx_chn->common.swdata_size = cfg->swdata_size;
+ tx_chn->tx_pause_on_err = cfg->tx_pause_on_err;
+ tx_chn->tx_filt_einfo = cfg->tx_filt_einfo;
+ tx_chn->tx_filt_pswords = cfg->tx_filt_pswords;
+ tx_chn->tx_supr_tdpkt = cfg->tx_supr_tdpkt;
+
+ ret = of_k3_udma_glue_parse_chn_by_id(udmax_np, &tx_chn->common, true, thread_id);
+ if (ret)
+ goto err;
+
+ ret = k3_udma_glue_request_tx_chn_common(dev, tx_chn, cfg);
+ if (ret)
+ goto err;
+
+ return tx_chn;
+
+err:
+ k3_udma_glue_release_tx_chn(tx_chn);
+ return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_GPL(k3_udma_glue_request_tx_chn_for_thread_id);
+
void k3_udma_glue_release_tx_chn(struct k3_udma_glue_tx_channel *tx_chn)
{
if (tx_chn->psil_paired) {
diff --git a/include/linux/dma/k3-udma-glue.h b/include/linux/dma/k3-udma-glue.h
index e443be4d3b4b..c81386ceb1c1 100644
--- a/include/linux/dma/k3-udma-glue.h
+++ b/include/linux/dma/k3-udma-glue.h
@@ -26,6 +26,11 @@ struct k3_udma_glue_tx_channel;
struct k3_udma_glue_tx_channel *k3_udma_glue_request_tx_chn(struct device *dev,
const char *name, struct k3_udma_glue_tx_channel_cfg *cfg);

+struct k3_udma_glue_tx_channel *
+k3_udma_glue_request_tx_chn_for_thread_id(struct device *dev,
+ struct k3_udma_glue_tx_channel_cfg *cfg,
+ struct device_node *udmax_np, u32 thread_id);
+
void k3_udma_glue_release_tx_chn(struct k3_udma_glue_tx_channel *tx_chn);
int k3_udma_glue_push_tx_chn(struct k3_udma_glue_tx_channel *tx_chn,
struct cppi5_host_desc_t *desc_tx,
--
2.34.1


2024-01-24 12:44:44

by Siddharth Vadapalli

[permalink] [raw]
Subject: [PATCH v4 4/4] dmaengine: ti: k3-udma-glue: Add function to request RX chan for thread ID

The existing function k3_udma_glue_request_remote_rx_chn() supports
requesting an RX DMA channel and flow by the name of the RX DMA channel.
Add support to request RX DMA channel for a given thread ID in the form of
a new function named k3_udma_glue_request_remote_rx_chn_for_thread_id().
Also, export it for use by drivers which are probed by alternate methods
(non device-tree) but still wish to make use of the existing DMA APIs. Such
drivers could be informed about the thread ID corresponding to the RX DMA
channel by RPMsg for example.

Since the new function k3_udma_glue_request_remote_rx_chn_for_thread_id()
reuses most of the code in k3_udma_glue_request_remote_rx_chn(), create a
new function named k3_udma_glue_request_remote_rx_chn_common() for the
common code.

Signed-off-by: Siddharth Vadapalli <[email protected]>
Acked-by: Peter Ujfalusi <[email protected]>
---
drivers/dma/ti/k3-udma-glue.c | 137 ++++++++++++++++++++++---------
include/linux/dma/k3-udma-glue.h | 5 ++
2 files changed, 103 insertions(+), 39 deletions(-)

diff --git a/drivers/dma/ti/k3-udma-glue.c b/drivers/dma/ti/k3-udma-glue.c
index a475bbea35ee..c9b93055dc9d 100644
--- a/drivers/dma/ti/k3-udma-glue.c
+++ b/drivers/dma/ti/k3-udma-glue.c
@@ -1073,52 +1073,21 @@ k3_udma_glue_request_rx_chn_priv(struct device *dev, const char *name,
return ERR_PTR(ret);
}

-static struct k3_udma_glue_rx_channel *
-k3_udma_glue_request_remote_rx_chn(struct device *dev, const char *name,
- struct k3_udma_glue_rx_channel_cfg *cfg)
+static int
+k3_udma_glue_request_remote_rx_chn_common(struct k3_udma_glue_rx_channel *rx_chn,
+ struct k3_udma_glue_rx_channel_cfg *cfg,
+ struct device *dev)
{
- struct k3_udma_glue_rx_channel *rx_chn;
int ret, i;

- if (cfg->flow_id_num <= 0 ||
- cfg->flow_id_use_rxchan_id ||
- cfg->def_flow_cfg ||
- cfg->flow_id_base < 0)
- return ERR_PTR(-EINVAL);
-
- /*
- * Remote RX channel is under control of Remote CPU core, so
- * Linux can only request and manipulate by dedicated RX flows
- */
-
- rx_chn = devm_kzalloc(dev, sizeof(*rx_chn), GFP_KERNEL);
- if (!rx_chn)
- return ERR_PTR(-ENOMEM);
-
- rx_chn->common.dev = dev;
- rx_chn->common.swdata_size = cfg->swdata_size;
- rx_chn->remote = true;
- rx_chn->udma_rchan_id = -1;
- rx_chn->flow_num = cfg->flow_id_num;
- rx_chn->flow_id_base = cfg->flow_id_base;
- rx_chn->psil_paired = false;
-
- /* parse of udmap channel */
- ret = of_k3_udma_glue_parse_chn(dev->of_node, name,
- &rx_chn->common, false);
- if (ret)
- goto err;
-
rx_chn->common.hdesc_size = cppi5_hdesc_calc_size(rx_chn->common.epib,
rx_chn->common.psdata_size,
rx_chn->common.swdata_size);

rx_chn->flows = devm_kcalloc(dev, rx_chn->flow_num,
sizeof(*rx_chn->flows), GFP_KERNEL);
- if (!rx_chn->flows) {
- ret = -ENOMEM;
- goto err;
- }
+ if (!rx_chn->flows)
+ return -ENOMEM;

rx_chn->common.chan_dev.class = &k3_udma_glue_devclass;
rx_chn->common.chan_dev.parent = xudma_get_device(rx_chn->common.udmax);
@@ -1129,7 +1098,7 @@ k3_udma_glue_request_remote_rx_chn(struct device *dev, const char *name,
dev_err(dev, "Channel Device registration failed %d\n", ret);
put_device(&rx_chn->common.chan_dev);
rx_chn->common.chan_dev.parent = NULL;
- goto err;
+ return ret;
}

if (xudma_is_pktdma(rx_chn->common.udmax)) {
@@ -1141,19 +1110,109 @@ k3_udma_glue_request_remote_rx_chn(struct device *dev, const char *name,

ret = k3_udma_glue_allocate_rx_flows(rx_chn, cfg);
if (ret)
- goto err;
+ return ret;

for (i = 0; i < rx_chn->flow_num; i++)
rx_chn->flows[i].udma_rflow_id = rx_chn->flow_id_base + i;

k3_udma_glue_dump_rx_chn(rx_chn);

+ return 0;
+}
+
+static struct k3_udma_glue_rx_channel *
+k3_udma_glue_request_remote_rx_chn(struct device *dev, const char *name,
+ struct k3_udma_glue_rx_channel_cfg *cfg)
+{
+ struct k3_udma_glue_rx_channel *rx_chn;
+ int ret;
+
+ if (cfg->flow_id_num <= 0 ||
+ cfg->flow_id_use_rxchan_id ||
+ cfg->def_flow_cfg ||
+ cfg->flow_id_base < 0)
+ return ERR_PTR(-EINVAL);
+
+ /*
+ * Remote RX channel is under control of Remote CPU core, so
+ * Linux can only request and manipulate by dedicated RX flows
+ */
+
+ rx_chn = devm_kzalloc(dev, sizeof(*rx_chn), GFP_KERNEL);
+ if (!rx_chn)
+ return ERR_PTR(-ENOMEM);
+
+ rx_chn->common.dev = dev;
+ rx_chn->common.swdata_size = cfg->swdata_size;
+ rx_chn->remote = true;
+ rx_chn->udma_rchan_id = -1;
+ rx_chn->flow_num = cfg->flow_id_num;
+ rx_chn->flow_id_base = cfg->flow_id_base;
+ rx_chn->psil_paired = false;
+
+ /* parse of udmap channel */
+ ret = of_k3_udma_glue_parse_chn(dev->of_node, name,
+ &rx_chn->common, false);
+ if (ret)
+ goto err;
+
+ ret = k3_udma_glue_request_remote_rx_chn_common(rx_chn, cfg, dev);
+ if (ret)
+ goto err;
+
+ return rx_chn;
+
+err:
+ k3_udma_glue_release_rx_chn(rx_chn);
+ return ERR_PTR(ret);
+}
+
+struct k3_udma_glue_rx_channel *
+k3_udma_glue_request_remote_rx_chn_for_thread_id(struct device *dev,
+ struct k3_udma_glue_rx_channel_cfg *cfg,
+ struct device_node *udmax_np, u32 thread_id)
+{
+ struct k3_udma_glue_rx_channel *rx_chn;
+ int ret;
+
+ if (cfg->flow_id_num <= 0 ||
+ cfg->flow_id_use_rxchan_id ||
+ cfg->def_flow_cfg ||
+ cfg->flow_id_base < 0)
+ return ERR_PTR(-EINVAL);
+
+ /*
+ * Remote RX channel is under control of Remote CPU core, so
+ * Linux can only request and manipulate by dedicated RX flows
+ */
+
+ rx_chn = devm_kzalloc(dev, sizeof(*rx_chn), GFP_KERNEL);
+ if (!rx_chn)
+ return ERR_PTR(-ENOMEM);
+
+ rx_chn->common.dev = dev;
+ rx_chn->common.swdata_size = cfg->swdata_size;
+ rx_chn->remote = true;
+ rx_chn->udma_rchan_id = -1;
+ rx_chn->flow_num = cfg->flow_id_num;
+ rx_chn->flow_id_base = cfg->flow_id_base;
+ rx_chn->psil_paired = false;
+
+ ret = of_k3_udma_glue_parse_chn_by_id(udmax_np, &rx_chn->common, false, thread_id);
+ if (ret)
+ goto err;
+
+ ret = k3_udma_glue_request_remote_rx_chn_common(rx_chn, cfg, dev);
+ if (ret)
+ goto err;
+
return rx_chn;

err:
k3_udma_glue_release_rx_chn(rx_chn);
return ERR_PTR(ret);
}
+EXPORT_SYMBOL_GPL(k3_udma_glue_request_remote_rx_chn_for_thread_id);

struct k3_udma_glue_rx_channel *
k3_udma_glue_request_rx_chn(struct device *dev, const char *name,
diff --git a/include/linux/dma/k3-udma-glue.h b/include/linux/dma/k3-udma-glue.h
index c81386ceb1c1..1e491c5dcac2 100644
--- a/include/linux/dma/k3-udma-glue.h
+++ b/include/linux/dma/k3-udma-glue.h
@@ -114,6 +114,11 @@ struct k3_udma_glue_rx_channel *k3_udma_glue_request_rx_chn(
const char *name,
struct k3_udma_glue_rx_channel_cfg *cfg);

+struct k3_udma_glue_rx_channel *
+k3_udma_glue_request_remote_rx_chn_for_thread_id(struct device *dev,
+ struct k3_udma_glue_rx_channel_cfg *cfg,
+ struct device_node *udmax_np, u32 thread_id);
+
void k3_udma_glue_release_rx_chn(struct k3_udma_glue_rx_channel *rx_chn);
int k3_udma_glue_enable_rx_chn(struct k3_udma_glue_rx_channel *rx_chn);
void k3_udma_glue_disable_rx_chn(struct k3_udma_glue_rx_channel *rx_chn);
--
2.34.1


2024-01-30 16:51:51

by Vinod Koul

[permalink] [raw]
Subject: Re: [PATCH v4 0/4] Add APIs to request TX/RX DMA channels for thread ID


On Wed, 24 Jan 2024 18:13:15 +0530, Siddharth Vadapalli wrote:
> The existing APIs for requesting TX and RX DMA channels rely on parsing
> a device-tree node to obtain the Channel/Thread IDs from their names.
> However, it is possible to know the thread IDs by alternative means such
> as being informed by Firmware on a remote core via RPMsg regarding the
> allocated TX/RX DMA channel thread IDs. In such cases, the driver can be
> probed by non device-tree methods such as RPMsg-bus, due to which it is not
> necessary that the device using the DMA has a device-tree node
> corresponding to it. Thus, add APIs to enable the driver to make use of
> the existing DMA APIs even when there's no device-tree node.
>
> [...]

Applied, thanks!

[1/4] dmaengine: ti: k3-udma-glue: Add function to parse channel by ID
commit: 81a1f90f20af71728f900f245aa69e9425fdef84
[2/4] dmaengine: ti: k3-udma-glue: Update name for remote RX channel device
commit: 7edd7a2fd345b10e80ee854aaacc6452d6f46a7e
[3/4] dmaengine: ti: k3-udma-glue: Add function to request TX chan for thread ID
commit: 7cbf7f4bf71a054d687c8860380c655a36d0f369
[4/4] dmaengine: ti: k3-udma-glue: Add function to request RX chan for thread ID
commit: e54df52312fed462a005706d5d7ed6250da91d1e

Best regards,
--
~Vinod