Re: [PATCH 1/4] dmaengine: mediatek: Add MediaTek UART APDMA support

2019-05-21 Thread Vinod Koul
On 27-04-19, 11:36, Long Cheng wrote:
> Add 8250 UART APDMA to support MediaTek UART. If MediaTek UART is
> enabled by SERIAL_8250_MT6577, and we can enable this driver to offload
> the UART device moving bytes.

Applied, thanks

-- 
~Vinod


[PATCH 1/4] dmaengine: mediatek: Add MediaTek UART APDMA support

2019-04-26 Thread Long Cheng
Add 8250 UART APDMA to support MediaTek UART. If MediaTek UART is
enabled by SERIAL_8250_MT6577, and we can enable this driver to offload
the UART device moving bytes.

Signed-off-by: Long Cheng 
Signed-off-by: Sean Wang 
---
 drivers/dma/mediatek/Kconfig  |   11 +
 drivers/dma/mediatek/Makefile |1 +
 drivers/dma/mediatek/mtk-uart-apdma.c |  666 +
 3 files changed, 678 insertions(+)
 create mode 100644 drivers/dma/mediatek/mtk-uart-apdma.c

diff --git a/drivers/dma/mediatek/Kconfig b/drivers/dma/mediatek/Kconfig
index 680fc05..ac49eb6 100644
--- a/drivers/dma/mediatek/Kconfig
+++ b/drivers/dma/mediatek/Kconfig
@@ -24,3 +24,14 @@ config MTK_CQDMA
 
  This controller provides the channels which is dedicated to
  memory-to-memory transfer to offload from CPU.
+
+config MTK_UART_APDMA
+   tristate "MediaTek SoCs APDMA support for UART"
+   depends on OF && SERIAL_8250_MT6577
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ Support for the UART DMA engine found on MediaTek MTK SoCs.
+ When SERIAL_8250_MT6577 is enabled, and if you want to use DMA,
+ you can enable the config. The DMA engine can only be used
+ with MediaTek SoCs.
diff --git a/drivers/dma/mediatek/Makefile b/drivers/dma/mediatek/Makefile
index 41bb381..61a6d29 100644
--- a/drivers/dma/mediatek/Makefile
+++ b/drivers/dma/mediatek/Makefile
@@ -1,2 +1,3 @@
+obj-$(CONFIG_MTK_UART_APDMA) += mtk-uart-apdma.o
 obj-$(CONFIG_MTK_HSDMA) += mtk-hsdma.o
 obj-$(CONFIG_MTK_CQDMA) += mtk-cqdma.o
diff --git a/drivers/dma/mediatek/mtk-uart-apdma.c 
b/drivers/dma/mediatek/mtk-uart-apdma.c
new file mode 100644
index 000..546995c
--- /dev/null
+++ b/drivers/dma/mediatek/mtk-uart-apdma.c
@@ -0,0 +1,666 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek UART APDMA driver.
+ *
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: Long Cheng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "../virt-dma.h"
+
+/* The default number of virtual channel */
+#define MTK_UART_APDMA_NR_VCHANS   8
+
+#define VFF_EN_B   BIT(0)
+#define VFF_STOP_B BIT(0)
+#define VFF_FLUSH_BBIT(0)
+#define VFF_4G_EN_BBIT(0)
+/* rx valid size >=  vff thre */
+#define VFF_RX_INT_EN_B(BIT(0) | BIT(1))
+/* tx left size >= vff thre */
+#define VFF_TX_INT_EN_BBIT(0)
+#define VFF_WARM_RST_B BIT(0)
+#define VFF_RX_INT_CLR_B   (BIT(0) | BIT(1))
+#define VFF_TX_INT_CLR_B   0
+#define VFF_STOP_CLR_B 0
+#define VFF_EN_CLR_B   0
+#define VFF_INT_EN_CLR_B   0
+#define VFF_4G_SUPPORT_CLR_B   0
+
+/*
+ * interrupt trigger level for tx
+ * if threshold is n, no polling is required to start tx.
+ * otherwise need polling VFF_FLUSH.
+ */
+#define VFF_TX_THRE(n) (n)
+/* interrupt trigger level for rx */
+#define VFF_RX_THRE(n) ((n) * 3 / 4)
+
+#define VFF_RING_SIZE  0x
+/* invert this bit when wrap ring head again */
+#define VFF_RING_WRAP  0x1
+
+#define VFF_INT_FLAG   0x00
+#define VFF_INT_EN 0x04
+#define VFF_EN 0x08
+#define VFF_RST0x0c
+#define VFF_STOP   0x10
+#define VFF_FLUSH  0x14
+#define VFF_ADDR   0x1c
+#define VFF_LEN0x24
+#define VFF_THRE   0x28
+#define VFF_WPT0x2c
+#define VFF_RPT0x30
+/* TX: the buffer size HW can read. RX: the buffer size SW can read. */
+#define VFF_VALID_SIZE 0x3c
+/* TX: the buffer size SW can write. RX: the buffer size HW can write. */
+#define VFF_LEFT_SIZE  0x40
+#define VFF_DEBUG_STATUS   0x50
+#define VFF_4G_SUPPORT 0x54
+
+struct mtk_uart_apdmadev {
+   struct dma_device ddev;
+   struct clk *clk;
+   bool support_33bits;
+   unsigned int dma_requests;
+};
+
+struct mtk_uart_apdma_desc {
+   struct virt_dma_desc vd;
+
+   dma_addr_t addr;
+   unsigned int avail_len;
+};
+
+struct mtk_chan {
+   struct virt_dma_chan vc;
+   struct dma_slave_config cfg;
+   struct mtk_uart_apdma_desc *desc;
+   enum dma_transfer_direction dir;
+
+   void __iomem *base;
+   unsigned int irq;
+
+   unsigned int rx_status;
+};
+
+static inline struct mtk_uart_apdmadev *
+to_mtk_uart_apdma_dev(struct dma_device *d)
+{
+   return container_of(d, struct mtk_uart_apdmadev, ddev);
+}
+
+static inline struct mtk_chan *to_mtk_uart_apdma_chan(struct dma_chan *c)
+{
+   return container_of(c, struct mtk_chan, vc.chan);
+}
+
+static inline struct mtk_uart_apdma_desc *to_mtk_uart_apdma_desc
+   (struct dma_async_tx_descriptor *t)
+{
+   return container_of(t, struct mtk_uart_apdma_desc, vd.tx);
+}
+
+static