[PATCH 4/4] dma: k3-udma: Handle Asel
Sascha Hauer
s.hauer at pengutronix.de
Tue Apr 29 07:14:23 PDT 2025
This adds support for the Asel aka "Address selection" bits to the
k3-udma driver.
These bits become important when the DDR firewalls are enabled. With DDR
firewalls the buffer addresses used by the PKTDMA engine need to be
tagged with the correct Asel value, otherwise they will be blocked by
the firewall.
The Asel values are read from the device tree and need to be placed in
bits 48-51 of the physical DMA addresses.
Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
drivers/dma/ti/k3-udma.c | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c
index dfec9f91e3..b9af13dcc0 100644
--- a/drivers/dma/ti/k3-udma.c
+++ b/drivers/dma/ti/k3-udma.c
@@ -26,6 +26,7 @@
#include "k3-psil-priv.h"
#define K3_UDMA_MAX_RFLOWS 1024
+#define K3_ADDRESS_ASEL_SHIFT 48
struct udma_chan;
@@ -195,6 +196,8 @@ struct udma_chan_config {
unsigned int enable_acc32:1;
unsigned int enable_burst:1;
unsigned int notdpkt:1; /* Suppress sending TDC packet */
+
+ u8 asel;
};
struct udma_chan {
@@ -958,6 +961,7 @@ static int udma_alloc_tx_resources(struct udma_chan *uc)
memset(&ring_cfg, 0, sizeof(ring_cfg));
ring_cfg.size = 16;
+ ring_cfg.asel = uc->config.asel;
ring_cfg.elm_size = K3_RINGACC_RING_ELSIZE_8;
ring_cfg.mode = K3_RINGACC_RING_MODE_RING;
@@ -1042,6 +1046,7 @@ static int udma_alloc_rx_resources(struct udma_chan *uc)
ring_cfg.size = 16;
ring_cfg.elm_size = K3_RINGACC_RING_ELSIZE_8;
ring_cfg.mode = K3_RINGACC_RING_MODE_RING;
+ ring_cfg.asel = uc->config.asel;
ret = k3_ringacc_ring_cfg(rflow->fd_ring, &ring_cfg);
ret |= k3_ringacc_ring_cfg(rflow->r_ring, &ring_cfg);
@@ -1751,6 +1756,7 @@ static int *udma_prep_dma_memcpy(struct udma_chan *uc, dma_addr_t dest,
u16 tr0_cnt0, tr0_cnt1, tr1_cnt0;
void *tr_desc;
size_t desc_size;
+ u64 asel = (u64)uc->config.asel << K3_ADDRESS_ASEL_SHIFT;
if (len < SZ_64K) {
num_tr = 1;
@@ -1792,6 +1798,9 @@ static int *udma_prep_dma_memcpy(struct udma_chan *uc, dma_addr_t dest,
CPPI5_TR_EVENT_SIZE_COMPLETION, 1);
cppi5_tr_csf_set(&tr_req[0].flags, CPPI5_TR_CSF_SUPR_EVT);
+ src |= asel;
+ dest |= asel;
+
tr_req[0].addr = src;
tr_req[0].icnt0 = tr0_cnt0;
tr_req[0].icnt1 = tr0_cnt1;
@@ -2339,6 +2348,7 @@ static int udma_send(struct dma *dma, dma_addr_t src, size_t len, void *metadata
struct udma_chan *uc;
u32 tc_ring_id;
int ret;
+ u64 asel;
if (metadata)
packet_data = *((struct ti_udma_drv_packet_data *)metadata);
@@ -2349,6 +2359,8 @@ static int udma_send(struct dma *dma, dma_addr_t src, size_t len, void *metadata
}
uc = &ud->channels[dma->id];
+ asel = (u64)uc->config.asel << K3_ADDRESS_ASEL_SHIFT;
+
if (uc->config.dir != DMA_MEM_TO_DEV)
return -EINVAL;
@@ -2358,6 +2370,8 @@ static int udma_send(struct dma *dma, dma_addr_t src, size_t len, void *metadata
cppi5_hdesc_reset_hbdesc(desc_tx);
+ src |= asel;
+
cppi5_hdesc_init(desc_tx,
uc->config.needs_epib ? CPPI5_INFO0_HDESC_EPIB_PRESENT : 0,
uc->config.psd_size);
@@ -2421,7 +2435,8 @@ static int udma_receive(struct dma *dma, dma_addr_t *dst, void *metadata)
packet_data->src_tag = port_id;
}
- *dst = buf_dma;
+ *dst = buf_dma & GENMASK_ULL(K3_ADDRESS_ASEL_SHIFT - 1, 0);
+
uc->num_rx_bufs--;
return pkt_len;
@@ -2470,6 +2485,8 @@ static int udma_of_xlate(struct dma *dma, struct of_phandle_args *args)
ep_config->mapped_channel_id >= 0) {
ucc->mapped_channel_id = ep_config->mapped_channel_id;
ucc->default_flow_id = ep_config->default_flow_id;
+ if (args->args_count == 2)
+ ucc->asel = args->args[1];
} else {
ucc->mapped_channel_id = -1;
ucc->default_flow_id = -1;
@@ -2498,6 +2515,7 @@ static int udma_prepare_rcv_buf(struct dma *dma, dma_addr_t dst, size_t size)
struct cppi5_host_desc_t *desc_rx;
struct udma_chan *uc;
u32 desc_num;
+ u64 asel;
if (dma->id >= (ud->rchan_cnt + ud->tchan_cnt)) {
dev_err(dma->dev, "invalid dma ch_id %lu\n", dma->id);
@@ -2511,6 +2529,7 @@ static int udma_prepare_rcv_buf(struct dma *dma, dma_addr_t dst, size_t size)
if (uc->num_rx_bufs >= UDMA_RX_DESC_NUM)
return -EINVAL;
+ asel = (u64)uc->config.asel << K3_ADDRESS_ASEL_SHIFT;
desc_num = uc->desc_rx_cur % UDMA_RX_DESC_NUM;
desc_rx = uc->desc_rx + (desc_num * uc->config.hdesc_size);
@@ -2520,6 +2539,7 @@ static int udma_prepare_rcv_buf(struct dma *dma, dma_addr_t dst, size_t size)
uc->config.needs_epib ? CPPI5_INFO0_HDESC_EPIB_PRESENT : 0,
uc->config.psd_size);
cppi5_hdesc_set_pktlen(desc_rx, size);
+ dst |= asel;
cppi5_hdesc_attach_buf(desc_rx, dst, size, dst, size);
udma_push_to_ring(uc->rflow->fd_ring, desc_rx);
--
2.39.5
More information about the barebox
mailing list