Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

dmaengine: sf-pdma: add mpfs-pdma compatible name

Sifive platform dma (sf-pdma) has both in-order and out-of-order
configurations but sf-pdam driver configured to do in-order DMA
transfers, with out-of-order configuration got better throughput
in the PolarFire SoC platform.

Add a PolarFire SoC specific compatible and code to support
for out-of-order dma transfers

Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
Signed-off-by: Shravan Chippa <shravan.chippa@microchip.com>
Link: https://lore.kernel.org/r/20231208103856.3732998-4-shravan.chippa@microchip.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Shravan Chippa and committed by
Vinod Koul
58eea79a 72b22006

+31 -4
+24 -3
drivers/dma/sf-pdma/sf-pdma.c
··· 25 25 26 26 #include "sf-pdma.h" 27 27 28 + #define PDMA_QUIRK_NO_STRICT_ORDERING BIT(0) 29 + 28 30 #ifndef readq 29 31 static inline unsigned long long readq(void __iomem *addr) 30 32 { ··· 68 66 static void sf_pdma_fill_desc(struct sf_pdma_desc *desc, 69 67 u64 dst, u64 src, u64 size) 70 68 { 71 - desc->xfer_type = PDMA_FULL_SPEED; 69 + desc->xfer_type = desc->chan->pdma->transfer_type; 72 70 desc->xfer_size = size; 73 71 desc->dst_addr = dst; 74 72 desc->src_addr = src; ··· 495 493 496 494 static int sf_pdma_probe(struct platform_device *pdev) 497 495 { 496 + const struct sf_pdma_driver_platdata *ddata; 498 497 struct sf_pdma *pdma; 499 498 int ret, n_chans; 500 499 const enum dma_slave_buswidth widths = ··· 520 517 return -ENOMEM; 521 518 522 519 pdma->n_chans = n_chans; 520 + 521 + pdma->transfer_type = PDMA_FULL_SPEED | PDMA_STRICT_ORDERING; 522 + 523 + ddata = device_get_match_data(&pdev->dev); 524 + if (ddata) { 525 + if (ddata->quirks & PDMA_QUIRK_NO_STRICT_ORDERING) 526 + pdma->transfer_type &= ~PDMA_STRICT_ORDERING; 527 + } 523 528 524 529 pdma->membase = devm_platform_ioremap_resource(pdev, 0); 525 530 if (IS_ERR(pdma->membase)) ··· 614 603 dma_async_device_unregister(&pdma->dma_dev); 615 604 } 616 605 606 + static const struct sf_pdma_driver_platdata mpfs_pdma = { 607 + .quirks = PDMA_QUIRK_NO_STRICT_ORDERING, 608 + }; 609 + 617 610 static const struct of_device_id sf_pdma_dt_ids[] = { 618 - { .compatible = "sifive,fu540-c000-pdma" }, 619 - { .compatible = "sifive,pdma0" }, 611 + { 612 + .compatible = "sifive,fu540-c000-pdma", 613 + }, { 614 + .compatible = "sifive,pdma0", 615 + }, { 616 + .compatible = "microchip,mpfs-pdma", 617 + .data = &mpfs_pdma, 618 + }, 620 619 {}, 621 620 }; 622 621 MODULE_DEVICE_TABLE(of, sf_pdma_dt_ids);
+7 -1
drivers/dma/sf-pdma/sf-pdma.h
··· 48 48 #define PDMA_ERR_STATUS_MASK GENMASK(31, 31) 49 49 50 50 /* Transfer Type */ 51 - #define PDMA_FULL_SPEED 0xFF000008 51 + #define PDMA_FULL_SPEED 0xFF000000 52 + #define PDMA_STRICT_ORDERING BIT(3) 52 53 53 54 /* Error Recovery */ 54 55 #define MAX_RETRY 1 ··· 113 112 struct dma_device dma_dev; 114 113 void __iomem *membase; 115 114 void __iomem *mappedbase; 115 + u32 transfer_type; 116 116 u32 n_chans; 117 117 struct sf_pdma_chan chans[] __counted_by(n_chans); 118 + }; 119 + 120 + struct sf_pdma_driver_platdata { 121 + u32 quirks; 118 122 }; 119 123 120 124 #endif /* _SF_PDMA_H */