[PATCH v2 0/4] Cleanup dma device in spl and move dma channel[0]

The channel allocation and deallocation for dma copy was happening on every dma transfer. This is a overhead for transactions like NAND, which does page reads recursively for complete data.
So, moving the dma allocation to probe and implement corresponding remove function and cleanup dma device while exiting from spl.
Enable SPL_DM_DEVICE_REMOVE, for device removal capability in SPL.
v2 <==> v1 ========== 1> Improve subject of commit. 2> Add warning on dma device not found. 3> Do channel allocation only for udma and bcdma. Passthrough for all other types.
Prasanth Babu Mantena (2): mach-k3: common.c: Remove dma device in spl exit configs: k3: Enable device removal in SPL
Santhosh Kumar K (2): dma: ti: k3-udma: Move udma_probe() below all APIs dma: ti: k3-udma: Move DMA channel[0] allocation to probe and add udma_remove()
arch/arm/mach-k3/common.c | 25 ++- configs/am62ax_evm_a53_defconfig | 1 + configs/am62ax_evm_r5_defconfig | 1 + configs/am62x_evm_a53_defconfig | 1 + configs/am62x_evm_r5_defconfig | 1 + configs/j7200_evm_a72_defconfig | 1 + configs/j7200_evm_r5_defconfig | 1 + configs/j721e_evm_a72_defconfig | 1 + configs/j721e_evm_r5_defconfig | 1 + configs/j721s2_evm_a72_defconfig | 1 + configs/j721s2_evm_r5_defconfig | 1 + configs/j784s4_evm_a72_defconfig | 1 + configs/j784s4_evm_r5_defconfig | 1 + drivers/dma/ti/k3-udma.c | 333 ++++++++++++++++--------------- 14 files changed, 209 insertions(+), 161 deletions(-)

While exiting from spl, remove any dma device active through spl_board_prepare_for_boot(). This is required for cleaning up any dma channels being used in spl and avoid issues with overlapping channel allocation in the next stage bootloaders.
Signed-off-by: Prasanth Babu Mantena p-mantena@ti.com --- arch/arm/mach-k3/common.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c index df48ec8d47..ff47739e9b 100644 --- a/arch/arm/mach-k3/common.c +++ b/arch/arm/mach-k3/common.c @@ -28,6 +28,8 @@ #include <env.h> #include <elf.h> #include <soc.h> +#include <dm/uclass-internal.h> +#include <dm/device-internal.h>
#include <asm/arch/k3-qos.h>
@@ -246,12 +248,33 @@ void spl_enable_cache(void) #endif }
-#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) +static __maybe_unused void k3_dma_remove(void) +{ + struct udevice *dev; + int rc; + + rc = uclass_find_device(UCLASS_DMA, 0, &dev); + if (!rc && dev) { + rc = device_remove(dev, DM_REMOVE_NORMAL); + if (rc) + pr_warn("Cannot remove dma device '%s' (err=%d)\n", + dev->name, rc); + } + else + pr_warn("DMA Device not found (err=%d)\n", rc); +} + void spl_board_prepare_for_boot(void) { +#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) dcache_disable(); +#endif +#if IS_ENABLED(CONFIG_SPL_DMA) && IS_ENABLED(CONFIG_SPL_DM_DEVICE_REMOVE) + k3_dma_remove(); +#endif }
+#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) void spl_board_prepare_for_linux(void) { dcache_disable();

Enable CONFIG_SPL_DM_DEVICE_REMOVE in a72 and r5.
Signed-off-by: Prasanth Babu Mantena p-mantena@ti.com --- configs/am62ax_evm_a53_defconfig | 1 + configs/am62ax_evm_r5_defconfig | 1 + configs/am62x_evm_a53_defconfig | 1 + configs/am62x_evm_r5_defconfig | 1 + configs/j7200_evm_a72_defconfig | 1 + configs/j7200_evm_r5_defconfig | 1 + configs/j721e_evm_a72_defconfig | 1 + configs/j721e_evm_r5_defconfig | 1 + configs/j721s2_evm_a72_defconfig | 1 + configs/j721s2_evm_r5_defconfig | 1 + configs/j784s4_evm_a72_defconfig | 1 + configs/j784s4_evm_r5_defconfig | 1 + 12 files changed, 12 insertions(+)
diff --git a/configs/am62ax_evm_a53_defconfig b/configs/am62ax_evm_a53_defconfig index b905ff74f2..8f507ffb25 100644 --- a/configs/am62ax_evm_a53_defconfig +++ b/configs/am62ax_evm_a53_defconfig @@ -46,6 +46,7 @@ CONFIG_MULTI_DTB_FIT=y CONFIG_SPL_MULTI_DTB_FIT=y CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y CONFIG_SPL_DM=y +CONFIG_SPL_DM_DEVICE_REMOVE=y CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_REGMAP=y CONFIG_SPL_REGMAP=y diff --git a/configs/am62ax_evm_r5_defconfig b/configs/am62ax_evm_r5_defconfig index 092d083062..c93d8eff76 100644 --- a/configs/am62ax_evm_r5_defconfig +++ b/configs/am62ax_evm_r5_defconfig @@ -70,6 +70,7 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_SYS_MMC_ENV_PART=1 # CONFIG_NET is not set CONFIG_SPL_DM=y +CONFIG_SPL_DM_DEVICE_REMOVE=y CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_REGMAP=y CONFIG_SPL_REGMAP=y diff --git a/configs/am62x_evm_a53_defconfig b/configs/am62x_evm_a53_defconfig index 0b7ee942a0..003fa4f868 100644 --- a/configs/am62x_evm_a53_defconfig +++ b/configs/am62x_evm_a53_defconfig @@ -63,6 +63,7 @@ CONFIG_SPL_MULTI_DTB_FIT=y CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPL_DM=y +CONFIG_SPL_DM_DEVICE_REMOVE=y CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_REGMAP=y CONFIG_SPL_REGMAP=y diff --git a/configs/am62x_evm_r5_defconfig b/configs/am62x_evm_r5_defconfig index 78ed3f62d0..c990e386e9 100644 --- a/configs/am62x_evm_r5_defconfig +++ b/configs/am62x_evm_r5_defconfig @@ -77,6 +77,7 @@ CONFIG_SPL_MULTI_DTB_FIT=y CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_SPL_DM=y +CONFIG_SPL_DM_DEVICE_REMOVE=y CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_REGMAP=y CONFIG_SPL_REGMAP=y diff --git a/configs/j7200_evm_a72_defconfig b/configs/j7200_evm_a72_defconfig index 137ca3f0d0..2e73559f8c 100644 --- a/configs/j7200_evm_a72_defconfig +++ b/configs/j7200_evm_a72_defconfig @@ -93,6 +93,7 @@ CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPL_DM=y +CONFIG_SPL_DM_DEVICE_REMOVE=y CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_REGMAP=y CONFIG_SPL_REGMAP=y diff --git a/configs/j7200_evm_r5_defconfig b/configs/j7200_evm_r5_defconfig index 774a9eff43..eed78ba260 100644 --- a/configs/j7200_evm_r5_defconfig +++ b/configs/j7200_evm_r5_defconfig @@ -78,6 +78,7 @@ CONFIG_OF_CONTROL=y CONFIG_SPL_OF_CONTROL=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_SPL_DM=y +CONFIG_SPL_DM_DEVICE_REMOVE=y CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_REGMAP=y CONFIG_SPL_REGMAP=y diff --git a/configs/j721e_evm_a72_defconfig b/configs/j721e_evm_a72_defconfig index 640c1be2b9..bd55634924 100644 --- a/configs/j721e_evm_a72_defconfig +++ b/configs/j721e_evm_a72_defconfig @@ -97,6 +97,7 @@ CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPL_DM=y +CONFIG_SPL_DM_DEVICE_REMOVE=y CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_REGMAP=y CONFIG_SPL_REGMAP=y diff --git a/configs/j721e_evm_r5_defconfig b/configs/j721e_evm_r5_defconfig index 3b4a7c3c0e..5aaf44661c 100644 --- a/configs/j721e_evm_r5_defconfig +++ b/configs/j721e_evm_r5_defconfig @@ -87,6 +87,7 @@ CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y CONFIG_ENV_OVERWRITE=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_SPL_DM=y +CONFIG_SPL_DM_DEVICE_REMOVE=y CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_REGMAP=y CONFIG_SPL_REGMAP=y diff --git a/configs/j721s2_evm_a72_defconfig b/configs/j721s2_evm_a72_defconfig index d78ebb5cfd..ebefe914b0 100644 --- a/configs/j721s2_evm_a72_defconfig +++ b/configs/j721s2_evm_a72_defconfig @@ -92,6 +92,7 @@ CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPL_DM=y +CONFIG_SPL_DM_DEVICE_REMOVE=y CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_REGMAP=y CONFIG_SPL_REGMAP=y diff --git a/configs/j721s2_evm_r5_defconfig b/configs/j721s2_evm_r5_defconfig index b6adb6a77d..4561ce594c 100644 --- a/configs/j721s2_evm_r5_defconfig +++ b/configs/j721s2_evm_r5_defconfig @@ -88,6 +88,7 @@ CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y CONFIG_ENV_OVERWRITE=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_SPL_DM=y +CONFIG_SPL_DM_DEVICE_REMOVE=y CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_REGMAP=y CONFIG_SPL_REGMAP=y diff --git a/configs/j784s4_evm_a72_defconfig b/configs/j784s4_evm_a72_defconfig index f0220170bb..c7fc6bedda 100644 --- a/configs/j784s4_evm_a72_defconfig +++ b/configs/j784s4_evm_a72_defconfig @@ -42,6 +42,7 @@ CONFIG_SPL_SYS_MMCSD_RAW_MODE=y CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x1400 CONFIG_SPL_DMA=y +CONFIG_SPL_DM_DEVICE_REMOVE=y CONFIG_SPL_ENV_SUPPORT=y CONFIG_SPL_FS_LOAD_PAYLOAD_NAME="u-boot.img" CONFIG_SPL_I2C=y diff --git a/configs/j784s4_evm_r5_defconfig b/configs/j784s4_evm_r5_defconfig index a116881949..4a74c4c4fe 100644 --- a/configs/j784s4_evm_r5_defconfig +++ b/configs/j784s4_evm_r5_defconfig @@ -75,6 +75,7 @@ CONFIG_SPL_MULTI_DTB_FIT=y CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_SPL_DM=y +CONFIG_SPL_DM_DEVICE_REMOVE=y CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_REGMAP=y CONFIG_SPL_REGMAP=y

From: Santhosh Kumar K s-k6@ti.com
The udma_probe() function was placed above many important APIs related to bcdma, pktdma, which restricts these APIs to be accessed during probe. So, move udma_probe() below all of them.
Signed-off-by: Santhosh Kumar K s-k6@ti.com Signed-off-by: Prasanth Babu Mantena p-mantena@ti.com --- drivers/dma/ti/k3-udma.c | 270 +++++++++++++++++++-------------------- 1 file changed, 135 insertions(+), 135 deletions(-)
diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c index e23d09e6b8..0543f5f4c8 100644 --- a/drivers/dma/ti/k3-udma.c +++ b/drivers/dma/ti/k3-udma.c @@ -1700,141 +1700,6 @@ static int setup_resources(struct udma_dev *ud) return ch_count; }
-static int udma_probe(struct udevice *dev) -{ - struct dma_dev_priv *uc_priv = dev_get_uclass_priv(dev); - struct udma_dev *ud = dev_get_priv(dev); - int i, ret; - struct udevice *tmp; - struct udevice *tisci_dev = NULL; - struct udma_tisci_rm *tisci_rm = &ud->tisci_rm; - ofnode navss_ofnode = ofnode_get_parent(dev_ofnode(dev)); - - ud->match_data = (void *)dev_get_driver_data(dev); - ret = udma_get_mmrs(dev); - if (ret) - return ret; - - ud->psil_base = ud->match_data->psil_base; - - ret = uclass_get_device_by_phandle(UCLASS_FIRMWARE, dev, - "ti,sci", &tisci_dev); - if (ret) { - debug("Failed to get TISCI phandle (%d)\n", ret); - tisci_rm->tisci = NULL; - return -EINVAL; - } - tisci_rm->tisci = (struct ti_sci_handle *) - (ti_sci_get_handle_from_sysfw(tisci_dev)); - - tisci_rm->tisci_dev_id = -1; - ret = dev_read_u32(dev, "ti,sci-dev-id", &tisci_rm->tisci_dev_id); - if (ret) { - dev_err(dev, "ti,sci-dev-id read failure %d\n", ret); - return ret; - } - - tisci_rm->tisci_navss_dev_id = -1; - ret = ofnode_read_u32(navss_ofnode, "ti,sci-dev-id", - &tisci_rm->tisci_navss_dev_id); - if (ret) { - dev_err(dev, "navss sci-dev-id read failure %d\n", ret); - return ret; - } - - tisci_rm->tisci_udmap_ops = &tisci_rm->tisci->ops.rm_udmap_ops; - tisci_rm->tisci_psil_ops = &tisci_rm->tisci->ops.rm_psil_ops; - - if (ud->match_data->type == DMA_TYPE_UDMA) { - ret = uclass_get_device_by_phandle(UCLASS_MISC, dev, - "ti,ringacc", &tmp); - ud->ringacc = dev_get_priv(tmp); - } else { - struct k3_ringacc_init_data ring_init_data; - - ring_init_data.tisci = ud->tisci_rm.tisci; - ring_init_data.tisci_dev_id = ud->tisci_rm.tisci_dev_id; - if (ud->match_data->type == DMA_TYPE_BCDMA) { - ring_init_data.num_rings = ud->bchan_cnt + - ud->tchan_cnt + - ud->rchan_cnt; - } else { - ring_init_data.num_rings = ud->rflow_cnt + - ud->tflow_cnt; - } - - ud->ringacc = k3_ringacc_dmarings_init(dev, &ring_init_data); - } - if (IS_ERR(ud->ringacc)) - return PTR_ERR(ud->ringacc); - - ud->dev = dev; - ret = setup_resources(ud); - if (ret < 0) - return ret; - - ud->ch_count = ret; - - for (i = 0; i < ud->bchan_cnt; i++) { - struct udma_bchan *bchan = &ud->bchans[i]; - - bchan->id = i; - bchan->reg_rt = ud->mmrs[MMR_BCHANRT] + i * 0x1000; - } - - for (i = 0; i < ud->tchan_cnt; i++) { - struct udma_tchan *tchan = &ud->tchans[i]; - - tchan->id = i; - tchan->reg_chan = ud->mmrs[MMR_TCHAN] + UDMA_CH_100(i); - tchan->reg_rt = ud->mmrs[MMR_TCHANRT] + UDMA_CH_1000(i); - } - - for (i = 0; i < ud->rchan_cnt; i++) { - struct udma_rchan *rchan = &ud->rchans[i]; - - rchan->id = i; - rchan->reg_chan = ud->mmrs[MMR_RCHAN] + UDMA_CH_100(i); - rchan->reg_rt = ud->mmrs[MMR_RCHANRT] + UDMA_CH_1000(i); - } - - for (i = 0; i < ud->rflow_cnt; i++) { - struct udma_rflow *rflow = &ud->rflows[i]; - - rflow->id = i; - rflow->reg_rflow = ud->mmrs[MMR_RFLOW] + UDMA_CH_40(i); - } - - for (i = 0; i < ud->ch_count; i++) { - struct udma_chan *uc = &ud->channels[i]; - - uc->ud = ud; - uc->id = i; - uc->config.remote_thread_id = -1; - uc->bchan = NULL; - uc->tchan = NULL; - uc->rchan = NULL; - uc->config.mapped_channel_id = -1; - uc->config.default_flow_id = -1; - uc->config.dir = DMA_MEM_TO_MEM; - sprintf(uc->name, "UDMA chan%d\n", i); - if (!i) - uc->in_use = true; - } - - pr_debug("%s(rev: 0x%08x) CAP0-3: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", - dev->name, - udma_read(ud->mmrs[MMR_GCFG], 0), - udma_read(ud->mmrs[MMR_GCFG], 0x20), - udma_read(ud->mmrs[MMR_GCFG], 0x24), - udma_read(ud->mmrs[MMR_GCFG], 0x28), - udma_read(ud->mmrs[MMR_GCFG], 0x2c)); - - uc_priv->supported = DMA_SUPPORTS_MEM_TO_MEM | DMA_SUPPORTS_MEM_TO_DEV; - - return 0; -} - static int udma_push_to_ring(struct k3_nav_ring *ring, void *elem) { u64 addr = 0; @@ -2717,6 +2582,141 @@ static int udma_get_cfg(struct dma *dma, u32 id, void **data) return -EINVAL; }
+static int udma_probe(struct udevice *dev) +{ + struct dma_dev_priv *uc_priv = dev_get_uclass_priv(dev); + struct udma_dev *ud = dev_get_priv(dev); + int i, ret; + struct udevice *tmp; + struct udevice *tisci_dev = NULL; + struct udma_tisci_rm *tisci_rm = &ud->tisci_rm; + ofnode navss_ofnode = ofnode_get_parent(dev_ofnode(dev)); + + ud->match_data = (void *)dev_get_driver_data(dev); + ret = udma_get_mmrs(dev); + if (ret) + return ret; + + ud->psil_base = ud->match_data->psil_base; + + ret = uclass_get_device_by_phandle(UCLASS_FIRMWARE, dev, + "ti,sci", &tisci_dev); + if (ret) { + debug("Failed to get TISCI phandle (%d)\n", ret); + tisci_rm->tisci = NULL; + return -EINVAL; + } + tisci_rm->tisci = (struct ti_sci_handle *) + (ti_sci_get_handle_from_sysfw(tisci_dev)); + + tisci_rm->tisci_dev_id = -1; + ret = dev_read_u32(dev, "ti,sci-dev-id", &tisci_rm->tisci_dev_id); + if (ret) { + dev_err(dev, "ti,sci-dev-id read failure %d\n", ret); + return ret; + } + + tisci_rm->tisci_navss_dev_id = -1; + ret = ofnode_read_u32(navss_ofnode, "ti,sci-dev-id", + &tisci_rm->tisci_navss_dev_id); + if (ret) { + dev_err(dev, "navss sci-dev-id read failure %d\n", ret); + return ret; + } + + tisci_rm->tisci_udmap_ops = &tisci_rm->tisci->ops.rm_udmap_ops; + tisci_rm->tisci_psil_ops = &tisci_rm->tisci->ops.rm_psil_ops; + + if (ud->match_data->type == DMA_TYPE_UDMA) { + ret = uclass_get_device_by_phandle(UCLASS_MISC, dev, + "ti,ringacc", &tmp); + ud->ringacc = dev_get_priv(tmp); + } else { + struct k3_ringacc_init_data ring_init_data; + + ring_init_data.tisci = ud->tisci_rm.tisci; + ring_init_data.tisci_dev_id = ud->tisci_rm.tisci_dev_id; + if (ud->match_data->type == DMA_TYPE_BCDMA) { + ring_init_data.num_rings = ud->bchan_cnt + + ud->tchan_cnt + + ud->rchan_cnt; + } else { + ring_init_data.num_rings = ud->rflow_cnt + + ud->tflow_cnt; + } + + ud->ringacc = k3_ringacc_dmarings_init(dev, &ring_init_data); + } + if (IS_ERR(ud->ringacc)) + return PTR_ERR(ud->ringacc); + + ud->dev = dev; + ret = setup_resources(ud); + if (ret < 0) + return ret; + + ud->ch_count = ret; + + for (i = 0; i < ud->bchan_cnt; i++) { + struct udma_bchan *bchan = &ud->bchans[i]; + + bchan->id = i; + bchan->reg_rt = ud->mmrs[MMR_BCHANRT] + i * 0x1000; + } + + for (i = 0; i < ud->tchan_cnt; i++) { + struct udma_tchan *tchan = &ud->tchans[i]; + + tchan->id = i; + tchan->reg_chan = ud->mmrs[MMR_TCHAN] + UDMA_CH_100(i); + tchan->reg_rt = ud->mmrs[MMR_TCHANRT] + UDMA_CH_1000(i); + } + + for (i = 0; i < ud->rchan_cnt; i++) { + struct udma_rchan *rchan = &ud->rchans[i]; + + rchan->id = i; + rchan->reg_chan = ud->mmrs[MMR_RCHAN] + UDMA_CH_100(i); + rchan->reg_rt = ud->mmrs[MMR_RCHANRT] + UDMA_CH_1000(i); + } + + for (i = 0; i < ud->rflow_cnt; i++) { + struct udma_rflow *rflow = &ud->rflows[i]; + + rflow->id = i; + rflow->reg_rflow = ud->mmrs[MMR_RFLOW] + UDMA_CH_40(i); + } + + for (i = 0; i < ud->ch_count; i++) { + struct udma_chan *uc = &ud->channels[i]; + + uc->ud = ud; + uc->id = i; + uc->config.remote_thread_id = -1; + uc->bchan = NULL; + uc->tchan = NULL; + uc->rchan = NULL; + uc->config.mapped_channel_id = -1; + uc->config.default_flow_id = -1; + uc->config.dir = DMA_MEM_TO_MEM; + sprintf(uc->name, "UDMA chan%d\n", i); + if (!i) + uc->in_use = true; + } + + pr_debug("%s(rev: 0x%08x) CAP0-3: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", + dev->name, + udma_read(ud->mmrs[MMR_GCFG], 0), + udma_read(ud->mmrs[MMR_GCFG], 0x20), + udma_read(ud->mmrs[MMR_GCFG], 0x24), + udma_read(ud->mmrs[MMR_GCFG], 0x28), + udma_read(ud->mmrs[MMR_GCFG], 0x2c)); + + uc_priv->supported = DMA_SUPPORTS_MEM_TO_MEM | DMA_SUPPORTS_MEM_TO_DEV; + + return 0; +} + static const struct dma_ops udma_ops = { .transfer = udma_transfer, .of_xlate = udma_of_xlate,

From: Santhosh Kumar K s-k6@ti.com
Currently, the allocation of DMA channel[0] for memcpy is happening in udma_transfer() for every transfer, which leads to a huge overhead for each transfer, especially in case of nand page reads. So, move this allocation to udma_probe(), as a result, the allocation is done once during probe.
Introduce udma_remove() for the cleanup of allocated channel during probe.
Signed-off-by: Santhosh Kumar K s-k6@ti.com Signed-off-by: Prasanth Babu Mantena p-mantena@ti.com --- drivers/dma/ti/k3-udma.c | 63 ++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 25 deletions(-)
diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c index 0543f5f4c8..dac4023ccf 100644 --- a/drivers/dma/ti/k3-udma.c +++ b/drivers/dma/ti/k3-udma.c @@ -2190,37 +2190,12 @@ static int udma_transfer(struct udevice *dev, int direction, /* Channel0 is reserved for memcpy */ struct udma_chan *uc = &ud->channels[0]; dma_addr_t paddr = 0; - int ret; - - switch (ud->match_data->type) { - case DMA_TYPE_UDMA: - ret = udma_alloc_chan_resources(uc); - break; - case DMA_TYPE_BCDMA: - ret = bcdma_alloc_chan_resources(uc); - break; - default: - return -EINVAL; - }; - if (ret) - return ret;
udma_prep_dma_memcpy(uc, dst, src, len); udma_start(uc); udma_poll_completion(uc, &paddr); udma_stop(uc);
- switch (ud->match_data->type) { - case DMA_TYPE_UDMA: - udma_free_chan_resources(uc); - break; - case DMA_TYPE_BCDMA: - bcdma_free_bchan_resources(uc); - break; - default: - return -EINVAL; - }; - return 0; }
@@ -2590,6 +2565,7 @@ static int udma_probe(struct udevice *dev) struct udevice *tmp; struct udevice *tisci_dev = NULL; struct udma_tisci_rm *tisci_rm = &ud->tisci_rm; + struct udma_chan *uc; ofnode navss_ofnode = ofnode_get_parent(dev_ofnode(dev));
ud->match_data = (void *)dev_get_driver_data(dev); @@ -2714,6 +2690,41 @@ static int udma_probe(struct udevice *dev)
uc_priv->supported = DMA_SUPPORTS_MEM_TO_MEM | DMA_SUPPORTS_MEM_TO_DEV;
+ uc = &ud->channels[0]; + ret = 0; + switch (ud->match_data->type) { + case DMA_TYPE_UDMA: + ret = udma_alloc_chan_resources(uc); + break; + case DMA_TYPE_BCDMA: + ret = bcdma_alloc_chan_resources(uc); + break; + default: + break; /* Do nothing in any other case */ + }; + + if (ret) + dev_err(dev, " Channel 0 allocation failure %d\n", ret); + + return ret; +} + +static int udma_remove(struct udevice *dev) +{ + struct udma_dev *ud = dev_get_priv(dev); + struct udma_chan *uc = &ud->channels[0]; + + switch (ud->match_data->type) { + case DMA_TYPE_UDMA: + udma_free_chan_resources(uc); + break; + case DMA_TYPE_BCDMA: + bcdma_free_bchan_resources(uc); + break; + default: + break; + }; + return 0; }
@@ -2855,5 +2866,7 @@ U_BOOT_DRIVER(ti_edma3) = { .of_match = udma_ids, .ops = &udma_ops, .probe = udma_probe, + .remove = udma_remove, .priv_auto = sizeof(struct udma_dev), + .flags = DM_FLAG_OS_PREPARE, };

Hi Prasanth,
The channel allocation and deallocation for dma copy was happening on every dma transfer. This is a overhead for transactions like NAND, which does page reads recursively for complete data.
So, moving the dma allocation to probe and implement corresponding remove function and cleanup dma device while exiting from spl.
Enable SPL_DM_DEVICE_REMOVE, for device removal capability in SPL.
v2 <==> v1
1> Improve subject of commit. 2> Add warning on dma device not found. 3> Do channel allocation only for udma and bcdma. Passthrough for all other types.
Prasanth Babu Mantena (2): mach-k3: common.c: Remove dma device in spl exit configs: k3: Enable device removal in SPL
Santhosh Kumar K (2): dma: ti: k3-udma: Move udma_probe() below all APIs dma: ti: k3-udma: Move DMA channel[0] allocation to probe and add udma_remove()
arch/arm/mach-k3/common.c | 25 ++- configs/am62ax_evm_a53_defconfig | 1 + configs/am62ax_evm_r5_defconfig | 1 + configs/am62x_evm_a53_defconfig | 1 + configs/am62x_evm_r5_defconfig | 1 + configs/j7200_evm_a72_defconfig | 1 + configs/j7200_evm_r5_defconfig | 1 + configs/j721e_evm_a72_defconfig | 1 + configs/j721e_evm_r5_defconfig | 1 + configs/j721s2_evm_a72_defconfig | 1 + configs/j721s2_evm_r5_defconfig | 1 + configs/j784s4_evm_a72_defconfig | 1 + configs/j784s4_evm_r5_defconfig | 1 +
Is there any reason why devices like j721e_beagleboneai64 and m62x_beagleplay and other TI devices aren't changed as part of this change?
Peter

On 23:10, Peter Robinson wrote: Hi Peter,
Hi Prasanth,
The channel allocation and deallocation for dma copy was happening on every dma transfer. This is a overhead for transactions like NAND, which does page reads recursively for complete data.
So, moving the dma allocation to probe and implement corresponding remove function and cleanup dma device while exiting from spl.
Enable SPL_DM_DEVICE_REMOVE, for device removal capability in SPL.
v2 <==> v1
1> Improve subject of commit. 2> Add warning on dma device not found. 3> Do channel allocation only for udma and bcdma. Passthrough for all other types.
Prasanth Babu Mantena (2): mach-k3: common.c: Remove dma device in spl exit configs: k3: Enable device removal in SPL
Santhosh Kumar K (2): dma: ti: k3-udma: Move udma_probe() below all APIs dma: ti: k3-udma: Move DMA channel[0] allocation to probe and add udma_remove()
arch/arm/mach-k3/common.c | 25 ++- configs/am62ax_evm_a53_defconfig | 1 + configs/am62ax_evm_r5_defconfig | 1 + configs/am62x_evm_a53_defconfig | 1 + configs/am62x_evm_r5_defconfig | 1 + configs/j7200_evm_a72_defconfig | 1 + configs/j7200_evm_r5_defconfig | 1 + configs/j721e_evm_a72_defconfig | 1 + configs/j721e_evm_r5_defconfig | 1 + configs/j721s2_evm_a72_defconfig | 1 + configs/j721s2_evm_r5_defconfig | 1 + configs/j784s4_evm_a72_defconfig | 1 + configs/j784s4_evm_r5_defconfig | 1 +
Is there any reason why devices like j721e_beagleboneai64 and m62x_beagleplay and other TI devices aren't changed as part of this change?
We donot have DMA enabled in SPL for these devices, as a result of which doesn't require removal of them at spl exit in current context. We donot have any onboard flashes on beagle boards, and hence DMA is not enabled in SPL for these boards, which is generally required for flash boot.
Thanks Prasanth
Peter

On Wed, 09 Oct 2024 20:26:59 +0530, Prasanth Babu Mantena wrote:
The channel allocation and deallocation for dma copy was happening on every dma transfer. This is a overhead for transactions like NAND, which does page reads recursively for complete data.
So, moving the dma allocation to probe and implement corresponding remove function and cleanup dma device while exiting from spl.
[...]
Applied to u-boot/master, thanks!
participants (4)
-
Peter Robinson
-
Prasanth Babu Mantena
-
Prasanth Mantena
-
Tom Rini