at91: kernel v5.15: copy config and patches from 5.10
[openwrt/openwrt.git] / target / linux / at91 / patches-5.15 / 134-dmaengine-at_xdmac-add-AXI-priority-support-and-reco.patch
diff --git a/target/linux/at91/patches-5.15/134-dmaengine-at_xdmac-add-AXI-priority-support-and-reco.patch b/target/linux/at91/patches-5.15/134-dmaengine-at_xdmac-add-AXI-priority-support-and-reco.patch
new file mode 100644 (file)
index 0000000..463d03a
--- /dev/null
@@ -0,0 +1,113 @@
+From 4833d6ea13a6d2c44a91247991a82c3eb6c1613e Mon Sep 17 00:00:00 2001
+From: Eugen Hristev <eugen.hristev@microchip.com>
+Date: Fri, 16 Oct 2020 12:39:18 +0300
+Subject: [PATCH 134/247] dmaengine: at_xdmac: add AXI priority support and
+ recommended settings
+
+The sama7g5 version of the XDMAC supports priority configuration and
+outstanding capabilities.
+Add defines for the specific registers for this configuration, together
+with recommended settings.
+However the settings are very different if the XDMAC is a mem2mem or a
+per2mem controller.
+Thus, we need to differentiate according to device tree property.
+
+Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
+Link: https://lore.kernel.org/r/20201016093918.290137-1-eugen.hristev@microchip.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+---
+ drivers/dma/at_xdmac.c | 47 ++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 47 insertions(+)
+
+--- a/drivers/dma/at_xdmac.c
++++ b/drivers/dma/at_xdmac.c
+@@ -30,7 +30,24 @@
+ #define               AT_XDMAC_FIFO_SZ(i)     (((i) >> 5) & 0x7FF)            /* Number of Bytes */
+ #define               AT_XDMAC_NB_REQ(i)      ((((i) >> 16) & 0x3F) + 1)      /* Number of Peripheral Requests Minus One */
+ #define AT_XDMAC_GCFG         0x04    /* Global Configuration Register */
++#define               AT_XDMAC_WRHP(i)                (((i) & 0xF) << 4)
++#define               AT_XDMAC_WRMP(i)                (((i) & 0xF) << 8)
++#define               AT_XDMAC_WRLP(i)                (((i) & 0xF) << 12)
++#define               AT_XDMAC_RDHP(i)                (((i) & 0xF) << 16)
++#define               AT_XDMAC_RDMP(i)                (((i) & 0xF) << 20)
++#define               AT_XDMAC_RDLP(i)                (((i) & 0xF) << 24)
++#define               AT_XDMAC_RDSG(i)                (((i) & 0xF) << 28)
++#define AT_XDMAC_GCFG_M2M     (AT_XDMAC_RDLP(0xF) | AT_XDMAC_WRLP(0xF))
++#define AT_XDMAC_GCFG_P2M     (AT_XDMAC_RDSG(0x1) | AT_XDMAC_RDHP(0x3) | \
++                              AT_XDMAC_WRHP(0x5))
+ #define AT_XDMAC_GWAC         0x08    /* Global Weighted Arbiter Configuration Register */
++#define               AT_XDMAC_PW0(i)         (((i) & 0xF) << 0)
++#define               AT_XDMAC_PW1(i)         (((i) & 0xF) << 4)
++#define               AT_XDMAC_PW2(i)         (((i) & 0xF) << 8)
++#define               AT_XDMAC_PW3(i)         (((i) & 0xF) << 12)
++#define AT_XDMAC_GWAC_M2M     0
++#define AT_XDMAC_GWAC_P2M     (AT_XDMAC_PW0(0xF) | AT_XDMAC_PW2(0xF))
++
+ #define AT_XDMAC_GIE          0x0C    /* Global Interrupt Enable Register */
+ #define AT_XDMAC_GID          0x10    /* Global Interrupt Disable Register */
+ #define AT_XDMAC_GIM          0x14    /* Global Interrupt Mask Register */
+@@ -190,6 +207,8 @@ struct at_xdmac_layout {
+       u8                              chan_cc_reg_base;
+       /* Source/Destination Interface must be specified or not */
+       bool                            sdif;
++      /* AXI queue priority configuration supported */
++      bool                            axi_config;
+ };
+ /* ----- Channels ----- */
+@@ -268,6 +287,7 @@ static const struct at_xdmac_layout at_x
+       .gswf = 0x40,
+       .chan_cc_reg_base = 0x50,
+       .sdif = true,
++      .axi_config = false,
+ };
+ static const struct at_xdmac_layout at_xdmac_sama7g5_layout = {
+@@ -280,6 +300,7 @@ static const struct at_xdmac_layout at_x
+       .gswf = 0x50,
+       .chan_cc_reg_base = 0x60,
+       .sdif = false,
++      .axi_config = true,
+ };
+ static inline void __iomem *at_xdmac_chan_reg_base(struct at_xdmac *atxdmac, unsigned int chan_nb)
+@@ -2003,6 +2024,30 @@ static int atmel_xdmac_resume(struct dev
+ }
+ #endif /* CONFIG_PM_SLEEP */
++static void at_xdmac_axi_config(struct platform_device *pdev)
++{
++      struct at_xdmac *atxdmac = (struct at_xdmac *)platform_get_drvdata(pdev);
++      bool dev_m2m = false;
++      u32 dma_requests;
++
++      if (!atxdmac->layout->axi_config)
++              return; /* Not supported */
++
++      if (!of_property_read_u32(pdev->dev.of_node, "dma-requests",
++                                &dma_requests)) {
++              dev_info(&pdev->dev, "controller in mem2mem mode.\n");
++              dev_m2m = true;
++      }
++
++      if (dev_m2m) {
++              at_xdmac_write(atxdmac, AT_XDMAC_GCFG, AT_XDMAC_GCFG_M2M);
++              at_xdmac_write(atxdmac, AT_XDMAC_GWAC, AT_XDMAC_GWAC_M2M);
++      } else {
++              at_xdmac_write(atxdmac, AT_XDMAC_GCFG, AT_XDMAC_GCFG_P2M);
++              at_xdmac_write(atxdmac, AT_XDMAC_GWAC, AT_XDMAC_GWAC_P2M);
++      }
++}
++
+ static int at_xdmac_probe(struct platform_device *pdev)
+ {
+       struct at_xdmac *atxdmac;
+@@ -2147,6 +2192,8 @@ static int at_xdmac_probe(struct platfor
+       dev_info(&pdev->dev, "%d channels, mapped at 0x%p\n",
+                nr_channels, atxdmac->regs);
++      at_xdmac_axi_config(pdev);
++
+       return 0;
+ err_dma_unregister: