Linux Serial subsystem development
 help / color / mirror / Atom feed
* Re: [GIT PULL] TTY/Serial patches for 4.21-rc1
From: pr-tracker-bot @ 2018-12-29  5:35 UTC (permalink / raw)
  To: Greg KH
  Cc: Linus Torvalds, Jiri Slaby, Stephen Rothwell, Andrew Morton,
	linux-kernel, linux-serial
In-Reply-To: <20181228153506.GA23511@kroah.com>

The pull request you sent on Fri, 28 Dec 2018 16:35:06 +0100:

> git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tags/tty-4.21-rc1

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/117eda8f71ff545cfdec8fe8073adbd173a1ceff

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.wiki.kernel.org/userdoc/prtracker

^ permalink raw reply

* [PATCH v8 0/2] add uart DMA function
From: Long Cheng @ 2018-12-29 10:30 UTC (permalink / raw)
  To: Vinod Koul, Randy Dunlap, Rob Herring, Mark Rutland, Ryder Lee,
	Sean Wang, Nicolas Boichat
  Cc: Matthias Brugger, Dan Williams, Greg Kroah-Hartman, Jiri Slaby,
	Sean Wang, dmaengine, devicetree, linux-arm-kernel,
	linux-mediatek, linux-kernel, linux-serial, srv_heupstream,
	Yingjoe Chen, YT Shen, Zhenbao Liu, Long Cheng

In Mediatek SOCs, the uart can support DMA function.
Base on DMA engine formwork, we add the DMA code to support uart. And put the code under drivers/dma.

This series contains document bindings, Kconfig to control the function enable or not,
device tree including interrupt and dma device node, the code of UART DMA

Changes compared to v7:
-modify apdma uart tx
Changes compared to v6:
-Correct spelling
Changes compared to v5:
-move 'requst irqs' to alloc channel
-remove tasklet.
Changes compared to v4:
-modify Kconfig depends on.
Changes compared to v3:
-fix CONFIG_PM, will cause build fail
Changes compared to v2:
-remove unimportant parameters
-instead of cookie, use APIs of virtual channel.
-use of_dma_xlate_by_chan_id.
Changes compared to v1:
-mian revised file, 8250_mtk_dma.c
--parameters renamed for standard
--remove atomic operation


Long Cheng (2):
  dmaengine: 8250_mtk_dma: add MediaTek uart DMA support
  arm: dts: mt2712: add uart APDMA to device tree

 arch/arm64/boot/dts/mediatek/mt2712e.dtsi |   50 +++
 drivers/dma/mediatek/8250_mtk_dma.c       |  694 +++++++++++++++++++++++++++++
 drivers/dma/mediatek/Kconfig              |   11 +
 drivers/dma/mediatek/Makefile             |    1 +
 4 files changed, 756 insertions(+)
 create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c

-- 
1.7.9.5

^ permalink raw reply

* [PATCH v8 1/2] dmaengine: 8250_mtk_dma: add MediaTek uart DMA support
From: Long Cheng @ 2018-12-29 10:30 UTC (permalink / raw)
  To: Vinod Koul, Randy Dunlap, Rob Herring, Mark Rutland, Ryder Lee,
	Sean Wang, Nicolas Boichat
  Cc: Matthias Brugger, Dan Williams, Greg Kroah-Hartman, Jiri Slaby,
	Sean Wang, dmaengine, devicetree, linux-arm-kernel,
	linux-mediatek, linux-kernel, linux-serial, srv_heupstream,
	Yingjoe Chen, YT Shen, Zhenbao Liu, Long Cheng
In-Reply-To: <1546079423-8361-1-git-send-email-long.cheng@mediatek.com>

In DMA engine framework, add 8250 uart dma to support MediaTek uart.
If MediaTek uart enabled(SERIAL_8250_MT6577), and want to improve
the performance, can enable the function.

Signed-off-by: Long Cheng <long.cheng@mediatek.com>
---
 drivers/dma/mediatek/8250_mtk_dma.c |  694 +++++++++++++++++++++++++++++++++++
 drivers/dma/mediatek/Kconfig        |   11 +
 drivers/dma/mediatek/Makefile       |    1 +
 3 files changed, 706 insertions(+)
 create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c

diff --git a/drivers/dma/mediatek/8250_mtk_dma.c b/drivers/dma/mediatek/8250_mtk_dma.c
new file mode 100644
index 0000000..c4090f2
--- /dev/null
+++ b/drivers/dma/mediatek/8250_mtk_dma.c
@@ -0,0 +1,694 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek 8250 DMA driver.
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Long Cheng <long.cheng@mediatek.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_dma.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/pm_runtime.h>
+#include <linux/iopoll.h>
+
+#include "../virt-dma.h"
+
+#define MTK_UART_APDMA_CHANNELS		(CONFIG_SERIAL_8250_NR_UARTS * 2)
+
+#define VFF_EN_B		BIT(0)
+#define VFF_STOP_B		BIT(0)
+#define VFF_FLUSH_B		BIT(0)
+#define VFF_4G_SUPPORT_B	BIT(0)
+#define VFF_RX_INT_EN0_B	BIT(0)	/*rx valid size >=  vff thre*/
+#define VFF_RX_INT_EN1_B	BIT(1)
+#define VFF_TX_INT_EN_B		BIT(0)	/*tx left size >= vff thre*/
+#define VFF_WARM_RST_B		BIT(0)
+#define VFF_RX_INT_FLAG_CLR_B	(BIT(0) | BIT(1))
+#define VFF_TX_INT_FLAG_CLR_B	0
+#define VFF_STOP_CLR_B		0
+#define VFF_FLUSH_CLR_B		0
+#define VFF_INT_EN_CLR_B	0
+#define VFF_4G_SUPPORT_CLR_B	0
+
+/* interrupt trigger level for tx */
+#define VFF_TX_THRE(n)		((n) * 7 / 8)
+/* interrupt trigger level for rx */
+#define VFF_RX_THRE(n)		((n) * 3 / 4)
+
+#define MTK_UART_APDMA_RING_SIZE	0xffffU
+/* invert this bit when wrap ring head again*/
+#define MTK_UART_APDMA_RING_WRAP	0x10000U
+
+#define VFF_INT_FLAG		0x00
+#define VFF_INT_EN		0x04
+#define VFF_EN			0x08
+#define VFF_RST			0x0c
+#define VFF_STOP		0x10
+#define VFF_FLUSH		0x14
+#define VFF_ADDR		0x1c
+#define VFF_LEN			0x24
+#define VFF_THRE		0x28
+#define VFF_WPT			0x2c
+#define VFF_RPT			0x30
+/*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_irq[MTK_UART_APDMA_CHANNELS];
+};
+
+struct mtk_uart_apdma_desc {
+	struct virt_dma_desc vd;
+
+	unsigned int avail_len;
+};
+
+struct mtk_chan {
+	struct virt_dma_chan vc;
+	struct dma_slave_config	cfg;
+	void __iomem *base;
+	struct mtk_uart_apdma_desc *desc;
+
+	bool requested;
+
+	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 void mtk_uart_apdma_chan_write(struct mtk_chan *c,
+			       unsigned int reg, unsigned int val)
+{
+	writel(val, c->base + reg);
+}
+
+static unsigned int
+mtk_uart_apdma_chan_read(struct mtk_chan *c, unsigned int reg)
+{
+	return readl(c->base + reg);
+}
+
+static void mtk_uart_apdma_desc_free(struct virt_dma_desc *vd)
+{
+	struct dma_chan *chan = vd->tx.chan;
+	struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
+
+	kfree(c->desc);
+	c->desc = NULL;
+}
+
+static void mtk_uart_apdma_start_tx(struct mtk_chan *c)
+{
+	unsigned int txcount = c->desc->avail_len;
+	unsigned int len, send, left, wpt, wrap;
+
+	if (mtk_uart_apdma_chan_read(c, VFF_LEFT_SIZE) == 0U) {
+		mtk_uart_apdma_chan_write(c, VFF_INT_EN, VFF_TX_INT_EN_B);
+	} else {
+		len = mtk_uart_apdma_chan_read(c, VFF_LEN);
+
+		while (((left = mtk_uart_apdma_chan_read(c,
+					VFF_LEFT_SIZE)) > 0U)
+				&& (c->desc->avail_len != 0U)) {
+			send = min_t(unsigned int, left, c->desc->avail_len);
+			wpt = mtk_uart_apdma_chan_read(c, VFF_WPT);
+			wrap = wpt & MTK_UART_APDMA_RING_WRAP ?
+					0U : MTK_UART_APDMA_RING_WRAP;
+
+			if ((wpt & (len - 1U)) + send < len)
+				mtk_uart_apdma_chan_write(c,
+						VFF_WPT, wpt + send);
+			else
+				mtk_uart_apdma_chan_write(c, VFF_WPT,
+						   ((wpt + send) & (len - 1U))
+						   | wrap);
+
+			c->desc->avail_len -= send;
+		}
+
+		if (txcount != c->desc->avail_len) {
+			mtk_uart_apdma_chan_write(c,
+					VFF_INT_EN, VFF_TX_INT_EN_B);
+			if (mtk_uart_apdma_chan_read(c,
+						VFF_FLUSH) == 0U)
+				mtk_uart_apdma_chan_write(c,
+						VFF_FLUSH, VFF_FLUSH_B);
+		}
+	}
+}
+
+static void mtk_uart_apdma_start_rx(struct mtk_chan *c)
+{
+	struct mtk_uart_apdma_desc *d = c->desc;
+	unsigned int rx_len, wg, rg, count;
+
+	if (mtk_uart_apdma_chan_read(c, VFF_VALID_SIZE) == 0U)
+		return;
+
+	if (d && vchan_next_desc(&c->vc)) {
+		rx_len = mtk_uart_apdma_chan_read(c, VFF_LEN);
+		rg = mtk_uart_apdma_chan_read(c, VFF_RPT);
+		wg = mtk_uart_apdma_chan_read(c, VFF_WPT);
+		count = ((rg ^ wg) & MTK_UART_APDMA_RING_WRAP) ?
+				((wg & MTK_UART_APDMA_RING_SIZE) +
+				rx_len - (rg & MTK_UART_APDMA_RING_SIZE)) :
+				((wg & MTK_UART_APDMA_RING_SIZE) -
+				(rg & MTK_UART_APDMA_RING_SIZE));
+
+		c->rx_status = count;
+		mtk_uart_apdma_chan_write(c, VFF_RPT, wg);
+
+		list_del(&d->vd.node);
+		vchan_cookie_complete(&d->vd);
+	}
+}
+
+static irqreturn_t mtk_uart_apdma_irq_handler(int irq, void *dev_id)
+{
+	struct dma_chan *chan = (struct dma_chan *)dev_id;
+	struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
+	struct mtk_uart_apdma_desc *d;
+	unsigned long flags;
+
+	spin_lock_irqsave(&c->vc.lock, flags);
+	switch (c->cfg.direction) {
+	case DMA_DEV_TO_MEM:
+		mtk_uart_apdma_chan_write(c,
+				VFF_INT_FLAG, VFF_RX_INT_FLAG_CLR_B);
+		mtk_uart_apdma_start_rx(c);
+		break;
+	case DMA_MEM_TO_DEV:
+		d = c->desc;
+
+		mtk_uart_apdma_chan_write(c,
+				VFF_INT_FLAG, VFF_TX_INT_FLAG_CLR_B);
+
+		if (d->avail_len != 0U) {
+			mtk_uart_apdma_start_tx(c);
+		} else {
+			list_del(&d->vd.node);
+			vchan_cookie_complete(&d->vd);
+		}
+		break;
+	default:
+		break;
+	}
+	spin_unlock_irqrestore(&c->vc.lock, flags);
+
+	return IRQ_HANDLED;
+}
+
+static int mtk_uart_apdma_alloc_chan_resources(struct dma_chan *chan)
+{
+	struct mtk_uart_apdmadev *mtkd = to_mtk_uart_apdma_dev(chan->device);
+	struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
+	u32 status;
+	int ret = -EBUSY;
+
+	pm_runtime_get_sync(mtkd->ddev.dev);
+
+	mtk_uart_apdma_chan_write(c, VFF_ADDR, 0);
+	mtk_uart_apdma_chan_write(c, VFF_THRE, 0);
+	mtk_uart_apdma_chan_write(c, VFF_LEN, 0);
+	mtk_uart_apdma_chan_write(c, VFF_RST, VFF_WARM_RST_B);
+
+	ret = readx_poll_timeout(readl,
+				 c->base + VFF_EN,
+				 status, status == 0, 10, 100);
+	if (ret) {
+		dev_err(c->vc.chan.device->dev,
+				"dma reset: fail, timeout\n");
+		goto exit;
+	}
+
+	if (!c->requested) {
+		c->requested = true;
+		ret = request_irq(mtkd->dma_irq[chan->chan_id],
+				  mtk_uart_apdma_irq_handler,
+				  IRQF_TRIGGER_NONE,
+				  KBUILD_MODNAME, chan);
+		if (ret < 0) {
+			dev_err(chan->device->dev, "Can't request dma IRQ\n");
+			return -EINVAL;
+		}
+	}
+
+	if (mtkd->support_33bits)
+		mtk_uart_apdma_chan_write(c,
+				VFF_4G_SUPPORT, VFF_4G_SUPPORT_CLR_B);
+
+exit:
+	return ret;
+}
+
+static void mtk_uart_apdma_free_chan_resources(struct dma_chan *chan)
+{
+	struct mtk_uart_apdmadev *mtkd = to_mtk_uart_apdma_dev(chan->device);
+	struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
+
+	if (c->requested) {
+		c->requested = false;
+		free_irq(mtkd->dma_irq[chan->chan_id], chan);
+	}
+
+	tasklet_kill(&c->vc.task);
+
+	vchan_free_chan_resources(&c->vc);
+
+	pm_runtime_put_sync(mtkd->ddev.dev);
+}
+
+static enum dma_status mtk_uart_apdma_tx_status(struct dma_chan *chan,
+					 dma_cookie_t cookie,
+					 struct dma_tx_state *txstate)
+{
+	struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
+	enum dma_status ret;
+	unsigned long flags;
+
+	if (!txstate)
+		return DMA_ERROR;
+
+	ret = dma_cookie_status(chan, cookie, txstate);
+	spin_lock_irqsave(&c->vc.lock, flags);
+	if (ret == DMA_IN_PROGRESS) {
+		c->rx_status = mtk_uart_apdma_chan_read(c, VFF_RPT)
+			     & MTK_UART_APDMA_RING_SIZE;
+		dma_set_residue(txstate, c->rx_status);
+	} else if (ret == DMA_COMPLETE && c->cfg.direction == DMA_DEV_TO_MEM) {
+		dma_set_residue(txstate, c->rx_status);
+	} else {
+		dma_set_residue(txstate, 0);
+	}
+	spin_unlock_irqrestore(&c->vc.lock, flags);
+
+	return ret;
+}
+
+/*
+ * dmaengine_prep_slave_single will call the function. and sglen is 1.
+ * 8250 uart using one ring buffer, and deal with one sg.
+ */
+static struct dma_async_tx_descriptor *mtk_uart_apdma_prep_slave_sg
+	(struct dma_chan *chan, struct scatterlist *sgl,
+	unsigned int sglen,	enum dma_transfer_direction dir,
+	unsigned long tx_flags, void *context)
+{
+	struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
+	struct mtk_uart_apdma_desc *d;
+
+	if ((dir != DMA_DEV_TO_MEM) &&
+		(dir != DMA_MEM_TO_DEV)) {
+		dev_err(chan->device->dev, "bad direction\n");
+		return NULL;
+	}
+
+	/* Now allocate and setup the descriptor */
+	d = kzalloc(sizeof(*d), GFP_ATOMIC);
+	if (!d)
+		return NULL;
+
+	/* sglen is 1 */
+	d->avail_len = sg_dma_len(sgl);
+
+	return vchan_tx_prep(&c->vc, &d->vd, tx_flags);
+}
+
+static void mtk_uart_apdma_issue_pending(struct dma_chan *chan)
+{
+	struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
+	struct virt_dma_desc *vd;
+	unsigned long flags;
+
+	spin_lock_irqsave(&c->vc.lock, flags);
+	if (c->cfg.direction == DMA_DEV_TO_MEM) {
+		if (vchan_issue_pending(&c->vc) && !c->desc) {
+			vd = vchan_next_desc(&c->vc);
+			c->desc = to_mtk_uart_apdma_desc(&vd->tx);
+			mtk_uart_apdma_start_rx(c);
+		}
+	} else if (c->cfg.direction == DMA_MEM_TO_DEV) {
+		if (vchan_issue_pending(&c->vc) && !c->desc) {
+			vd = vchan_next_desc(&c->vc);
+			c->desc = to_mtk_uart_apdma_desc(&vd->tx);
+			mtk_uart_apdma_start_tx(c);
+		}
+	}
+	spin_unlock_irqrestore(&c->vc.lock, flags);
+}
+
+static int mtk_uart_apdma_slave_config(struct dma_chan *chan,
+				struct dma_slave_config *cfg)
+{
+	struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
+	struct mtk_uart_apdmadev *mtkd =
+				to_mtk_uart_apdma_dev(c->vc.chan.device);
+
+	c->cfg = *cfg;
+
+	if (cfg->direction == DMA_DEV_TO_MEM) {
+		unsigned int rx_len = cfg->src_addr_width * 1024;
+
+		mtk_uart_apdma_chan_write(c, VFF_ADDR, cfg->src_addr);
+		mtk_uart_apdma_chan_write(c, VFF_LEN, rx_len);
+		mtk_uart_apdma_chan_write(c, VFF_THRE, VFF_RX_THRE(rx_len));
+		mtk_uart_apdma_chan_write(c,
+				VFF_INT_EN, VFF_RX_INT_EN0_B
+				| VFF_RX_INT_EN1_B);
+		mtk_uart_apdma_chan_write(c, VFF_RPT, 0);
+		mtk_uart_apdma_chan_write(c,
+				VFF_INT_FLAG, VFF_RX_INT_FLAG_CLR_B);
+		mtk_uart_apdma_chan_write(c, VFF_EN, VFF_EN_B);
+	} else if (cfg->direction == DMA_MEM_TO_DEV)	{
+		unsigned int tx_len = cfg->dst_addr_width * 1024;
+
+		mtk_uart_apdma_chan_write(c, VFF_ADDR, cfg->dst_addr);
+		mtk_uart_apdma_chan_write(c, VFF_LEN, tx_len);
+		mtk_uart_apdma_chan_write(c, VFF_THRE, VFF_TX_THRE(tx_len));
+		mtk_uart_apdma_chan_write(c, VFF_WPT, 0);
+		mtk_uart_apdma_chan_write(c,
+				VFF_INT_FLAG, VFF_TX_INT_FLAG_CLR_B);
+		mtk_uart_apdma_chan_write(c, VFF_EN, VFF_EN_B);
+	}
+
+	if (mtkd->support_33bits)
+		mtk_uart_apdma_chan_write(c, VFF_4G_SUPPORT, VFF_4G_SUPPORT_B);
+
+	if (mtk_uart_apdma_chan_read(c, VFF_EN) != VFF_EN_B) {
+		dev_err(chan->device->dev,
+			"config dma dir[%d] fail\n", cfg->direction);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int mtk_uart_apdma_terminate_all(struct dma_chan *chan)
+{
+	struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
+	unsigned long flags;
+	u32 status;
+	int ret;
+
+	spin_lock_irqsave(&c->vc.lock, flags);
+
+	mtk_uart_apdma_chan_write(c, VFF_FLUSH, VFF_FLUSH_CLR_B);
+	/* Wait for flush */
+	ret = readx_poll_timeout(readl,
+				 c->base + VFF_FLUSH,
+				 status,
+				 (status & VFF_FLUSH_B) != VFF_FLUSH_B,
+				 10, 100);
+	if (ret)
+		dev_err(c->vc.chan.device->dev,
+			"dma stop: polling FLUSH fail, DEBUG=0x%x\n",
+			mtk_uart_apdma_chan_read(c, VFF_DEBUG_STATUS));
+
+	/*set stop as 1 -> wait until en is 0 -> set stop as 0*/
+	mtk_uart_apdma_chan_write(c, VFF_STOP, VFF_STOP_B);
+	ret = readx_poll_timeout(readl,
+				 c->base + VFF_EN,
+				 status, status == 0, 10, 100);
+	if (ret)
+		dev_err(c->vc.chan.device->dev,
+			"dma stop: polling VFF_EN fail, DEBUG=0x%x\n",
+			mtk_uart_apdma_chan_read(c, VFF_DEBUG_STATUS));
+
+	mtk_uart_apdma_chan_write(c, VFF_STOP, VFF_STOP_CLR_B);
+	mtk_uart_apdma_chan_write(c, VFF_INT_EN, VFF_INT_EN_CLR_B);
+
+	switch (c->cfg.direction) {
+	case DMA_DEV_TO_MEM:
+		mtk_uart_apdma_chan_write(c,
+				VFF_INT_FLAG, VFF_RX_INT_FLAG_CLR_B);
+		break;
+	case DMA_MEM_TO_DEV:
+		mtk_uart_apdma_chan_write(c,
+				VFF_INT_FLAG, VFF_TX_INT_FLAG_CLR_B);
+		break;
+	default:
+		break;
+	}
+
+	spin_unlock_irqrestore(&c->vc.lock, flags);
+
+	return 0;
+}
+
+static int mtk_uart_apdma_device_pause(struct dma_chan *chan)
+{
+	/* just for check caps pass */
+	return 0;
+}
+
+static int mtk_uart_apdma_device_resume(struct dma_chan *chan)
+{
+	/* just for check caps pass */
+	return 0;
+}
+
+static void mtk_uart_apdma_free(struct mtk_uart_apdmadev *mtkd)
+{
+	while (list_empty(&mtkd->ddev.channels) == 0) {
+		struct mtk_chan *c = list_first_entry(&mtkd->ddev.channels,
+			struct mtk_chan, vc.chan.device_node);
+
+		list_del(&c->vc.chan.device_node);
+		tasklet_kill(&c->vc.task);
+	}
+}
+
+static const struct of_device_id mtk_uart_apdma_match[] = {
+	{ .compatible = "mediatek,mt6577-uart-dma", },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mtk_uart_apdma_match);
+
+static int mtk_uart_apdma_probe(struct platform_device *pdev)
+{
+	struct mtk_uart_apdmadev *mtkd;
+	struct resource *res;
+	struct mtk_chan *c;
+	unsigned int i;
+	int rc;
+
+	mtkd = devm_kzalloc(&pdev->dev, sizeof(*mtkd), GFP_KERNEL);
+	if (!mtkd)
+		return -ENOMEM;
+
+	mtkd->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(mtkd->clk)) {
+		dev_err(&pdev->dev, "No clock specified\n");
+		rc = PTR_ERR(mtkd->clk);
+		goto err_no_dma;
+	}
+
+	if (of_property_read_bool(pdev->dev.of_node, "dma-33bits")) {
+		dev_info(&pdev->dev, "Support dma 33bits\n");
+		mtkd->support_33bits = true;
+	}
+
+	rc = dma_set_mask_and_coherent(&pdev->dev,
+				DMA_BIT_MASK(32 | mtkd->support_33bits));
+	if (rc)
+		goto err_no_dma;
+
+	dma_cap_set(DMA_SLAVE, mtkd->ddev.cap_mask);
+	mtkd->ddev.device_alloc_chan_resources =
+				mtk_uart_apdma_alloc_chan_resources;
+	mtkd->ddev.device_free_chan_resources =
+				mtk_uart_apdma_free_chan_resources;
+	mtkd->ddev.device_tx_status = mtk_uart_apdma_tx_status;
+	mtkd->ddev.device_issue_pending = mtk_uart_apdma_issue_pending;
+	mtkd->ddev.device_prep_slave_sg = mtk_uart_apdma_prep_slave_sg;
+	mtkd->ddev.device_config = mtk_uart_apdma_slave_config;
+	mtkd->ddev.device_pause = mtk_uart_apdma_device_pause;
+	mtkd->ddev.device_resume = mtk_uart_apdma_device_resume;
+	mtkd->ddev.device_terminate_all = mtk_uart_apdma_terminate_all;
+	mtkd->ddev.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE);
+	mtkd->ddev.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE);
+	mtkd->ddev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
+	mtkd->ddev.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT;
+	mtkd->ddev.dev = &pdev->dev;
+	INIT_LIST_HEAD(&mtkd->ddev.channels);
+
+	for (i = 0; i < MTK_UART_APDMA_CHANNELS; i++) {
+		c = devm_kzalloc(mtkd->ddev.dev, sizeof(*c), GFP_KERNEL);
+		if (!c) {
+			rc = -ENODEV;
+			goto err_no_dma;
+		}
+
+		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+		if (!res) {
+			rc = -ENODEV;
+			goto err_no_dma;
+		}
+
+		c->base = devm_ioremap_resource(&pdev->dev, res);
+		if (IS_ERR(c->base)) {
+			rc = PTR_ERR(c->base);
+			goto err_no_dma;
+		}
+		c->requested = false;
+		c->vc.desc_free = mtk_uart_apdma_desc_free;
+		vchan_init(&c->vc, &mtkd->ddev);
+
+		mtkd->dma_irq[i] = platform_get_irq(pdev, i);
+		if ((int)mtkd->dma_irq[i] < 0) {
+			dev_err(&pdev->dev, "failed to get IRQ[%d]\n", i);
+			rc = -EINVAL;
+			goto err_no_dma;
+		}
+	}
+
+	pm_runtime_enable(&pdev->dev);
+	pm_runtime_set_active(&pdev->dev);
+
+	rc = dma_async_device_register(&mtkd->ddev);
+	if (rc)
+		goto rpm_disable;
+
+	platform_set_drvdata(pdev, mtkd);
+
+	if (pdev->dev.of_node) {
+		/* Device-tree DMA controller registration */
+		rc = of_dma_controller_register(pdev->dev.of_node,
+						of_dma_xlate_by_chan_id,
+						mtkd);
+		if (rc)
+			goto dma_remove;
+	}
+
+	return rc;
+
+dma_remove:
+	dma_async_device_unregister(&mtkd->ddev);
+rpm_disable:
+	pm_runtime_disable(&pdev->dev);
+err_no_dma:
+	mtk_uart_apdma_free(mtkd);
+	return rc;
+}
+
+static int mtk_uart_apdma_remove(struct platform_device *pdev)
+{
+	struct mtk_uart_apdmadev *mtkd = platform_get_drvdata(pdev);
+
+	if (pdev->dev.of_node)
+		of_dma_controller_free(pdev->dev.of_node);
+
+	pm_runtime_disable(&pdev->dev);
+	pm_runtime_put_noidle(&pdev->dev);
+
+	dma_async_device_unregister(&mtkd->ddev);
+	mtk_uart_apdma_free(mtkd);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int mtk_uart_apdma_suspend(struct device *dev)
+{
+	struct mtk_uart_apdmadev *mtkd = dev_get_drvdata(dev);
+
+	if (!pm_runtime_suspended(dev))
+		clk_disable_unprepare(mtkd->clk);
+
+	return 0;
+}
+
+static int mtk_uart_apdma_resume(struct device *dev)
+{
+	int ret;
+	struct mtk_uart_apdmadev *mtkd = dev_get_drvdata(dev);
+
+	if (!pm_runtime_suspended(dev)) {
+		ret = clk_prepare_enable(mtkd->clk);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+#ifdef CONFIG_PM
+static int mtk_uart_apdma_runtime_suspend(struct device *dev)
+{
+	struct mtk_uart_apdmadev *mtkd = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(mtkd->clk);
+
+	return 0;
+}
+
+static int mtk_uart_apdma_runtime_resume(struct device *dev)
+{
+	int ret;
+	struct mtk_uart_apdmadev *mtkd = dev_get_drvdata(dev);
+
+	ret = clk_prepare_enable(mtkd->clk);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+#endif /* CONFIG_PM */
+
+static const struct dev_pm_ops mtk_uart_apdma_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(mtk_uart_apdma_suspend, mtk_uart_apdma_resume)
+	SET_RUNTIME_PM_OPS(mtk_uart_apdma_runtime_suspend,
+			   mtk_uart_apdma_runtime_resume, NULL)
+};
+
+static struct platform_driver mtk_uart_apdma_driver = {
+	.probe	= mtk_uart_apdma_probe,
+	.remove	= mtk_uart_apdma_remove,
+	.driver = {
+		.name		= KBUILD_MODNAME,
+		.pm		= &mtk_uart_apdma_pm_ops,
+		.of_match_table = of_match_ptr(mtk_uart_apdma_match),
+	},
+};
+
+module_platform_driver(mtk_uart_apdma_driver);
+
+MODULE_DESCRIPTION("MediaTek UART APDMA Controller Driver");
+MODULE_AUTHOR("Long Cheng <long.cheng@mediatek.com>");
+MODULE_LICENSE("GPL v2");
+
diff --git a/drivers/dma/mediatek/Kconfig b/drivers/dma/mediatek/Kconfig
index 27bac0b..1a523c87 100644
--- a/drivers/dma/mediatek/Kconfig
+++ b/drivers/dma/mediatek/Kconfig
@@ -1,4 +1,15 @@
 
+config DMA_MTK_UART
+	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.
+
 config MTK_HSDMA
 	tristate "MediaTek High-Speed DMA controller support"
 	depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/dma/mediatek/Makefile b/drivers/dma/mediatek/Makefile
index 6e778f8..2f2efd9 100644
--- a/drivers/dma/mediatek/Makefile
+++ b/drivers/dma/mediatek/Makefile
@@ -1 +1,2 @@
+obj-$(CONFIG_DMA_MTK_UART) += 8250_mtk_dma.o
 obj-$(CONFIG_MTK_HSDMA) += mtk-hsdma.o
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v8 2/2] arm: dts: mt2712: add uart APDMA to device tree
From: Long Cheng @ 2018-12-29 10:30 UTC (permalink / raw)
  To: Vinod Koul, Randy Dunlap, Rob Herring, Mark Rutland, Ryder Lee,
	Sean Wang, Nicolas Boichat
  Cc: Matthias Brugger, Dan Williams, Greg Kroah-Hartman, Jiri Slaby,
	Sean Wang, dmaengine, devicetree, linux-arm-kernel,
	linux-mediatek, linux-kernel, linux-serial, srv_heupstream,
	Yingjoe Chen, YT Shen, Zhenbao Liu, Long Cheng
In-Reply-To: <1546079423-8361-1-git-send-email-long.cheng@mediatek.com>

1. add uart APDMA controller device node
2. add uart 0/1/2/3/4/5 DMA function

Signed-off-by: Long Cheng <long.cheng@mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi |   50 +++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
index 976d92a..be1a22a 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -300,6 +300,9 @@
 		interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_LOW>;
 		clocks = <&baud_clk>, <&sys_clk>;
 		clock-names = "baud", "bus";
+		dmas = <&apdma 10
+			&apdma 11>;
+		dma-names = "tx", "rx";
 		status = "disabled";
 	};
 
@@ -369,6 +372,38 @@
 			 (GIC_CPU_MASK_RAW(0x13) | IRQ_TYPE_LEVEL_HIGH)>;
 	};
 
+	apdma: dma-controller@11000400 {
+		compatible = "mediatek,mt2712-uart-dma",
+			     "mediatek,mt6577-uart-dma";
+		reg = <0 0x11000400 0 0x80>,
+		      <0 0x11000480 0 0x80>,
+		      <0 0x11000500 0 0x80>,
+		      <0 0x11000580 0 0x80>,
+		      <0 0x11000600 0 0x80>,
+		      <0 0x11000680 0 0x80>,
+		      <0 0x11000700 0 0x80>,
+		      <0 0x11000780 0 0x80>,
+		      <0 0x11000800 0 0x80>,
+		      <0 0x11000880 0 0x80>,
+		      <0 0x11000900 0 0x80>,
+		      <0 0x11000980 0 0x80>;
+		interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_SPI 104 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_SPI 105 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_SPI 106 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_SPI 107 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_SPI 108 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_SPI 109 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_SPI 111 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_SPI 112 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_SPI 113 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_SPI 114 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&pericfg CLK_PERI_AP_DMA>;
+		clock-names = "apdma";
+		#dma-cells = <1>;
+	};
+
 	auxadc: adc@11001000 {
 		compatible = "mediatek,mt2712-auxadc";
 		reg = <0 0x11001000 0 0x1000>;
@@ -385,6 +420,9 @@
 		interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>;
 		clocks = <&baud_clk>, <&sys_clk>;
 		clock-names = "baud", "bus";
+		dmas = <&apdma 0
+			&apdma 1>;
+		dma-names = "tx", "rx";
 		status = "disabled";
 	};
 
@@ -395,6 +433,9 @@
 		interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_LOW>;
 		clocks = <&baud_clk>, <&sys_clk>;
 		clock-names = "baud", "bus";
+		dmas = <&apdma 2
+			&apdma 3>;
+		dma-names = "tx", "rx";
 		status = "disabled";
 	};
 
@@ -405,6 +446,9 @@
 		interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_LOW>;
 		clocks = <&baud_clk>, <&sys_clk>;
 		clock-names = "baud", "bus";
+		dmas = <&apdma 4
+			&apdma 5>;
+		dma-names = "tx", "rx";
 		status = "disabled";
 	};
 
@@ -415,6 +459,9 @@
 		interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_LOW>;
 		clocks = <&baud_clk>, <&sys_clk>;
 		clock-names = "baud", "bus";
+		dmas = <&apdma 6
+			&apdma 7>;
+		dma-names = "tx", "rx";
 		status = "disabled";
 	};
 
@@ -629,6 +676,9 @@
 		interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_LOW>;
 		clocks = <&baud_clk>, <&sys_clk>;
 		clock-names = "baud", "bus";
+		dmas = <&apdma 8
+			&apdma 9>;
+		dma-names = "tx", "rx";
 		status = "disabled";
 	};
 
-- 
1.7.9.5

^ permalink raw reply related

* Re: [PATCH v7 00/11] Add initial RDA8810PL SoC and Orange Pi boards support
From: Olof Johansson @ 2018-12-31 21:13 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: arnd, arm, linux-arm-kernel, robh+dt, gregkh, jslaby,
	linux-unisoc, afaerber, linux-kernel, devicetree, linux-serial,
	amit.kucheria, linus.walleij, zhao_steven
In-Reply-To: <20181218150238.23010-1-manivannan.sadhasivam@linaro.org>

On Tue, Dec 18, 2018 at 08:32:27PM +0530, Manivannan Sadhasivam wrote:
> Hello Maintainers,
> 
> This patch series adds initial RDA8810PL SoC and Orange Pi boards (2G IoT and
> i96) support. RDA8810PL is an ARM Cortex A5 based SoC with Vivante's GC860
> GPU. The SoC has been added as a new ARM sub architecture with myself as the
> maintainer.
> 
> More information about the boards can be found in below links:
> 
> 1. Orange Pi 2G-IoT - http://www.orangepi.org/OrangePi2GIOT/
> 2. Orange Pi i96 - https://www.96boards.org/product/orangepi-i96/
> 
> All patches are reviewed by the corresponding subsystem maintainers. The
> clocksource and irqchip patches are reviewed and merged while the serial
> driver got review from Greg but I'm not sure who will apply it.
> 
> So as per my discussion with Arnd, sending the individual patches instead
> of a Pull request so that the rest of the patches can go through the
> ARM SoC tree.
> 
> Please consider applying it.

Hi,

I've applied this series to our next/late branch. It's a branch we'll try to
get merged by the end of the merge window, but it's not a guarantee that we'll
be able to get it done. If not, the material will be moved to the next release
instead.


Thanks!


-Olof

^ permalink raw reply

* Re: [PATCH v7 00/11] Add initial RDA8810PL SoC and Orange Pi boards support
From: Manivannan Sadhasivam @ 2019-01-01  3:02 UTC (permalink / raw)
  To: Olof Johansson
  Cc: devicetree, arm, arnd, gregkh, linus.walleij, linux-kernel,
	amit.kucheria, linux-unisoc, robh+dt, linux-serial, jslaby,
	afaerber, linux-arm-kernel, zhao_steven
In-Reply-To: <20181231211342.ulg4jytermffqi34@localhost>

Hi Olof,

On Mon, Dec 31, 2018 at 01:13:42PM -0800, Olof Johansson wrote:
> On Tue, Dec 18, 2018 at 08:32:27PM +0530, Manivannan Sadhasivam wrote:
> > Hello Maintainers,
> > 
> > This patch series adds initial RDA8810PL SoC and Orange Pi boards (2G IoT and
> > i96) support. RDA8810PL is an ARM Cortex A5 based SoC with Vivante's GC860
> > GPU. The SoC has been added as a new ARM sub architecture with myself as the
> > maintainer.
> > 
> > More information about the boards can be found in below links:
> > 
> > 1. Orange Pi 2G-IoT - http://www.orangepi.org/OrangePi2GIOT/
> > 2. Orange Pi i96 - https://www.96boards.org/product/orangepi-i96/
> > 
> > All patches are reviewed by the corresponding subsystem maintainers. The
> > clocksource and irqchip patches are reviewed and merged while the serial
> > driver got review from Greg but I'm not sure who will apply it.
> > 
> > So as per my discussion with Arnd, sending the individual patches instead
> > of a Pull request so that the rest of the patches can go through the
> > ARM SoC tree.
> > 
> > Please consider applying it.
> 
> Hi,
> 
> I've applied this series to our next/late branch. It's a branch we'll try to
> get merged by the end of the merge window, but it's not a guarantee that we'll
> be able to get it done. If not, the material will be moved to the next release
> instead.
>

Okay, thanks for the update!

Regards,
Mani

> 
> Thanks!
> 
> 
> -Olof

^ permalink raw reply

* [PATCH v9 0/2] add uart DMA function
From: Long Cheng @ 2019-01-02  2:12 UTC (permalink / raw)
  To: Vinod Koul, Randy Dunlap, Rob Herring, Mark Rutland, Ryder Lee,
	Sean Wang, Nicolas Boichat
  Cc: Zhenbao Liu, devicetree, YT Shen, srv_heupstream,
	Greg Kroah-Hartman, Sean Wang, linux-kernel, dmaengine,
	Long Cheng, linux-mediatek, linux-serial, Jiri Slaby,
	Matthias Brugger, Yingjoe Chen, Dan Williams, linux-arm-kernel

In Mediatek SOCs, the uart can support DMA function.
Base on DMA engine formwork, we add the DMA code to support uart. And put the code under drivers/dma.

This series contains document bindings, Kconfig to control the function enable or not,
device tree including interrupt and dma device node, the code of UART DMA

Changes compared to v8
-revise missing items
Changes compared to v7:
-modify apdma uart tx
Changes compared to v6:
-Correct spelling
Changes compared to v5:
-move 'requst irqs' to alloc channel
-remove tasklet.
Changes compared to v4:
-modify Kconfig depends on.
Changes compared to v3:
-fix CONFIG_PM, will cause build fail
Changes compared to v2:
-remove unimportant parameters
-instead of cookie, use APIs of virtual channel.
-use of_dma_xlate_by_chan_id.
Changes compared to v1:
-mian revised file, 8250_mtk_dma.c
--parameters renamed for standard
--remove atomic operation

^ permalink raw reply

* [PATCH v9 1/2] dmaengine: 8250_mtk_dma: add MediaTek uart DMA support
From: Long Cheng @ 2019-01-02  2:12 UTC (permalink / raw)
  To: Vinod Koul, Randy Dunlap, Rob Herring, Mark Rutland, Ryder Lee,
	Sean Wang, Nicolas Boichat
  Cc: Matthias Brugger, Dan Williams, Greg Kroah-Hartman, Jiri Slaby,
	Sean Wang, dmaengine, devicetree, linux-arm-kernel,
	linux-mediatek, linux-kernel, linux-serial, srv_heupstream,
	Yingjoe Chen, YT Shen, Zhenbao Liu, Long Cheng
In-Reply-To: <1546395178-8880-1-git-send-email-long.cheng@mediatek.com>

In DMA engine framework, add 8250 uart dma to support MediaTek uart.
If MediaTek uart enabled(SERIAL_8250_MT6577), and want to improve
the performance, can enable the function.

Signed-off-by: Long Cheng <long.cheng@mediatek.com>
---
 drivers/dma/mediatek/8250_mtk_dma.c |  652 +++++++++++++++++++++++++++++++++++
 drivers/dma/mediatek/Kconfig        |   11 +
 drivers/dma/mediatek/Makefile       |    1 +
 3 files changed, 664 insertions(+)
 create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c

diff --git a/drivers/dma/mediatek/8250_mtk_dma.c b/drivers/dma/mediatek/8250_mtk_dma.c
new file mode 100644
index 0000000..dbf811e
--- /dev/null
+++ b/drivers/dma/mediatek/8250_mtk_dma.c
@@ -0,0 +1,652 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek 8250 DMA driver.
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Long Cheng <long.cheng@mediatek.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_dma.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#include "../virt-dma.h"
+
+#define MTK_UART_APDMA_CHANNELS		(CONFIG_SERIAL_8250_NR_UARTS * 2)
+
+#define VFF_EN_B		BIT(0)
+#define VFF_STOP_B		BIT(0)
+#define VFF_FLUSH_B		BIT(0)
+#define VFF_4G_SUPPORT_B	BIT(0)
+#define VFF_RX_INT_EN0_B	BIT(0)	/*rx valid size >=  vff thre*/
+#define VFF_RX_INT_EN1_B	BIT(1)
+#define VFF_TX_INT_EN_B		BIT(0)	/*tx left size >= vff thre*/
+#define VFF_WARM_RST_B		BIT(0)
+#define VFF_RX_INT_FLAG_CLR_B	(BIT(0) | BIT(1))
+#define VFF_TX_INT_FLAG_CLR_B	0
+#define VFF_STOP_CLR_B		0
+#define VFF_INT_EN_CLR_B	0
+#define VFF_4G_SUPPORT_CLR_B	0
+
+/* interrupt trigger level for tx */
+#define VFF_TX_THRE(n)		((n) * 7 / 8)
+/* interrupt trigger level for rx */
+#define VFF_RX_THRE(n)		((n) * 3 / 4)
+
+#define VFF_RING_SIZE	0xffffU
+/* invert this bit when wrap ring head again*/
+#define VFF_RING_WRAP	0x10000U
+
+#define VFF_INT_FLAG		0x00
+#define VFF_INT_EN		0x04
+#define VFF_EN			0x08
+#define VFF_RST			0x0c
+#define VFF_STOP		0x10
+#define VFF_FLUSH		0x14
+#define VFF_ADDR		0x1c
+#define VFF_LEN			0x24
+#define VFF_THRE		0x28
+#define VFF_WPT			0x2c
+#define VFF_RPT			0x30
+/*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_irq[MTK_UART_APDMA_CHANNELS];
+};
+
+struct mtk_uart_apdma_desc {
+	struct virt_dma_desc vd;
+
+	unsigned int avail_len;
+};
+
+struct mtk_chan {
+	struct virt_dma_chan vc;
+	struct dma_slave_config	cfg;
+	void __iomem *base;
+	struct mtk_uart_apdma_desc *desc;
+
+	bool requested;
+
+	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 void mtk_uart_apdma_write(struct mtk_chan *c,
+			       unsigned int reg, unsigned int val)
+{
+	writel(val, c->base + reg);
+}
+
+static unsigned int mtk_uart_apdma_read(struct mtk_chan *c, unsigned int reg)
+{
+	return readl(c->base + reg);
+}
+
+static void mtk_uart_apdma_desc_free(struct virt_dma_desc *vd)
+{
+	struct dma_chan *chan = vd->tx.chan;
+	struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
+
+	kfree(c->desc);
+}
+
+static void mtk_uart_apdma_start_tx(struct mtk_chan *c)
+{
+	unsigned int len, send, left, wpt, d_wpt, tmp;
+	int ret;
+
+	left = mtk_uart_apdma_read(c, VFF_LEFT_SIZE);
+	if (!left) {
+		mtk_uart_apdma_write(c, VFF_INT_EN, VFF_TX_INT_EN_B);
+		return;
+	}
+
+	/* Wait 1sec for flush,  can't sleep*/
+	ret = readx_poll_timeout(readl, c->base + VFF_FLUSH, tmp,
+			tmp != VFF_FLUSH_B, 0, 1000000);
+	if (ret)
+		dev_warn(c->vc.chan.device->dev, "tx: fail, debug=0x%x\n",
+			mtk_uart_apdma_read(c, VFF_DEBUG_STATUS));
+
+	send = min_t(unsigned int, left, c->desc->avail_len);
+	wpt = mtk_uart_apdma_read(c, VFF_WPT);
+	len = mtk_uart_apdma_read(c, VFF_LEN);
+
+	d_wpt = wpt + send;
+	if ((d_wpt & VFF_RING_SIZE) >= len) {
+		d_wpt = d_wpt - len;
+		d_wpt = d_wpt ^ VFF_RING_WRAP;
+	}
+	mtk_uart_apdma_write(c, VFF_WPT, d_wpt);
+
+	c->desc->avail_len -= send;
+
+	mtk_uart_apdma_write(c, VFF_INT_EN, VFF_TX_INT_EN_B);
+	if (mtk_uart_apdma_read(c, VFF_FLUSH) == 0U)
+		mtk_uart_apdma_write(c, VFF_FLUSH, VFF_FLUSH_B);
+}
+
+static void mtk_uart_apdma_start_rx(struct mtk_chan *c)
+{
+	struct mtk_uart_apdma_desc *d = c->desc;
+	unsigned int len, wg, rg, cnt;
+
+	if ((mtk_uart_apdma_read(c, VFF_VALID_SIZE) == 0U) ||
+		!d || !vchan_next_desc(&c->vc))
+		return;
+
+	len = mtk_uart_apdma_read(c, VFF_LEN);
+	rg = mtk_uart_apdma_read(c, VFF_RPT);
+	wg = mtk_uart_apdma_read(c, VFF_WPT);
+	if ((rg ^ wg) & VFF_RING_WRAP)
+		cnt = (wg & VFF_RING_SIZE) + len - (rg & VFF_RING_SIZE);
+	else
+		cnt = (wg & VFF_RING_SIZE) - (rg & VFF_RING_SIZE);
+
+	c->rx_status = cnt;
+	mtk_uart_apdma_write(c, VFF_RPT, wg);
+
+	list_del(&d->vd.node);
+	vchan_cookie_complete(&d->vd);
+}
+
+static irqreturn_t mtk_uart_apdma_irq_handler(int irq, void *dev_id)
+{
+	struct dma_chan *chan = (struct dma_chan *)dev_id;
+	struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
+	struct mtk_uart_apdma_desc *d;
+	unsigned long flags;
+
+	spin_lock_irqsave(&c->vc.lock, flags);
+	if (c->cfg.direction == DMA_DEV_TO_MEM) {
+		mtk_uart_apdma_write(c, VFF_INT_FLAG, VFF_RX_INT_FLAG_CLR_B);
+		mtk_uart_apdma_start_rx(c);
+	} else if (c->cfg.direction == DMA_MEM_TO_DEV) {
+		d = c->desc;
+
+		mtk_uart_apdma_write(c, VFF_INT_FLAG, VFF_TX_INT_FLAG_CLR_B);
+
+		if (d->avail_len != 0U) {
+			mtk_uart_apdma_start_tx(c);
+		} else {
+			list_del(&d->vd.node);
+			vchan_cookie_complete(&d->vd);
+		}
+	}
+	spin_unlock_irqrestore(&c->vc.lock, flags);
+
+	return IRQ_HANDLED;
+}
+
+static int mtk_uart_apdma_alloc_chan_resources(struct dma_chan *chan)
+{
+	struct mtk_uart_apdmadev *mtkd = to_mtk_uart_apdma_dev(chan->device);
+	struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
+	u32 tmp;
+	int ret;
+
+	pm_runtime_get_sync(mtkd->ddev.dev);
+
+	mtk_uart_apdma_write(c, VFF_ADDR, 0);
+	mtk_uart_apdma_write(c, VFF_THRE, 0);
+	mtk_uart_apdma_write(c, VFF_LEN, 0);
+	mtk_uart_apdma_write(c, VFF_RST, VFF_WARM_RST_B);
+
+	ret = readx_poll_timeout(readl, c->base + VFF_EN, tmp,
+			tmp == 0, 10, 100);
+	if (ret) {
+		dev_err(chan->device->dev, "dma reset: fail, timeout\n");
+		return ret;
+	}
+
+	if (!c->requested) {
+		c->requested = true;
+		ret = request_irq(mtkd->dma_irq[chan->chan_id],
+				  mtk_uart_apdma_irq_handler, IRQF_TRIGGER_NONE,
+				  KBUILD_MODNAME, chan);
+		if (ret < 0) {
+			dev_err(chan->device->dev, "Can't request dma IRQ\n");
+			return -EINVAL;
+		}
+	}
+
+	if (mtkd->support_33bits)
+		mtk_uart_apdma_write(c, VFF_4G_SUPPORT, VFF_4G_SUPPORT_CLR_B);
+
+	return ret;
+}
+
+static void mtk_uart_apdma_free_chan_resources(struct dma_chan *chan)
+{
+	struct mtk_uart_apdmadev *mtkd = to_mtk_uart_apdma_dev(chan->device);
+	struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
+
+	if (c->requested) {
+		c->requested = false;
+		free_irq(mtkd->dma_irq[chan->chan_id], chan);
+	}
+
+	tasklet_kill(&c->vc.task);
+
+	vchan_free_chan_resources(&c->vc);
+
+	pm_runtime_put_sync(mtkd->ddev.dev);
+}
+
+static enum dma_status mtk_uart_apdma_tx_status(struct dma_chan *chan,
+					 dma_cookie_t cookie,
+					 struct dma_tx_state *txstate)
+{
+	struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
+	enum dma_status ret;
+	unsigned long flags;
+
+	if (!txstate)
+		return DMA_ERROR;
+
+	ret = dma_cookie_status(chan, cookie, txstate);
+	spin_lock_irqsave(&c->vc.lock, flags);
+	if (ret == DMA_IN_PROGRESS) {
+		c->rx_status = mtk_uart_apdma_read(c, VFF_RPT) & VFF_RING_SIZE;
+		dma_set_residue(txstate, c->rx_status);
+	} else if (ret == DMA_COMPLETE && c->cfg.direction == DMA_DEV_TO_MEM) {
+		dma_set_residue(txstate, c->rx_status);
+	} else {
+		dma_set_residue(txstate, 0);
+	}
+	spin_unlock_irqrestore(&c->vc.lock, flags);
+
+	return ret;
+}
+
+/*
+ * dmaengine_prep_slave_single will call the function. and sglen is 1.
+ * 8250 uart using one ring buffer, and deal with one sg.
+ */
+static struct dma_async_tx_descriptor *mtk_uart_apdma_prep_slave_sg
+	(struct dma_chan *chan, struct scatterlist *sgl,
+	unsigned int sglen, enum dma_transfer_direction dir,
+	unsigned long tx_flags, void *context)
+{
+	struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
+	struct mtk_uart_apdma_desc *d;
+
+	if ((dir != DMA_DEV_TO_MEM) &&
+		(dir != DMA_MEM_TO_DEV)) {
+		dev_err(chan->device->dev, "bad direction\n");
+		return NULL;
+	}
+
+	/* Now allocate and setup the descriptor */
+	d = kzalloc(sizeof(*d), GFP_ATOMIC);
+	if (!d)
+		return NULL;
+
+	/* sglen is 1 */
+	d->avail_len = sg_dma_len(sgl);
+
+	return vchan_tx_prep(&c->vc, &d->vd, tx_flags);
+}
+
+static void mtk_uart_apdma_issue_pending(struct dma_chan *chan)
+{
+	struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
+	struct virt_dma_desc *vd;
+	unsigned long flags;
+
+	spin_lock_irqsave(&c->vc.lock, flags);
+	if (c->cfg.direction == DMA_DEV_TO_MEM) {
+		if (vchan_issue_pending(&c->vc)) {
+			vd = vchan_next_desc(&c->vc);
+			c->desc = to_mtk_uart_apdma_desc(&vd->tx);
+			mtk_uart_apdma_start_rx(c);
+		}
+	} else if (c->cfg.direction == DMA_MEM_TO_DEV) {
+		if (vchan_issue_pending(&c->vc)) {
+			vd = vchan_next_desc(&c->vc);
+			c->desc = to_mtk_uart_apdma_desc(&vd->tx);
+			mtk_uart_apdma_start_tx(c);
+		}
+	}
+	spin_unlock_irqrestore(&c->vc.lock, flags);
+}
+
+static int mtk_uart_apdma_slave_config(struct dma_chan *chan,
+				struct dma_slave_config *cfg)
+{
+	struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
+	struct mtk_uart_apdmadev *mtkd =
+				to_mtk_uart_apdma_dev(c->vc.chan.device);
+
+	c->cfg = *cfg;
+
+	if (cfg->direction == DMA_DEV_TO_MEM) {
+		unsigned int rx_len = cfg->src_addr_width * 1024;
+
+		mtk_uart_apdma_write(c, VFF_ADDR, cfg->src_addr);
+		mtk_uart_apdma_write(c, VFF_LEN, rx_len);
+		mtk_uart_apdma_write(c, VFF_THRE, VFF_RX_THRE(rx_len));
+		mtk_uart_apdma_write(c, VFF_INT_EN,
+				VFF_RX_INT_EN0_B | VFF_RX_INT_EN1_B);
+		mtk_uart_apdma_write(c, VFF_RPT, 0);
+		mtk_uart_apdma_write(c, VFF_INT_FLAG, VFF_RX_INT_FLAG_CLR_B);
+		mtk_uart_apdma_write(c, VFF_EN, VFF_EN_B);
+	} else if (cfg->direction == DMA_MEM_TO_DEV)	{
+		unsigned int tx_len = cfg->dst_addr_width * 1024;
+
+		mtk_uart_apdma_write(c, VFF_ADDR, cfg->dst_addr);
+		mtk_uart_apdma_write(c, VFF_LEN, tx_len);
+		mtk_uart_apdma_write(c, VFF_THRE, VFF_TX_THRE(tx_len));
+		mtk_uart_apdma_write(c, VFF_WPT, 0);
+		mtk_uart_apdma_write(c, VFF_INT_FLAG, VFF_TX_INT_FLAG_CLR_B);
+		mtk_uart_apdma_write(c, VFF_EN, VFF_EN_B);
+	}
+
+	if (mtkd->support_33bits)
+		mtk_uart_apdma_write(c, VFF_4G_SUPPORT, VFF_4G_SUPPORT_B);
+
+	if (mtk_uart_apdma_read(c, VFF_EN) != VFF_EN_B) {
+		dev_err(chan->device->dev, "dir[%d] fail\n", cfg->direction);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int mtk_uart_apdma_terminate_all(struct dma_chan *chan)
+{
+	struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
+	unsigned long flags;
+	u32 tmp;
+	int ret;
+
+	spin_lock_irqsave(&c->vc.lock, flags);
+
+	mtk_uart_apdma_write(c, VFF_FLUSH, VFF_FLUSH_B);
+	/* Wait 1sec for flush,  can't sleep*/
+	ret = readx_poll_timeout(readl, c->base + VFF_FLUSH, tmp,
+			tmp != VFF_FLUSH_B, 0, 1000000);
+	if (ret)
+		dev_err(c->vc.chan.device->dev, "flush: fail, debug=0x%x\n",
+			mtk_uart_apdma_read(c, VFF_DEBUG_STATUS));
+
+	/*set stop as 1 -> wait until en is 0 -> set stop as 0*/
+	mtk_uart_apdma_write(c, VFF_STOP, VFF_STOP_B);
+	ret = readx_poll_timeout(readl, c->base + VFF_EN, tmp,
+			tmp == 0, 10, 100);
+	if (ret)
+		dev_err(c->vc.chan.device->dev, "stop: fail, debug=0x%x\n",
+			mtk_uart_apdma_read(c, VFF_DEBUG_STATUS));
+
+	mtk_uart_apdma_write(c, VFF_STOP, VFF_STOP_CLR_B);
+	mtk_uart_apdma_write(c, VFF_INT_EN, VFF_INT_EN_CLR_B);
+
+	if (c->cfg.direction == DMA_DEV_TO_MEM)
+		mtk_uart_apdma_write(c, VFF_INT_FLAG, VFF_RX_INT_FLAG_CLR_B);
+	else if (c->cfg.direction == DMA_MEM_TO_DEV)
+		mtk_uart_apdma_write(c, VFF_INT_FLAG, VFF_TX_INT_FLAG_CLR_B);
+
+	spin_unlock_irqrestore(&c->vc.lock, flags);
+
+	return 0;
+}
+
+static int mtk_uart_apdma_device_pause(struct dma_chan *chan)
+{
+	/* just for check caps pass */
+	return 0;
+}
+
+static int mtk_uart_apdma_device_resume(struct dma_chan *chan)
+{
+	/* just for check caps pass */
+	return 0;
+}
+
+static void mtk_uart_apdma_free(struct mtk_uart_apdmadev *mtkd)
+{
+	while (list_empty(&mtkd->ddev.channels) == 0) {
+		struct mtk_chan *c = list_first_entry(&mtkd->ddev.channels,
+			struct mtk_chan, vc.chan.device_node);
+
+		list_del(&c->vc.chan.device_node);
+		tasklet_kill(&c->vc.task);
+	}
+}
+
+static const struct of_device_id mtk_uart_apdma_match[] = {
+	{ .compatible = "mediatek,mt6577-uart-dma", },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mtk_uart_apdma_match);
+
+static int mtk_uart_apdma_probe(struct platform_device *pdev)
+{
+	struct mtk_uart_apdmadev *mtkd;
+	struct resource *res;
+	struct mtk_chan *c;
+	unsigned int i;
+	int rc;
+
+	mtkd = devm_kzalloc(&pdev->dev, sizeof(*mtkd), GFP_KERNEL);
+	if (!mtkd)
+		return -ENOMEM;
+
+	mtkd->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(mtkd->clk)) {
+		dev_err(&pdev->dev, "No clock specified\n");
+		rc = PTR_ERR(mtkd->clk);
+		return rc;
+	}
+
+	if (of_property_read_bool(pdev->dev.of_node, "dma-33bits"))
+		mtkd->support_33bits = true;
+
+	rc = dma_set_mask_and_coherent(&pdev->dev,
+				DMA_BIT_MASK(32 | mtkd->support_33bits));
+	if (rc)
+		return rc;
+
+	dma_cap_set(DMA_SLAVE, mtkd->ddev.cap_mask);
+	mtkd->ddev.device_alloc_chan_resources =
+				mtk_uart_apdma_alloc_chan_resources;
+	mtkd->ddev.device_free_chan_resources =
+				mtk_uart_apdma_free_chan_resources;
+	mtkd->ddev.device_tx_status = mtk_uart_apdma_tx_status;
+	mtkd->ddev.device_issue_pending = mtk_uart_apdma_issue_pending;
+	mtkd->ddev.device_prep_slave_sg = mtk_uart_apdma_prep_slave_sg;
+	mtkd->ddev.device_config = mtk_uart_apdma_slave_config;
+	mtkd->ddev.device_pause = mtk_uart_apdma_device_pause;
+	mtkd->ddev.device_resume = mtk_uart_apdma_device_resume;
+	mtkd->ddev.device_terminate_all = mtk_uart_apdma_terminate_all;
+	mtkd->ddev.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE);
+	mtkd->ddev.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE);
+	mtkd->ddev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
+	mtkd->ddev.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT;
+	mtkd->ddev.dev = &pdev->dev;
+	INIT_LIST_HEAD(&mtkd->ddev.channels);
+
+	for (i = 0; i < MTK_UART_APDMA_CHANNELS; i++) {
+		c = devm_kzalloc(mtkd->ddev.dev, sizeof(*c), GFP_KERNEL);
+		if (!c) {
+			rc = -ENODEV;
+			goto err_no_dma;
+		}
+
+		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+		if (!res) {
+			rc = -ENODEV;
+			goto err_no_dma;
+		}
+
+		c->base = devm_ioremap_resource(&pdev->dev, res);
+		if (IS_ERR(c->base)) {
+			rc = PTR_ERR(c->base);
+			goto err_no_dma;
+		}
+		c->requested = false;
+		c->vc.desc_free = mtk_uart_apdma_desc_free;
+		vchan_init(&c->vc, &mtkd->ddev);
+
+		mtkd->dma_irq[i] = platform_get_irq(pdev, i);
+		if ((int)mtkd->dma_irq[i] < 0) {
+			dev_err(&pdev->dev, "failed to get IRQ[%d]\n", i);
+			rc = -EINVAL;
+			goto err_no_dma;
+		}
+	}
+
+	pm_runtime_enable(&pdev->dev);
+	pm_runtime_set_active(&pdev->dev);
+
+	rc = dma_async_device_register(&mtkd->ddev);
+	if (rc)
+		goto rpm_disable;
+
+	platform_set_drvdata(pdev, mtkd);
+
+	if (pdev->dev.of_node) {
+		/* Device-tree DMA controller registration */
+		rc = of_dma_controller_register(pdev->dev.of_node,
+						of_dma_xlate_by_chan_id,
+						mtkd);
+		if (rc)
+			goto dma_remove;
+	}
+
+	return rc;
+
+dma_remove:
+	dma_async_device_unregister(&mtkd->ddev);
+rpm_disable:
+	pm_runtime_disable(&pdev->dev);
+err_no_dma:
+	mtk_uart_apdma_free(mtkd);
+	return rc;
+}
+
+static int mtk_uart_apdma_remove(struct platform_device *pdev)
+{
+	struct mtk_uart_apdmadev *mtkd = platform_get_drvdata(pdev);
+
+	if (pdev->dev.of_node)
+		of_dma_controller_free(pdev->dev.of_node);
+
+	pm_runtime_disable(&pdev->dev);
+	pm_runtime_put_noidle(&pdev->dev);
+
+	dma_async_device_unregister(&mtkd->ddev);
+	mtk_uart_apdma_free(mtkd);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int mtk_uart_apdma_suspend(struct device *dev)
+{
+	struct mtk_uart_apdmadev *mtkd = dev_get_drvdata(dev);
+
+	if (!pm_runtime_suspended(dev))
+		clk_disable_unprepare(mtkd->clk);
+
+	return 0;
+}
+
+static int mtk_uart_apdma_resume(struct device *dev)
+{
+	int ret;
+	struct mtk_uart_apdmadev *mtkd = dev_get_drvdata(dev);
+
+	if (!pm_runtime_suspended(dev)) {
+		ret = clk_prepare_enable(mtkd->clk);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+#ifdef CONFIG_PM
+static int mtk_uart_apdma_runtime_suspend(struct device *dev)
+{
+	struct mtk_uart_apdmadev *mtkd = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(mtkd->clk);
+
+	return 0;
+}
+
+static int mtk_uart_apdma_runtime_resume(struct device *dev)
+{
+	int ret;
+	struct mtk_uart_apdmadev *mtkd = dev_get_drvdata(dev);
+
+	ret = clk_prepare_enable(mtkd->clk);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+#endif /* CONFIG_PM */
+
+static const struct dev_pm_ops mtk_uart_apdma_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(mtk_uart_apdma_suspend, mtk_uart_apdma_resume)
+	SET_RUNTIME_PM_OPS(mtk_uart_apdma_runtime_suspend,
+			   mtk_uart_apdma_runtime_resume, NULL)
+};
+
+static struct platform_driver mtk_uart_apdma_driver = {
+	.probe	= mtk_uart_apdma_probe,
+	.remove	= mtk_uart_apdma_remove,
+	.driver = {
+		.name		= KBUILD_MODNAME,
+		.pm		= &mtk_uart_apdma_pm_ops,
+		.of_match_table = of_match_ptr(mtk_uart_apdma_match),
+	},
+};
+
+module_platform_driver(mtk_uart_apdma_driver);
+
+MODULE_DESCRIPTION("MediaTek UART APDMA Controller Driver");
+MODULE_AUTHOR("Long Cheng <long.cheng@mediatek.com>");
+MODULE_LICENSE("GPL v2");
+
diff --git a/drivers/dma/mediatek/Kconfig b/drivers/dma/mediatek/Kconfig
index 27bac0b..1a523c87 100644
--- a/drivers/dma/mediatek/Kconfig
+++ b/drivers/dma/mediatek/Kconfig
@@ -1,4 +1,15 @@
 
+config DMA_MTK_UART
+	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.
+
 config MTK_HSDMA
 	tristate "MediaTek High-Speed DMA controller support"
 	depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/dma/mediatek/Makefile b/drivers/dma/mediatek/Makefile
index 6e778f8..2f2efd9 100644
--- a/drivers/dma/mediatek/Makefile
+++ b/drivers/dma/mediatek/Makefile
@@ -1 +1,2 @@
+obj-$(CONFIG_DMA_MTK_UART) += 8250_mtk_dma.o
 obj-$(CONFIG_MTK_HSDMA) += mtk-hsdma.o
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v9 2/2] arm: dts: mt2712: add uart APDMA to device tree
From: Long Cheng @ 2019-01-02  2:12 UTC (permalink / raw)
  To: Vinod Koul, Randy Dunlap, Rob Herring, Mark Rutland, Ryder Lee,
	Sean Wang, Nicolas Boichat
  Cc: Zhenbao Liu, devicetree-u79uwXL29TY76Z2rM5mHXA,
	srv_heupstream-NuS5LvNUpcJWk0Htik3J/w, Greg Kroah-Hartman,
	Sean Wang, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	dmaengine-u79uwXL29TY76Z2rM5mHXA, Long Cheng,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-serial-u79uwXL29TY76Z2rM5mHXA, Jiri Slaby, Matthias Brugger,
	Yingjoe Chen, Dan Williams,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1546395178-8880-1-git-send-email-long.cheng-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>

1. add uart APDMA controller device node
2. add uart 0/1/2/3/4/5 DMA function

Signed-off-by: Long Cheng <long.cheng-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
---
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi |   50 +++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
index 976d92a..be1a22a 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -300,6 +300,9 @@
 		interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_LOW>;
 		clocks = <&baud_clk>, <&sys_clk>;
 		clock-names = "baud", "bus";
+		dmas = <&apdma 10
+			&apdma 11>;
+		dma-names = "tx", "rx";
 		status = "disabled";
 	};
 
@@ -369,6 +372,38 @@
 			 (GIC_CPU_MASK_RAW(0x13) | IRQ_TYPE_LEVEL_HIGH)>;
 	};
 
+	apdma: dma-controller@11000400 {
+		compatible = "mediatek,mt2712-uart-dma",
+			     "mediatek,mt6577-uart-dma";
+		reg = <0 0x11000400 0 0x80>,
+		      <0 0x11000480 0 0x80>,
+		      <0 0x11000500 0 0x80>,
+		      <0 0x11000580 0 0x80>,
+		      <0 0x11000600 0 0x80>,
+		      <0 0x11000680 0 0x80>,
+		      <0 0x11000700 0 0x80>,
+		      <0 0x11000780 0 0x80>,
+		      <0 0x11000800 0 0x80>,
+		      <0 0x11000880 0 0x80>,
+		      <0 0x11000900 0 0x80>,
+		      <0 0x11000980 0 0x80>;
+		interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_SPI 104 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_SPI 105 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_SPI 106 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_SPI 107 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_SPI 108 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_SPI 109 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_SPI 111 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_SPI 112 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_SPI 113 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_SPI 114 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&pericfg CLK_PERI_AP_DMA>;
+		clock-names = "apdma";
+		#dma-cells = <1>;
+	};
+
 	auxadc: adc@11001000 {
 		compatible = "mediatek,mt2712-auxadc";
 		reg = <0 0x11001000 0 0x1000>;
@@ -385,6 +420,9 @@
 		interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>;
 		clocks = <&baud_clk>, <&sys_clk>;
 		clock-names = "baud", "bus";
+		dmas = <&apdma 0
+			&apdma 1>;
+		dma-names = "tx", "rx";
 		status = "disabled";
 	};
 
@@ -395,6 +433,9 @@
 		interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_LOW>;
 		clocks = <&baud_clk>, <&sys_clk>;
 		clock-names = "baud", "bus";
+		dmas = <&apdma 2
+			&apdma 3>;
+		dma-names = "tx", "rx";
 		status = "disabled";
 	};
 
@@ -405,6 +446,9 @@
 		interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_LOW>;
 		clocks = <&baud_clk>, <&sys_clk>;
 		clock-names = "baud", "bus";
+		dmas = <&apdma 4
+			&apdma 5>;
+		dma-names = "tx", "rx";
 		status = "disabled";
 	};
 
@@ -415,6 +459,9 @@
 		interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_LOW>;
 		clocks = <&baud_clk>, <&sys_clk>;
 		clock-names = "baud", "bus";
+		dmas = <&apdma 6
+			&apdma 7>;
+		dma-names = "tx", "rx";
 		status = "disabled";
 	};
 
@@ -629,6 +676,9 @@
 		interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_LOW>;
 		clocks = <&baud_clk>, <&sys_clk>;
 		clock-names = "baud", "bus";
+		dmas = <&apdma 8
+			&apdma 9>;
+		dma-names = "tx", "rx";
 		status = "disabled";
 	};
 
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 0/4] tty: serial: qcom_geni_serial: Assorted cleanups
From: Ryan Case @ 2019-01-02 21:36 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Evan Green, Doug Anderson, linux-kernel, linux-serial,
	Stephen Boyd, Ryan Case


This is a series of cleanups for issues raised in prior reviews that
were unrelated to the patches at hand.


Ryan Case (4):
  tty: serial: qcom_geni_serial: Remove use of *_relaxed() and mb()
  tty: serial: qcom_geni_serial: Remove set_rfr_wm() and related
    variables
  tty: serial: qcom_geni_serial: Remove xfer_mode variable
  tty: serial: qcom_geni_serial: Use u32 for register variables

 drivers/tty/serial/qcom_geni_serial.c | 270 ++++++++++----------------
 1 file changed, 104 insertions(+), 166 deletions(-)

-- 
2.20.1.415.g653613c723-goog

^ permalink raw reply

* [PATCH 1/4] tty: serial: qcom_geni_serial: Remove use of *_relaxed() and mb()
From: Ryan Case @ 2019-01-02 21:36 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Evan Green, Doug Anderson, linux-kernel, linux-serial,
	Stephen Boyd, Ryan Case
In-Reply-To: <20190102213636.40866-1-ryandcase@chromium.org>

A frequent side comment has been to remove the use of writel_relaxed,
readl_relaxed, and mb.

Signed-off-by: Ryan Case <ryandcase@chromium.org>
---

 drivers/tty/serial/qcom_geni_serial.c | 187 +++++++++++---------------
 1 file changed, 80 insertions(+), 107 deletions(-)

diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index 2b1e73193dad..dc95b96148ed 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -230,7 +230,7 @@ static unsigned int qcom_geni_serial_get_mctrl(struct uart_port *uport)
 	if (uart_console(uport) || !uart_cts_enabled(uport)) {
 		mctrl |= TIOCM_CTS;
 	} else {
-		geni_ios = readl_relaxed(uport->membase + SE_GENI_IOS);
+		geni_ios = readl(uport->membase + SE_GENI_IOS);
 		if (!(geni_ios & IO2_DATA_IN))
 			mctrl |= TIOCM_CTS;
 	}
@@ -248,7 +248,7 @@ static void qcom_geni_serial_set_mctrl(struct uart_port *uport,
 
 	if (!(mctrl & TIOCM_RTS))
 		uart_manual_rfr = UART_MANUAL_RFR_EN | UART_RFR_NOT_READY;
-	writel_relaxed(uart_manual_rfr, uport->membase + SE_UART_MANUAL_RFR);
+	writel(uart_manual_rfr, uport->membase + SE_UART_MANUAL_RFR);
 }
 
 static const char *qcom_geni_serial_get_type(struct uart_port *uport)
@@ -277,9 +277,6 @@ static bool qcom_geni_serial_poll_bit(struct uart_port *uport,
 	unsigned int fifo_bits;
 	unsigned long timeout_us = 20000;
 
-	/* Ensure polling is not re-ordered before the prior writes/reads */
-	mb();
-
 	if (uport->private_data) {
 		port = to_dev_port(uport, uport);
 		baud = port->baud;
@@ -299,7 +296,7 @@ static bool qcom_geni_serial_poll_bit(struct uart_port *uport,
 	 */
 	timeout_us = DIV_ROUND_UP(timeout_us, 10) * 10;
 	while (timeout_us) {
-		reg = readl_relaxed(uport->membase + offset);
+		reg = readl(uport->membase + offset);
 		if ((bool)(reg & field) == set)
 			return true;
 		udelay(10);
@@ -312,7 +309,7 @@ static void qcom_geni_serial_setup_tx(struct uart_port *uport, u32 xmit_size)
 {
 	u32 m_cmd;
 
-	writel_relaxed(xmit_size, uport->membase + SE_UART_TX_TRANS_LEN);
+	writel(xmit_size, uport->membase + SE_UART_TX_TRANS_LEN);
 	m_cmd = UART_START_TX << M_OPCODE_SHFT;
 	writel(m_cmd, uport->membase + SE_GENI_M_CMD0);
 }
@@ -325,13 +322,13 @@ static void qcom_geni_serial_poll_tx_done(struct uart_port *uport)
 	done = qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS,
 						M_CMD_DONE_EN, true);
 	if (!done) {
-		writel_relaxed(M_GENI_CMD_ABORT, uport->membase +
+		writel(M_GENI_CMD_ABORT, uport->membase +
 						SE_GENI_M_CMD_CTRL_REG);
 		irq_clear |= M_CMD_ABORT_EN;
 		qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS,
 							M_CMD_ABORT_EN, true);
 	}
-	writel_relaxed(irq_clear, uport->membase + SE_GENI_M_IRQ_CLEAR);
+	writel(irq_clear, uport->membase + SE_GENI_M_IRQ_CLEAR);
 }
 
 static void qcom_geni_serial_abort_rx(struct uart_port *uport)
@@ -341,8 +338,8 @@ static void qcom_geni_serial_abort_rx(struct uart_port *uport)
 	writel(S_GENI_CMD_ABORT, uport->membase + SE_GENI_S_CMD_CTRL_REG);
 	qcom_geni_serial_poll_bit(uport, SE_GENI_S_CMD_CTRL_REG,
 					S_GENI_CMD_ABORT, false);
-	writel_relaxed(irq_clear, uport->membase + SE_GENI_S_IRQ_CLEAR);
-	writel_relaxed(FORCE_DEFAULT, uport->membase + GENI_FORCE_DEFAULT_REG);
+	writel(irq_clear, uport->membase + SE_GENI_S_IRQ_CLEAR);
+	writel(FORCE_DEFAULT, uport->membase + GENI_FORCE_DEFAULT_REG);
 }
 
 #ifdef CONFIG_CONSOLE_POLL
@@ -351,19 +348,13 @@ static int qcom_geni_serial_get_char(struct uart_port *uport)
 	u32 rx_fifo;
 	u32 status;
 
-	status = readl_relaxed(uport->membase + SE_GENI_M_IRQ_STATUS);
-	writel_relaxed(status, uport->membase + SE_GENI_M_IRQ_CLEAR);
-
-	status = readl_relaxed(uport->membase + SE_GENI_S_IRQ_STATUS);
-	writel_relaxed(status, uport->membase + SE_GENI_S_IRQ_CLEAR);
+	status = readl(uport->membase + SE_GENI_M_IRQ_STATUS);
+	writel(status, uport->membase + SE_GENI_M_IRQ_CLEAR);
 
-	/*
-	 * Ensure the writes to clear interrupts is not re-ordered after
-	 * reading the data.
-	 */
-	mb();
+	status = readl(uport->membase + SE_GENI_S_IRQ_STATUS);
+	writel(status, uport->membase + SE_GENI_S_IRQ_CLEAR);
 
-	status = readl_relaxed(uport->membase + SE_GENI_RX_FIFO_STATUS);
+	status = readl(uport->membase + SE_GENI_RX_FIFO_STATUS);
 	if (!(status & RX_FIFO_WC_MSK))
 		return NO_POLL_CHAR;
 
@@ -376,12 +367,12 @@ static void qcom_geni_serial_poll_put_char(struct uart_port *uport,
 {
 	struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
 
-	writel_relaxed(port->tx_wm, uport->membase + SE_GENI_TX_WATERMARK_REG);
+	writel(port->tx_wm, uport->membase + SE_GENI_TX_WATERMARK_REG);
 	qcom_geni_serial_setup_tx(uport, 1);
 	WARN_ON(!qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS,
 						M_TX_FIFO_WATERMARK_EN, true));
-	writel_relaxed(c, uport->membase + SE_GENI_TX_FIFOn);
-	writel_relaxed(M_TX_FIFO_WATERMARK_EN, uport->membase +
+	writel(c, uport->membase + SE_GENI_TX_FIFOn);
+	writel(M_TX_FIFO_WATERMARK_EN, uport->membase +
 							SE_GENI_M_IRQ_CLEAR);
 	qcom_geni_serial_poll_tx_done(uport);
 }
@@ -390,7 +381,7 @@ static void qcom_geni_serial_poll_put_char(struct uart_port *uport,
 #ifdef CONFIG_SERIAL_QCOM_GENI_CONSOLE
 static void qcom_geni_serial_wr_char(struct uart_port *uport, int ch)
 {
-	writel_relaxed(ch, uport->membase + SE_GENI_TX_FIFOn);
+	writel(ch, uport->membase + SE_GENI_TX_FIFOn);
 }
 
 static void
@@ -409,7 +400,7 @@ __qcom_geni_serial_console_write(struct uart_port *uport, const char *s,
 			bytes_to_send++;
 	}
 
-	writel_relaxed(DEF_TX_WM, uport->membase + SE_GENI_TX_WATERMARK_REG);
+	writel(DEF_TX_WM, uport->membase + SE_GENI_TX_WATERMARK_REG);
 	qcom_geni_serial_setup_tx(uport, bytes_to_send);
 	for (i = 0; i < count; ) {
 		size_t chars_to_write = 0;
@@ -427,7 +418,7 @@ __qcom_geni_serial_console_write(struct uart_port *uport, const char *s,
 		chars_to_write = min_t(size_t, count - i, avail / 2);
 		uart_console_write(uport, s + i, chars_to_write,
 						qcom_geni_serial_wr_char);
-		writel_relaxed(M_TX_FIFO_WATERMARK_EN, uport->membase +
+		writel(M_TX_FIFO_WATERMARK_EN, uport->membase +
 							SE_GENI_M_IRQ_CLEAR);
 		i += chars_to_write;
 	}
@@ -456,7 +447,7 @@ static void qcom_geni_serial_console_write(struct console *co, const char *s,
 	else
 		spin_lock_irqsave(&uport->lock, flags);
 
-	geni_status = readl_relaxed(uport->membase + SE_GENI_STATUS);
+	geni_status = readl(uport->membase + SE_GENI_STATUS);
 
 	/* Cancel the current write to log the fault */
 	if (!locked) {
@@ -466,10 +457,10 @@ static void qcom_geni_serial_console_write(struct console *co, const char *s,
 			geni_se_abort_m_cmd(&port->se);
 			qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS,
 							M_CMD_ABORT_EN, true);
-			writel_relaxed(M_CMD_ABORT_EN, uport->membase +
+			writel(M_CMD_ABORT_EN, uport->membase +
 							SE_GENI_M_IRQ_CLEAR);
 		}
-		writel_relaxed(M_CMD_CANCEL_EN, uport->membase +
+		writel(M_CMD_CANCEL_EN, uport->membase +
 							SE_GENI_M_IRQ_CLEAR);
 	} else if ((geni_status & M_GENI_CMD_ACTIVE) && !port->tx_remaining) {
 		/*
@@ -479,9 +470,9 @@ static void qcom_geni_serial_console_write(struct console *co, const char *s,
 		qcom_geni_serial_poll_tx_done(uport);
 
 		if (uart_circ_chars_pending(&uport->state->xmit)) {
-			irq_en = readl_relaxed(uport->membase +
+			irq_en = readl(uport->membase +
 					SE_GENI_M_IRQ_EN);
-			writel_relaxed(irq_en | M_TX_FIFO_WATERMARK_EN,
+			writel(irq_en | M_TX_FIFO_WATERMARK_EN,
 					uport->membase + SE_GENI_M_IRQ_EN);
 		}
 	}
@@ -585,12 +576,12 @@ static void qcom_geni_serial_start_tx(struct uart_port *uport)
 		if (!qcom_geni_serial_tx_empty(uport))
 			return;
 
-		irq_en = readl_relaxed(uport->membase +	SE_GENI_M_IRQ_EN);
+		irq_en = readl(uport->membase +	SE_GENI_M_IRQ_EN);
 		irq_en |= M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN;
 
-		writel_relaxed(port->tx_wm, uport->membase +
+		writel(port->tx_wm, uport->membase +
 						SE_GENI_TX_WATERMARK_REG);
-		writel_relaxed(irq_en, uport->membase +	SE_GENI_M_IRQ_EN);
+		writel(irq_en, uport->membase +	SE_GENI_M_IRQ_EN);
 	}
 }
 
@@ -600,35 +591,29 @@ static void qcom_geni_serial_stop_tx(struct uart_port *uport)
 	u32 status;
 	struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
 
-	irq_en = readl_relaxed(uport->membase + SE_GENI_M_IRQ_EN);
+	irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
 	irq_en &= ~M_CMD_DONE_EN;
 	if (port->xfer_mode == GENI_SE_FIFO) {
 		irq_en &= ~M_TX_FIFO_WATERMARK_EN;
-		writel_relaxed(0, uport->membase +
+		writel(0, uport->membase +
 				     SE_GENI_TX_WATERMARK_REG);
 	}
-	writel_relaxed(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
-	status = readl_relaxed(uport->membase + SE_GENI_STATUS);
+	writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
+	status = readl(uport->membase + SE_GENI_STATUS);
 	/* Possible stop tx is called multiple times. */
 	if (!(status & M_GENI_CMD_ACTIVE))
 		return;
 
-	/*
-	 * Ensure cancel command write is not re-ordered before checking
-	 * the status of the Primary Sequencer.
-	 */
-	mb();
-
 	geni_se_cancel_m_cmd(&port->se);
 	if (!qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS,
 						M_CMD_CANCEL_EN, true)) {
 		geni_se_abort_m_cmd(&port->se);
 		qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS,
 						M_CMD_ABORT_EN, true);
-		writel_relaxed(M_CMD_ABORT_EN, uport->membase +
+		writel(M_CMD_ABORT_EN, uport->membase +
 							SE_GENI_M_IRQ_CLEAR);
 	}
-	writel_relaxed(M_CMD_CANCEL_EN, uport->membase + SE_GENI_M_IRQ_CLEAR);
+	writel(M_CMD_CANCEL_EN, uport->membase + SE_GENI_M_IRQ_CLEAR);
 }
 
 static void qcom_geni_serial_start_rx(struct uart_port *uport)
@@ -637,26 +622,20 @@ static void qcom_geni_serial_start_rx(struct uart_port *uport)
 	u32 status;
 	struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
 
-	status = readl_relaxed(uport->membase + SE_GENI_STATUS);
+	status = readl(uport->membase + SE_GENI_STATUS);
 	if (status & S_GENI_CMD_ACTIVE)
 		qcom_geni_serial_stop_rx(uport);
 
-	/*
-	 * Ensure setup command write is not re-ordered before checking
-	 * the status of the Secondary Sequencer.
-	 */
-	mb();
-
 	geni_se_setup_s_cmd(&port->se, UART_START_READ, 0);
 
 	if (port->xfer_mode == GENI_SE_FIFO) {
-		irq_en = readl_relaxed(uport->membase + SE_GENI_S_IRQ_EN);
+		irq_en = readl(uport->membase + SE_GENI_S_IRQ_EN);
 		irq_en |= S_RX_FIFO_WATERMARK_EN | S_RX_FIFO_LAST_EN;
-		writel_relaxed(irq_en, uport->membase + SE_GENI_S_IRQ_EN);
+		writel(irq_en, uport->membase + SE_GENI_S_IRQ_EN);
 
-		irq_en = readl_relaxed(uport->membase + SE_GENI_M_IRQ_EN);
+		irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
 		irq_en |= M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN;
-		writel_relaxed(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
+		writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
 	}
 }
 
@@ -668,31 +647,25 @@ static void qcom_geni_serial_stop_rx(struct uart_port *uport)
 	u32 irq_clear = S_CMD_DONE_EN;
 
 	if (port->xfer_mode == GENI_SE_FIFO) {
-		irq_en = readl_relaxed(uport->membase + SE_GENI_S_IRQ_EN);
+		irq_en = readl(uport->membase + SE_GENI_S_IRQ_EN);
 		irq_en &= ~(S_RX_FIFO_WATERMARK_EN | S_RX_FIFO_LAST_EN);
-		writel_relaxed(irq_en, uport->membase + SE_GENI_S_IRQ_EN);
+		writel(irq_en, uport->membase + SE_GENI_S_IRQ_EN);
 
-		irq_en = readl_relaxed(uport->membase + SE_GENI_M_IRQ_EN);
+		irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
 		irq_en &= ~(M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN);
-		writel_relaxed(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
+		writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
 	}
 
-	status = readl_relaxed(uport->membase + SE_GENI_STATUS);
+	status = readl(uport->membase + SE_GENI_STATUS);
 	/* Possible stop rx is called multiple times. */
 	if (!(status & S_GENI_CMD_ACTIVE))
 		return;
 
-	/*
-	 * Ensure cancel command write is not re-ordered before checking
-	 * the status of the Secondary Sequencer.
-	 */
-	mb();
-
 	geni_se_cancel_s_cmd(&port->se);
 	qcom_geni_serial_poll_bit(uport, SE_GENI_S_CMD_CTRL_REG,
 					S_GENI_CMD_CANCEL, false);
-	status = readl_relaxed(uport->membase + SE_GENI_STATUS);
-	writel_relaxed(irq_clear, uport->membase + SE_GENI_S_IRQ_CLEAR);
+	status = readl(uport->membase + SE_GENI_STATUS);
+	writel(irq_clear, uport->membase + SE_GENI_S_IRQ_CLEAR);
 	if (status & S_GENI_CMD_ACTIVE)
 		qcom_geni_serial_abort_rx(uport);
 }
@@ -706,7 +679,7 @@ static void qcom_geni_serial_handle_rx(struct uart_port *uport, bool drop)
 	u32 total_bytes;
 	struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
 
-	status = readl_relaxed(uport->membase +	SE_GENI_RX_FIFO_STATUS);
+	status = readl(uport->membase +	SE_GENI_RX_FIFO_STATUS);
 	word_cnt = status & RX_FIFO_WC_MSK;
 	last_word_partial = status & RX_LAST;
 	last_word_byte_cnt = (status & RX_LAST_BYTE_VALID_MSK) >>
@@ -736,7 +709,7 @@ static void qcom_geni_serial_handle_tx(struct uart_port *uport, bool done,
 	unsigned int chunk;
 	int tail;
 
-	status = readl_relaxed(uport->membase + SE_GENI_TX_FIFO_STATUS);
+	status = readl(uport->membase + SE_GENI_TX_FIFO_STATUS);
 
 	/* Complete the current tx command before taking newly added data */
 	if (active)
@@ -762,9 +735,9 @@ static void qcom_geni_serial_handle_tx(struct uart_port *uport, bool done,
 		qcom_geni_serial_setup_tx(uport, pending);
 		port->tx_remaining = pending;
 
-		irq_en = readl_relaxed(uport->membase + SE_GENI_M_IRQ_EN);
+		irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
 		if (!(irq_en & M_TX_FIFO_WATERMARK_EN))
-			writel_relaxed(irq_en | M_TX_FIFO_WATERMARK_EN,
+			writel(irq_en | M_TX_FIFO_WATERMARK_EN,
 					uport->membase + SE_GENI_M_IRQ_EN);
 	}
 
@@ -797,14 +770,14 @@ static void qcom_geni_serial_handle_tx(struct uart_port *uport, bool done,
 	 * cleared it in qcom_geni_serial_isr it will have already reasserted
 	 * so we must clear it again here after our writes.
 	 */
-	writel_relaxed(M_TX_FIFO_WATERMARK_EN,
+	writel(M_TX_FIFO_WATERMARK_EN,
 			uport->membase + SE_GENI_M_IRQ_CLEAR);
 
 out_write_wakeup:
 	if (!port->tx_remaining) {
-		irq_en = readl_relaxed(uport->membase + SE_GENI_M_IRQ_EN);
+		irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
 		if (irq_en & M_TX_FIFO_WATERMARK_EN)
-			writel_relaxed(irq_en & ~M_TX_FIFO_WATERMARK_EN,
+			writel(irq_en & ~M_TX_FIFO_WATERMARK_EN,
 					uport->membase + SE_GENI_M_IRQ_EN);
 	}
 
@@ -828,12 +801,12 @@ static irqreturn_t qcom_geni_serial_isr(int isr, void *dev)
 		return IRQ_NONE;
 
 	spin_lock_irqsave(&uport->lock, flags);
-	m_irq_status = readl_relaxed(uport->membase + SE_GENI_M_IRQ_STATUS);
-	s_irq_status = readl_relaxed(uport->membase + SE_GENI_S_IRQ_STATUS);
-	geni_status = readl_relaxed(uport->membase + SE_GENI_STATUS);
-	m_irq_en = readl_relaxed(uport->membase + SE_GENI_M_IRQ_EN);
-	writel_relaxed(m_irq_status, uport->membase + SE_GENI_M_IRQ_CLEAR);
-	writel_relaxed(s_irq_status, uport->membase + SE_GENI_S_IRQ_CLEAR);
+	m_irq_status = readl(uport->membase + SE_GENI_M_IRQ_STATUS);
+	s_irq_status = readl(uport->membase + SE_GENI_S_IRQ_STATUS);
+	geni_status = readl(uport->membase + SE_GENI_STATUS);
+	m_irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
+	writel(m_irq_status, uport->membase + SE_GENI_M_IRQ_CLEAR);
+	writel(s_irq_status, uport->membase + SE_GENI_S_IRQ_CLEAR);
 
 	if (WARN_ON(m_irq_status & M_ILLEGAL_CMD_EN))
 		goto out_unlock;
@@ -931,7 +904,7 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport)
 	get_tx_fifo_size(port);
 
 	set_rfr_wm(port);
-	writel_relaxed(rxstale, uport->membase + SE_UART_RX_STALE_CNT);
+	writel(rxstale, uport->membase + SE_UART_RX_STALE_CNT);
 	/*
 	 * Make an unconditional cancel on the main sequencer to reset
 	 * it else we could end up in data loss scenarios.
@@ -1035,10 +1008,10 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
 	ser_clk_cfg |= clk_div << CLK_DIV_SHFT;
 
 	/* parity */
-	tx_trans_cfg = readl_relaxed(uport->membase + SE_UART_TX_TRANS_CFG);
-	tx_parity_cfg = readl_relaxed(uport->membase + SE_UART_TX_PARITY_CFG);
-	rx_trans_cfg = readl_relaxed(uport->membase + SE_UART_RX_TRANS_CFG);
-	rx_parity_cfg = readl_relaxed(uport->membase + SE_UART_RX_PARITY_CFG);
+	tx_trans_cfg = readl(uport->membase + SE_UART_TX_TRANS_CFG);
+	tx_parity_cfg = readl(uport->membase + SE_UART_TX_PARITY_CFG);
+	rx_trans_cfg = readl(uport->membase + SE_UART_RX_TRANS_CFG);
+	rx_parity_cfg = readl(uport->membase + SE_UART_RX_PARITY_CFG);
 	if (termios->c_cflag & PARENB) {
 		tx_trans_cfg |= UART_TX_PAR_EN;
 		rx_trans_cfg |= UART_RX_PAR_EN;
@@ -1094,17 +1067,17 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
 		uart_update_timeout(uport, termios->c_cflag, baud);
 
 	if (!uart_console(uport))
-		writel_relaxed(port->loopback,
+		writel(port->loopback,
 				uport->membase + SE_UART_LOOPBACK_CFG);
-	writel_relaxed(tx_trans_cfg, uport->membase + SE_UART_TX_TRANS_CFG);
-	writel_relaxed(tx_parity_cfg, uport->membase + SE_UART_TX_PARITY_CFG);
-	writel_relaxed(rx_trans_cfg, uport->membase + SE_UART_RX_TRANS_CFG);
-	writel_relaxed(rx_parity_cfg, uport->membase + SE_UART_RX_PARITY_CFG);
-	writel_relaxed(bits_per_char, uport->membase + SE_UART_TX_WORD_LEN);
-	writel_relaxed(bits_per_char, uport->membase + SE_UART_RX_WORD_LEN);
-	writel_relaxed(stop_bit_len, uport->membase + SE_UART_TX_STOP_BIT_LEN);
-	writel_relaxed(ser_clk_cfg, uport->membase + GENI_SER_M_CLK_CFG);
-	writel_relaxed(ser_clk_cfg, uport->membase + GENI_SER_S_CLK_CFG);
+	writel(tx_trans_cfg, uport->membase + SE_UART_TX_TRANS_CFG);
+	writel(tx_parity_cfg, uport->membase + SE_UART_TX_PARITY_CFG);
+	writel(rx_trans_cfg, uport->membase + SE_UART_RX_TRANS_CFG);
+	writel(rx_parity_cfg, uport->membase + SE_UART_RX_PARITY_CFG);
+	writel(bits_per_char, uport->membase + SE_UART_TX_WORD_LEN);
+	writel(bits_per_char, uport->membase + SE_UART_RX_WORD_LEN);
+	writel(stop_bit_len, uport->membase + SE_UART_TX_STOP_BIT_LEN);
+	writel(ser_clk_cfg, uport->membase + GENI_SER_M_CLK_CFG);
+	writel(ser_clk_cfg, uport->membase + GENI_SER_S_CLK_CFG);
 out_restart_rx:
 	qcom_geni_serial_start_rx(uport);
 }
@@ -1195,13 +1168,13 @@ static int __init qcom_geni_serial_earlycon_setup(struct earlycon_device *dev,
 	geni_se_init(&se, DEF_FIFO_DEPTH_WORDS / 2, DEF_FIFO_DEPTH_WORDS - 2);
 	geni_se_select_mode(&se, GENI_SE_FIFO);
 
-	writel_relaxed(tx_trans_cfg, uport->membase + SE_UART_TX_TRANS_CFG);
-	writel_relaxed(tx_parity_cfg, uport->membase + SE_UART_TX_PARITY_CFG);
-	writel_relaxed(rx_trans_cfg, uport->membase + SE_UART_RX_TRANS_CFG);
-	writel_relaxed(rx_parity_cfg, uport->membase + SE_UART_RX_PARITY_CFG);
-	writel_relaxed(bits_per_char, uport->membase + SE_UART_TX_WORD_LEN);
-	writel_relaxed(bits_per_char, uport->membase + SE_UART_RX_WORD_LEN);
-	writel_relaxed(stop_bit_len, uport->membase + SE_UART_TX_STOP_BIT_LEN);
+	writel(tx_trans_cfg, uport->membase + SE_UART_TX_TRANS_CFG);
+	writel(tx_parity_cfg, uport->membase + SE_UART_TX_PARITY_CFG);
+	writel(rx_trans_cfg, uport->membase + SE_UART_RX_TRANS_CFG);
+	writel(rx_parity_cfg, uport->membase + SE_UART_RX_PARITY_CFG);
+	writel(bits_per_char, uport->membase + SE_UART_TX_WORD_LEN);
+	writel(bits_per_char, uport->membase + SE_UART_RX_WORD_LEN);
+	writel(stop_bit_len, uport->membase + SE_UART_TX_STOP_BIT_LEN);
 
 	dev->con->write = qcom_geni_serial_earlycon_write;
 	dev->con->setup = NULL;
-- 
2.20.1.415.g653613c723-goog

^ permalink raw reply related

* [PATCH 2/4] tty: serial: qcom_geni_serial: Remove set_rfr_wm() and related variables
From: Ryan Case @ 2019-01-02 21:36 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Evan Green, Doug Anderson, linux-kernel, linux-serial,
	Stephen Boyd, Ryan Case
In-Reply-To: <20190102213636.40866-1-ryandcase@chromium.org>

The variables of tx_wm and rx_wm were set to the same define value in
all cases, never updated, and the define was sometimes used
interchangably. Remove the variables/function and use the fixed value.

Signed-off-by: Ryan Case <ryandcase@chromium.org>
---

 drivers/tty/serial/qcom_geni_serial.c | 23 +++--------------------
 1 file changed, 3 insertions(+), 20 deletions(-)

diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index dc95b96148ed..5521ed4a0708 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -105,9 +105,6 @@ struct qcom_geni_serial_port {
 	u32 tx_fifo_depth;
 	u32 tx_fifo_width;
 	u32 rx_fifo_depth;
-	u32 tx_wm;
-	u32 rx_wm;
-	u32 rx_rfr;
 	enum geni_se_xfer_mode xfer_mode;
 	bool setup;
 	int (*handle_rx)(struct uart_port *uport, u32 bytes, bool drop);
@@ -365,9 +362,7 @@ static int qcom_geni_serial_get_char(struct uart_port *uport)
 static void qcom_geni_serial_poll_put_char(struct uart_port *uport,
 							unsigned char c)
 {
-	struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
-
-	writel(port->tx_wm, uport->membase + SE_GENI_TX_WATERMARK_REG);
+	writel(DEF_TX_WM, uport->membase + SE_GENI_TX_WATERMARK_REG);
 	qcom_geni_serial_setup_tx(uport, 1);
 	WARN_ON(!qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS,
 						M_TX_FIFO_WATERMARK_EN, true));
@@ -579,7 +574,7 @@ static void qcom_geni_serial_start_tx(struct uart_port *uport)
 		irq_en = readl(uport->membase +	SE_GENI_M_IRQ_EN);
 		irq_en |= M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN;
 
-		writel(port->tx_wm, uport->membase +
+		writel(DEF_TX_WM, uport->membase +
 						SE_GENI_TX_WATERMARK_REG);
 		writel(irq_en, uport->membase +	SE_GENI_M_IRQ_EN);
 	}
@@ -852,17 +847,6 @@ static void get_tx_fifo_size(struct qcom_geni_serial_port *port)
 		(port->tx_fifo_depth * port->tx_fifo_width) / BITS_PER_BYTE;
 }
 
-static void set_rfr_wm(struct qcom_geni_serial_port *port)
-{
-	/*
-	 * Set RFR (Flow off) to FIFO_DEPTH - 2.
-	 * RX WM level at 10% RX_FIFO_DEPTH.
-	 * TX WM level at 10% TX_FIFO_DEPTH.
-	 */
-	port->rx_rfr = port->rx_fifo_depth - 2;
-	port->rx_wm = UART_CONSOLE_RX_WM;
-	port->tx_wm = DEF_TX_WM;
-}
 
 static void qcom_geni_serial_shutdown(struct uart_port *uport)
 {
@@ -903,7 +887,6 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport)
 
 	get_tx_fifo_size(port);
 
-	set_rfr_wm(port);
 	writel(rxstale, uport->membase + SE_UART_RX_STALE_CNT);
 	/*
 	 * Make an unconditional cancel on the main sequencer to reset
@@ -916,7 +899,7 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport)
 						false, true, false);
 	geni_se_config_packing(&port->se, BITS_PER_BYTE, port->rx_bytes_pw,
 						false, false, true);
-	geni_se_init(&port->se, port->rx_wm, port->rx_rfr);
+	geni_se_init(&port->se, UART_CONSOLE_RX_WM, port->rx_fifo_depth - 2);
 	geni_se_select_mode(&port->se, port->xfer_mode);
 	if (!uart_console(uport)) {
 		port->rx_fifo = devm_kcalloc(uport->dev,
-- 
2.20.1.415.g653613c723-goog

^ permalink raw reply related

* [PATCH 3/4] tty: serial: qcom_geni_serial: Remove xfer_mode variable
From: Ryan Case @ 2019-01-02 21:36 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Evan Green, Doug Anderson, linux-kernel, linux-serial,
	Stephen Boyd, Ryan Case
In-Reply-To: <20190102213636.40866-1-ryandcase@chromium.org>

The driver only supports FIFO mode so setting and checking this variable
is unnecessary. If DMA support is ever addedd then such checks can be
introduced.

Signed-off-by: Ryan Case <ryandcase@chromium.org>
---

 drivers/tty/serial/qcom_geni_serial.c | 66 ++++++++++-----------------
 1 file changed, 24 insertions(+), 42 deletions(-)

diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index 5521ed4a0708..3103aa0adc86 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -105,7 +105,6 @@ struct qcom_geni_serial_port {
 	u32 tx_fifo_depth;
 	u32 tx_fifo_width;
 	u32 rx_fifo_depth;
-	enum geni_se_xfer_mode xfer_mode;
 	bool setup;
 	int (*handle_rx)(struct uart_port *uport, u32 bytes, bool drop);
 	unsigned int baud;
@@ -555,29 +554,20 @@ static int handle_rx_uart(struct uart_port *uport, u32 bytes, bool drop)
 static void qcom_geni_serial_start_tx(struct uart_port *uport)
 {
 	u32 irq_en;
-	struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
 	u32 status;
 
-	if (port->xfer_mode == GENI_SE_FIFO) {
-		/*
-		 * readl ensures reading & writing of IRQ_EN register
-		 * is not re-ordered before checking the status of the
-		 * Serial Engine.
-		 */
-		status = readl(uport->membase + SE_GENI_STATUS);
-		if (status & M_GENI_CMD_ACTIVE)
-			return;
+	status = readl(uport->membase + SE_GENI_STATUS);
+	if (status & M_GENI_CMD_ACTIVE)
+		return;
 
-		if (!qcom_geni_serial_tx_empty(uport))
-			return;
+	if (!qcom_geni_serial_tx_empty(uport))
+		return;
 
-		irq_en = readl(uport->membase +	SE_GENI_M_IRQ_EN);
-		irq_en |= M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN;
+	irq_en = readl(uport->membase +	SE_GENI_M_IRQ_EN);
+	irq_en |= M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN;
 
-		writel(DEF_TX_WM, uport->membase +
-						SE_GENI_TX_WATERMARK_REG);
-		writel(irq_en, uport->membase +	SE_GENI_M_IRQ_EN);
-	}
+	writel(DEF_TX_WM, uport->membase + SE_GENI_TX_WATERMARK_REG);
+	writel(irq_en, uport->membase +	SE_GENI_M_IRQ_EN);
 }
 
 static void qcom_geni_serial_stop_tx(struct uart_port *uport)
@@ -588,11 +578,8 @@ static void qcom_geni_serial_stop_tx(struct uart_port *uport)
 
 	irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
 	irq_en &= ~M_CMD_DONE_EN;
-	if (port->xfer_mode == GENI_SE_FIFO) {
-		irq_en &= ~M_TX_FIFO_WATERMARK_EN;
-		writel(0, uport->membase +
-				     SE_GENI_TX_WATERMARK_REG);
-	}
+	irq_en &= ~M_TX_FIFO_WATERMARK_EN;
+	writel(0, uport->membase + SE_GENI_TX_WATERMARK_REG);
 	writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
 	status = readl(uport->membase + SE_GENI_STATUS);
 	/* Possible stop tx is called multiple times. */
@@ -623,15 +610,13 @@ static void qcom_geni_serial_start_rx(struct uart_port *uport)
 
 	geni_se_setup_s_cmd(&port->se, UART_START_READ, 0);
 
-	if (port->xfer_mode == GENI_SE_FIFO) {
-		irq_en = readl(uport->membase + SE_GENI_S_IRQ_EN);
-		irq_en |= S_RX_FIFO_WATERMARK_EN | S_RX_FIFO_LAST_EN;
-		writel(irq_en, uport->membase + SE_GENI_S_IRQ_EN);
+	irq_en = readl(uport->membase + SE_GENI_S_IRQ_EN);
+	irq_en |= S_RX_FIFO_WATERMARK_EN | S_RX_FIFO_LAST_EN;
+	writel(irq_en, uport->membase + SE_GENI_S_IRQ_EN);
 
-		irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
-		irq_en |= M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN;
-		writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
-	}
+	irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
+	irq_en |= M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN;
+	writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
 }
 
 static void qcom_geni_serial_stop_rx(struct uart_port *uport)
@@ -641,15 +626,13 @@ static void qcom_geni_serial_stop_rx(struct uart_port *uport)
 	struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
 	u32 irq_clear = S_CMD_DONE_EN;
 
-	if (port->xfer_mode == GENI_SE_FIFO) {
-		irq_en = readl(uport->membase + SE_GENI_S_IRQ_EN);
-		irq_en &= ~(S_RX_FIFO_WATERMARK_EN | S_RX_FIFO_LAST_EN);
-		writel(irq_en, uport->membase + SE_GENI_S_IRQ_EN);
+	irq_en = readl(uport->membase + SE_GENI_S_IRQ_EN);
+	irq_en &= ~(S_RX_FIFO_WATERMARK_EN | S_RX_FIFO_LAST_EN);
+	writel(irq_en, uport->membase + SE_GENI_S_IRQ_EN);
 
-		irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
-		irq_en &= ~(M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN);
-		writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
-	}
+	irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
+	irq_en &= ~(M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN);
+	writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
 
 	status = readl(uport->membase + SE_GENI_STATUS);
 	/* Possible stop rx is called multiple times. */
@@ -892,7 +875,6 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport)
 	 * Make an unconditional cancel on the main sequencer to reset
 	 * it else we could end up in data loss scenarios.
 	 */
-	port->xfer_mode = GENI_SE_FIFO;
 	if (uart_console(uport))
 		qcom_geni_serial_poll_tx_done(uport);
 	geni_se_config_packing(&port->se, BITS_PER_BYTE, port->tx_bytes_pw,
@@ -900,7 +882,7 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport)
 	geni_se_config_packing(&port->se, BITS_PER_BYTE, port->rx_bytes_pw,
 						false, false, true);
 	geni_se_init(&port->se, UART_CONSOLE_RX_WM, port->rx_fifo_depth - 2);
-	geni_se_select_mode(&port->se, port->xfer_mode);
+	geni_se_select_mode(&port->se, GENI_SE_FIFO);
 	if (!uart_console(uport)) {
 		port->rx_fifo = devm_kcalloc(uport->dev,
 			port->rx_fifo_depth, sizeof(u32), GFP_KERNEL);
-- 
2.20.1.415.g653613c723-goog

^ permalink raw reply related

* [PATCH 4/4] tty: serial: qcom_geni_serial: Use u32 for register variables
From: Ryan Case @ 2019-01-02 21:36 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Evan Green, Doug Anderson, linux-kernel, linux-serial,
	Stephen Boyd, Ryan Case
In-Reply-To: <20190102213636.40866-1-ryandcase@chromium.org>

Signed-off-by: Ryan Case <ryandcase@chromium.org>
---

 drivers/tty/serial/qcom_geni_serial.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index 3103aa0adc86..fa67a2ced420 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -765,12 +765,12 @@ static void qcom_geni_serial_handle_tx(struct uart_port *uport, bool done,
 
 static irqreturn_t qcom_geni_serial_isr(int isr, void *dev)
 {
-	unsigned int m_irq_status;
-	unsigned int s_irq_status;
-	unsigned int geni_status;
+	u32 m_irq_en;
+	u32 m_irq_status;
+	u32 s_irq_status;
+	u32 geni_status;
 	struct uart_port *uport = dev;
 	unsigned long flags;
-	unsigned int m_irq_en;
 	bool drop_rx = false;
 	struct tty_port *tport = &uport->state->port;
 	struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
@@ -948,14 +948,14 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
 				struct ktermios *termios, struct ktermios *old)
 {
 	unsigned int baud;
-	unsigned int bits_per_char;
-	unsigned int tx_trans_cfg;
-	unsigned int tx_parity_cfg;
-	unsigned int rx_trans_cfg;
-	unsigned int rx_parity_cfg;
-	unsigned int stop_bit_len;
+	u32 bits_per_char;
+	u32 tx_trans_cfg;
+	u32 tx_parity_cfg;
+	u32 rx_trans_cfg;
+	u32 rx_parity_cfg;
+	u32 stop_bit_len;
 	unsigned int clk_div;
-	unsigned long ser_clk_cfg;
+	u32 ser_clk_cfg;
 	struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
 	unsigned long clk_rate;
 
-- 
2.20.1.415.g653613c723-goog

^ permalink raw reply related

* Re: [PATCH v9 1/2] dmaengine: 8250_mtk_dma: add MediaTek uart DMA support
From: Nicolas Boichat @ 2019-01-03  1:39 UTC (permalink / raw)
  To: Long Cheng
  Cc: Mark Rutland, devicetree, Ryder Lee, Zhenbao Liu, linux-serial,
	srv_heupstream, Greg Kroah-Hartman, Randy Dunlap, lkml, Sean Wang,
	YT Shen, dmaengine, Vinod Koul, Rob Herring, linux-mediatek,
	Sean Wang, Jiri Slaby, Matthias Brugger, Yingjoe Chen,
	Dan Williams, linux-arm Mailing List
In-Reply-To: <1546395178-8880-2-git-send-email-long.cheng@mediatek.com>

On Wed, Jan 2, 2019 at 10:13 AM Long Cheng <long.cheng@mediatek.com> wrote:
>
> In DMA engine framework, add 8250 uart dma to support MediaTek uart.
> If MediaTek uart enabled(SERIAL_8250_MT6577), and want to improve
> the performance, can enable the function.
>
> Signed-off-by: Long Cheng <long.cheng@mediatek.com>
> ---
>  drivers/dma/mediatek/8250_mtk_dma.c |  652 +++++++++++++++++++++++++++++++++++
>  drivers/dma/mediatek/Kconfig        |   11 +
>  drivers/dma/mediatek/Makefile       |    1 +
>  3 files changed, 664 insertions(+)
>  create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c
>
> diff --git a/drivers/dma/mediatek/8250_mtk_dma.c b/drivers/dma/mediatek/8250_mtk_dma.c
> new file mode 100644
> index 0000000..dbf811e
> --- /dev/null
> +++ b/drivers/dma/mediatek/8250_mtk_dma.c
> @@ -0,0 +1,652 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * MediaTek 8250 DMA driver.
> + *
> + * Copyright (c) 2018 MediaTek Inc.
> + * Author: Long Cheng <long.cheng@mediatek.com>
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/dmaengine.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/err.h>
> +#include <linux/init.h>
> +#include <linux/interrupt.h>
> +#include <linux/iopoll.h>
> +#include <linux/kernel.h>
> +#include <linux/list.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/of_dma.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/slab.h>
> +#include <linux/spinlock.h>
> +
> +#include "../virt-dma.h"
> +
> +#define MTK_UART_APDMA_CHANNELS                (CONFIG_SERIAL_8250_NR_UARTS * 2)
> +
> +#define VFF_EN_B               BIT(0)
> +#define VFF_STOP_B             BIT(0)
> +#define VFF_FLUSH_B            BIT(0)
> +#define VFF_4G_SUPPORT_B       BIT(0)
> +#define VFF_RX_INT_EN0_B       BIT(0)  /*rx valid size >=  vff thre*/
> +#define VFF_RX_INT_EN1_B       BIT(1)
> +#define VFF_TX_INT_EN_B                BIT(0)  /*tx left size >= vff thre*/
> +#define VFF_WARM_RST_B         BIT(0)
> +#define VFF_RX_INT_FLAG_CLR_B  (BIT(0) | BIT(1))
> +#define VFF_TX_INT_FLAG_CLR_B  0
> +#define VFF_STOP_CLR_B         0
> +#define VFF_INT_EN_CLR_B       0
> +#define VFF_4G_SUPPORT_CLR_B   0
> +
> +/* interrupt trigger level for tx */
> +#define VFF_TX_THRE(n)         ((n) * 7 / 8)
> +/* interrupt trigger level for rx */
> +#define VFF_RX_THRE(n)         ((n) * 3 / 4)
> +
> +#define VFF_RING_SIZE  0xffffU

Well, the size is actually 0x10000. Maybe call this VFF_RING_SIZE_MASK?

> +/* invert this bit when wrap ring head again*/
> +#define VFF_RING_WRAP  0x10000U
> +
> +#define VFF_INT_FLAG           0x00
> +#define VFF_INT_EN             0x04
> +#define VFF_EN                 0x08
> +#define VFF_RST                        0x0c
> +#define VFF_STOP               0x10
> +#define VFF_FLUSH              0x14
> +#define VFF_ADDR               0x1c
> +#define VFF_LEN                        0x24
> +#define VFF_THRE               0x28
> +#define VFF_WPT                        0x2c
> +#define VFF_RPT                        0x30
> +/*TX: the buffer size HW can read. RX: the buffer size SW can read.*/

nit: Spaces after /* and before */ (and a lot more occurences below,
please fix them all).

> +#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_irq[MTK_UART_APDMA_CHANNELS];
> +};
> +
> +struct mtk_uart_apdma_desc {
> +       struct virt_dma_desc vd;
> +
> +       unsigned int avail_len;
> +};
> +
> +struct mtk_chan {
> +       struct virt_dma_chan vc;
> +       struct dma_slave_config cfg;
> +       void __iomem *base;
> +       struct mtk_uart_apdma_desc *desc;
> +
> +       bool requested;
> +
> +       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 void mtk_uart_apdma_write(struct mtk_chan *c,
> +                              unsigned int reg, unsigned int val)
> +{
> +       writel(val, c->base + reg);
> +}
> +
> +static unsigned int mtk_uart_apdma_read(struct mtk_chan *c, unsigned int reg)
> +{
> +       return readl(c->base + reg);
> +}
> +
> +static void mtk_uart_apdma_desc_free(struct virt_dma_desc *vd)
> +{
> +       struct dma_chan *chan = vd->tx.chan;
> +       struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
> +
> +       kfree(c->desc);
> +}
> +
> +static void mtk_uart_apdma_start_tx(struct mtk_chan *c)
> +{
> +       unsigned int len, send, left, wpt, d_wpt, tmp;
> +       int ret;
> +
> +       left = mtk_uart_apdma_read(c, VFF_LEFT_SIZE);
> +       if (!left) {
> +               mtk_uart_apdma_write(c, VFF_INT_EN, VFF_TX_INT_EN_B);
> +               return;
> +       }
> +
> +       /* Wait 1sec for flush,  can't sleep*/

nit: one space after ',', period after 'sleep', space before '*'.

> +       ret = readx_poll_timeout(readl, c->base + VFF_FLUSH, tmp,
> +                       tmp != VFF_FLUSH_B, 0, 1000000);
> +       if (ret)
> +               dev_warn(c->vc.chan.device->dev, "tx: fail, debug=0x%x\n",
> +                       mtk_uart_apdma_read(c, VFF_DEBUG_STATUS));

Why do we need to wait for flush now? The previous implementation did
not require this...

> +
> +       send = min_t(unsigned int, left, c->desc->avail_len);
> +       wpt = mtk_uart_apdma_read(c, VFF_WPT);
> +       len = mtk_uart_apdma_read(c, VFF_LEN);
> +
> +       d_wpt = wpt + send;
> +       if ((d_wpt & VFF_RING_SIZE) >= len) {

I don't get why you need to add "& VFF_RING_SIZE". If wpt + send >
VFF_RING_SIZE, don't you need to toggle VFF_RING_WRAP too?

> +               d_wpt = d_wpt - len;
> +               d_wpt = d_wpt ^ VFF_RING_WRAP;
> +       }
> +       mtk_uart_apdma_write(c, VFF_WPT, d_wpt);
> +
> +       c->desc->avail_len -= send;
> +
> +       mtk_uart_apdma_write(c, VFF_INT_EN, VFF_TX_INT_EN_B);
> +       if (mtk_uart_apdma_read(c, VFF_FLUSH) == 0U)
> +               mtk_uart_apdma_write(c, VFF_FLUSH, VFF_FLUSH_B);
> +}

(thanks for the rest of the changes, this looks much more readable)

> +
> +static void mtk_uart_apdma_start_rx(struct mtk_chan *c)
> +{
> +       struct mtk_uart_apdma_desc *d = c->desc;
> +       unsigned int len, wg, rg, cnt;
> +
> +       if ((mtk_uart_apdma_read(c, VFF_VALID_SIZE) == 0U) ||
> +               !d || !vchan_next_desc(&c->vc))
> +               return;
> +
> +       len = mtk_uart_apdma_read(c, VFF_LEN);
> +       rg = mtk_uart_apdma_read(c, VFF_RPT);
> +       wg = mtk_uart_apdma_read(c, VFF_WPT);
> +       if ((rg ^ wg) & VFF_RING_WRAP)
> +               cnt = (wg & VFF_RING_SIZE) + len - (rg & VFF_RING_SIZE);
> +       else
> +               cnt = (wg & VFF_RING_SIZE) - (rg & VFF_RING_SIZE);
> +
> +       c->rx_status = cnt;
> +       mtk_uart_apdma_write(c, VFF_RPT, wg);
> +
> +       list_del(&d->vd.node);
> +       vchan_cookie_complete(&d->vd);
> +}
> +
> +static irqreturn_t mtk_uart_apdma_irq_handler(int irq, void *dev_id)
> +{
> +       struct dma_chan *chan = (struct dma_chan *)dev_id;
> +       struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
> +       struct mtk_uart_apdma_desc *d;
> +       unsigned long flags;
> +
> +       spin_lock_irqsave(&c->vc.lock, flags);
> +       if (c->cfg.direction == DMA_DEV_TO_MEM) {
> +               mtk_uart_apdma_write(c, VFF_INT_FLAG, VFF_RX_INT_FLAG_CLR_B);
> +               mtk_uart_apdma_start_rx(c);
> +       } else if (c->cfg.direction == DMA_MEM_TO_DEV) {
> +               d = c->desc;
> +
> +               mtk_uart_apdma_write(c, VFF_INT_FLAG, VFF_TX_INT_FLAG_CLR_B);
> +
> +               if (d->avail_len != 0U) {
> +                       mtk_uart_apdma_start_tx(c);
> +               } else {
> +                       list_del(&d->vd.node);
> +                       vchan_cookie_complete(&d->vd);
> +               }
> +       }
> +       spin_unlock_irqrestore(&c->vc.lock, flags);
> +
> +       return IRQ_HANDLED;
> +}
> +
> +static int mtk_uart_apdma_alloc_chan_resources(struct dma_chan *chan)
> +{
> +       struct mtk_uart_apdmadev *mtkd = to_mtk_uart_apdma_dev(chan->device);
> +       struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
> +       u32 tmp;

In the rest of the code, you use `unsigned int` as type. I think u32
is a little bit better, but please be consistent.

> +       int ret;
> +
> +       pm_runtime_get_sync(mtkd->ddev.dev);
> +
> +       mtk_uart_apdma_write(c, VFF_ADDR, 0);
> +       mtk_uart_apdma_write(c, VFF_THRE, 0);
> +       mtk_uart_apdma_write(c, VFF_LEN, 0);
> +       mtk_uart_apdma_write(c, VFF_RST, VFF_WARM_RST_B);
> +
> +       ret = readx_poll_timeout(readl, c->base + VFF_EN, tmp,
> +                       tmp == 0, 10, 100);
> +       if (ret) {
> +               dev_err(chan->device->dev, "dma reset: fail, timeout\n");
> +               return ret;
> +       }
> +
> +       if (!c->requested) {
> +               c->requested = true;
> +               ret = request_irq(mtkd->dma_irq[chan->chan_id],
> +                                 mtk_uart_apdma_irq_handler, IRQF_TRIGGER_NONE,
> +                                 KBUILD_MODNAME, chan);
> +               if (ret < 0) {
> +                       dev_err(chan->device->dev, "Can't request dma IRQ\n");
> +                       return -EINVAL;
> +               }
> +       }
> +
> +       if (mtkd->support_33bits)
> +               mtk_uart_apdma_write(c, VFF_4G_SUPPORT, VFF_4G_SUPPORT_CLR_B);
> +
> +       return ret;
> +}
> +
> +static void mtk_uart_apdma_free_chan_resources(struct dma_chan *chan)
> +{
> +       struct mtk_uart_apdmadev *mtkd = to_mtk_uart_apdma_dev(chan->device);
> +       struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
> +
> +       if (c->requested) {
> +               c->requested = false;
> +               free_irq(mtkd->dma_irq[chan->chan_id], chan);
> +       }
> +
> +       tasklet_kill(&c->vc.task);
> +
> +       vchan_free_chan_resources(&c->vc);
> +
> +       pm_runtime_put_sync(mtkd->ddev.dev);
> +}
> +
> +static enum dma_status mtk_uart_apdma_tx_status(struct dma_chan *chan,
> +                                        dma_cookie_t cookie,
> +                                        struct dma_tx_state *txstate)
> +{
> +       struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
> +       enum dma_status ret;
> +       unsigned long flags;
> +
> +       if (!txstate)
> +               return DMA_ERROR;
> +
> +       ret = dma_cookie_status(chan, cookie, txstate);
> +       spin_lock_irqsave(&c->vc.lock, flags);
> +       if (ret == DMA_IN_PROGRESS) {
> +               c->rx_status = mtk_uart_apdma_read(c, VFF_RPT) & VFF_RING_SIZE;
> +               dma_set_residue(txstate, c->rx_status);
> +       } else if (ret == DMA_COMPLETE && c->cfg.direction == DMA_DEV_TO_MEM) {
> +               dma_set_residue(txstate, c->rx_status);
> +       } else {
> +               dma_set_residue(txstate, 0);
> +       }
> +       spin_unlock_irqrestore(&c->vc.lock, flags);
> +
> +       return ret;
> +}
> +
> +/*
> + * dmaengine_prep_slave_single will call the function. and sglen is 1.
> + * 8250 uart using one ring buffer, and deal with one sg.
> + */
> +static struct dma_async_tx_descriptor *mtk_uart_apdma_prep_slave_sg
> +       (struct dma_chan *chan, struct scatterlist *sgl,
> +       unsigned int sglen, enum dma_transfer_direction dir,
> +       unsigned long tx_flags, void *context)
> +{
> +       struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
> +       struct mtk_uart_apdma_desc *d;
> +
> +       if ((dir != DMA_DEV_TO_MEM) &&
> +               (dir != DMA_MEM_TO_DEV)) {

This line fits in 80 chars.

> +               dev_err(chan->device->dev, "bad direction\n");
> +               return NULL;
> +       }
> +
> +       /* Now allocate and setup the descriptor */
> +       d = kzalloc(sizeof(*d), GFP_ATOMIC);
> +       if (!d)
> +               return NULL;
> +
> +       /* sglen is 1 */
> +       d->avail_len = sg_dma_len(sgl);
> +
> +       return vchan_tx_prep(&c->vc, &d->vd, tx_flags);
> +}
> +
> +static void mtk_uart_apdma_issue_pending(struct dma_chan *chan)
> +{
> +       struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
> +       struct virt_dma_desc *vd;
> +       unsigned long flags;
> +
> +       spin_lock_irqsave(&c->vc.lock, flags);
> +       if (c->cfg.direction == DMA_DEV_TO_MEM) {
> +               if (vchan_issue_pending(&c->vc)) {
> +                       vd = vchan_next_desc(&c->vc);
> +                       c->desc = to_mtk_uart_apdma_desc(&vd->tx);
> +                       mtk_uart_apdma_start_rx(c);
> +               }
> +       } else if (c->cfg.direction == DMA_MEM_TO_DEV) {
> +               if (vchan_issue_pending(&c->vc)) {
> +                       vd = vchan_next_desc(&c->vc);
> +                       c->desc = to_mtk_uart_apdma_desc(&vd->tx);
> +                       mtk_uart_apdma_start_tx(c);
> +               }
> +       }
> +       spin_unlock_irqrestore(&c->vc.lock, flags);
> +}
> +
> +static int mtk_uart_apdma_slave_config(struct dma_chan *chan,
> +                               struct dma_slave_config *cfg)
> +{
> +       struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
> +       struct mtk_uart_apdmadev *mtkd =
> +                               to_mtk_uart_apdma_dev(c->vc.chan.device);
> +
> +       c->cfg = *cfg;
> +
> +       if (cfg->direction == DMA_DEV_TO_MEM) {
> +               unsigned int rx_len = cfg->src_addr_width * 1024;
> +
> +               mtk_uart_apdma_write(c, VFF_ADDR, cfg->src_addr);
> +               mtk_uart_apdma_write(c, VFF_LEN, rx_len);
> +               mtk_uart_apdma_write(c, VFF_THRE, VFF_RX_THRE(rx_len));
> +               mtk_uart_apdma_write(c, VFF_INT_EN,
> +                               VFF_RX_INT_EN0_B | VFF_RX_INT_EN1_B);
> +               mtk_uart_apdma_write(c, VFF_RPT, 0);
> +               mtk_uart_apdma_write(c, VFF_INT_FLAG, VFF_RX_INT_FLAG_CLR_B);
> +               mtk_uart_apdma_write(c, VFF_EN, VFF_EN_B);
> +       } else if (cfg->direction == DMA_MEM_TO_DEV)    {
> +               unsigned int tx_len = cfg->dst_addr_width * 1024;
> +
> +               mtk_uart_apdma_write(c, VFF_ADDR, cfg->dst_addr);
> +               mtk_uart_apdma_write(c, VFF_LEN, tx_len);
> +               mtk_uart_apdma_write(c, VFF_THRE, VFF_TX_THRE(tx_len));
> +               mtk_uart_apdma_write(c, VFF_WPT, 0);
> +               mtk_uart_apdma_write(c, VFF_INT_FLAG, VFF_TX_INT_FLAG_CLR_B);
> +               mtk_uart_apdma_write(c, VFF_EN, VFF_EN_B);
> +       }
> +
> +       if (mtkd->support_33bits)
> +               mtk_uart_apdma_write(c, VFF_4G_SUPPORT, VFF_4G_SUPPORT_B);
> +
> +       if (mtk_uart_apdma_read(c, VFF_EN) != VFF_EN_B) {
> +               dev_err(chan->device->dev, "dir[%d] fail\n", cfg->direction);
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +
> +static int mtk_uart_apdma_terminate_all(struct dma_chan *chan)
> +{
> +       struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
> +       unsigned long flags;
> +       u32 tmp;
> +       int ret;
> +
> +       spin_lock_irqsave(&c->vc.lock, flags);
> +
> +       mtk_uart_apdma_write(c, VFF_FLUSH, VFF_FLUSH_B);
> +       /* Wait 1sec for flush,  can't sleep*/

ditto about comment format

> +       ret = readx_poll_timeout(readl, c->base + VFF_FLUSH, tmp,
> +                       tmp != VFF_FLUSH_B, 0, 1000000);
> +       if (ret)
> +               dev_err(c->vc.chan.device->dev, "flush: fail, debug=0x%x\n",
> +                       mtk_uart_apdma_read(c, VFF_DEBUG_STATUS));
> +
> +       /*set stop as 1 -> wait until en is 0 -> set stop as 0*/
> +       mtk_uart_apdma_write(c, VFF_STOP, VFF_STOP_B);
> +       ret = readx_poll_timeout(readl, c->base + VFF_EN, tmp,
> +                       tmp == 0, 10, 100);
> +       if (ret)
> +               dev_err(c->vc.chan.device->dev, "stop: fail, debug=0x%x\n",
> +                       mtk_uart_apdma_read(c, VFF_DEBUG_STATUS));
> +
> +       mtk_uart_apdma_write(c, VFF_STOP, VFF_STOP_CLR_B);
> +       mtk_uart_apdma_write(c, VFF_INT_EN, VFF_INT_EN_CLR_B);
> +
> +       if (c->cfg.direction == DMA_DEV_TO_MEM)
> +               mtk_uart_apdma_write(c, VFF_INT_FLAG, VFF_RX_INT_FLAG_CLR_B);
> +       else if (c->cfg.direction == DMA_MEM_TO_DEV)
> +               mtk_uart_apdma_write(c, VFF_INT_FLAG, VFF_TX_INT_FLAG_CLR_B);
> +
> +       spin_unlock_irqrestore(&c->vc.lock, flags);
> +
> +       return 0;
> +}
> +
> +static int mtk_uart_apdma_device_pause(struct dma_chan *chan)
> +{
> +       /* just for check caps pass */
> +       return 0;
> +}

This is still not right... Hopefully somebody more familiar with the
DMA subsystem can weigh in, but maybe it's enough to wait for the
current transfer to be flushed and temporarily disable interrupts?
e.g. call mtk_uart_apdma_terminate_all above?

> +
> +static int mtk_uart_apdma_device_resume(struct dma_chan *chan)
> +{
> +       /* just for check caps pass */
> +       return 0;
> +}

Drop this one since you don't really need it.

> +
> +static void mtk_uart_apdma_free(struct mtk_uart_apdmadev *mtkd)
> +{
> +       while (list_empty(&mtkd->ddev.channels) == 0) {

!list_empty(

> +               struct mtk_chan *c = list_first_entry(&mtkd->ddev.channels,
> +                       struct mtk_chan, vc.chan.device_node);
> +
> +               list_del(&c->vc.chan.device_node);
> +               tasklet_kill(&c->vc.task);
> +       }
> +}
> +
> +static const struct of_device_id mtk_uart_apdma_match[] = {
> +       { .compatible = "mediatek,mt6577-uart-dma", },
> +       { /* sentinel */ },
> +};
> +MODULE_DEVICE_TABLE(of, mtk_uart_apdma_match);
> +
> +static int mtk_uart_apdma_probe(struct platform_device *pdev)
> +{
> +       struct mtk_uart_apdmadev *mtkd;
> +       struct resource *res;
> +       struct mtk_chan *c;
> +       unsigned int i;
> +       int rc;
> +
> +       mtkd = devm_kzalloc(&pdev->dev, sizeof(*mtkd), GFP_KERNEL);
> +       if (!mtkd)
> +               return -ENOMEM;
> +
> +       mtkd->clk = devm_clk_get(&pdev->dev, NULL);
> +       if (IS_ERR(mtkd->clk)) {
> +               dev_err(&pdev->dev, "No clock specified\n");
> +               rc = PTR_ERR(mtkd->clk);
> +               return rc;
> +       }
> +
> +       if (of_property_read_bool(pdev->dev.of_node, "dma-33bits"))
> +               mtkd->support_33bits = true;

I don't think this should be a device tree property. Typically we'd
have multiple compatible strings for (slightly) different HW blocks,
and enable 33bits only on HW that have support.

See how it's done in drivers/i2c/busses/i2c-mt65xx.c, for example.

> +
> +       rc = dma_set_mask_and_coherent(&pdev->dev,
> +                               DMA_BIT_MASK(32 | mtkd->support_33bits));

I'd feel a little more confortable if you used a variable instead:

int dma_bits = 32;

if (support_33bits)
   dma_bits = 33;

..., DMA_BIT_MASK(dma_bits));

> +       if (rc)
> +               return rc;
> +
> +       dma_cap_set(DMA_SLAVE, mtkd->ddev.cap_mask);
> +       mtkd->ddev.device_alloc_chan_resources =
> +                               mtk_uart_apdma_alloc_chan_resources;
> +       mtkd->ddev.device_free_chan_resources =
> +                               mtk_uart_apdma_free_chan_resources;
> +       mtkd->ddev.device_tx_status = mtk_uart_apdma_tx_status;
> +       mtkd->ddev.device_issue_pending = mtk_uart_apdma_issue_pending;
> +       mtkd->ddev.device_prep_slave_sg = mtk_uart_apdma_prep_slave_sg;
> +       mtkd->ddev.device_config = mtk_uart_apdma_slave_config;
> +       mtkd->ddev.device_pause = mtk_uart_apdma_device_pause;
> +       mtkd->ddev.device_resume = mtk_uart_apdma_device_resume;
> +       mtkd->ddev.device_terminate_all = mtk_uart_apdma_terminate_all;
> +       mtkd->ddev.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE);
> +       mtkd->ddev.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE);
> +       mtkd->ddev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
> +       mtkd->ddev.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT;
> +       mtkd->ddev.dev = &pdev->dev;
> +       INIT_LIST_HEAD(&mtkd->ddev.channels);
> +
> +       for (i = 0; i < MTK_UART_APDMA_CHANNELS; i++) {
> +               c = devm_kzalloc(mtkd->ddev.dev, sizeof(*c), GFP_KERNEL);
> +               if (!c) {
> +                       rc = -ENODEV;
> +                       goto err_no_dma;
> +               }
> +
> +               res = platform_get_resource(pdev, IORESOURCE_MEM, i);
> +               if (!res) {
> +                       rc = -ENODEV;
> +                       goto err_no_dma;
> +               }
> +
> +               c->base = devm_ioremap_resource(&pdev->dev, res);
> +               if (IS_ERR(c->base)) {
> +                       rc = PTR_ERR(c->base);
> +                       goto err_no_dma;
> +               }
> +               c->requested = false;
> +               c->vc.desc_free = mtk_uart_apdma_desc_free;
> +               vchan_init(&c->vc, &mtkd->ddev);
> +
> +               mtkd->dma_irq[i] = platform_get_irq(pdev, i);
> +               if ((int)mtkd->dma_irq[i] < 0) {
> +                       dev_err(&pdev->dev, "failed to get IRQ[%d]\n", i);
> +                       rc = -EINVAL;
> +                       goto err_no_dma;
> +               }
> +       }
> +
> +       pm_runtime_enable(&pdev->dev);
> +       pm_runtime_set_active(&pdev->dev);
> +
> +       rc = dma_async_device_register(&mtkd->ddev);
> +       if (rc)
> +               goto rpm_disable;
> +
> +       platform_set_drvdata(pdev, mtkd);
> +
> +       if (pdev->dev.of_node) {
> +               /* Device-tree DMA controller registration */
> +               rc = of_dma_controller_register(pdev->dev.of_node,
> +                                               of_dma_xlate_by_chan_id,
> +                                               mtkd);
> +               if (rc)
> +                       goto dma_remove;
> +       }
> +
> +       return rc;
> +
> +dma_remove:
> +       dma_async_device_unregister(&mtkd->ddev);
> +rpm_disable:
> +       pm_runtime_disable(&pdev->dev);
> +err_no_dma:
> +       mtk_uart_apdma_free(mtkd);
> +       return rc;
> +}
> +
> +static int mtk_uart_apdma_remove(struct platform_device *pdev)
> +{
> +       struct mtk_uart_apdmadev *mtkd = platform_get_drvdata(pdev);
> +
> +       if (pdev->dev.of_node)
> +               of_dma_controller_free(pdev->dev.of_node);
> +
> +       pm_runtime_disable(&pdev->dev);
> +       pm_runtime_put_noidle(&pdev->dev);
> +
> +       dma_async_device_unregister(&mtkd->ddev);
> +       mtk_uart_apdma_free(mtkd);
> +
> +       return 0;
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int mtk_uart_apdma_suspend(struct device *dev)
> +{
> +       struct mtk_uart_apdmadev *mtkd = dev_get_drvdata(dev);
> +
> +       if (!pm_runtime_suspended(dev))
> +               clk_disable_unprepare(mtkd->clk);
> +
> +       return 0;
> +}
> +
> +static int mtk_uart_apdma_resume(struct device *dev)
> +{
> +       int ret;
> +       struct mtk_uart_apdmadev *mtkd = dev_get_drvdata(dev);
> +
> +       if (!pm_runtime_suspended(dev)) {
> +               ret = clk_prepare_enable(mtkd->clk);
> +               if (ret)
> +                       return ret;
> +       }
> +
> +       return 0;
> +}
> +#endif /* CONFIG_PM_SLEEP */
> +
> +#ifdef CONFIG_PM
> +static int mtk_uart_apdma_runtime_suspend(struct device *dev)
> +{
> +       struct mtk_uart_apdmadev *mtkd = dev_get_drvdata(dev);
> +
> +       clk_disable_unprepare(mtkd->clk);
> +
> +       return 0;
> +}
> +
> +static int mtk_uart_apdma_runtime_resume(struct device *dev)
> +{
> +       int ret;
> +       struct mtk_uart_apdmadev *mtkd = dev_get_drvdata(dev);
> +
> +       ret = clk_prepare_enable(mtkd->clk);
> +       if (ret)
> +               return ret;
> +
> +       return 0;
> +}
> +#endif /* CONFIG_PM */
> +
> +static const struct dev_pm_ops mtk_uart_apdma_pm_ops = {
> +       SET_SYSTEM_SLEEP_PM_OPS(mtk_uart_apdma_suspend, mtk_uart_apdma_resume)
> +       SET_RUNTIME_PM_OPS(mtk_uart_apdma_runtime_suspend,
> +                          mtk_uart_apdma_runtime_resume, NULL)
> +};
> +
> +static struct platform_driver mtk_uart_apdma_driver = {
> +       .probe  = mtk_uart_apdma_probe,
> +       .remove = mtk_uart_apdma_remove,
> +       .driver = {
> +               .name           = KBUILD_MODNAME,
> +               .pm             = &mtk_uart_apdma_pm_ops,
> +               .of_match_table = of_match_ptr(mtk_uart_apdma_match),
> +       },
> +};
> +
> +module_platform_driver(mtk_uart_apdma_driver);
> +
> +MODULE_DESCRIPTION("MediaTek UART APDMA Controller Driver");
> +MODULE_AUTHOR("Long Cheng <long.cheng@mediatek.com>");
> +MODULE_LICENSE("GPL v2");
> +
> diff --git a/drivers/dma/mediatek/Kconfig b/drivers/dma/mediatek/Kconfig
> index 27bac0b..1a523c87 100644
> --- a/drivers/dma/mediatek/Kconfig
> +++ b/drivers/dma/mediatek/Kconfig
> @@ -1,4 +1,15 @@
>
> +config DMA_MTK_UART
> +       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.
> +
>  config MTK_HSDMA
>         tristate "MediaTek High-Speed DMA controller support"
>         depends on ARCH_MEDIATEK || COMPILE_TEST
> diff --git a/drivers/dma/mediatek/Makefile b/drivers/dma/mediatek/Makefile
> index 6e778f8..2f2efd9 100644
> --- a/drivers/dma/mediatek/Makefile
> +++ b/drivers/dma/mediatek/Makefile
> @@ -1 +1,2 @@
> +obj-$(CONFIG_DMA_MTK_UART) += 8250_mtk_dma.o
>  obj-$(CONFIG_MTK_HSDMA) += mtk-hsdma.o
> --
> 1.7.9.5
>

^ permalink raw reply

* Re: [PATCH v9 1/2] dmaengine: 8250_mtk_dma: add MediaTek uart DMA support
From: Randy Dunlap @ 2019-01-03  2:03 UTC (permalink / raw)
  To: Nicolas Boichat, Long Cheng
  Cc: Vinod Koul, Rob Herring, Mark Rutland, Ryder Lee, Sean Wang,
	Matthias Brugger, Dan Williams, Greg Kroah-Hartman, Jiri Slaby,
	Sean Wang, dmaengine, devicetree, linux-arm Mailing List,
	linux-mediatek, lkml, linux-serial, srv_heupstream, Yingjoe Chen,
	YT Shen, Zhenbao Liu
In-Reply-To: <CANMq1KB=yuEJxUdi8M9deDhAv24WZ-4h+26cFq7AzBi8uyd88Q@mail.gmail.com>

Hi,

While you are making changes, here are a few more:


On 1/2/19 5:39 PM, Nicolas Boichat wrote:
> diff --git a/drivers/dma/mediatek/Kconfig b/drivers/dma/mediatek/Kconfig
> index 27bac0b..1a523c87 100644
> --- a/drivers/dma/mediatek/Kconfig
> +++ b/drivers/dma/mediatek/Kconfig
> @@ -1,4 +1,15 @@
> 
> +config DMA_MTK_UART
> +       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,

	    When

> +         you can enable the config. the DMA engine can only be used

	                               The

> +         with MediaTek SoCs.
> +

Also, use tabs to indent instead of spaces.
The lines (tristate, depends, select, and help) should be indented with one tab.
The help text lines should be indented with one tab + 2 spaces.

>  config MTK_HSDMA
>         tristate "MediaTek High-Speed DMA controller support"
>         depends on ARCH_MEDIATEK || COMPILE_TEST


thanks,
-- 
~Randy

^ permalink raw reply

* Re: [PATCH v5 6/6] arm64: dts: Add Mediatek SoC MT8183 and evaluation board dts and Makefile
From: Erin Lo @ 2019-01-03  2:40 UTC (permalink / raw)
  To: Rob Herring
  Cc: Matthias Brugger, Mark Rutland, Thomas Gleixner, Jason Cooper,
	Marc Zyngier, Greg Kroah-Hartman, Stephen Boyd, devicetree,
	srv_heupstream, linux-kernel, linux-serial, linux-mediatek,
	linux-arm-kernel, yingjoe.chen, mars.cheng, eddie.huang,
	linux-clk, Ben Ho, Seiya Wang, Zhiyong Tao, Weiyi Lu
In-Reply-To: <20181228221101.GA1044@bogus>

On Fri, 2018-12-28 at 16:11 -0600, Rob Herring wrote:
> On Fri, Dec 28, 2018 at 04:09:41PM +0800, Erin Lo wrote:
> > From: Ben Ho <Ben.Ho@mediatek.com>
> > 
> > Add basic chip support for Mediatek 8183, include
> > pinctrl file, uart node with correct uart clocks, pwrap device
> > M4U, smi-common and smi-larbs.
> > 
> > Add clock controller nodes, include topckgen, infracfg,
> > apmixedsys and subsystem.
> > 
> > Add power controller and scpsys node.
> > 
> > Signed-off-by: Ben Ho <Ben.Ho@mediatek.com>
> > Signed-off-by: Erin Lo <erin.lo@mediatek.com>
> > Signed-off-by: Seiya Wang <seiya.wang@mediatek.com>
> > Signed-off-by: Zhiyong Tao <zhiyong.tao@mediatek.com>
> > Signed-off-by: Weiyi Lu <weiyi.lu@mediatek.com>
> > Signed-off-by: Yong Wu <yong.wu@mediatek.com>
> > Signed-off-by: Mengqi Zhang <Mengqi.Zhang@mediatek.com>
> > Signed-off-by: Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>
> > Signed-off-by: Eddie Huang <eddie.huang@mediatek.com>
> > ---
> >  arch/arm64/boot/dts/mediatek/Makefile         |    1 +
> >  arch/arm64/boot/dts/mediatek/mt8183-evb.dts   |  136 +++
> >  arch/arm64/boot/dts/mediatek/mt8183-pinfunc.h | 1120 +++++++++++++++++++++++++
> >  arch/arm64/boot/dts/mediatek/mt8183.dtsi      |  547 ++++++++++++
> >  4 files changed, 1804 insertions(+)
> >  create mode 100644 arch/arm64/boot/dts/mediatek/mt8183-evb.dts
> >  create mode 100644 arch/arm64/boot/dts/mediatek/mt8183-pinfunc.h
> >  create mode 100644 arch/arm64/boot/dts/mediatek/mt8183.dtsi
> > 
> > diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
> > index e8f952f..458bbc4 100644
> > --- a/arch/arm64/boot/dts/mediatek/Makefile
> > +++ b/arch/arm64/boot/dts/mediatek/Makefile
> > @@ -7,3 +7,4 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-x20-dev.dtb
> >  dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-rfb1.dtb
> >  dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-bananapi-bpi-r64.dtb
> >  dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-evb.dtb
> > +dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-evb.dtb
> > diff --git a/arch/arm64/boot/dts/mediatek/mt8183-evb.dts b/arch/arm64/boot/dts/mediatek/mt8183-evb.dts
> > new file mode 100644
> > index 0000000..5d308cb
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/mediatek/mt8183-evb.dts
> > @@ -0,0 +1,136 @@
> > +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> > +/*
> > + * Copyright (c) 2018 MediaTek Inc.
> > + * Author: Ben Ho <ben.ho@mediatek.com>
> > + *	   Erin Lo <erin.lo@mediatek.com>
> > + */
> > +
> > +/dts-v1/;
> > +#include "mt8183.dtsi"
> > +
> > +/ {
> > +	model = "MediaTek MT8183 evaluation board";
> > +	compatible = "mediatek,mt8183-evb", "mediatek,mt8183";
> > +
> > +	aliases {
> > +		serial0 = &uart0;
> > +	};
> > +
> > +	memory@40000000 {
> > +		device_type = "memory";
> > +		reg = <0 0x40000000 0 0x80000000>;
> > +	};
> > +
> > +	chosen {
> > +		stdout-path = "serial0:921600n8";
> > +	};
> > +};
> > +
> > +&pio {
> > +	spi_pins_0: spi0@0{
> 
> Build your dtb with W=1 and fix the warnings.

I will do it next time.
Thank you~

> 
> > +		pins_spi{
> > +			pinmux = <PINMUX_GPIO85__FUNC_SPI0_MI>,
> > +				 <PINMUX_GPIO86__FUNC_SPI0_CSB>,
> > +				 <PINMUX_GPIO87__FUNC_SPI0_MO>,
> > +				 <PINMUX_GPIO88__FUNC_SPI0_CLK>;
> > +			bias-disable;
> > +		};
> > +	};
> > +
> > +	spi_pins_1: spi1@0{
> > +		pins_spi{
> > +			pinmux = <PINMUX_GPIO161__FUNC_SPI1_A_MI>,
> > +				 <PINMUX_GPIO162__FUNC_SPI1_A_CSB>,
> > +				 <PINMUX_GPIO163__FUNC_SPI1_A_MO>,
> > +				 <PINMUX_GPIO164__FUNC_SPI1_A_CLK>;
> > +			bias-disable;
> > +		};
> > +	};
> > +
> > +	spi_pins_2: spi2@0{
> > +		pins_spi{
> > +			pinmux = <PINMUX_GPIO0__FUNC_SPI2_CSB>,
> > +				 <PINMUX_GPIO1__FUNC_SPI2_MO>,
> > +				 <PINMUX_GPIO2__FUNC_SPI2_CLK>,
> > +				 <PINMUX_GPIO94__FUNC_SPI2_MI>;
> > +			bias-disable;
> > +		};
> > +	};
> > +
> > +	spi_pins_3: spi3@0{
> > +		pins_spi{
> > +			pinmux = <PINMUX_GPIO21__FUNC_SPI3_MI>,
> > +				 <PINMUX_GPIO22__FUNC_SPI3_CSB>,
> > +				 <PINMUX_GPIO23__FUNC_SPI3_MO>,
> > +				 <PINMUX_GPIO24__FUNC_SPI3_CLK>;
> > +			bias-disable;
> > +		};
> > +	};
> > +
> > +	spi_pins_4: spi4@0{
> > +		pins_spi{
> > +			pinmux = <PINMUX_GPIO17__FUNC_SPI4_MI>,
> > +				 <PINMUX_GPIO18__FUNC_SPI4_CSB>,
> > +				 <PINMUX_GPIO19__FUNC_SPI4_MO>,
> > +				 <PINMUX_GPIO20__FUNC_SPI4_CLK>;
> > +			bias-disable;
> > +		};
> > +	};
> > +
> > +	spi_pins_5: spi5@0{
> > +		pins_spi{
> > +			pinmux = <PINMUX_GPIO13__FUNC_SPI5_MI>,
> > +				 <PINMUX_GPIO14__FUNC_SPI5_CSB>,
> > +				 <PINMUX_GPIO15__FUNC_SPI5_MO>,
> > +				 <PINMUX_GPIO16__FUNC_SPI5_CLK>;
> > +			bias-disable;
> > +		};
> > +	};
> > +};
> > +
> > +&spi0 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&spi_pins_0>;
> > +	mediatek,pad-select = <0>;
> > +	status = "okay";
> > +};
> > +
> > +&spi1 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&spi_pins_1>;
> > +	mediatek,pad-select = <0>;
> > +	status = "okay";
> > +};
> > +
> > +&spi2 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&spi_pins_2>;
> > +	mediatek,pad-select = <0>;
> > +	status = "okay";
> > +};
> > +
> > +&spi3 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&spi_pins_3>;
> > +	mediatek,pad-select = <0>;
> > +	status = "okay";
> > +};
> > +
> > +&spi4 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&spi_pins_4>;
> > +	mediatek,pad-select = <0>;
> > +	status = "okay";
> > +};
> > +
> > +&spi5 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&spi_pins_5>;
> > +	mediatek,pad-select = <0>;
> > +	status = "okay";
> > +
> > +};
> > +
> > +&uart0 {
> > +	status = "okay";
> > +};
> > diff --git a/arch/arm64/boot/dts/mediatek/mt8183-pinfunc.h b/arch/arm64/boot/dts/mediatek/mt8183-pinfunc.h
> > new file mode 100644
> > index 0000000..768e41e
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/mediatek/mt8183-pinfunc.h
> > @@ -0,0 +1,1120 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2018 MediaTek Inc.
> > + * Author: Zhiyong Tao <zhiyong.tao@mediatek.com>
> > + *
> > + */
> > +
> > +#ifndef __MT8183_PINFUNC_H
> > +#define __MT8183_PINFUNC_H
> > +
> > +#include <dt-bindings/pinctrl/mt65xx.h>
> > +
> > +#define PINMUX_GPIO0__FUNC_GPIO0 (MTK_PIN_NO(0) | 0)
> > +#define PINMUX_GPIO0__FUNC_MRG_SYNC (MTK_PIN_NO(0) | 1)
> > +#define PINMUX_GPIO0__FUNC_PCM0_SYNC (MTK_PIN_NO(0) | 2)
> > +#define PINMUX_GPIO0__FUNC_TP_GPIO0_AO (MTK_PIN_NO(0) | 3)
> > +#define PINMUX_GPIO0__FUNC_SRCLKENAI0 (MTK_PIN_NO(0) | 4)
> > +#define PINMUX_GPIO0__FUNC_SCP_SPI2_CS (MTK_PIN_NO(0) | 5)
> > +#define PINMUX_GPIO0__FUNC_I2S3_MCK (MTK_PIN_NO(0) | 6)
> > +#define PINMUX_GPIO0__FUNC_SPI2_CSB (MTK_PIN_NO(0) | 7)
> > +
> > +#define PINMUX_GPIO1__FUNC_GPIO1 (MTK_PIN_NO(1) | 0)
> > +#define PINMUX_GPIO1__FUNC_MRG_CLK (MTK_PIN_NO(1) | 1)
> > +#define PINMUX_GPIO1__FUNC_PCM0_CLK (MTK_PIN_NO(1) | 2)
> > +#define PINMUX_GPIO1__FUNC_TP_GPIO1_AO (MTK_PIN_NO(1) | 3)
> > +#define PINMUX_GPIO1__FUNC_CLKM3 (MTK_PIN_NO(1) | 4)
> > +#define PINMUX_GPIO1__FUNC_SCP_SPI2_MO (MTK_PIN_NO(1) | 5)
> > +#define PINMUX_GPIO1__FUNC_I2S3_BCK (MTK_PIN_NO(1) | 6)
> > +#define PINMUX_GPIO1__FUNC_SPI2_MO (MTK_PIN_NO(1) | 7)
> > +
> > +#define PINMUX_GPIO2__FUNC_GPIO2 (MTK_PIN_NO(2) | 0)
> > +#define PINMUX_GPIO2__FUNC_MRG_DO (MTK_PIN_NO(2) | 1)
> > +#define PINMUX_GPIO2__FUNC_PCM0_DO (MTK_PIN_NO(2) | 2)
> > +#define PINMUX_GPIO2__FUNC_TP_GPIO2_AO (MTK_PIN_NO(2) | 3)
> > +#define PINMUX_GPIO2__FUNC_SCL6 (MTK_PIN_NO(2) | 4)
> > +#define PINMUX_GPIO2__FUNC_SCP_SPI2_CK (MTK_PIN_NO(2) | 5)
> > +#define PINMUX_GPIO2__FUNC_I2S3_LRCK (MTK_PIN_NO(2) | 6)
> > +#define PINMUX_GPIO2__FUNC_SPI2_CLK (MTK_PIN_NO(2) | 7)
> > +
> > +#define PINMUX_GPIO3__FUNC_GPIO3 (MTK_PIN_NO(3) | 0)
> > +#define PINMUX_GPIO3__FUNC_MRG_DI (MTK_PIN_NO(3) | 1)
> > +#define PINMUX_GPIO3__FUNC_PCM0_DI (MTK_PIN_NO(3) | 2)
> > +#define PINMUX_GPIO3__FUNC_TP_GPIO3_AO (MTK_PIN_NO(3) | 3)
> > +#define PINMUX_GPIO3__FUNC_SDA6 (MTK_PIN_NO(3) | 4)
> > +#define PINMUX_GPIO3__FUNC_TDM_MCK (MTK_PIN_NO(3) | 5)
> > +#define PINMUX_GPIO3__FUNC_I2S3_DO (MTK_PIN_NO(3) | 6)
> > +#define PINMUX_GPIO3__FUNC_SCP_VREQ_VAO (MTK_PIN_NO(3) | 7)
> > +
> > +#define PINMUX_GPIO4__FUNC_GPIO4 (MTK_PIN_NO(4) | 0)
> > +#define PINMUX_GPIO4__FUNC_PWM_B (MTK_PIN_NO(4) | 1)
> > +#define PINMUX_GPIO4__FUNC_I2S0_MCK (MTK_PIN_NO(4) | 2)
> > +#define PINMUX_GPIO4__FUNC_SSPM_UTXD_AO (MTK_PIN_NO(4) | 3)
> > +#define PINMUX_GPIO4__FUNC_MD_URXD1 (MTK_PIN_NO(4) | 4)
> > +#define PINMUX_GPIO4__FUNC_TDM_BCK (MTK_PIN_NO(4) | 5)
> > +#define PINMUX_GPIO4__FUNC_TP_GPIO4_AO (MTK_PIN_NO(4) | 6)
> > +#define PINMUX_GPIO4__FUNC_DAP_MD32_SWD (MTK_PIN_NO(4) | 7)
> > +
> > +#define PINMUX_GPIO5__FUNC_GPIO5 (MTK_PIN_NO(5) | 0)
> > +#define PINMUX_GPIO5__FUNC_PWM_C (MTK_PIN_NO(5) | 1)
> > +#define PINMUX_GPIO5__FUNC_I2S0_BCK (MTK_PIN_NO(5) | 2)
> > +#define PINMUX_GPIO5__FUNC_SSPM_URXD_AO (MTK_PIN_NO(5) | 3)
> > +#define PINMUX_GPIO5__FUNC_MD_UTXD1 (MTK_PIN_NO(5) | 4)
> > +#define PINMUX_GPIO5__FUNC_TDM_LRCK (MTK_PIN_NO(5) | 5)
> > +#define PINMUX_GPIO5__FUNC_TP_GPIO5_AO (MTK_PIN_NO(5) | 6)
> > +#define PINMUX_GPIO5__FUNC_DAP_MD32_SWCK (MTK_PIN_NO(5) | 7)
> > +
> > +#define PINMUX_GPIO6__FUNC_GPIO6 (MTK_PIN_NO(6) | 0)
> > +#define PINMUX_GPIO6__FUNC_PWM_A (MTK_PIN_NO(6) | 1)
> > +#define PINMUX_GPIO6__FUNC_I2S0_LRCK (MTK_PIN_NO(6) | 2)
> > +#define PINMUX_GPIO6__FUNC_IDDIG (MTK_PIN_NO(6) | 3)
> > +#define PINMUX_GPIO6__FUNC_MD_URXD0 (MTK_PIN_NO(6) | 4)
> > +#define PINMUX_GPIO6__FUNC_TDM_DATA0 (MTK_PIN_NO(6) | 5)
> > +#define PINMUX_GPIO6__FUNC_TP_GPIO6_AO (MTK_PIN_NO(6) | 6)
> > +#define PINMUX_GPIO6__FUNC_CMFLASH (MTK_PIN_NO(6) | 7)
> > +
> > +#define PINMUX_GPIO7__FUNC_GPIO7 (MTK_PIN_NO(7) | 0)
> > +#define PINMUX_GPIO7__FUNC_SPI1_B_MI (MTK_PIN_NO(7) | 1)
> > +#define PINMUX_GPIO7__FUNC_I2S0_DI (MTK_PIN_NO(7) | 2)
> > +#define PINMUX_GPIO7__FUNC_USB_DRVVBUS (MTK_PIN_NO(7) | 3)
> > +#define PINMUX_GPIO7__FUNC_MD_UTXD0 (MTK_PIN_NO(7) | 4)
> > +#define PINMUX_GPIO7__FUNC_TDM_DATA1 (MTK_PIN_NO(7) | 5)
> > +#define PINMUX_GPIO7__FUNC_TP_GPIO7_AO (MTK_PIN_NO(7) | 6)
> > +#define PINMUX_GPIO7__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(7) | 7)
> > +
> > +#define PINMUX_GPIO8__FUNC_GPIO8 (MTK_PIN_NO(8) | 0)
> > +#define PINMUX_GPIO8__FUNC_SPI1_B_CSB (MTK_PIN_NO(8) | 1)
> > +#define PINMUX_GPIO8__FUNC_ANT_SEL3 (MTK_PIN_NO(8) | 2)
> > +#define PINMUX_GPIO8__FUNC_SCL7 (MTK_PIN_NO(8) | 3)
> > +#define PINMUX_GPIO8__FUNC_CONN_MCU_TRST_B (MTK_PIN_NO(8) | 4)
> > +#define PINMUX_GPIO8__FUNC_TDM_DATA2 (MTK_PIN_NO(8) | 5)
> > +#define PINMUX_GPIO8__FUNC_MD_INT0 (MTK_PIN_NO(8) | 6)
> > +#define PINMUX_GPIO8__FUNC_JTRSTN_SEL1 (MTK_PIN_NO(8) | 7)
> > +
> > +#define PINMUX_GPIO9__FUNC_GPIO9 (MTK_PIN_NO(9) | 0)
> > +#define PINMUX_GPIO9__FUNC_SPI1_B_MO (MTK_PIN_NO(9) | 1)
> > +#define PINMUX_GPIO9__FUNC_ANT_SEL4 (MTK_PIN_NO(9) | 2)
> > +#define PINMUX_GPIO9__FUNC_CMMCLK2 (MTK_PIN_NO(9) | 3)
> > +#define PINMUX_GPIO9__FUNC_CONN_MCU_DBGACK_N (MTK_PIN_NO(9) | 4)
> > +#define PINMUX_GPIO9__FUNC_SSPM_JTAG_TRSTN (MTK_PIN_NO(9) | 5)
> > +#define PINMUX_GPIO9__FUNC_IO_JTAG_TRSTN (MTK_PIN_NO(9) | 6)
> > +#define PINMUX_GPIO9__FUNC_DBG_MON_B10 (MTK_PIN_NO(9) | 7)
> > +
> > +#define PINMUX_GPIO10__FUNC_GPIO10 (MTK_PIN_NO(10) | 0)
> > +#define PINMUX_GPIO10__FUNC_SPI1_B_CLK (MTK_PIN_NO(10) | 1)
> > +#define PINMUX_GPIO10__FUNC_ANT_SEL5 (MTK_PIN_NO(10) | 2)
> > +#define PINMUX_GPIO10__FUNC_CMMCLK3 (MTK_PIN_NO(10) | 3)
> > +#define PINMUX_GPIO10__FUNC_CONN_MCU_DBGI_N (MTK_PIN_NO(10) | 4)
> > +#define PINMUX_GPIO10__FUNC_TDM_DATA3 (MTK_PIN_NO(10) | 5)
> > +#define PINMUX_GPIO10__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(10) | 6)
> > +#define PINMUX_GPIO10__FUNC_DBG_MON_B11 (MTK_PIN_NO(10) | 7)
> > +
> > +#define PINMUX_GPIO11__FUNC_GPIO11 (MTK_PIN_NO(11) | 0)
> > +#define PINMUX_GPIO11__FUNC_TP_URXD1_AO (MTK_PIN_NO(11) | 1)
> > +#define PINMUX_GPIO11__FUNC_IDDIG (MTK_PIN_NO(11) | 2)
> > +#define PINMUX_GPIO11__FUNC_SCL6 (MTK_PIN_NO(11) | 3)
> > +#define PINMUX_GPIO11__FUNC_UCTS1 (MTK_PIN_NO(11) | 4)
> > +#define PINMUX_GPIO11__FUNC_UCTS0 (MTK_PIN_NO(11) | 5)
> > +#define PINMUX_GPIO11__FUNC_SRCLKENAI1 (MTK_PIN_NO(11) | 6)
> > +#define PINMUX_GPIO11__FUNC_I2S5_MCK (MTK_PIN_NO(11) | 7)
> > +
> > +#define PINMUX_GPIO12__FUNC_GPIO12 (MTK_PIN_NO(12) | 0)
> > +#define PINMUX_GPIO12__FUNC_TP_UTXD1_AO (MTK_PIN_NO(12) | 1)
> > +#define PINMUX_GPIO12__FUNC_USB_DRVVBUS (MTK_PIN_NO(12) | 2)
> > +#define PINMUX_GPIO12__FUNC_SDA6 (MTK_PIN_NO(12) | 3)
> > +#define PINMUX_GPIO12__FUNC_URTS1 (MTK_PIN_NO(12) | 4)
> > +#define PINMUX_GPIO12__FUNC_URTS0 (MTK_PIN_NO(12) | 5)
> > +#define PINMUX_GPIO12__FUNC_I2S2_DI2 (MTK_PIN_NO(12) | 6)
> > +#define PINMUX_GPIO12__FUNC_I2S5_BCK (MTK_PIN_NO(12) | 7)
> > +
> > +#define PINMUX_GPIO13__FUNC_GPIO13 (MTK_PIN_NO(13) | 0)
> > +#define PINMUX_GPIO13__FUNC_DBPI_D0 (MTK_PIN_NO(13) | 1)
> > +#define PINMUX_GPIO13__FUNC_SPI5_MI (MTK_PIN_NO(13) | 2)
> > +#define PINMUX_GPIO13__FUNC_PCM0_SYNC (MTK_PIN_NO(13) | 3)
> > +#define PINMUX_GPIO13__FUNC_MD_URXD0 (MTK_PIN_NO(13) | 4)
> > +#define PINMUX_GPIO13__FUNC_ANT_SEL3 (MTK_PIN_NO(13) | 5)
> > +#define PINMUX_GPIO13__FUNC_I2S0_MCK (MTK_PIN_NO(13) | 6)
> > +#define PINMUX_GPIO13__FUNC_DBG_MON_B15 (MTK_PIN_NO(13) | 7)
> > +
> > +#define PINMUX_GPIO14__FUNC_GPIO14 (MTK_PIN_NO(14) | 0)
> > +#define PINMUX_GPIO14__FUNC_DBPI_D1 (MTK_PIN_NO(14) | 1)
> > +#define PINMUX_GPIO14__FUNC_SPI5_CSB (MTK_PIN_NO(14) | 2)
> > +#define PINMUX_GPIO14__FUNC_PCM0_CLK (MTK_PIN_NO(14) | 3)
> > +#define PINMUX_GPIO14__FUNC_MD_UTXD0 (MTK_PIN_NO(14) | 4)
> > +#define PINMUX_GPIO14__FUNC_ANT_SEL4 (MTK_PIN_NO(14) | 5)
> > +#define PINMUX_GPIO14__FUNC_I2S0_BCK (MTK_PIN_NO(14) | 6)
> > +#define PINMUX_GPIO14__FUNC_DBG_MON_B16 (MTK_PIN_NO(14) | 7)
> > +
> > +#define PINMUX_GPIO15__FUNC_GPIO15 (MTK_PIN_NO(15) | 0)
> > +#define PINMUX_GPIO15__FUNC_DBPI_D2 (MTK_PIN_NO(15) | 1)
> > +#define PINMUX_GPIO15__FUNC_SPI5_MO (MTK_PIN_NO(15) | 2)
> > +#define PINMUX_GPIO15__FUNC_PCM0_DO (MTK_PIN_NO(15) | 3)
> > +#define PINMUX_GPIO15__FUNC_MD_URXD1 (MTK_PIN_NO(15) | 4)
> > +#define PINMUX_GPIO15__FUNC_ANT_SEL5 (MTK_PIN_NO(15) | 5)
> > +#define PINMUX_GPIO15__FUNC_I2S0_LRCK (MTK_PIN_NO(15) | 6)
> > +#define PINMUX_GPIO15__FUNC_DBG_MON_B17 (MTK_PIN_NO(15) | 7)
> > +
> > +#define PINMUX_GPIO16__FUNC_GPIO16 (MTK_PIN_NO(16) | 0)
> > +#define PINMUX_GPIO16__FUNC_DBPI_D3 (MTK_PIN_NO(16) | 1)
> > +#define PINMUX_GPIO16__FUNC_SPI5_CLK (MTK_PIN_NO(16) | 2)
> > +#define PINMUX_GPIO16__FUNC_PCM0_DI (MTK_PIN_NO(16) | 3)
> > +#define PINMUX_GPIO16__FUNC_MD_UTXD1 (MTK_PIN_NO(16) | 4)
> > +#define PINMUX_GPIO16__FUNC_ANT_SEL6 (MTK_PIN_NO(16) | 5)
> > +#define PINMUX_GPIO16__FUNC_I2S0_DI (MTK_PIN_NO(16) | 6)
> > +#define PINMUX_GPIO16__FUNC_DBG_MON_B23 (MTK_PIN_NO(16) | 7)
> > +
> > +#define PINMUX_GPIO17__FUNC_GPIO17 (MTK_PIN_NO(17) | 0)
> > +#define PINMUX_GPIO17__FUNC_DBPI_D4 (MTK_PIN_NO(17) | 1)
> > +#define PINMUX_GPIO17__FUNC_SPI4_MI (MTK_PIN_NO(17) | 2)
> > +#define PINMUX_GPIO17__FUNC_CONN_MCU_TRST_B (MTK_PIN_NO(17) | 3)
> > +#define PINMUX_GPIO17__FUNC_MD_INT0 (MTK_PIN_NO(17) | 4)
> > +#define PINMUX_GPIO17__FUNC_ANT_SEL7 (MTK_PIN_NO(17) | 5)
> > +#define PINMUX_GPIO17__FUNC_I2S3_MCK (MTK_PIN_NO(17) | 6)
> > +#define PINMUX_GPIO17__FUNC_DBG_MON_A1 (MTK_PIN_NO(17) | 7)
> > +
> > +#define PINMUX_GPIO18__FUNC_GPIO18 (MTK_PIN_NO(18) | 0)
> > +#define PINMUX_GPIO18__FUNC_DBPI_D5 (MTK_PIN_NO(18) | 1)
> > +#define PINMUX_GPIO18__FUNC_SPI4_CSB (MTK_PIN_NO(18) | 2)
> > +#define PINMUX_GPIO18__FUNC_CONN_MCU_DBGI_N (MTK_PIN_NO(18) | 3)
> > +#define PINMUX_GPIO18__FUNC_MD_INT0 (MTK_PIN_NO(18) | 4)
> > +#define PINMUX_GPIO18__FUNC_SCP_VREQ_VAO (MTK_PIN_NO(18) | 5)
> > +#define PINMUX_GPIO18__FUNC_I2S3_BCK (MTK_PIN_NO(18) | 6)
> > +#define PINMUX_GPIO18__FUNC_DBG_MON_A2 (MTK_PIN_NO(18) | 7)
> > +
> > +#define PINMUX_GPIO19__FUNC_GPIO19 (MTK_PIN_NO(19) | 0)
> > +#define PINMUX_GPIO19__FUNC_DBPI_D6 (MTK_PIN_NO(19) | 1)
> > +#define PINMUX_GPIO19__FUNC_SPI4_MO (MTK_PIN_NO(19) | 2)
> > +#define PINMUX_GPIO19__FUNC_CONN_MCU_TDO (MTK_PIN_NO(19) | 3)
> > +#define PINMUX_GPIO19__FUNC_MD_INT2_C2K_UIM1_HOT_PLUG (MTK_PIN_NO(19) | 4)
> > +#define PINMUX_GPIO19__FUNC_URXD1 (MTK_PIN_NO(19) | 5)
> > +#define PINMUX_GPIO19__FUNC_I2S3_LRCK (MTK_PIN_NO(19) | 6)
> > +#define PINMUX_GPIO19__FUNC_DBG_MON_A3 (MTK_PIN_NO(19) | 7)
> > +
> > +#define PINMUX_GPIO20__FUNC_GPIO20 (MTK_PIN_NO(20) | 0)
> > +#define PINMUX_GPIO20__FUNC_DBPI_D7 (MTK_PIN_NO(20) | 1)
> > +#define PINMUX_GPIO20__FUNC_SPI4_CLK (MTK_PIN_NO(20) | 2)
> > +#define PINMUX_GPIO20__FUNC_CONN_MCU_DBGACK_N (MTK_PIN_NO(20) | 3)
> > +#define PINMUX_GPIO20__FUNC_MD_INT1_C2K_UIM0_HOT_PLUG (MTK_PIN_NO(20) | 4)
> > +#define PINMUX_GPIO20__FUNC_UTXD1 (MTK_PIN_NO(20) | 5)
> > +#define PINMUX_GPIO20__FUNC_I2S3_DO (MTK_PIN_NO(20) | 6)
> > +#define PINMUX_GPIO20__FUNC_DBG_MON_A19 (MTK_PIN_NO(20) | 7)
> > +
> > +#define PINMUX_GPIO21__FUNC_GPIO21 (MTK_PIN_NO(21) | 0)
> > +#define PINMUX_GPIO21__FUNC_DBPI_D8 (MTK_PIN_NO(21) | 1)
> > +#define PINMUX_GPIO21__FUNC_SPI3_MI (MTK_PIN_NO(21) | 2)
> > +#define PINMUX_GPIO21__FUNC_CONN_MCU_TMS (MTK_PIN_NO(21) | 3)
> > +#define PINMUX_GPIO21__FUNC_DAP_MD32_SWD (MTK_PIN_NO(21) | 4)
> > +#define PINMUX_GPIO21__FUNC_CONN_MCU_AICE_TMSC (MTK_PIN_NO(21) | 5)
> > +#define PINMUX_GPIO21__FUNC_I2S2_MCK (MTK_PIN_NO(21) | 6)
> > +#define PINMUX_GPIO21__FUNC_DBG_MON_B5 (MTK_PIN_NO(21) | 7)
> > +
> > +#define PINMUX_GPIO22__FUNC_GPIO22 (MTK_PIN_NO(22) | 0)
> > +#define PINMUX_GPIO22__FUNC_DBPI_D9 (MTK_PIN_NO(22) | 1)
> > +#define PINMUX_GPIO22__FUNC_SPI3_CSB (MTK_PIN_NO(22) | 2)
> > +#define PINMUX_GPIO22__FUNC_CONN_MCU_TCK (MTK_PIN_NO(22) | 3)
> > +#define PINMUX_GPIO22__FUNC_DAP_MD32_SWCK (MTK_PIN_NO(22) | 4)
> > +#define PINMUX_GPIO22__FUNC_CONN_MCU_AICE_TCKC (MTK_PIN_NO(22) | 5)
> > +#define PINMUX_GPIO22__FUNC_I2S2_BCK (MTK_PIN_NO(22) | 6)
> > +#define PINMUX_GPIO22__FUNC_DBG_MON_B6 (MTK_PIN_NO(22) | 7)
> > +
> > +#define PINMUX_GPIO23__FUNC_GPIO23 (MTK_PIN_NO(23) | 0)
> > +#define PINMUX_GPIO23__FUNC_DBPI_D10 (MTK_PIN_NO(23) | 1)
> > +#define PINMUX_GPIO23__FUNC_SPI3_MO (MTK_PIN_NO(23) | 2)
> > +#define PINMUX_GPIO23__FUNC_CONN_MCU_TDI (MTK_PIN_NO(23) | 3)
> > +#define PINMUX_GPIO23__FUNC_UCTS1 (MTK_PIN_NO(23) | 4)
> > +#define PINMUX_GPIO23__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(23) | 5)
> > +#define PINMUX_GPIO23__FUNC_I2S2_LRCK (MTK_PIN_NO(23) | 6)
> > +#define PINMUX_GPIO23__FUNC_DBG_MON_B7 (MTK_PIN_NO(23) | 7)
> > +
> > +#define PINMUX_GPIO24__FUNC_GPIO24 (MTK_PIN_NO(24) | 0)
> > +#define PINMUX_GPIO24__FUNC_DBPI_D11 (MTK_PIN_NO(24) | 1)
> > +#define PINMUX_GPIO24__FUNC_SPI3_CLK (MTK_PIN_NO(24) | 2)
> > +#define PINMUX_GPIO24__FUNC_SRCLKENAI0 (MTK_PIN_NO(24) | 3)
> > +#define PINMUX_GPIO24__FUNC_URTS1 (MTK_PIN_NO(24) | 4)
> > +#define PINMUX_GPIO24__FUNC_IO_JTAG_TCK (MTK_PIN_NO(24) | 5)
> > +#define PINMUX_GPIO24__FUNC_I2S2_DI (MTK_PIN_NO(24) | 6)
> > +#define PINMUX_GPIO24__FUNC_DBG_MON_B31 (MTK_PIN_NO(24) | 7)
> > +
> > +#define PINMUX_GPIO25__FUNC_GPIO25 (MTK_PIN_NO(25) | 0)
> > +#define PINMUX_GPIO25__FUNC_DBPI_HSYNC (MTK_PIN_NO(25) | 1)
> > +#define PINMUX_GPIO25__FUNC_ANT_SEL0 (MTK_PIN_NO(25) | 2)
> > +#define PINMUX_GPIO25__FUNC_SCL6 (MTK_PIN_NO(25) | 3)
> > +#define PINMUX_GPIO25__FUNC_KPCOL2 (MTK_PIN_NO(25) | 4)
> > +#define PINMUX_GPIO25__FUNC_IO_JTAG_TMS (MTK_PIN_NO(25) | 5)
> > +#define PINMUX_GPIO25__FUNC_I2S1_MCK (MTK_PIN_NO(25) | 6)
> > +#define PINMUX_GPIO25__FUNC_DBG_MON_B0 (MTK_PIN_NO(25) | 7)
> > +
> > +#define PINMUX_GPIO26__FUNC_GPIO26 (MTK_PIN_NO(26) | 0)
> > +#define PINMUX_GPIO26__FUNC_DBPI_VSYNC (MTK_PIN_NO(26) | 1)
> > +#define PINMUX_GPIO26__FUNC_ANT_SEL1 (MTK_PIN_NO(26) | 2)
> > +#define PINMUX_GPIO26__FUNC_SDA6 (MTK_PIN_NO(26) | 3)
> > +#define PINMUX_GPIO26__FUNC_KPROW2 (MTK_PIN_NO(26) | 4)
> > +#define PINMUX_GPIO26__FUNC_IO_JTAG_TDI (MTK_PIN_NO(26) | 5)
> > +#define PINMUX_GPIO26__FUNC_I2S1_BCK (MTK_PIN_NO(26) | 6)
> > +#define PINMUX_GPIO26__FUNC_DBG_MON_B1 (MTK_PIN_NO(26) | 7)
> > +
> > +#define PINMUX_GPIO27__FUNC_GPIO27 (MTK_PIN_NO(27) | 0)
> > +#define PINMUX_GPIO27__FUNC_DBPI_DE (MTK_PIN_NO(27) | 1)
> > +#define PINMUX_GPIO27__FUNC_ANT_SEL2 (MTK_PIN_NO(27) | 2)
> > +#define PINMUX_GPIO27__FUNC_SCL7 (MTK_PIN_NO(27) | 3)
> > +#define PINMUX_GPIO27__FUNC_DMIC_CLK (MTK_PIN_NO(27) | 4)
> > +#define PINMUX_GPIO27__FUNC_IO_JTAG_TDO (MTK_PIN_NO(27) | 5)
> > +#define PINMUX_GPIO27__FUNC_I2S1_LRCK (MTK_PIN_NO(27) | 6)
> > +#define PINMUX_GPIO27__FUNC_DBG_MON_B9 (MTK_PIN_NO(27) | 7)
> > +
> > +#define PINMUX_GPIO28__FUNC_GPIO28 (MTK_PIN_NO(28) | 0)
> > +#define PINMUX_GPIO28__FUNC_DBPI_CK (MTK_PIN_NO(28) | 1)
> > +#define PINMUX_GPIO28__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(28) | 2)
> > +#define PINMUX_GPIO28__FUNC_SDA7 (MTK_PIN_NO(28) | 3)
> > +#define PINMUX_GPIO28__FUNC_DMIC_DAT (MTK_PIN_NO(28) | 4)
> > +#define PINMUX_GPIO28__FUNC_IO_JTAG_TRSTN (MTK_PIN_NO(28) | 5)
> > +#define PINMUX_GPIO28__FUNC_I2S1_DO (MTK_PIN_NO(28) | 6)
> > +#define PINMUX_GPIO28__FUNC_DBG_MON_B32 (MTK_PIN_NO(28) | 7)
> > +
> > +#define PINMUX_GPIO29__FUNC_GPIO29 (MTK_PIN_NO(29) | 0)
> > +#define PINMUX_GPIO29__FUNC_MSDC1_CLK (MTK_PIN_NO(29) | 1)
> > +#define PINMUX_GPIO29__FUNC_IO_JTAG_TCK (MTK_PIN_NO(29) | 2)
> > +#define PINMUX_GPIO29__FUNC_UDI_TCK (MTK_PIN_NO(29) | 3)
> > +#define PINMUX_GPIO29__FUNC_CONN_DSP_JCK (MTK_PIN_NO(29) | 4)
> > +#define PINMUX_GPIO29__FUNC_SSPM_JTAG_TCK (MTK_PIN_NO(29) | 5)
> > +#define PINMUX_GPIO29__FUNC_PCM1_CLK (MTK_PIN_NO(29) | 6)
> > +#define PINMUX_GPIO29__FUNC_DBG_MON_A6 (MTK_PIN_NO(29) | 7)
> > +
> > +#define PINMUX_GPIO30__FUNC_GPIO30 (MTK_PIN_NO(30) | 0)
> > +#define PINMUX_GPIO30__FUNC_MSDC1_DAT3 (MTK_PIN_NO(30) | 1)
> > +#define PINMUX_GPIO30__FUNC_DAP_MD32_SWD (MTK_PIN_NO(30) | 2)
> > +#define PINMUX_GPIO30__FUNC_CONN_MCU_AICE_TMSC (MTK_PIN_NO(30) | 3)
> > +#define PINMUX_GPIO30__FUNC_CONN_DSP_JINTP (MTK_PIN_NO(30) | 4)
> > +#define PINMUX_GPIO30__FUNC_SSPM_JTAG_TRSTN (MTK_PIN_NO(30) | 5)
> > +#define PINMUX_GPIO30__FUNC_PCM1_DI (MTK_PIN_NO(30) | 6)
> > +#define PINMUX_GPIO30__FUNC_DBG_MON_A7 (MTK_PIN_NO(30) | 7)
> > +
> > +#define PINMUX_GPIO31__FUNC_GPIO31 (MTK_PIN_NO(31) | 0)
> > +#define PINMUX_GPIO31__FUNC_MSDC1_CMD (MTK_PIN_NO(31) | 1)
> > +#define PINMUX_GPIO31__FUNC_IO_JTAG_TMS (MTK_PIN_NO(31) | 2)
> > +#define PINMUX_GPIO31__FUNC_UDI_TMS (MTK_PIN_NO(31) | 3)
> > +#define PINMUX_GPIO31__FUNC_CONN_DSP_JMS (MTK_PIN_NO(31) | 4)
> > +#define PINMUX_GPIO31__FUNC_SSPM_JTAG_TMS (MTK_PIN_NO(31) | 5)
> > +#define PINMUX_GPIO31__FUNC_PCM1_SYNC (MTK_PIN_NO(31) | 6)
> > +#define PINMUX_GPIO31__FUNC_DBG_MON_A8 (MTK_PIN_NO(31) | 7)
> > +
> > +#define PINMUX_GPIO32__FUNC_GPIO32 (MTK_PIN_NO(32) | 0)
> > +#define PINMUX_GPIO32__FUNC_MSDC1_DAT0 (MTK_PIN_NO(32) | 1)
> > +#define PINMUX_GPIO32__FUNC_IO_JTAG_TDI (MTK_PIN_NO(32) | 2)
> > +#define PINMUX_GPIO32__FUNC_UDI_TDI (MTK_PIN_NO(32) | 3)
> > +#define PINMUX_GPIO32__FUNC_CONN_DSP_JDI (MTK_PIN_NO(32) | 4)
> > +#define PINMUX_GPIO32__FUNC_SSPM_JTAG_TDI (MTK_PIN_NO(32) | 5)
> > +#define PINMUX_GPIO32__FUNC_PCM1_DO0 (MTK_PIN_NO(32) | 6)
> > +#define PINMUX_GPIO32__FUNC_DBG_MON_A9 (MTK_PIN_NO(32) | 7)
> > +
> > +#define PINMUX_GPIO33__FUNC_GPIO33 (MTK_PIN_NO(33) | 0)
> > +#define PINMUX_GPIO33__FUNC_MSDC1_DAT2 (MTK_PIN_NO(33) | 1)
> > +#define PINMUX_GPIO33__FUNC_IO_JTAG_TRSTN (MTK_PIN_NO(33) | 2)
> > +#define PINMUX_GPIO33__FUNC_UDI_NTRST (MTK_PIN_NO(33) | 3)
> > +#define PINMUX_GPIO33__FUNC_DAP_MD32_SWCK (MTK_PIN_NO(33) | 4)
> > +#define PINMUX_GPIO33__FUNC_CONN_MCU_AICE_TCKC (MTK_PIN_NO(33) | 5)
> > +#define PINMUX_GPIO33__FUNC_PCM1_DO2 (MTK_PIN_NO(33) | 6)
> > +#define PINMUX_GPIO33__FUNC_DBG_MON_A10 (MTK_PIN_NO(33) | 7)
> > +
> > +#define PINMUX_GPIO34__FUNC_GPIO34 (MTK_PIN_NO(34) | 0)
> > +#define PINMUX_GPIO34__FUNC_MSDC1_DAT1 (MTK_PIN_NO(34) | 1)
> > +#define PINMUX_GPIO34__FUNC_IO_JTAG_TDO (MTK_PIN_NO(34) | 2)
> > +#define PINMUX_GPIO34__FUNC_UDI_TDO (MTK_PIN_NO(34) | 3)
> > +#define PINMUX_GPIO34__FUNC_CONN_DSP_JDO (MTK_PIN_NO(34) | 4)
> > +#define PINMUX_GPIO34__FUNC_SSPM_JTAG_TDO (MTK_PIN_NO(34) | 5)
> > +#define PINMUX_GPIO34__FUNC_PCM1_DO1 (MTK_PIN_NO(34) | 6)
> > +#define PINMUX_GPIO34__FUNC_DBG_MON_A11 (MTK_PIN_NO(34) | 7)
> > +
> > +#define PINMUX_GPIO35__FUNC_GPIO35 (MTK_PIN_NO(35) | 0)
> > +#define PINMUX_GPIO35__FUNC_MD1_SIM2_SIO (MTK_PIN_NO(35) | 1)
> > +#define PINMUX_GPIO35__FUNC_CCU_JTAG_TDO (MTK_PIN_NO(35) | 2)
> > +#define PINMUX_GPIO35__FUNC_MD1_SIM1_SIO (MTK_PIN_NO(35) | 3)
> > +#define PINMUX_GPIO35__FUNC_SCP_JTAG_TDO (MTK_PIN_NO(35) | 5)
> > +#define PINMUX_GPIO35__FUNC_CONN_DSP_JMS (MTK_PIN_NO(35) | 6)
> > +#define PINMUX_GPIO35__FUNC_DBG_MON_A28 (MTK_PIN_NO(35) | 7)
> > +
> > +#define PINMUX_GPIO36__FUNC_GPIO36 (MTK_PIN_NO(36) | 0)
> > +#define PINMUX_GPIO36__FUNC_MD1_SIM2_SRST (MTK_PIN_NO(36) | 1)
> > +#define PINMUX_GPIO36__FUNC_CCU_JTAG_TMS (MTK_PIN_NO(36) | 2)
> > +#define PINMUX_GPIO36__FUNC_MD1_SIM1_SRST (MTK_PIN_NO(36) | 3)
> > +#define PINMUX_GPIO36__FUNC_CONN_MCU_AICE_TMSC (MTK_PIN_NO(36) | 4)
> > +#define PINMUX_GPIO36__FUNC_SCP_JTAG_TMS (MTK_PIN_NO(36) | 5)
> > +#define PINMUX_GPIO36__FUNC_CONN_DSP_JINTP (MTK_PIN_NO(36) | 6)
> > +#define PINMUX_GPIO36__FUNC_DBG_MON_A29 (MTK_PIN_NO(36) | 7)
> > +
> > +#define PINMUX_GPIO37__FUNC_GPIO37 (MTK_PIN_NO(37) | 0)
> > +#define PINMUX_GPIO37__FUNC_MD1_SIM2_SCLK (MTK_PIN_NO(37) | 1)
> > +#define PINMUX_GPIO37__FUNC_CCU_JTAG_TDI (MTK_PIN_NO(37) | 2)
> > +#define PINMUX_GPIO37__FUNC_MD1_SIM1_SCLK (MTK_PIN_NO(37) | 3)
> > +#define PINMUX_GPIO37__FUNC_SCP_JTAG_TDI (MTK_PIN_NO(37) | 5)
> > +#define PINMUX_GPIO37__FUNC_CONN_DSP_JDO (MTK_PIN_NO(37) | 6)
> > +#define PINMUX_GPIO37__FUNC_DBG_MON_A30 (MTK_PIN_NO(37) | 7)
> > +
> > +#define PINMUX_GPIO38__FUNC_GPIO38 (MTK_PIN_NO(38) | 0)
> > +#define PINMUX_GPIO38__FUNC_MD1_SIM1_SCLK (MTK_PIN_NO(38) | 1)
> > +#define PINMUX_GPIO38__FUNC_MD1_SIM2_SCLK (MTK_PIN_NO(38) | 3)
> > +#define PINMUX_GPIO38__FUNC_CONN_MCU_AICE_TCKC (MTK_PIN_NO(38) | 4)
> > +#define PINMUX_GPIO38__FUNC_DBG_MON_A20 (MTK_PIN_NO(38) | 7)
> > +
> > +#define PINMUX_GPIO39__FUNC_GPIO39 (MTK_PIN_NO(39) | 0)
> > +#define PINMUX_GPIO39__FUNC_MD1_SIM1_SRST (MTK_PIN_NO(39) | 1)
> > +#define PINMUX_GPIO39__FUNC_CCU_JTAG_TCK (MTK_PIN_NO(39) | 2)
> > +#define PINMUX_GPIO39__FUNC_MD1_SIM2_SRST (MTK_PIN_NO(39) | 3)
> > +#define PINMUX_GPIO39__FUNC_SCP_JTAG_TCK (MTK_PIN_NO(39) | 5)
> > +#define PINMUX_GPIO39__FUNC_CONN_DSP_JCK (MTK_PIN_NO(39) | 6)
> > +#define PINMUX_GPIO39__FUNC_DBG_MON_A31 (MTK_PIN_NO(39) | 7)
> > +
> > +#define PINMUX_GPIO40__FUNC_GPIO40 (MTK_PIN_NO(40) | 0)
> > +#define PINMUX_GPIO40__FUNC_MD1_SIM1_SIO (MTK_PIN_NO(40) | 1)
> > +#define PINMUX_GPIO40__FUNC_CCU_JTAG_TRST (MTK_PIN_NO(40) | 2)
> > +#define PINMUX_GPIO40__FUNC_MD1_SIM2_SIO (MTK_PIN_NO(40) | 3)
> > +#define PINMUX_GPIO40__FUNC_SCP_JTAG_TRSTN (MTK_PIN_NO(40) | 5)
> > +#define PINMUX_GPIO40__FUNC_CONN_DSP_JDI (MTK_PIN_NO(40) | 6)
> > +#define PINMUX_GPIO40__FUNC_DBG_MON_A32 (MTK_PIN_NO(40) | 7)
> > +
> > +#define PINMUX_GPIO41__FUNC_GPIO41 (MTK_PIN_NO(41) | 0)
> > +#define PINMUX_GPIO41__FUNC_IDDIG (MTK_PIN_NO(41) | 1)
> > +#define PINMUX_GPIO41__FUNC_URXD1 (MTK_PIN_NO(41) | 2)
> > +#define PINMUX_GPIO41__FUNC_UCTS0 (MTK_PIN_NO(41) | 3)
> > +#define PINMUX_GPIO41__FUNC_SSPM_UTXD_AO (MTK_PIN_NO(41) | 4)
> > +#define PINMUX_GPIO41__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(41) | 5)
> > +#define PINMUX_GPIO41__FUNC_DMIC_CLK (MTK_PIN_NO(41) | 6)
> > +
> > +#define PINMUX_GPIO42__FUNC_GPIO42 (MTK_PIN_NO(42) | 0)
> > +#define PINMUX_GPIO42__FUNC_USB_DRVVBUS (MTK_PIN_NO(42) | 1)
> > +#define PINMUX_GPIO42__FUNC_UTXD1 (MTK_PIN_NO(42) | 2)
> > +#define PINMUX_GPIO42__FUNC_URTS0 (MTK_PIN_NO(42) | 3)
> > +#define PINMUX_GPIO42__FUNC_SSPM_URXD_AO (MTK_PIN_NO(42) | 4)
> > +#define PINMUX_GPIO42__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(42) | 5)
> > +#define PINMUX_GPIO42__FUNC_DMIC_DAT (MTK_PIN_NO(42) | 6)
> > +
> > +#define PINMUX_GPIO43__FUNC_GPIO43 (MTK_PIN_NO(43) | 0)
> > +#define PINMUX_GPIO43__FUNC_DISP_PWM (MTK_PIN_NO(43) | 1)
> > +
> > +#define PINMUX_GPIO44__FUNC_GPIO44 (MTK_PIN_NO(44) | 0)
> > +#define PINMUX_GPIO44__FUNC_DSI_TE (MTK_PIN_NO(44) | 1)
> > +
> > +#define PINMUX_GPIO45__FUNC_GPIO45 (MTK_PIN_NO(45) | 0)
> > +#define PINMUX_GPIO45__FUNC_LCM_RST (MTK_PIN_NO(45) | 1)
> > +
> > +#define PINMUX_GPIO46__FUNC_GPIO46 (MTK_PIN_NO(46) | 0)
> > +#define PINMUX_GPIO46__FUNC_MD_INT2_C2K_UIM1_HOT_PLUG (MTK_PIN_NO(46) | 1)
> > +#define PINMUX_GPIO46__FUNC_URXD1 (MTK_PIN_NO(46) | 2)
> > +#define PINMUX_GPIO46__FUNC_UCTS1 (MTK_PIN_NO(46) | 3)
> > +#define PINMUX_GPIO46__FUNC_CCU_UTXD_AO (MTK_PIN_NO(46) | 4)
> > +#define PINMUX_GPIO46__FUNC_TP_UCTS1_AO (MTK_PIN_NO(46) | 5)
> > +#define PINMUX_GPIO46__FUNC_IDDIG (MTK_PIN_NO(46) | 6)
> > +#define PINMUX_GPIO46__FUNC_I2S5_LRCK (MTK_PIN_NO(46) | 7)
> > +
> > +#define PINMUX_GPIO47__FUNC_GPIO47 (MTK_PIN_NO(47) | 0)
> > +#define PINMUX_GPIO47__FUNC_MD_INT1_C2K_UIM0_HOT_PLUG (MTK_PIN_NO(47) | 1)
> > +#define PINMUX_GPIO47__FUNC_UTXD1 (MTK_PIN_NO(47) | 2)
> > +#define PINMUX_GPIO47__FUNC_URTS1 (MTK_PIN_NO(47) | 3)
> > +#define PINMUX_GPIO47__FUNC_CCU_URXD_AO (MTK_PIN_NO(47) | 4)
> > +#define PINMUX_GPIO47__FUNC_TP_URTS1_AO (MTK_PIN_NO(47) | 5)
> > +#define PINMUX_GPIO47__FUNC_USB_DRVVBUS (MTK_PIN_NO(47) | 6)
> > +#define PINMUX_GPIO47__FUNC_I2S5_DO (MTK_PIN_NO(47) | 7)
> > +
> > +#define PINMUX_GPIO48__FUNC_GPIO48 (MTK_PIN_NO(48) | 0)
> > +#define PINMUX_GPIO48__FUNC_SCL5 (MTK_PIN_NO(48) | 1)
> > +
> > +#define PINMUX_GPIO49__FUNC_GPIO49 (MTK_PIN_NO(49) | 0)
> > +#define PINMUX_GPIO49__FUNC_SDA5 (MTK_PIN_NO(49) | 1)
> > +
> > +#define PINMUX_GPIO50__FUNC_GPIO50 (MTK_PIN_NO(50) | 0)
> > +#define PINMUX_GPIO50__FUNC_SCL3 (MTK_PIN_NO(50) | 1)
> > +
> > +#define PINMUX_GPIO51__FUNC_GPIO51 (MTK_PIN_NO(51) | 0)
> > +#define PINMUX_GPIO51__FUNC_SDA3 (MTK_PIN_NO(51) | 1)
> > +
> > +#define PINMUX_GPIO52__FUNC_GPIO52 (MTK_PIN_NO(52) | 0)
> > +#define PINMUX_GPIO52__FUNC_BPI_ANT2 (MTK_PIN_NO(52) | 1)
> > +
> > +#define PINMUX_GPIO53__FUNC_GPIO53 (MTK_PIN_NO(53) | 0)
> > +#define PINMUX_GPIO53__FUNC_BPI_ANT0 (MTK_PIN_NO(53) | 1)
> > +
> > +#define PINMUX_GPIO54__FUNC_GPIO54 (MTK_PIN_NO(54) | 0)
> > +#define PINMUX_GPIO54__FUNC_BPI_OLAT1 (MTK_PIN_NO(54) | 1)
> > +
> > +#define PINMUX_GPIO55__FUNC_GPIO55 (MTK_PIN_NO(55) | 0)
> > +#define PINMUX_GPIO55__FUNC_BPI_BUS8 (MTK_PIN_NO(55) | 1)
> > +
> > +#define PINMUX_GPIO56__FUNC_GPIO56 (MTK_PIN_NO(56) | 0)
> > +#define PINMUX_GPIO56__FUNC_BPI_BUS9 (MTK_PIN_NO(56) | 1)
> > +#define PINMUX_GPIO56__FUNC_SCL_6306 (MTK_PIN_NO(56) | 2)
> > +
> > +#define PINMUX_GPIO57__FUNC_GPIO57 (MTK_PIN_NO(57) | 0)
> > +#define PINMUX_GPIO57__FUNC_BPI_BUS10 (MTK_PIN_NO(57) | 1)
> > +#define PINMUX_GPIO57__FUNC_SDA_6306 (MTK_PIN_NO(57) | 2)
> > +
> > +#define PINMUX_GPIO58__FUNC_GPIO58 (MTK_PIN_NO(58) | 0)
> > +#define PINMUX_GPIO58__FUNC_RFIC0_BSI_D2 (MTK_PIN_NO(58) | 1)
> > +#define PINMUX_GPIO58__FUNC_SPM_BSI_D2 (MTK_PIN_NO(58) | 2)
> > +#define PINMUX_GPIO58__FUNC_PWM_B (MTK_PIN_NO(58) | 3)
> > +
> > +#define PINMUX_GPIO59__FUNC_GPIO59 (MTK_PIN_NO(59) | 0)
> > +#define PINMUX_GPIO59__FUNC_RFIC0_BSI_D1 (MTK_PIN_NO(59) | 1)
> > +#define PINMUX_GPIO59__FUNC_SPM_BSI_D1 (MTK_PIN_NO(59) | 2)
> > +
> > +#define PINMUX_GPIO60__FUNC_GPIO60 (MTK_PIN_NO(60) | 0)
> > +#define PINMUX_GPIO60__FUNC_RFIC0_BSI_D0 (MTK_PIN_NO(60) | 1)
> > +#define PINMUX_GPIO60__FUNC_SPM_BSI_D0 (MTK_PIN_NO(60) | 2)
> > +
> > +#define PINMUX_GPIO61__FUNC_GPIO61 (MTK_PIN_NO(61) | 0)
> > +#define PINMUX_GPIO61__FUNC_MIPI1_SDATA (MTK_PIN_NO(61) | 1)
> > +
> > +#define PINMUX_GPIO62__FUNC_GPIO62 (MTK_PIN_NO(62) | 0)
> > +#define PINMUX_GPIO62__FUNC_MIPI1_SCLK (MTK_PIN_NO(62) | 1)
> > +
> > +#define PINMUX_GPIO63__FUNC_GPIO63 (MTK_PIN_NO(63) | 0)
> > +#define PINMUX_GPIO63__FUNC_MIPI0_SDATA (MTK_PIN_NO(63) | 1)
> > +
> > +#define PINMUX_GPIO64__FUNC_GPIO64 (MTK_PIN_NO(64) | 0)
> > +#define PINMUX_GPIO64__FUNC_MIPI0_SCLK (MTK_PIN_NO(64) | 1)
> > +
> > +#define PINMUX_GPIO65__FUNC_GPIO65 (MTK_PIN_NO(65) | 0)
> > +#define PINMUX_GPIO65__FUNC_MIPI3_SDATA (MTK_PIN_NO(65) | 1)
> > +#define PINMUX_GPIO65__FUNC_BPI_OLAT2 (MTK_PIN_NO(65) | 2)
> > +
> > +#define PINMUX_GPIO66__FUNC_GPIO66 (MTK_PIN_NO(66) | 0)
> > +#define PINMUX_GPIO66__FUNC_MIPI3_SCLK (MTK_PIN_NO(66) | 1)
> > +#define PINMUX_GPIO66__FUNC_BPI_OLAT3 (MTK_PIN_NO(66) | 2)
> > +
> > +#define PINMUX_GPIO67__FUNC_GPIO67 (MTK_PIN_NO(67) | 0)
> > +#define PINMUX_GPIO67__FUNC_MIPI2_SDATA (MTK_PIN_NO(67) | 1)
> > +
> > +#define PINMUX_GPIO68__FUNC_GPIO68 (MTK_PIN_NO(68) | 0)
> > +#define PINMUX_GPIO68__FUNC_MIPI2_SCLK (MTK_PIN_NO(68) | 1)
> > +
> > +#define PINMUX_GPIO69__FUNC_GPIO69 (MTK_PIN_NO(69) | 0)
> > +#define PINMUX_GPIO69__FUNC_BPI_BUS7 (MTK_PIN_NO(69) | 1)
> > +
> > +#define PINMUX_GPIO70__FUNC_GPIO70 (MTK_PIN_NO(70) | 0)
> > +#define PINMUX_GPIO70__FUNC_BPI_BUS6 (MTK_PIN_NO(70) | 1)
> > +
> > +#define PINMUX_GPIO71__FUNC_GPIO71 (MTK_PIN_NO(71) | 0)
> > +#define PINMUX_GPIO71__FUNC_BPI_BUS5 (MTK_PIN_NO(71) | 1)
> > +
> > +#define PINMUX_GPIO72__FUNC_GPIO72 (MTK_PIN_NO(72) | 0)
> > +#define PINMUX_GPIO72__FUNC_BPI_BUS4 (MTK_PIN_NO(72) | 1)
> > +
> > +#define PINMUX_GPIO73__FUNC_GPIO73 (MTK_PIN_NO(73) | 0)
> > +#define PINMUX_GPIO73__FUNC_BPI_BUS3 (MTK_PIN_NO(73) | 1)
> > +
> > +#define PINMUX_GPIO74__FUNC_GPIO74 (MTK_PIN_NO(74) | 0)
> > +#define PINMUX_GPIO74__FUNC_BPI_BUS2 (MTK_PIN_NO(74) | 1)
> > +
> > +#define PINMUX_GPIO75__FUNC_GPIO75 (MTK_PIN_NO(75) | 0)
> > +#define PINMUX_GPIO75__FUNC_BPI_BUS1 (MTK_PIN_NO(75) | 1)
> > +
> > +#define PINMUX_GPIO76__FUNC_GPIO76 (MTK_PIN_NO(76) | 0)
> > +#define PINMUX_GPIO76__FUNC_BPI_BUS0 (MTK_PIN_NO(76) | 1)
> > +
> > +#define PINMUX_GPIO77__FUNC_GPIO77 (MTK_PIN_NO(77) | 0)
> > +#define PINMUX_GPIO77__FUNC_BPI_ANT1 (MTK_PIN_NO(77) | 1)
> > +
> > +#define PINMUX_GPIO78__FUNC_GPIO78 (MTK_PIN_NO(78) | 0)
> > +#define PINMUX_GPIO78__FUNC_BPI_OLAT0 (MTK_PIN_NO(78) | 1)
> > +
> > +#define PINMUX_GPIO79__FUNC_GPIO79 (MTK_PIN_NO(79) | 0)
> > +#define PINMUX_GPIO79__FUNC_BPI_PA_VM1 (MTK_PIN_NO(79) | 1)
> > +#define PINMUX_GPIO79__FUNC_MIPI4_SDATA (MTK_PIN_NO(79) | 2)
> > +
> > +#define PINMUX_GPIO80__FUNC_GPIO80 (MTK_PIN_NO(80) | 0)
> > +#define PINMUX_GPIO80__FUNC_BPI_PA_VM0 (MTK_PIN_NO(80) | 1)
> > +#define PINMUX_GPIO80__FUNC_MIPI4_SCLK (MTK_PIN_NO(80) | 2)
> > +
> > +#define PINMUX_GPIO81__FUNC_GPIO81 (MTK_PIN_NO(81) | 0)
> > +#define PINMUX_GPIO81__FUNC_SDA1 (MTK_PIN_NO(81) | 1)
> > +
> > +#define PINMUX_GPIO82__FUNC_GPIO82 (MTK_PIN_NO(82) | 0)
> > +#define PINMUX_GPIO82__FUNC_SDA0 (MTK_PIN_NO(82) | 1)
> > +
> > +#define PINMUX_GPIO83__FUNC_GPIO83 (MTK_PIN_NO(83) | 0)
> > +#define PINMUX_GPIO83__FUNC_SCL0 (MTK_PIN_NO(83) | 1)
> > +
> > +#define PINMUX_GPIO84__FUNC_GPIO84 (MTK_PIN_NO(84) | 0)
> > +#define PINMUX_GPIO84__FUNC_SCL1 (MTK_PIN_NO(84) | 1)
> > +
> > +#define PINMUX_GPIO85__FUNC_GPIO85 (MTK_PIN_NO(85) | 0)
> > +#define PINMUX_GPIO85__FUNC_SPI0_MI (MTK_PIN_NO(85) | 1)
> > +#define PINMUX_GPIO85__FUNC_SCP_SPI0_MI (MTK_PIN_NO(85) | 2)
> > +#define PINMUX_GPIO85__FUNC_CLKM3 (MTK_PIN_NO(85) | 3)
> > +#define PINMUX_GPIO85__FUNC_I2S1_BCK (MTK_PIN_NO(85) | 4)
> > +#define PINMUX_GPIO85__FUNC_MFG_DFD_JTAG_TDO (MTK_PIN_NO(85) | 5)
> > +#define PINMUX_GPIO85__FUNC_DFD_TDO (MTK_PIN_NO(85) | 6)
> > +#define PINMUX_GPIO85__FUNC_JTDO_SEL1 (MTK_PIN_NO(85) | 7)
> > +
> > +#define PINMUX_GPIO86__FUNC_GPIO86 (MTK_PIN_NO(86) | 0)
> > +#define PINMUX_GPIO86__FUNC_SPI0_CSB (MTK_PIN_NO(86) | 1)
> > +#define PINMUX_GPIO86__FUNC_SCP_SPI0_CS (MTK_PIN_NO(86) | 2)
> > +#define PINMUX_GPIO86__FUNC_CLKM0 (MTK_PIN_NO(86) | 3)
> > +#define PINMUX_GPIO86__FUNC_I2S1_LRCK (MTK_PIN_NO(86) | 4)
> > +#define PINMUX_GPIO86__FUNC_MFG_DFD_JTAG_TMS (MTK_PIN_NO(86) | 5)
> > +#define PINMUX_GPIO86__FUNC_DFD_TMS (MTK_PIN_NO(86) | 6)
> > +#define PINMUX_GPIO86__FUNC_JTMS_SEL1 (MTK_PIN_NO(86) | 7)
> > +
> > +#define PINMUX_GPIO87__FUNC_GPIO87 (MTK_PIN_NO(87) | 0)
> > +#define PINMUX_GPIO87__FUNC_SPI0_MO (MTK_PIN_NO(87) | 1)
> > +#define PINMUX_GPIO87__FUNC_SCP_SPI0_MO (MTK_PIN_NO(87) | 2)
> > +#define PINMUX_GPIO87__FUNC_SDA1 (MTK_PIN_NO(87) | 3)
> > +#define PINMUX_GPIO87__FUNC_I2S1_DO (MTK_PIN_NO(87) | 4)
> > +#define PINMUX_GPIO87__FUNC_MFG_DFD_JTAG_TDI (MTK_PIN_NO(87) | 5)
> > +#define PINMUX_GPIO87__FUNC_DFD_TDI (MTK_PIN_NO(87) | 6)
> > +#define PINMUX_GPIO87__FUNC_JTDI_SEL1 (MTK_PIN_NO(87) | 7)
> > +
> > +#define PINMUX_GPIO88__FUNC_GPIO88 (MTK_PIN_NO(88) | 0)
> > +#define PINMUX_GPIO88__FUNC_SPI0_CLK (MTK_PIN_NO(88) | 1)
> > +#define PINMUX_GPIO88__FUNC_SCP_SPI0_CK (MTK_PIN_NO(88) | 2)
> > +#define PINMUX_GPIO88__FUNC_SCL1 (MTK_PIN_NO(88) | 3)
> > +#define PINMUX_GPIO88__FUNC_I2S1_MCK (MTK_PIN_NO(88) | 4)
> > +#define PINMUX_GPIO88__FUNC_MFG_DFD_JTAG_TCK (MTK_PIN_NO(88) | 5)
> > +#define PINMUX_GPIO88__FUNC_DFD_TCK_XI (MTK_PIN_NO(88) | 6)
> > +#define PINMUX_GPIO88__FUNC_JTCK_SEL1 (MTK_PIN_NO(88) | 7)
> > +
> > +#define PINMUX_GPIO89__FUNC_GPIO89 (MTK_PIN_NO(89) | 0)
> > +#define PINMUX_GPIO89__FUNC_SRCLKENAI0 (MTK_PIN_NO(89) | 1)
> > +#define PINMUX_GPIO89__FUNC_PWM_C (MTK_PIN_NO(89) | 2)
> > +#define PINMUX_GPIO89__FUNC_I2S5_BCK (MTK_PIN_NO(89) | 3)
> > +#define PINMUX_GPIO89__FUNC_ANT_SEL6 (MTK_PIN_NO(89) | 4)
> > +#define PINMUX_GPIO89__FUNC_SDA8 (MTK_PIN_NO(89) | 5)
> > +#define PINMUX_GPIO89__FUNC_CMVREF0 (MTK_PIN_NO(89) | 6)
> > +#define PINMUX_GPIO89__FUNC_DBG_MON_A21 (MTK_PIN_NO(89) | 7)
> > +
> > +#define PINMUX_GPIO90__FUNC_GPIO90 (MTK_PIN_NO(90) | 0)
> > +#define PINMUX_GPIO90__FUNC_PWM_A (MTK_PIN_NO(90) | 1)
> > +#define PINMUX_GPIO90__FUNC_CMMCLK2 (MTK_PIN_NO(90) | 2)
> > +#define PINMUX_GPIO90__FUNC_I2S5_LRCK (MTK_PIN_NO(90) | 3)
> > +#define PINMUX_GPIO90__FUNC_SCP_VREQ_VAO (MTK_PIN_NO(90) | 4)
> > +#define PINMUX_GPIO90__FUNC_SCL8 (MTK_PIN_NO(90) | 5)
> > +#define PINMUX_GPIO90__FUNC_PTA_RXD (MTK_PIN_NO(90) | 6)
> > +#define PINMUX_GPIO90__FUNC_DBG_MON_A22 (MTK_PIN_NO(90) | 7)
> > +
> > +#define PINMUX_GPIO91__FUNC_GPIO91 (MTK_PIN_NO(91) | 0)
> > +#define PINMUX_GPIO91__FUNC_KPROW1 (MTK_PIN_NO(91) | 1)
> > +#define PINMUX_GPIO91__FUNC_PWM_B (MTK_PIN_NO(91) | 2)
> > +#define PINMUX_GPIO91__FUNC_I2S5_DO (MTK_PIN_NO(91) | 3)
> > +#define PINMUX_GPIO91__FUNC_ANT_SEL7 (MTK_PIN_NO(91) | 4)
> > +#define PINMUX_GPIO91__FUNC_CMMCLK3 (MTK_PIN_NO(91) | 5)
> > +#define PINMUX_GPIO91__FUNC_PTA_TXD (MTK_PIN_NO(91) | 6)
> > +
> > +#define PINMUX_GPIO92__FUNC_GPIO92 (MTK_PIN_NO(92) | 0)
> > +#define PINMUX_GPIO92__FUNC_KPROW0 (MTK_PIN_NO(92) | 1)
> > +
> > +#define PINMUX_GPIO93__FUNC_GPIO93 (MTK_PIN_NO(93) | 0)
> > +#define PINMUX_GPIO93__FUNC_KPCOL0 (MTK_PIN_NO(93) | 1)
> > +#define PINMUX_GPIO93__FUNC_DBG_MON_B27 (MTK_PIN_NO(93) | 7)
> > +
> > +#define PINMUX_GPIO94__FUNC_GPIO94 (MTK_PIN_NO(94) | 0)
> > +#define PINMUX_GPIO94__FUNC_KPCOL1 (MTK_PIN_NO(94) | 1)
> > +#define PINMUX_GPIO94__FUNC_I2S2_DI2 (MTK_PIN_NO(94) | 2)
> > +#define PINMUX_GPIO94__FUNC_I2S5_MCK (MTK_PIN_NO(94) | 3)
> > +#define PINMUX_GPIO94__FUNC_CMMCLK2 (MTK_PIN_NO(94) | 4)
> > +#define PINMUX_GPIO94__FUNC_SCP_SPI2_MI (MTK_PIN_NO(94) | 5)
> > +#define PINMUX_GPIO94__FUNC_SRCLKENAI1 (MTK_PIN_NO(94) | 6)
> > +#define PINMUX_GPIO94__FUNC_SPI2_MI (MTK_PIN_NO(94) | 7)
> > +
> > +#define PINMUX_GPIO95__FUNC_GPIO95 (MTK_PIN_NO(95) | 0)
> > +#define PINMUX_GPIO95__FUNC_URXD0 (MTK_PIN_NO(95) | 1)
> > +#define PINMUX_GPIO95__FUNC_UTXD0 (MTK_PIN_NO(95) | 2)
> > +#define PINMUX_GPIO95__FUNC_MD_URXD0 (MTK_PIN_NO(95) | 3)
> > +#define PINMUX_GPIO95__FUNC_MD_URXD1 (MTK_PIN_NO(95) | 4)
> > +#define PINMUX_GPIO95__FUNC_SSPM_URXD_AO (MTK_PIN_NO(95) | 5)
> > +#define PINMUX_GPIO95__FUNC_CCU_URXD_AO (MTK_PIN_NO(95) | 6)
> > +
> > +#define PINMUX_GPIO96__FUNC_GPIO96 (MTK_PIN_NO(96) | 0)
> > +#define PINMUX_GPIO96__FUNC_UTXD0 (MTK_PIN_NO(96) | 1)
> > +#define PINMUX_GPIO96__FUNC_URXD0 (MTK_PIN_NO(96) | 2)
> > +#define PINMUX_GPIO96__FUNC_MD_UTXD0 (MTK_PIN_NO(96) | 3)
> > +#define PINMUX_GPIO96__FUNC_MD_UTXD1 (MTK_PIN_NO(96) | 4)
> > +#define PINMUX_GPIO96__FUNC_SSPM_UTXD_AO (MTK_PIN_NO(96) | 5)
> > +#define PINMUX_GPIO96__FUNC_CCU_UTXD_AO (MTK_PIN_NO(96) | 6)
> > +#define PINMUX_GPIO96__FUNC_DBG_MON_B2 (MTK_PIN_NO(96) | 7)
> > +
> > +#define PINMUX_GPIO97__FUNC_GPIO97 (MTK_PIN_NO(97) | 0)
> > +#define PINMUX_GPIO97__FUNC_UCTS0 (MTK_PIN_NO(97) | 1)
> > +#define PINMUX_GPIO97__FUNC_I2S2_MCK (MTK_PIN_NO(97) | 2)
> > +#define PINMUX_GPIO97__FUNC_IDDIG (MTK_PIN_NO(97) | 3)
> > +#define PINMUX_GPIO97__FUNC_CONN_MCU_TDO (MTK_PIN_NO(97) | 4)
> > +#define PINMUX_GPIO97__FUNC_SSPM_JTAG_TDO (MTK_PIN_NO(97) | 5)
> > +#define PINMUX_GPIO97__FUNC_IO_JTAG_TDO (MTK_PIN_NO(97) | 6)
> > +#define PINMUX_GPIO97__FUNC_DBG_MON_B3 (MTK_PIN_NO(97) | 7)
> > +
> > +#define PINMUX_GPIO98__FUNC_GPIO98 (MTK_PIN_NO(98) | 0)
> > +#define PINMUX_GPIO98__FUNC_URTS0 (MTK_PIN_NO(98) | 1)
> > +#define PINMUX_GPIO98__FUNC_I2S2_BCK (MTK_PIN_NO(98) | 2)
> > +#define PINMUX_GPIO98__FUNC_USB_DRVVBUS (MTK_PIN_NO(98) | 3)
> > +#define PINMUX_GPIO98__FUNC_CONN_MCU_TMS (MTK_PIN_NO(98) | 4)
> > +#define PINMUX_GPIO98__FUNC_SSPM_JTAG_TMS (MTK_PIN_NO(98) | 5)
> > +#define PINMUX_GPIO98__FUNC_IO_JTAG_TMS (MTK_PIN_NO(98) | 6)
> > +#define PINMUX_GPIO98__FUNC_DBG_MON_B4 (MTK_PIN_NO(98) | 7)
> > +
> > +#define PINMUX_GPIO99__FUNC_GPIO99 (MTK_PIN_NO(99) | 0)
> > +#define PINMUX_GPIO99__FUNC_CMMCLK0 (MTK_PIN_NO(99) | 1)
> > +#define PINMUX_GPIO99__FUNC_CONN_MCU_AICE_TMSC (MTK_PIN_NO(99) | 4)
> > +#define PINMUX_GPIO99__FUNC_DBG_MON_B28 (MTK_PIN_NO(99) | 7)
> > +
> > +#define PINMUX_GPIO100__FUNC_GPIO100 (MTK_PIN_NO(100) | 0)
> > +#define PINMUX_GPIO100__FUNC_CMMCLK1 (MTK_PIN_NO(100) | 1)
> > +#define PINMUX_GPIO100__FUNC_PWM_C (MTK_PIN_NO(100) | 2)
> > +#define PINMUX_GPIO100__FUNC_MD_INT1_C2K_UIM0_HOT_PLUG (MTK_PIN_NO(100) | 3)
> > +#define PINMUX_GPIO100__FUNC_CONN_MCU_AICE_TCKC (MTK_PIN_NO(100) | 4)
> > +#define PINMUX_GPIO100__FUNC_DBG_MON_B29 (MTK_PIN_NO(100) | 7)
> > +
> > +#define PINMUX_GPIO101__FUNC_GPIO101 (MTK_PIN_NO(101) | 0)
> > +#define PINMUX_GPIO101__FUNC_CLKM2 (MTK_PIN_NO(101) | 1)
> > +#define PINMUX_GPIO101__FUNC_I2S2_LRCK (MTK_PIN_NO(101) | 2)
> > +#define PINMUX_GPIO101__FUNC_CMVREF1 (MTK_PIN_NO(101) | 3)
> > +#define PINMUX_GPIO101__FUNC_CONN_MCU_TCK (MTK_PIN_NO(101) | 4)
> > +#define PINMUX_GPIO101__FUNC_SSPM_JTAG_TCK (MTK_PIN_NO(101) | 5)
> > +#define PINMUX_GPIO101__FUNC_IO_JTAG_TCK (MTK_PIN_NO(101) | 6)
> > +
> > +#define PINMUX_GPIO102__FUNC_GPIO102 (MTK_PIN_NO(102) | 0)
> > +#define PINMUX_GPIO102__FUNC_CLKM1 (MTK_PIN_NO(102) | 1)
> > +#define PINMUX_GPIO102__FUNC_I2S2_DI (MTK_PIN_NO(102) | 2)
> > +#define PINMUX_GPIO102__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(102) | 3)
> > +#define PINMUX_GPIO102__FUNC_CONN_MCU_TDI (MTK_PIN_NO(102) | 4)
> > +#define PINMUX_GPIO102__FUNC_SSPM_JTAG_TDI (MTK_PIN_NO(102) | 5)
> > +#define PINMUX_GPIO102__FUNC_IO_JTAG_TDI (MTK_PIN_NO(102) | 6)
> > +#define PINMUX_GPIO102__FUNC_DBG_MON_B8 (MTK_PIN_NO(102) | 7)
> > +
> > +#define PINMUX_GPIO103__FUNC_GPIO103 (MTK_PIN_NO(103) | 0)
> > +#define PINMUX_GPIO103__FUNC_SCL2 (MTK_PIN_NO(103) | 1)
> > +
> > +#define PINMUX_GPIO104__FUNC_GPIO104 (MTK_PIN_NO(104) | 0)
> > +#define PINMUX_GPIO104__FUNC_SDA2 (MTK_PIN_NO(104) | 1)
> > +
> > +#define PINMUX_GPIO105__FUNC_GPIO105 (MTK_PIN_NO(105) | 0)
> > +#define PINMUX_GPIO105__FUNC_SCL4 (MTK_PIN_NO(105) | 1)
> > +
> > +#define PINMUX_GPIO106__FUNC_GPIO106 (MTK_PIN_NO(106) | 0)
> > +#define PINMUX_GPIO106__FUNC_SDA4 (MTK_PIN_NO(106) | 1)
> > +
> > +#define PINMUX_GPIO107__FUNC_GPIO107 (MTK_PIN_NO(107) | 0)
> > +#define PINMUX_GPIO107__FUNC_DMIC_CLK (MTK_PIN_NO(107) | 1)
> > +#define PINMUX_GPIO107__FUNC_ANT_SEL0 (MTK_PIN_NO(107) | 2)
> > +#define PINMUX_GPIO107__FUNC_CLKM0 (MTK_PIN_NO(107) | 3)
> > +#define PINMUX_GPIO107__FUNC_SDA7 (MTK_PIN_NO(107) | 4)
> > +#define PINMUX_GPIO107__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(107) | 5)
> > +#define PINMUX_GPIO107__FUNC_PWM_A (MTK_PIN_NO(107) | 6)
> > +#define PINMUX_GPIO107__FUNC_DBG_MON_B12 (MTK_PIN_NO(107) | 7)
> > +
> > +#define PINMUX_GPIO108__FUNC_GPIO108 (MTK_PIN_NO(108) | 0)
> > +#define PINMUX_GPIO108__FUNC_CMMCLK2 (MTK_PIN_NO(108) | 1)
> > +#define PINMUX_GPIO108__FUNC_ANT_SEL1 (MTK_PIN_NO(108) | 2)
> > +#define PINMUX_GPIO108__FUNC_CLKM1 (MTK_PIN_NO(108) | 3)
> > +#define PINMUX_GPIO108__FUNC_SCL8 (MTK_PIN_NO(108) | 4)
> > +#define PINMUX_GPIO108__FUNC_DAP_MD32_SWD (MTK_PIN_NO(108) | 5)
> > +#define PINMUX_GPIO108__FUNC_PWM_B (MTK_PIN_NO(108) | 6)
> > +#define PINMUX_GPIO108__FUNC_DBG_MON_B13 (MTK_PIN_NO(108) | 7)
> > +
> > +#define PINMUX_GPIO109__FUNC_GPIO109 (MTK_PIN_NO(109) | 0)
> > +#define PINMUX_GPIO109__FUNC_DMIC_DAT (MTK_PIN_NO(109) | 1)
> > +#define PINMUX_GPIO109__FUNC_ANT_SEL2 (MTK_PIN_NO(109) | 2)
> > +#define PINMUX_GPIO109__FUNC_CLKM2 (MTK_PIN_NO(109) | 3)
> > +#define PINMUX_GPIO109__FUNC_SDA8 (MTK_PIN_NO(109) | 4)
> > +#define PINMUX_GPIO109__FUNC_DAP_MD32_SWCK (MTK_PIN_NO(109) | 5)
> > +#define PINMUX_GPIO109__FUNC_PWM_C (MTK_PIN_NO(109) | 6)
> > +#define PINMUX_GPIO109__FUNC_DBG_MON_B14 (MTK_PIN_NO(109) | 7)
> > +
> > +#define PINMUX_GPIO110__FUNC_GPIO110 (MTK_PIN_NO(110) | 0)
> > +#define PINMUX_GPIO110__FUNC_SCL7 (MTK_PIN_NO(110) | 1)
> > +#define PINMUX_GPIO110__FUNC_ANT_SEL0 (MTK_PIN_NO(110) | 2)
> > +#define PINMUX_GPIO110__FUNC_TP_URXD1_AO (MTK_PIN_NO(110) | 3)
> > +#define PINMUX_GPIO110__FUNC_USB_DRVVBUS (MTK_PIN_NO(110) | 4)
> > +#define PINMUX_GPIO110__FUNC_SRCLKENAI1 (MTK_PIN_NO(110) | 5)
> > +#define PINMUX_GPIO110__FUNC_KPCOL2 (MTK_PIN_NO(110) | 6)
> > +#define PINMUX_GPIO110__FUNC_URXD1 (MTK_PIN_NO(110) | 7)
> > +
> > +#define PINMUX_GPIO111__FUNC_GPIO111 (MTK_PIN_NO(111) | 0)
> > +#define PINMUX_GPIO111__FUNC_CMMCLK3 (MTK_PIN_NO(111) | 1)
> > +#define PINMUX_GPIO111__FUNC_ANT_SEL1 (MTK_PIN_NO(111) | 2)
> > +#define PINMUX_GPIO111__FUNC_SRCLKENAI0 (MTK_PIN_NO(111) | 3)
> > +#define PINMUX_GPIO111__FUNC_SCP_VREQ_VAO (MTK_PIN_NO(111) | 4)
> > +#define PINMUX_GPIO111__FUNC_MD_INT2_C2K_UIM1_HOT_PLUG (MTK_PIN_NO(111) | 5)
> > +#define PINMUX_GPIO111__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(111) | 7)
> > +
> > +#define PINMUX_GPIO112__FUNC_GPIO112 (MTK_PIN_NO(112) | 0)
> > +#define PINMUX_GPIO112__FUNC_SDA7 (MTK_PIN_NO(112) | 1)
> > +#define PINMUX_GPIO112__FUNC_ANT_SEL2 (MTK_PIN_NO(112) | 2)
> > +#define PINMUX_GPIO112__FUNC_TP_UTXD1_AO (MTK_PIN_NO(112) | 3)
> > +#define PINMUX_GPIO112__FUNC_IDDIG (MTK_PIN_NO(112) | 4)
> > +#define PINMUX_GPIO112__FUNC_AGPS_SYNC (MTK_PIN_NO(112) | 5)
> > +#define PINMUX_GPIO112__FUNC_KPROW2 (MTK_PIN_NO(112) | 6)
> > +#define PINMUX_GPIO112__FUNC_UTXD1 (MTK_PIN_NO(112) | 7)
> > +
> > +#define PINMUX_GPIO113__FUNC_GPIO113 (MTK_PIN_NO(113) | 0)
> > +#define PINMUX_GPIO113__FUNC_CONN_TOP_CLK (MTK_PIN_NO(113) | 1)
> > +#define PINMUX_GPIO113__FUNC_SCL6 (MTK_PIN_NO(113) | 3)
> > +#define PINMUX_GPIO113__FUNC_AUXIF_CLK0 (MTK_PIN_NO(113) | 4)
> > +#define PINMUX_GPIO113__FUNC_TP_UCTS1_AO (MTK_PIN_NO(113) | 6)
> > +
> > +#define PINMUX_GPIO114__FUNC_GPIO114 (MTK_PIN_NO(114) | 0)
> > +#define PINMUX_GPIO114__FUNC_CONN_TOP_DATA (MTK_PIN_NO(114) | 1)
> > +#define PINMUX_GPIO114__FUNC_SDA6 (MTK_PIN_NO(114) | 3)
> > +#define PINMUX_GPIO114__FUNC_AUXIF_ST0 (MTK_PIN_NO(114) | 4)
> > +#define PINMUX_GPIO114__FUNC_TP_URTS1_AO (MTK_PIN_NO(114) | 6)
> > +
> > +#define PINMUX_GPIO115__FUNC_GPIO115 (MTK_PIN_NO(115) | 0)
> > +#define PINMUX_GPIO115__FUNC_CONN_BT_CLK (MTK_PIN_NO(115) | 1)
> > +#define PINMUX_GPIO115__FUNC_UTXD1 (MTK_PIN_NO(115) | 2)
> > +#define PINMUX_GPIO115__FUNC_PTA_TXD (MTK_PIN_NO(115) | 3)
> > +#define PINMUX_GPIO115__FUNC_AUXIF_CLK1 (MTK_PIN_NO(115) | 4)
> > +#define PINMUX_GPIO115__FUNC_DAP_MD32_SWD (MTK_PIN_NO(115) | 5)
> > +#define PINMUX_GPIO115__FUNC_TP_UTXD1_AO (MTK_PIN_NO(115) | 6)
> > +
> > +#define PINMUX_GPIO116__FUNC_GPIO116 (MTK_PIN_NO(116) | 0)
> > +#define PINMUX_GPIO116__FUNC_CONN_BT_DATA (MTK_PIN_NO(116) | 1)
> > +#define PINMUX_GPIO116__FUNC_IPU_JTAG_TRST (MTK_PIN_NO(116) | 2)
> > +#define PINMUX_GPIO116__FUNC_AUXIF_ST1 (MTK_PIN_NO(116) | 4)
> > +#define PINMUX_GPIO116__FUNC_DAP_MD32_SWCK (MTK_PIN_NO(116) | 5)
> > +#define PINMUX_GPIO116__FUNC_TP_URXD2_AO (MTK_PIN_NO(116) | 6)
> > +#define PINMUX_GPIO116__FUNC_DBG_MON_A0 (MTK_PIN_NO(116) | 7)
> > +
> > +#define PINMUX_GPIO117__FUNC_GPIO117 (MTK_PIN_NO(117) | 0)
> > +#define PINMUX_GPIO117__FUNC_CONN_WF_HB0 (MTK_PIN_NO(117) | 1)
> > +#define PINMUX_GPIO117__FUNC_IPU_JTAG_TDO (MTK_PIN_NO(117) | 2)
> > +#define PINMUX_GPIO117__FUNC_TP_UTXD2_AO (MTK_PIN_NO(117) | 6)
> > +#define PINMUX_GPIO117__FUNC_DBG_MON_A4 (MTK_PIN_NO(117) | 7)
> > +
> > +#define PINMUX_GPIO118__FUNC_GPIO118 (MTK_PIN_NO(118) | 0)
> > +#define PINMUX_GPIO118__FUNC_CONN_WF_HB1 (MTK_PIN_NO(118) | 1)
> > +#define PINMUX_GPIO118__FUNC_IPU_JTAG_TDI (MTK_PIN_NO(118) | 2)
> > +#define PINMUX_GPIO118__FUNC_SSPM_URXD_AO (MTK_PIN_NO(118) | 5)
> > +#define PINMUX_GPIO118__FUNC_TP_UCTS2_AO (MTK_PIN_NO(118) | 6)
> > +#define PINMUX_GPIO118__FUNC_DBG_MON_A5 (MTK_PIN_NO(118) | 7)
> > +
> > +#define PINMUX_GPIO119__FUNC_GPIO119 (MTK_PIN_NO(119) | 0)
> > +#define PINMUX_GPIO119__FUNC_CONN_WF_HB2 (MTK_PIN_NO(119) | 1)
> > +#define PINMUX_GPIO119__FUNC_IPU_JTAG_TCK (MTK_PIN_NO(119) | 2)
> > +#define PINMUX_GPIO119__FUNC_SSPM_UTXD_AO (MTK_PIN_NO(119) | 5)
> > +#define PINMUX_GPIO119__FUNC_TP_URTS2_AO (MTK_PIN_NO(119) | 6)
> > +
> > +#define PINMUX_GPIO120__FUNC_GPIO120 (MTK_PIN_NO(120) | 0)
> > +#define PINMUX_GPIO120__FUNC_CONN_WB_PTA (MTK_PIN_NO(120) | 1)
> > +#define PINMUX_GPIO120__FUNC_IPU_JTAG_TMS (MTK_PIN_NO(120) | 2)
> > +#define PINMUX_GPIO120__FUNC_CCU_URXD_AO (MTK_PIN_NO(120) | 5)
> > +
> > +#define PINMUX_GPIO121__FUNC_GPIO121 (MTK_PIN_NO(121) | 0)
> > +#define PINMUX_GPIO121__FUNC_CONN_HRST_B (MTK_PIN_NO(121) | 1)
> > +#define PINMUX_GPIO121__FUNC_URXD1 (MTK_PIN_NO(121) | 2)
> > +#define PINMUX_GPIO121__FUNC_PTA_RXD (MTK_PIN_NO(121) | 3)
> > +#define PINMUX_GPIO121__FUNC_CCU_UTXD_AO (MTK_PIN_NO(121) | 5)
> > +#define PINMUX_GPIO121__FUNC_TP_URXD1_AO (MTK_PIN_NO(121) | 6)
> > +
> > +#define PINMUX_GPIO122__FUNC_GPIO122 (MTK_PIN_NO(122) | 0)
> > +#define PINMUX_GPIO122__FUNC_MSDC0_CMD (MTK_PIN_NO(122) | 1)
> > +#define PINMUX_GPIO122__FUNC_SSPM_URXD2_AO (MTK_PIN_NO(122) | 2)
> > +#define PINMUX_GPIO122__FUNC_ANT_SEL1 (MTK_PIN_NO(122) | 3)
> > +#define PINMUX_GPIO122__FUNC_DBG_MON_A12 (MTK_PIN_NO(122) | 7)
> > +
> > +#define PINMUX_GPIO123__FUNC_GPIO123 (MTK_PIN_NO(123) | 0)
> > +#define PINMUX_GPIO123__FUNC_MSDC0_DAT0 (MTK_PIN_NO(123) | 1)
> > +#define PINMUX_GPIO123__FUNC_ANT_SEL0 (MTK_PIN_NO(123) | 3)
> > +#define PINMUX_GPIO123__FUNC_DBG_MON_A13 (MTK_PIN_NO(123) | 7)
> > +
> > +#define PINMUX_GPIO124__FUNC_GPIO124 (MTK_PIN_NO(124) | 0)
> > +#define PINMUX_GPIO124__FUNC_MSDC0_CLK (MTK_PIN_NO(124) | 1)
> > +#define PINMUX_GPIO124__FUNC_DBG_MON_A14 (MTK_PIN_NO(124) | 7)
> > +
> > +#define PINMUX_GPIO125__FUNC_GPIO125 (MTK_PIN_NO(125) | 0)
> > +#define PINMUX_GPIO125__FUNC_MSDC0_DAT2 (MTK_PIN_NO(125) | 1)
> > +#define PINMUX_GPIO125__FUNC_MRG_CLK (MTK_PIN_NO(125) | 3)
> > +#define PINMUX_GPIO125__FUNC_DBG_MON_A15 (MTK_PIN_NO(125) | 7)
> > +
> > +#define PINMUX_GPIO126__FUNC_GPIO126 (MTK_PIN_NO(126) | 0)
> > +#define PINMUX_GPIO126__FUNC_MSDC0_DAT4 (MTK_PIN_NO(126) | 1)
> > +#define PINMUX_GPIO126__FUNC_ANT_SEL5 (MTK_PIN_NO(126) | 3)
> > +#define PINMUX_GPIO126__FUNC_UFS_MPHY_SCL (MTK_PIN_NO(126) | 6)
> > +#define PINMUX_GPIO126__FUNC_DBG_MON_A16 (MTK_PIN_NO(126) | 7)
> > +
> > +#define PINMUX_GPIO127__FUNC_GPIO127 (MTK_PIN_NO(127) | 0)
> > +#define PINMUX_GPIO127__FUNC_MSDC0_DAT6 (MTK_PIN_NO(127) | 1)
> > +#define PINMUX_GPIO127__FUNC_ANT_SEL4 (MTK_PIN_NO(127) | 3)
> > +#define PINMUX_GPIO127__FUNC_UFS_MPHY_SDA (MTK_PIN_NO(127) | 6)
> > +#define PINMUX_GPIO127__FUNC_DBG_MON_A17 (MTK_PIN_NO(127) | 7)
> > +
> > +#define PINMUX_GPIO128__FUNC_GPIO128 (MTK_PIN_NO(128) | 0)
> > +#define PINMUX_GPIO128__FUNC_MSDC0_DAT1 (MTK_PIN_NO(128) | 1)
> > +#define PINMUX_GPIO128__FUNC_ANT_SEL2 (MTK_PIN_NO(128) | 3)
> > +#define PINMUX_GPIO128__FUNC_UFS_UNIPRO_SDA (MTK_PIN_NO(128) | 6)
> > +#define PINMUX_GPIO128__FUNC_DBG_MON_A18 (MTK_PIN_NO(128) | 7)
> > +
> > +#define PINMUX_GPIO129__FUNC_GPIO129 (MTK_PIN_NO(129) | 0)
> > +#define PINMUX_GPIO129__FUNC_MSDC0_DAT5 (MTK_PIN_NO(129) | 1)
> > +#define PINMUX_GPIO129__FUNC_ANT_SEL3 (MTK_PIN_NO(129) | 3)
> > +#define PINMUX_GPIO129__FUNC_UFS_UNIPRO_SCL (MTK_PIN_NO(129) | 6)
> > +#define PINMUX_GPIO129__FUNC_DBG_MON_A23 (MTK_PIN_NO(129) | 7)
> > +
> > +#define PINMUX_GPIO130__FUNC_GPIO130 (MTK_PIN_NO(130) | 0)
> > +#define PINMUX_GPIO130__FUNC_MSDC0_DAT7 (MTK_PIN_NO(130) | 1)
> > +#define PINMUX_GPIO130__FUNC_MRG_DO (MTK_PIN_NO(130) | 3)
> > +#define PINMUX_GPIO130__FUNC_DBG_MON_A24 (MTK_PIN_NO(130) | 7)
> > +
> > +#define PINMUX_GPIO131__FUNC_GPIO131 (MTK_PIN_NO(131) | 0)
> > +#define PINMUX_GPIO131__FUNC_MSDC0_DSL (MTK_PIN_NO(131) | 1)
> > +#define PINMUX_GPIO131__FUNC_MRG_SYNC (MTK_PIN_NO(131) | 3)
> > +#define PINMUX_GPIO131__FUNC_DBG_MON_A25 (MTK_PIN_NO(131) | 7)
> > +
> > +#define PINMUX_GPIO132__FUNC_GPIO132 (MTK_PIN_NO(132) | 0)
> > +#define PINMUX_GPIO132__FUNC_MSDC0_DAT3 (MTK_PIN_NO(132) | 1)
> > +#define PINMUX_GPIO132__FUNC_MRG_DI (MTK_PIN_NO(132) | 3)
> > +#define PINMUX_GPIO132__FUNC_DBG_MON_A26 (MTK_PIN_NO(132) | 7)
> > +
> > +#define PINMUX_GPIO133__FUNC_GPIO133 (MTK_PIN_NO(133) | 0)
> > +#define PINMUX_GPIO133__FUNC_MSDC0_RSTB (MTK_PIN_NO(133) | 1)
> > +#define PINMUX_GPIO133__FUNC_AGPS_SYNC (MTK_PIN_NO(133) | 3)
> > +#define PINMUX_GPIO133__FUNC_DBG_MON_A27 (MTK_PIN_NO(133) | 7)
> > +
> > +#define PINMUX_GPIO134__FUNC_GPIO134 (MTK_PIN_NO(134) | 0)
> > +#define PINMUX_GPIO134__FUNC_RTC32K_CK (MTK_PIN_NO(134) | 1)
> > +
> > +#define PINMUX_GPIO135__FUNC_GPIO135 (MTK_PIN_NO(135) | 0)
> > +#define PINMUX_GPIO135__FUNC_WATCHDOG (MTK_PIN_NO(135) | 1)
> > +
> > +#define PINMUX_GPIO136__FUNC_GPIO136 (MTK_PIN_NO(136) | 0)
> > +#define PINMUX_GPIO136__FUNC_AUD_CLK_MOSI (MTK_PIN_NO(136) | 1)
> > +#define PINMUX_GPIO136__FUNC_AUD_CLK_MISO (MTK_PIN_NO(136) | 2)
> > +#define PINMUX_GPIO136__FUNC_I2S1_MCK (MTK_PIN_NO(136) | 3)
> > +#define PINMUX_GPIO136__FUNC_UFS_UNIPRO_SCL (MTK_PIN_NO(136) | 6)
> > +
> > +#define PINMUX_GPIO137__FUNC_GPIO137 (MTK_PIN_NO(137) | 0)
> > +#define PINMUX_GPIO137__FUNC_AUD_SYNC_MOSI (MTK_PIN_NO(137) | 1)
> > +#define PINMUX_GPIO137__FUNC_AUD_SYNC_MISO (MTK_PIN_NO(137) | 2)
> > +#define PINMUX_GPIO137__FUNC_I2S1_BCK (MTK_PIN_NO(137) | 3)
> > +
> > +#define PINMUX_GPIO138__FUNC_GPIO138 (MTK_PIN_NO(138) | 0)
> > +#define PINMUX_GPIO138__FUNC_AUD_DAT_MOSI0 (MTK_PIN_NO(138) | 1)
> > +#define PINMUX_GPIO138__FUNC_AUD_DAT_MISO0 (MTK_PIN_NO(138) | 2)
> > +#define PINMUX_GPIO138__FUNC_I2S1_LRCK (MTK_PIN_NO(138) | 3)
> > +#define PINMUX_GPIO138__FUNC_DBG_MON_B24 (MTK_PIN_NO(138) | 7)
> > +
> > +#define PINMUX_GPIO139__FUNC_GPIO139 (MTK_PIN_NO(139) | 0)
> > +#define PINMUX_GPIO139__FUNC_AUD_DAT_MOSI1 (MTK_PIN_NO(139) | 1)
> > +#define PINMUX_GPIO139__FUNC_AUD_DAT_MISO1 (MTK_PIN_NO(139) | 2)
> > +#define PINMUX_GPIO139__FUNC_I2S1_DO (MTK_PIN_NO(139) | 3)
> > +#define PINMUX_GPIO139__FUNC_UFS_MPHY_SDA (MTK_PIN_NO(139) | 6)
> > +
> > +#define PINMUX_GPIO140__FUNC_GPIO140 (MTK_PIN_NO(140) | 0)
> > +#define PINMUX_GPIO140__FUNC_AUD_CLK_MISO (MTK_PIN_NO(140) | 1)
> > +#define PINMUX_GPIO140__FUNC_AUD_CLK_MOSI (MTK_PIN_NO(140) | 2)
> > +#define PINMUX_GPIO140__FUNC_I2S0_MCK (MTK_PIN_NO(140) | 3)
> > +#define PINMUX_GPIO140__FUNC_UFS_UNIPRO_SDA (MTK_PIN_NO(140) | 6)
> > +
> > +#define PINMUX_GPIO141__FUNC_GPIO141 (MTK_PIN_NO(141) | 0)
> > +#define PINMUX_GPIO141__FUNC_AUD_SYNC_MISO (MTK_PIN_NO(141) | 1)
> > +#define PINMUX_GPIO141__FUNC_AUD_SYNC_MOSI (MTK_PIN_NO(141) | 2)
> > +#define PINMUX_GPIO141__FUNC_I2S0_BCK (MTK_PIN_NO(141) | 3)
> > +
> > +#define PINMUX_GPIO142__FUNC_GPIO142 (MTK_PIN_NO(142) | 0)
> > +#define PINMUX_GPIO142__FUNC_AUD_DAT_MISO0 (MTK_PIN_NO(142) | 1)
> > +#define PINMUX_GPIO142__FUNC_AUD_DAT_MOSI0 (MTK_PIN_NO(142) | 2)
> > +#define PINMUX_GPIO142__FUNC_I2S0_LRCK (MTK_PIN_NO(142) | 3)
> > +#define PINMUX_GPIO142__FUNC_VOW_DAT_MISO (MTK_PIN_NO(142) | 4)
> > +#define PINMUX_GPIO142__FUNC_DBG_MON_B25 (MTK_PIN_NO(142) | 7)
> > +
> > +#define PINMUX_GPIO143__FUNC_GPIO143 (MTK_PIN_NO(143) | 0)
> > +#define PINMUX_GPIO143__FUNC_AUD_DAT_MISO1 (MTK_PIN_NO(143) | 1)
> > +#define PINMUX_GPIO143__FUNC_AUD_DAT_MOSI1 (MTK_PIN_NO(143) | 2)
> > +#define PINMUX_GPIO143__FUNC_I2S0_DI (MTK_PIN_NO(143) | 3)
> > +#define PINMUX_GPIO143__FUNC_VOW_CLK_MISO (MTK_PIN_NO(143) | 4)
> > +#define PINMUX_GPIO143__FUNC_UFS_MPHY_SCL (MTK_PIN_NO(143) | 6)
> > +#define PINMUX_GPIO143__FUNC_DBG_MON_B26 (MTK_PIN_NO(143) | 7)
> > +
> > +#define PINMUX_GPIO144__FUNC_GPIO144 (MTK_PIN_NO(144) | 0)
> > +#define PINMUX_GPIO144__FUNC_PWRAP_SPI0_MI (MTK_PIN_NO(144) | 1)
> > +#define PINMUX_GPIO144__FUNC_PWRAP_SPI0_MO (MTK_PIN_NO(144) | 2)
> > +
> > +#define PINMUX_GPIO145__FUNC_GPIO145 (MTK_PIN_NO(145) | 0)
> > +#define PINMUX_GPIO145__FUNC_PWRAP_SPI0_CSN (MTK_PIN_NO(145) | 1)
> > +
> > +#define PINMUX_GPIO146__FUNC_GPIO146 (MTK_PIN_NO(146) | 0)
> > +#define PINMUX_GPIO146__FUNC_PWRAP_SPI0_MO (MTK_PIN_NO(146) | 1)
> > +#define PINMUX_GPIO146__FUNC_PWRAP_SPI0_MI (MTK_PIN_NO(146) | 2)
> > +
> > +#define PINMUX_GPIO147__FUNC_GPIO147 (MTK_PIN_NO(147) | 0)
> > +#define PINMUX_GPIO147__FUNC_PWRAP_SPI0_CK (MTK_PIN_NO(147) | 1)
> > +
> > +#define PINMUX_GPIO148__FUNC_GPIO148 (MTK_PIN_NO(148) | 0)
> > +#define PINMUX_GPIO148__FUNC_SRCLKENA0 (MTK_PIN_NO(148) | 1)
> > +
> > +#define PINMUX_GPIO149__FUNC_GPIO149 (MTK_PIN_NO(149) | 0)
> > +#define PINMUX_GPIO149__FUNC_SRCLKENA1 (MTK_PIN_NO(149) | 1)
> > +
> > +#define PINMUX_GPIO150__FUNC_GPIO150 (MTK_PIN_NO(150) | 0)
> > +#define PINMUX_GPIO150__FUNC_PWM_A (MTK_PIN_NO(150) | 1)
> > +#define PINMUX_GPIO150__FUNC_CMFLASH (MTK_PIN_NO(150) | 2)
> > +#define PINMUX_GPIO150__FUNC_CLKM0 (MTK_PIN_NO(150) | 3)
> > +#define PINMUX_GPIO150__FUNC_DBG_MON_B30 (MTK_PIN_NO(150) | 7)
> > +
> > +#define PINMUX_GPIO151__FUNC_GPIO151 (MTK_PIN_NO(151) | 0)
> > +#define PINMUX_GPIO151__FUNC_PWM_B (MTK_PIN_NO(151) | 1)
> > +#define PINMUX_GPIO151__FUNC_CMVREF0 (MTK_PIN_NO(151) | 2)
> > +#define PINMUX_GPIO151__FUNC_CLKM1 (MTK_PIN_NO(151) | 3)
> > +#define PINMUX_GPIO151__FUNC_DBG_MON_B20 (MTK_PIN_NO(151) | 7)
> > +
> > +#define PINMUX_GPIO152__FUNC_GPIO152 (MTK_PIN_NO(152) | 0)
> > +#define PINMUX_GPIO152__FUNC_PWM_C (MTK_PIN_NO(152) | 1)
> > +#define PINMUX_GPIO152__FUNC_CMFLASH (MTK_PIN_NO(152) | 2)
> > +#define PINMUX_GPIO152__FUNC_CLKM2 (MTK_PIN_NO(152) | 3)
> > +#define PINMUX_GPIO152__FUNC_DBG_MON_B21 (MTK_PIN_NO(152) | 7)
> > +
> > +#define PINMUX_GPIO153__FUNC_GPIO153 (MTK_PIN_NO(153) | 0)
> > +#define PINMUX_GPIO153__FUNC_PWM_A (MTK_PIN_NO(153) | 1)
> > +#define PINMUX_GPIO153__FUNC_CMVREF0 (MTK_PIN_NO(153) | 2)
> > +#define PINMUX_GPIO153__FUNC_CLKM3 (MTK_PIN_NO(153) | 3)
> > +#define PINMUX_GPIO153__FUNC_DBG_MON_B22 (MTK_PIN_NO(153) | 7)
> > +
> > +#define PINMUX_GPIO154__FUNC_GPIO154 (MTK_PIN_NO(154) | 0)
> > +#define PINMUX_GPIO154__FUNC_SCP_VREQ_VAO (MTK_PIN_NO(154) | 1)
> > +#define PINMUX_GPIO154__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(154) | 2)
> > +#define PINMUX_GPIO154__FUNC_DBG_MON_B18 (MTK_PIN_NO(154) | 7)
> > +
> > +#define PINMUX_GPIO155__FUNC_GPIO155 (MTK_PIN_NO(155) | 0)
> > +#define PINMUX_GPIO155__FUNC_ANT_SEL0 (MTK_PIN_NO(155) | 1)
> > +#define PINMUX_GPIO155__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(155) | 2)
> > +#define PINMUX_GPIO155__FUNC_CMVREF1 (MTK_PIN_NO(155) | 3)
> > +#define PINMUX_GPIO155__FUNC_SCP_JTAG_TDI (MTK_PIN_NO(155) | 7)
> > +
> > +#define PINMUX_GPIO156__FUNC_GPIO156 (MTK_PIN_NO(156) | 0)
> > +#define PINMUX_GPIO156__FUNC_ANT_SEL1 (MTK_PIN_NO(156) | 1)
> > +#define PINMUX_GPIO156__FUNC_SRCLKENAI0 (MTK_PIN_NO(156) | 2)
> > +#define PINMUX_GPIO156__FUNC_SCL6 (MTK_PIN_NO(156) | 3)
> > +#define PINMUX_GPIO156__FUNC_KPCOL2 (MTK_PIN_NO(156) | 4)
> > +#define PINMUX_GPIO156__FUNC_IDDIG (MTK_PIN_NO(156) | 5)
> > +#define PINMUX_GPIO156__FUNC_SCP_JTAG_TCK (MTK_PIN_NO(156) | 7)
> > +
> > +#define PINMUX_GPIO157__FUNC_GPIO157 (MTK_PIN_NO(157) | 0)
> > +#define PINMUX_GPIO157__FUNC_ANT_SEL2 (MTK_PIN_NO(157) | 1)
> > +#define PINMUX_GPIO157__FUNC_SRCLKENAI1 (MTK_PIN_NO(157) | 2)
> > +#define PINMUX_GPIO157__FUNC_SDA6 (MTK_PIN_NO(157) | 3)
> > +#define PINMUX_GPIO157__FUNC_KPROW2 (MTK_PIN_NO(157) | 4)
> > +#define PINMUX_GPIO157__FUNC_USB_DRVVBUS (MTK_PIN_NO(157) | 5)
> > +#define PINMUX_GPIO157__FUNC_SCP_JTAG_TRSTN (MTK_PIN_NO(157) | 7)
> > +
> > +#define PINMUX_GPIO158__FUNC_GPIO158 (MTK_PIN_NO(158) | 0)
> > +#define PINMUX_GPIO158__FUNC_ANT_SEL3 (MTK_PIN_NO(158) | 1)
> > +
> > +#define PINMUX_GPIO159__FUNC_GPIO159 (MTK_PIN_NO(159) | 0)
> > +#define PINMUX_GPIO159__FUNC_ANT_SEL4 (MTK_PIN_NO(159) | 1)
> > +
> > +#define PINMUX_GPIO160__FUNC_GPIO160 (MTK_PIN_NO(160) | 0)
> > +#define PINMUX_GPIO160__FUNC_ANT_SEL5 (MTK_PIN_NO(160) | 1)
> > +
> > +#define PINMUX_GPIO161__FUNC_GPIO161 (MTK_PIN_NO(161) | 0)
> > +#define PINMUX_GPIO161__FUNC_SPI1_A_MI (MTK_PIN_NO(161) | 1)
> > +#define PINMUX_GPIO161__FUNC_SCP_SPI1_MI (MTK_PIN_NO(161) | 2)
> > +#define PINMUX_GPIO161__FUNC_IDDIG (MTK_PIN_NO(161) | 3)
> > +#define PINMUX_GPIO161__FUNC_ANT_SEL6 (MTK_PIN_NO(161) | 4)
> > +#define PINMUX_GPIO161__FUNC_KPCOL2 (MTK_PIN_NO(161) | 5)
> > +#define PINMUX_GPIO161__FUNC_PTA_RXD (MTK_PIN_NO(161) | 6)
> > +#define PINMUX_GPIO161__FUNC_DBG_MON_B19 (MTK_PIN_NO(161) | 7)
> > +
> > +#define PINMUX_GPIO162__FUNC_GPIO162 (MTK_PIN_NO(162) | 0)
> > +#define PINMUX_GPIO162__FUNC_SPI1_A_CSB (MTK_PIN_NO(162) | 1)
> > +#define PINMUX_GPIO162__FUNC_SCP_SPI1_CS (MTK_PIN_NO(162) | 2)
> > +#define PINMUX_GPIO162__FUNC_USB_DRVVBUS (MTK_PIN_NO(162) | 3)
> > +#define PINMUX_GPIO162__FUNC_ANT_SEL5 (MTK_PIN_NO(162) | 4)
> > +#define PINMUX_GPIO162__FUNC_KPROW2 (MTK_PIN_NO(162) | 5)
> > +#define PINMUX_GPIO162__FUNC_PTA_TXD (MTK_PIN_NO(162) | 6)
> > +
> > +#define PINMUX_GPIO163__FUNC_GPIO163 (MTK_PIN_NO(163) | 0)
> > +#define PINMUX_GPIO163__FUNC_SPI1_A_MO (MTK_PIN_NO(163) | 1)
> > +#define PINMUX_GPIO163__FUNC_SCP_SPI1_MO (MTK_PIN_NO(163) | 2)
> > +#define PINMUX_GPIO163__FUNC_SDA1 (MTK_PIN_NO(163) | 3)
> > +#define PINMUX_GPIO163__FUNC_ANT_SEL4 (MTK_PIN_NO(163) | 4)
> > +#define PINMUX_GPIO163__FUNC_CMMCLK2 (MTK_PIN_NO(163) | 5)
> > +#define PINMUX_GPIO163__FUNC_DMIC_CLK (MTK_PIN_NO(163) | 6)
> > +
> > +#define PINMUX_GPIO164__FUNC_GPIO164 (MTK_PIN_NO(164) | 0)
> > +#define PINMUX_GPIO164__FUNC_SPI1_A_CLK (MTK_PIN_NO(164) | 1)
> > +#define PINMUX_GPIO164__FUNC_SCP_SPI1_CK (MTK_PIN_NO(164) | 2)
> > +#define PINMUX_GPIO164__FUNC_SCL1 (MTK_PIN_NO(164) | 3)
> > +#define PINMUX_GPIO164__FUNC_ANT_SEL3 (MTK_PIN_NO(164) | 4)
> > +#define PINMUX_GPIO164__FUNC_CMMCLK3 (MTK_PIN_NO(164) | 5)
> > +#define PINMUX_GPIO164__FUNC_DMIC_DAT (MTK_PIN_NO(164) | 6)
> > +
> > +#define PINMUX_GPIO165__FUNC_GPIO165 (MTK_PIN_NO(165) | 0)
> > +#define PINMUX_GPIO165__FUNC_PWM_B (MTK_PIN_NO(165) | 1)
> > +#define PINMUX_GPIO165__FUNC_CMMCLK2 (MTK_PIN_NO(165) | 2)
> > +#define PINMUX_GPIO165__FUNC_SCP_VREQ_VAO (MTK_PIN_NO(165) | 3)
> > +#define PINMUX_GPIO165__FUNC_TDM_MCK_2ND (MTK_PIN_NO(165) | 6)
> > +#define PINMUX_GPIO165__FUNC_SCP_JTAG_TDO (MTK_PIN_NO(165) | 7)
> > +
> > +#define PINMUX_GPIO166__FUNC_GPIO166 (MTK_PIN_NO(166) | 0)
> > +#define PINMUX_GPIO166__FUNC_ANT_SEL6 (MTK_PIN_NO(166) | 1)
> > +
> > +#define PINMUX_GPIO167__FUNC_GPIO167 (MTK_PIN_NO(167) | 0)
> > +#define PINMUX_GPIO167__FUNC_RFIC0_BSI_EN (MTK_PIN_NO(167) | 1)
> > +#define PINMUX_GPIO167__FUNC_SPM_BSI_EN (MTK_PIN_NO(167) | 2)
> > +
> > +#define PINMUX_GPIO168__FUNC_GPIO168 (MTK_PIN_NO(168) | 0)
> > +#define PINMUX_GPIO168__FUNC_RFIC0_BSI_CK (MTK_PIN_NO(168) | 1)
> > +#define PINMUX_GPIO168__FUNC_SPM_BSI_CK (MTK_PIN_NO(168) | 2)
> > +
> > +#define PINMUX_GPIO169__FUNC_GPIO169 (MTK_PIN_NO(169) | 0)
> > +#define PINMUX_GPIO169__FUNC_PWM_C (MTK_PIN_NO(169) | 1)
> > +#define PINMUX_GPIO169__FUNC_CMMCLK3 (MTK_PIN_NO(169) | 2)
> > +#define PINMUX_GPIO169__FUNC_CMVREF1 (MTK_PIN_NO(169) | 3)
> > +#define PINMUX_GPIO169__FUNC_ANT_SEL7 (MTK_PIN_NO(169) | 4)
> > +#define PINMUX_GPIO169__FUNC_AGPS_SYNC (MTK_PIN_NO(169) | 5)
> > +#define PINMUX_GPIO169__FUNC_TDM_BCK_2ND (MTK_PIN_NO(169) | 6)
> > +#define PINMUX_GPIO169__FUNC_SCP_JTAG_TMS (MTK_PIN_NO(169) | 7)
> > +
> > +#define PINMUX_GPIO170__FUNC_GPIO170 (MTK_PIN_NO(170) | 0)
> > +#define PINMUX_GPIO170__FUNC_I2S1_BCK (MTK_PIN_NO(170) | 1)
> > +#define PINMUX_GPIO170__FUNC_I2S3_BCK (MTK_PIN_NO(170) | 2)
> > +#define PINMUX_GPIO170__FUNC_SCL7 (MTK_PIN_NO(170) | 3)
> > +#define PINMUX_GPIO170__FUNC_I2S5_BCK (MTK_PIN_NO(170) | 4)
> > +#define PINMUX_GPIO170__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(170) | 5)
> > +#define PINMUX_GPIO170__FUNC_TDM_LRCK_2ND (MTK_PIN_NO(170) | 6)
> > +#define PINMUX_GPIO170__FUNC_ANT_SEL3 (MTK_PIN_NO(170) | 7)
> > +
> > +#define PINMUX_GPIO171__FUNC_GPIO171 (MTK_PIN_NO(171) | 0)
> > +#define PINMUX_GPIO171__FUNC_I2S1_LRCK (MTK_PIN_NO(171) | 1)
> > +#define PINMUX_GPIO171__FUNC_I2S3_LRCK (MTK_PIN_NO(171) | 2)
> > +#define PINMUX_GPIO171__FUNC_SDA7 (MTK_PIN_NO(171) | 3)
> > +#define PINMUX_GPIO171__FUNC_I2S5_LRCK (MTK_PIN_NO(171) | 4)
> > +#define PINMUX_GPIO171__FUNC_URXD1 (MTK_PIN_NO(171) | 5)
> > +#define PINMUX_GPIO171__FUNC_TDM_DATA0_2ND (MTK_PIN_NO(171) | 6)
> > +#define PINMUX_GPIO171__FUNC_ANT_SEL4 (MTK_PIN_NO(171) | 7)
> > +
> > +#define PINMUX_GPIO172__FUNC_GPIO172 (MTK_PIN_NO(172) | 0)
> > +#define PINMUX_GPIO172__FUNC_I2S1_DO (MTK_PIN_NO(172) | 1)
> > +#define PINMUX_GPIO172__FUNC_I2S3_DO (MTK_PIN_NO(172) | 2)
> > +#define PINMUX_GPIO172__FUNC_SCL8 (MTK_PIN_NO(172) | 3)
> > +#define PINMUX_GPIO172__FUNC_I2S5_DO (MTK_PIN_NO(172) | 4)
> > +#define PINMUX_GPIO172__FUNC_UTXD1 (MTK_PIN_NO(172) | 5)
> > +#define PINMUX_GPIO172__FUNC_TDM_DATA1_2ND (MTK_PIN_NO(172) | 6)
> > +#define PINMUX_GPIO172__FUNC_ANT_SEL5 (MTK_PIN_NO(172) | 7)
> > +
> > +#define PINMUX_GPIO173__FUNC_GPIO173 (MTK_PIN_NO(173) | 0)
> > +#define PINMUX_GPIO173__FUNC_I2S1_MCK (MTK_PIN_NO(173) | 1)
> > +#define PINMUX_GPIO173__FUNC_I2S3_MCK (MTK_PIN_NO(173) | 2)
> > +#define PINMUX_GPIO173__FUNC_SDA8 (MTK_PIN_NO(173) | 3)
> > +#define PINMUX_GPIO173__FUNC_I2S5_MCK (MTK_PIN_NO(173) | 4)
> > +#define PINMUX_GPIO173__FUNC_UCTS0 (MTK_PIN_NO(173) | 5)
> > +#define PINMUX_GPIO173__FUNC_TDM_DATA2_2ND (MTK_PIN_NO(173) | 6)
> > +#define PINMUX_GPIO173__FUNC_ANT_SEL6 (MTK_PIN_NO(173) | 7)
> > +
> > +#define PINMUX_GPIO174__FUNC_GPIO174 (MTK_PIN_NO(174) | 0)
> > +#define PINMUX_GPIO174__FUNC_I2S2_DI (MTK_PIN_NO(174) | 1)
> > +#define PINMUX_GPIO174__FUNC_I2S0_DI (MTK_PIN_NO(174) | 2)
> > +#define PINMUX_GPIO174__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(174) | 3)
> > +#define PINMUX_GPIO174__FUNC_I2S2_DI2 (MTK_PIN_NO(174) | 4)
> > +#define PINMUX_GPIO174__FUNC_URTS0 (MTK_PIN_NO(174) | 5)
> > +#define PINMUX_GPIO174__FUNC_TDM_DATA3_2ND (MTK_PIN_NO(174) | 6)
> > +#define PINMUX_GPIO174__FUNC_ANT_SEL7 (MTK_PIN_NO(174) | 7)
> > +
> > +#define PINMUX_GPIO175__FUNC_GPIO175 (MTK_PIN_NO(175) | 0)
> > +#define PINMUX_GPIO175__FUNC_ANT_SEL7 (MTK_PIN_NO(175) | 1)
> > +
> > +#define PINMUX_GPIO176__FUNC_GPIO176 (MTK_PIN_NO(176) | 0)
> > +
> > +#define PINMUX_GPIO177__FUNC_GPIO177 (MTK_PIN_NO(177) | 0)
> > +
> > +#define PINMUX_GPIO178__FUNC_GPIO178 (MTK_PIN_NO(178) | 0)
> > +
> > +#define PINMUX_GPIO179__FUNC_GPIO179 (MTK_PIN_NO(179) | 0)
> > +
> > +#endif /* __MT8183-PINFUNC_H */
> > diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> > new file mode 100644
> > index 0000000..cf6712b
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> > @@ -0,0 +1,547 @@
> > +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> > +/*
> > + * Copyright (c) 2018 MediaTek Inc.
> > + * Author: Ben Ho <ben.ho@mediatek.com>
> > + *	   Erin Lo <erin.lo@mediatek.com>
> > + */
> > +
> > +#include <dt-bindings/clock/mt8183-clk.h>
> > +#include <dt-bindings/interrupt-controller/arm-gic.h>
> > +#include <dt-bindings/interrupt-controller/irq.h>
> > +#include <dt-bindings/memory/mt8183-larb-port.h>
> > +#include <dt-bindings/power/mt8183-power.h>
> > +#include "mt8183-pinfunc.h"
> > +
> > +/ {
> > +	compatible = "mediatek,mt8183";
> > +	interrupt-parent = <&sysirq>;
> > +	#address-cells = <2>;
> > +	#size-cells = <2>;
> > +
> > +	cpus {
> > +		#address-cells = <1>;
> > +		#size-cells = <0>;
> > +
> > +		cpu-map {
> > +			cluster0 {
> > +				core0 {
> > +					cpu = <&cpu0>;
> > +				};
> > +				core1 {
> > +					cpu = <&cpu1>;
> > +				};
> > +				core2 {
> > +					cpu = <&cpu2>;
> > +				};
> > +				core3 {
> > +					cpu = <&cpu3>;
> > +				};
> > +			};
> > +
> > +			cluster1 {
> > +				core0 {
> > +					cpu = <&cpu4>;
> > +				};
> > +				core1 {
> > +					cpu = <&cpu5>;
> > +				};
> > +				core2 {
> > +					cpu = <&cpu6>;
> > +				};
> > +				core3 {
> > +					cpu = <&cpu7>;
> > +				};
> > +			};
> > +		};
> > +
> > +		cpu0: cpu@000 {
> 
> Drop leading 0s.

I will fix it in next version.

> 
> > +			device_type = "cpu";
> > +			compatible = "arm,cortex-a53";
> > +			reg = <0x000>;
> > +			enable-method = "psci";
> > +		};
> > +
> > +		cpu1: cpu@001 {
> > +			device_type = "cpu";
> > +			compatible = "arm,cortex-a53";
> > +			reg = <0x001>;
> > +			enable-method = "psci";
> > +		};
> > +
> > +		cpu2: cpu@002 {
> > +			device_type = "cpu";
> > +			compatible = "arm,cortex-a53";
> > +			reg = <0x002>;
> > +			enable-method = "psci";
> > +		};
> > +
> > +		cpu3: cpu@003 {
> > +			device_type = "cpu";
> > +			compatible = "arm,cortex-a53";
> > +			reg = <0x003>;
> > +			enable-method = "psci";
> > +		};
> > +
> > +		cpu4: cpu@100 {
> > +			device_type = "cpu";
> > +			compatible = "arm,cortex-a73";
> > +			reg = <0x100>;
> > +			enable-method = "psci";
> > +		};
> > +
> > +		cpu5: cpu@101 {
> > +			device_type = "cpu";
> > +			compatible = "arm,cortex-a73";
> > +			reg = <0x101>;
> > +			enable-method = "psci";
> > +		};
> > +
> > +		cpu6: cpu@102 {
> > +			device_type = "cpu";
> > +			compatible = "arm,cortex-a73";
> > +			reg = <0x102>;
> > +			enable-method = "psci";
> > +		};
> > +
> > +		cpu7: cpu@103 {
> > +			device_type = "cpu";
> > +			compatible = "arm,cortex-a73";
> > +			reg = <0x103>;
> > +			enable-method = "psci";
> > +		};
> > +	};
> > +
> > +	pmu_a53 {
> 
> Don't use '_' in node names.

I will fix it in next version.

> 
> > +		compatible = "arm,cortex-a53-pmu";
> > +		interrupt-parent = <&gic>;
> > +		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW &ppi_cluster0>;
> > +	};
> > +
> > +	pmu_a73 {
> > +		compatible = "arm,cortex-a73-pmu";
> > +		interrupt-parent = <&gic>;
> > +		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW &ppi_cluster1>;
> > +	};
> > +
> > +	psci {
> > +		compatible      = "arm,psci-1.0";
> > +		method          = "smc";
> > +	};
> > +
> > +	clk26m: oscillator@0 {
> 
> Unit-address without reg is not valid.

I will fix it in next version.

> 
> > +		compatible = "fixed-clock";
> > +		#clock-cells = <0>;
> > +		clock-frequency = <26000000>;
> > +		clock-output-names = "clk26m";
> > +	};
> > +
> > +	timer {
> > +		compatible = "arm,armv8-timer";
> > +		interrupt-parent = <&gic>;
> > +		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW 0>,
> > +			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW 0>,
> > +			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW 0>,
> > +			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW 0>;
> > +	};
> > +
> > +	gic: interrupt-controller@0c000000 {
> 
> Drop leading 0s...
> 

I will fix it in next version.


> Put all mmio peripherals under 1 or more bus nodes.
> 

I look up arch/arm64/boot/dts/renesas/r8a774a1.dtsi..
+                       reg = <0x0 0xf1010000 0 0x1000>,
+                             <0x0 0xf1020000 0 0x20000>,
+                             <0x0 0xf1040000 0 0x20000>,
+                             <0x0 0xf1060000 0 0x20000>;

Is it outdated?


> > +		compatible = "arm,gic-v3";
> > +		#interrupt-cells = <4>;
> > +		interrupt-parent = <&gic>;
> > +		interrupt-controller;
> > +		reg = <0 0x0c000000 0 0x40000>,  /* GICD */
> > +		      <0 0x0c100000 0 0x200000>, /* GICR */
> > +		      <0 0x0c400000 0 0x2000>,   /* GICC */
> > +		      <0 0x0c410000 0 0x1000>,   /* GICH */
> > +		      <0 0x0c420000 0 0x2000>;   /* GICV */
> > +
> > +		interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH 0>;
> > +		ppi-partitions {
> > +			ppi_cluster0: interrupt-partition-0 {
> > +				affinity = <&cpu0 &cpu1 &cpu2 &cpu3>;
> > +			};
> > +			ppi_cluster1: interrupt-partition-1 {
> > +				affinity = <&cpu4 &cpu5 &cpu6 &cpu7>;
> > +			};
> > +		};
> > +	};
> > +
> > +	mcucfg: syscon@0c530000 {
> > +		compatible = "mediatek,mt8183-mcucfg", "syscon";
> > +		reg = <0 0x0c530000 0 0x1000>;
> > +		#clock-cells = <1>;
> > +	};
> > +
> > +	sysirq: intpol-controller@0c530a80 {
> > +		compatible = "mediatek,mt8183-sysirq",
> > +			     "mediatek,mt6577-sysirq";
> > +		interrupt-controller;
> > +		#interrupt-cells = <4>;
> > +		interrupt-parent = <&gic>;
> > +		reg = <0 0x0c530a80 0 0x50>;
> > +	};
> > +
> > +	topckgen: syscon@10000000 {
> > +		compatible = "mediatek,mt8183-topckgen", "syscon";
> > +		reg = <0 0x10000000 0 0x1000>;
> > +		#clock-cells = <1>;
> > +	};
> > +
> > +	infracfg: syscon@10001000 {
> > +		compatible = "mediatek,mt8183-infracfg", "syscon";
> > +		reg = <0 0x10001000 0 0x1000>;
> > +		#clock-cells = <1>;
> > +	};
> > +
> > +	scpsys: syscon@10006000 {
> > +		compatible = "mediatek,mt8183-scpsys", "syscon";
> > +		#power-domain-cells = <1>;
> > +		reg = <0 0x10006000 0 0x1000>;
> > +		clocks = <&topckgen CLK_TOP_MUX_AUD_INTBUS>,
> > +			 <&infracfg CLK_INFRA_AUDIO>,
> > +			 <&infracfg CLK_INFRA_AUDIO_26M_BCLK>,
> > +			 <&topckgen CLK_TOP_MUX_MFG>,
> > +			 <&topckgen CLK_TOP_MUX_MM>,
> > +			 <&topckgen CLK_TOP_MUX_CAM>,
> > +			 <&topckgen CLK_TOP_MUX_IMG>,
> > +			 <&topckgen CLK_TOP_MUX_IPU_IF>,
> > +			 <&topckgen CLK_TOP_MUX_DSP>,
> > +			 <&topckgen CLK_TOP_MUX_DSP1>,
> > +			 <&topckgen CLK_TOP_MUX_DSP2>,
> > +			 <&mmsys CLK_MM_SMI_COMMON>,
> > +			 <&mmsys CLK_MM_SMI_LARB0>,
> > +			 <&mmsys CLK_MM_SMI_LARB1>,
> > +			 <&mmsys CLK_MM_GALS_COMM0>,
> > +			 <&mmsys CLK_MM_GALS_COMM1>,
> > +			 <&mmsys CLK_MM_GALS_CCU2MM>,
> > +			 <&mmsys CLK_MM_GALS_IPU12MM>,
> > +			 <&mmsys CLK_MM_GALS_IMG2MM>,
> > +			 <&mmsys CLK_MM_GALS_CAM2MM>,
> > +			 <&mmsys CLK_MM_GALS_IPU2MM>,
> > +			 <&imgsys CLK_IMG_LARB5>,
> > +			 <&imgsys CLK_IMG_LARB2>,
> > +			 <&camsys CLK_CAM_LARB6>,
> > +			 <&camsys CLK_CAM_LARB3>,
> > +			 <&camsys CLK_CAM_SENINF>,
> > +			 <&camsys CLK_CAM_CAMSV0>,
> > +			 <&camsys CLK_CAM_CAMSV1>,
> > +			 <&camsys CLK_CAM_CAMSV2>,
> > +			 <&camsys CLK_CAM_CCU>,
> > +			 <&ipu_conn CLK_IPU_CONN_IPU>,
> > +			 <&ipu_conn CLK_IPU_CONN_AHB>,
> > +			 <&ipu_conn CLK_IPU_CONN_AXI>,
> > +			 <&ipu_conn CLK_IPU_CONN_ISP>,
> > +			 <&ipu_conn CLK_IPU_CONN_CAM_ADL>,
> > +			 <&ipu_conn CLK_IPU_CONN_IMG_ADL>;
> > +		clock-names = "audio", "audio1", "audio2",
> > +			      "mfg", "mm", "cam",
> > +			      "isp", "vpu", "vpu1",
> > +			      "vpu2", "vpu3", "mm-0",
> > +			      "mm-1", "mm-2", "mm-3",
> > +			      "mm-4", "mm-5", "mm-6",
> > +			      "mm-7", "mm-8", "mm-9",
> > +			      "isp-0", "isp-1", "cam-0",
> > +			      "cam-1", "cam-2", "cam-3",
> > +			      "cam-4", "cam-5", "cam-6",
> > +			      "vpu-0", "vpu-1", "vpu-2",
> > +			      "vpu-3", "vpu-4", "vpu-5";
> > +		infracfg = <&infracfg>;
> > +		smi_comm = <&smi_common>;
> > +	};
> > +
> > +	pio: pinctrl@1000b000 {
> > +		compatible = "mediatek,mt8183-pinctrl";
> > +		reg = <0 0x10005000 0 0x1000>,
> > +		      <0 0x11f20000 0 0x1000>,
> > +		      <0 0x11e80000 0 0x1000>,
> > +		      <0 0x11e70000 0 0x1000>,
> > +		      <0 0x11e90000 0 0x1000>,
> > +		      <0 0x11d30000 0 0x1000>,
> > +		      <0 0x11d20000 0 0x1000>,
> > +		      <0 0x11c50000 0 0x1000>,
> > +		      <0 0x11f30000 0 0x1000>,
> > +		      <0 0x1000b000 0 0x1000>;
> > +		reg-names = "iocfg0", "iocfg1", "iocfg2",
> > +			    "iocfg3", "iocfg4", "iocfg5",
> > +			    "iocfg6", "iocfg7", "iocfg8",
> > +			    "eint";
> > +		gpio-controller;
> > +		#gpio-cells = <2>;
> > +		gpio-ranges = <&pio 0 0 192>;
> > +		interrupt-controller;
> > +		interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH 0>;
> > +		interrupt-parent = <&gic>;
> > +		#interrupt-cells = <4>;
> > +	};
> > +
> > +	apmixedsys: syscon@1000c000 {
> > +		compatible = "mediatek,mt8183-apmixedsys", "syscon";
> > +		reg = <0 0x1000c000 0 0x1000>;
> > +		#clock-cells = <1>;
> > +	};
> > +
> > +	pwrap: pwrap@1000d000 {
> > +		compatible = "mediatek,mt8183-pwrap";
> > +		reg = <0 0x1000d000 0 0x1000>;
> > +		reg-names = "pwrap";
> > +		interrupts = <GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH 0>;
> > +		clocks = <&topckgen CLK_TOP_MUX_PMICSPI>,
> > +			 <&infracfg CLK_INFRA_PMIC_AP>;
> > +		clock-names = "spi", "wrap";
> > +	};
> > +
> > +	iommu: iommu@10205000 {
> > +		compatible = "mediatek,mt8183-m4u";
> > +		reg = <0 0x10205000 0 0x1000>;
> > +		interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_LOW 0>;
> > +		mediatek,larbs = <&larb0 &larb1 &larb2 &larb3
> > +				  &larb4 &larb5 &larb6>;
> > +		#iommu-cells = <1>;
> > +	};
> > +
> > +	uart0: serial@11002000 {
> > +		compatible = "mediatek,mt8183-uart",
> > +			     "mediatek,mt6577-uart";
> > +		reg = <0 0x11002000 0 0x1000>;
> > +		interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW 0>;
> > +		clocks = <&clk26m>, <&infracfg CLK_INFRA_UART0>;
> > +		clock-names = "baud", "bus";
> > +		status = "disabled";
> > +	};
> > +
> > +	uart1: serial@11003000 {
> > +		compatible = "mediatek,mt8183-uart",
> > +			     "mediatek,mt6577-uart";
> > +		reg = <0 0x11003000 0 0x1000>;
> > +		interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_LOW 0>;
> > +		clocks = <&clk26m>, <&infracfg CLK_INFRA_UART1>;
> > +		clock-names = "baud", "bus";
> > +		status = "disabled";
> > +	};
> > +
> > +	uart2: serial@11004000 {
> > +		compatible = "mediatek,mt8183-uart",
> > +			     "mediatek,mt6577-uart";
> > +		reg = <0 0x11004000 0 0x1000>;
> > +		interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_LOW 0>;
> > +		clocks = <&clk26m>, <&infracfg CLK_INFRA_UART2>;
> > +		clock-names = "baud", "bus";
> > +		status = "disabled";
> > +	};
> > +
> > +	spi0: spi@1100a000 {
> > +		compatible = "mediatek,mt8183-spi";
> > +		#address-cells = <1>;
> > +		#size-cells = <0>;
> > +		reg = <0 0x1100a000 0 0x1000>;
> > +		interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_LOW 0>;
> > +		clocks = <&topckgen CLK_TOP_SYSPLL_D5_D2>,
> > +			 <&topckgen CLK_TOP_MUX_SPI>,
> > +			 <&infracfg CLK_INFRA_SPI0>;
> > +		clock-names = "parent-clk", "sel-clk", "spi-clk";
> > +		status = "disabled";
> > +	};
> > +
> > +	spi1: spi@11010000 {
> > +		compatible = "mediatek,mt8183-spi";
> > +		#address-cells = <1>;
> > +		#size-cells = <0>;
> > +		reg = <0 0x11010000 0 0x1000>;
> > +		interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_LOW 0>;
> > +		clocks = <&topckgen CLK_TOP_SYSPLL_D5_D2>,
> > +			 <&topckgen CLK_TOP_MUX_SPI>,
> > +			 <&infracfg CLK_INFRA_SPI1>;
> > +		clock-names = "parent-clk", "sel-clk", "spi-clk";
> > +		status = "disabled";
> > +	};
> > +
> > +	spi2: spi@11012000 {
> > +		compatible = "mediatek,mt8183-spi";
> > +		#address-cells = <1>;
> > +		#size-cells = <0>;
> > +		reg = <0 0x11012000 0 0x1000>;
> > +		interrupts = <GIC_SPI 129 IRQ_TYPE_LEVEL_LOW 0>;
> > +		clocks = <&topckgen CLK_TOP_SYSPLL_D5_D2>,
> > +			 <&topckgen CLK_TOP_MUX_SPI>,
> > +			 <&infracfg CLK_INFRA_SPI2>;
> > +		clock-names = "parent-clk", "sel-clk", "spi-clk";
> > +		status = "disabled";
> > +	};
> > +
> > +	spi3: spi@11013000 {
> > +		compatible = "mediatek,mt8183-spi";
> > +		#address-cells = <1>;
> > +		#size-cells = <0>;
> > +		reg = <0 0x11013000 0 0x1000>;
> > +		interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_LOW 0>;
> > +		clocks = <&topckgen CLK_TOP_SYSPLL_D5_D2>,
> > +			 <&topckgen CLK_TOP_MUX_SPI>,
> > +			 <&infracfg CLK_INFRA_SPI3>;
> > +		clock-names = "parent-clk", "sel-clk", "spi-clk";
> > +		status = "disabled";
> > +	};
> > +
> > +	spi4: spi@11018000 {
> > +		compatible = "mediatek,mt8183-spi";
> > +		#address-cells = <1>;
> > +		#size-cells = <0>;
> > +		reg = <0 0x11018000 0 0x1000>;
> > +		interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_LOW 0>;
> > +		clocks = <&topckgen CLK_TOP_SYSPLL_D5_D2>,
> > +			 <&topckgen CLK_TOP_MUX_SPI>,
> > +			 <&infracfg CLK_INFRA_SPI4>;
> > +		clock-names = "parent-clk", "sel-clk", "spi-clk";
> > +		status = "disabled";
> > +	};
> > +
> > +	spi5: spi@11019000 {
> > +		compatible = "mediatek,mt8183-spi";
> > +		#address-cells = <1>;
> > +		#size-cells = <0>;
> > +		reg = <0 0x11019000 0 0x1000>;
> > +		interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_LOW 0>;
> > +		clocks = <&topckgen CLK_TOP_SYSPLL_D5_D2>,
> > +			 <&topckgen CLK_TOP_MUX_SPI>,
> > +			 <&infracfg CLK_INFRA_SPI5>;
> > +		clock-names = "parent-clk", "sel-clk", "spi-clk";
> > +		status = "disabled";
> > +	};
> > +
> > +	audiosys: syscon@11220000 {
> > +		compatible = "mediatek,mt8183-audiosys", "syscon";
> > +		reg = <0 0x11220000 0 0x1000>;
> > +		#clock-cells = <1>;
> > +	};
> > +
> > +	mfgcfg: syscon@13000000 {
> > +		compatible = "mediatek,mt8183-mfgcfg", "syscon";
> > +		reg = <0 0x13000000 0 0x1000>;
> > +		#clock-cells = <1>;
> > +	};
> > +
> > +	mmsys: syscon@14000000 {
> > +		compatible = "mediatek,mt8183-mmsys", "syscon";
> > +		reg = <0 0x14000000 0 0x1000>;
> > +		#clock-cells = <1>;
> > +	};
> > +
> > +	larb0: larb@14017000 {
> > +		compatible = "mediatek,mt8183-smi-larb";
> > +		reg = <0 0x14017000 0 0x1000>;
> > +		mediatek,smi = <&smi_common>;
> > +		clocks = <&mmsys CLK_MM_SMI_LARB0>,
> > +			 <&mmsys CLK_MM_SMI_LARB0>;
> > +		clock-names = "apb", "smi";
> > +	};
> > +
> > +	smi_common: smi@14019000 {
> > +		compatible = "mediatek,mt8183-smi-common", "syscon";
> > +		reg = <0 0x14019000 0 0x1000>;
> > +		clocks = <&mmsys CLK_MM_SMI_COMMON>,
> > +			 <&mmsys CLK_MM_SMI_COMMON>,
> > +			 <&mmsys CLK_MM_GALS_COMM0>,
> > +			 <&mmsys CLK_MM_GALS_COMM1>;
> > +		clock-names = "apb", "smi", "gals0", "gals1";
> > +	};
> > +
> > +	imgsys: syscon@15020000 {
> > +		compatible = "mediatek,mt8183-imgsys", "syscon";
> > +		reg = <0 0x15020000 0 0x1000>;
> > +		#clock-cells = <1>;
> > +	};
> > +
> > +	larb5: larb@15021000 {
> > +		compatible = "mediatek,mt8183-smi-larb";
> > +		reg = <0 0x15021000 0 0x1000>;
> > +		mediatek,smi = <&smi_common>;
> > +		clocks = <&imgsys CLK_IMG_LARB5>, <&imgsys CLK_IMG_LARB5>,
> > +			 <&mmsys CLK_MM_GALS_IMG2MM>;
> > +		clock-names = "apb", "smi", "gals";
> > +	};
> > +
> > +	larb2: larb@1502f000 {
> > +		compatible = "mediatek,mt8183-smi-larb";
> > +		reg = <0 0x1502f000 0 0x1000>;
> > +		mediatek,smi = <&smi_common>;
> > +		clocks = <&imgsys CLK_IMG_LARB2>, <&imgsys CLK_IMG_LARB2>,
> > +			 <&mmsys CLK_MM_GALS_IPU2MM>;
> > +		clock-names = "apb", "smi", "gals";
> > +	};
> > +
> > +	vdecsys: syscon@16000000 {
> > +		compatible = "mediatek,mt8183-vdecsys", "syscon";
> > +		reg = <0 0x16000000 0 0x1000>;
> > +		#clock-cells = <1>;
> > +	};
> > +
> > +	larb1: larb@16010000 {
> > +		compatible = "mediatek,mt8183-smi-larb";
> > +		reg = <0 0x16010000 0 0x1000>;
> > +		mediatek,smi = <&smi_common>;
> > +		clocks = <&vdecsys CLK_VDEC_VDEC>, <&vdecsys CLK_VDEC_LARB1>;
> > +		clock-names = "apb", "smi";
> > +	};
> > +
> > +	vencsys: syscon@17000000 {
> > +		compatible = "mediatek,mt8183-vencsys", "syscon";
> > +		reg = <0 0x17000000 0 0x1000>;
> > +		#clock-cells = <1>;
> > +	};
> > +
> > +	larb4: larb@17010000 {
> > +		compatible = "mediatek,mt8183-smi-larb";
> > +		reg = <0 0x17010000 0 0x1000>;
> > +		mediatek,smi = <&smi_common>;
> > +		clocks = <&vencsys CLK_VENC_LARB>,
> > +			 <&vencsys CLK_VENC_LARB>;
> > +		clock-names = "apb", "smi";
> > +	};
> > +
> > +	ipu_conn: syscon@19000000 {
> > +		compatible = "mediatek,mt8183-ipu_conn", "syscon";
> > +		reg = <0 0x19000000 0 0x1000>;
> > +		#clock-cells = <1>;
> > +	};
> > +
> > +	ipu_adl: syscon@19010000 {
> > +		compatible = "mediatek,mt8183-ipu_adl", "syscon";
> > +		reg = <0 0x19010000 0 0x1000>;
> > +		#clock-cells = <1>;
> > +	};
> > +
> > +	ipu_core0: syscon@19180000 {
> > +		compatible = "mediatek,mt8183-ipu_core0", "syscon";
> > +		reg = <0 0x19180000 0 0x1000>;
> > +		#clock-cells = <1>;
> > +	};
> > +
> > +	ipu_core1: syscon@19280000 {
> > +		compatible = "mediatek,mt8183-ipu_core1", "syscon";
> > +		reg = <0 0x19280000 0 0x1000>;
> > +		#clock-cells = <1>;
> > +	};
> > +
> > +	camsys: syscon@1a000000 {
> > +		compatible = "mediatek,mt8183-camsys", "syscon";
> > +		reg = <0 0x1a000000 0 0x1000>;
> > +		#clock-cells = <1>;
> > +	};
> > +
> > +	larb6: larb@1a001000 {
> > +		compatible = "mediatek,mt8183-smi-larb";
> > +		reg = <0 0x1a001000 0 0x1000>;
> > +		mediatek,smi = <&smi_common>;
> > +		clocks = <&camsys CLK_CAM_LARB6>, <&camsys CLK_CAM_LARB6>,
> > +			 <&mmsys CLK_MM_GALS_CAM2MM>;
> > +		clock-names = "apb", "smi", "gals";
> > +	};
> > +
> > +	larb3: larb@1a002000 {
> > +		compatible = "mediatek,mt8183-smi-larb";
> > +		reg = <0 0x1a002000 0 0x1000>;
> > +		mediatek,smi = <&smi_common>;
> > +		clocks = <&camsys CLK_CAM_LARB3>, <&camsys CLK_CAM_LARB3>,
> > +			 <&mmsys CLK_MM_GALS_IPU12MM>;
> > +		clock-names = "apb", "smi", "gals";
> > +	};
> > +};
> > -- 
> > 1.9.1
> > 

^ permalink raw reply

* Re: [PATCH 4/4] tty: serial: qcom_geni_serial: Use u32 for register variables
From: Stephen Boyd @ 2019-01-03 21:22 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Evan Green, Doug Anderson, linux-kernel, linux-serial, Ryan Case
In-Reply-To: <20190102213636.40866-5-ryandcase@chromium.org>

Quoting Ryan Case (2019-01-02 13:36:36)
> Signed-off-by: Ryan Case <ryandcase@chromium.org>
> ---

It'd be nice to have any sort of commit text here with the motivation
for the change (code clarity is my motivation).

Besides that nitpick

Reviewed-by: Stephen Boyd <swboyd@chromium.org>

^ permalink raw reply

* Re: [PATCH v5 5/6] dt-bindings: pinctrl: mt8183: add binding document
From: Zhiyong Tao @ 2019-01-04  7:08 UTC (permalink / raw)
  To: Rob Herring
  Cc: Erin Lo (羅雅齡), Matthias Brugger,
	Mark Rutland, Thomas Gleixner, Jason Cooper, Marc Zyngier,
	Greg Kroah-Hartman, Stephen Boyd, devicetree@vger.kernel.org,
	srv_heupstream, linux-kernel@vger.kernel.org,
	linux-serial@vger.kernel.org, linux-mediatek@lists.infradead.org,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <20181228220405.GA8739@bogus>

On Sat, 2018-12-29 at 06:04 +0800, Rob Herring wrote:
> On Fri, Dec 28, 2018 at 04:09:40PM +0800, Erin Lo wrote:
> > From: Zhiyong Tao <zhiyong.tao@mediatek.com>
> > 
> > The commit adds mt8183 compatible node in binding document.
> > 
> > Signed-off-by: Zhiyong Tao <zhiyong.tao@mediatek.com>
> > Signed-off-by: Erin Lo <erin.lo@mediatek.com>
> > ---
> >  .../devicetree/bindings/pinctrl/pinctrl-mt8183.txt | 110 +++++++++++++++++++++
> >  1 file changed, 110 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt
> > new file mode 100644
> > index 0000000..7b5285e
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt
> > @@ -0,0 +1,110 @@
> > +* Mediatek MT8183 Pin Controller
> > +
> > +The Mediatek's Pin controller is used to control SoC pins.
> > +
> > +Required properties:
> > +- compatible: value should be one of the following.
> > +	"mediatek,mt8183-pinctrl", compatible with mt8183 pinctrl.
> > +- gpio-controller : Marks the device node as a gpio controller.
> > +- #gpio-cells: number of cells in GPIO specifier. Since the generic GPIO
> > +  binding is used, the amount of cells must be specified as 2. See the below
> > +  mentioned gpio binding representation for description of particular cells.
> > +- gpio-ranges : gpio valid number range.
> > +
> > +	Eg: <&pio 6 0>
> > +	<[phandle of the gpio controller node]
> > +	[line number within the gpio controller]
> > +	[flags]>
> > +
> > +	Values for gpio specifier:
> > +	- Line number: is a value between 0 to 202.
> > +	- Flags:  bit field of flags, as defined in <dt-bindings/gpio/gpio.h>.
> > +            Only the following flags are supported:
> > +            0 - GPIO_ACTIVE_HIGH
> > +            1 - GPIO_ACTIVE_LOW
> > +
> > +Optional properties:
> > +- reg: physicall address base for gpio base registers.
> 
> s/physicall/physical/
> 
> reg should never be optional. 
> 
> Need to say how many reg entries.

==> Thanks for your suggestion. We will change 'reg' to Required
properties and add the reg entries in next version.
> 
> > +- reg-names: gpio base registers name.
> 
> Need to say what are the names. However, I don't find the names in the 
> example all that useful, so I'd just drop it.

==> we will add the reg-names in next version.
They are used in the sample code, such as:
> +		reg-names = "iocfg0", "iocfg1", "iocfg2",
> > +			    "iocfg3", "iocfg4", "iocfg5",
> > +			    "iocfg6", "iocfg7", "iocfg8";

> 
> > +- interrupt-controller: Marks the device node as an interrupt controller
> > +- #interrupt-cells: Should be two.
> > +- interrupts : The interrupt outputs from the controller.
> > +
> > +Please refer to pinctrl-bindings.txt in this directory for details of the
> > +common pinctrl bindings used by client devices.
> > +
> > +Subnode format
> > +A pinctrl node should contain at least one subnodes representing the
> > +pinctrl groups available on the machine. Each subnode will list the
> > +pins it needs, and how they should be configured, with regard to muxer
> > +configuration, pullups, drive strength, input enable/disable and input schmitt.
> > +
> > +    node {
> > +	pinmux = <PIN_NUMBER_PINMUX>;
> > +	GENERIC_PINCONFIG;
> > +    };
> > +
> > +Required properties:
> > +- pinmux: integer array, represents gpio pin number and mux setting.
> > +    Supported pin number and mux varies for different SoCs, and are defined
> > +    as macros in boot/dts/<soc>-pinfunc.h directly.
> > +
> > +Optional properties:
> > +- GENERIC_PINCONFIG: is the generic pinconfig options to use, bias-disable,
> > +    bias-pull-down, bias-pull-up, input-enable, input-disable, output-low, output-high,
> > +    input-schmitt-enable, input-schmitt-disable and drive-strength are valid.
> > +
> > +    Some special pins have extra pull up strength, there are R0 and R1 pull-up
> > +    resistors available, but for user, it's only need to set R1R0 as 00, 01, 10 or 11.
> > +    So when config mediatek,pull-up-adv or mediatek,pull-down-adv,
> > +    it support arguments for those special pins.
> > +
> > +    When config drive-strength, it can support some arguments, such as
> > +    MTK_DRIVE_4mA, MTK_DRIVE_6mA, etc. See dt-bindings/pinctrl/mt65xx.h.
> > +
> > +Examples:
> > +
> > +#include "mt8183-pinfunc.h"
> > +
> > +...
> > +{
> > +	pio: pinctrl@10005000 {
> > +		compatible = "mediatek,mt8183-pinctrl";
> > +		reg = <0 0x10005000 0 0x1000>,
> > +		      <0 0x11F20000 0 0x1000>,
> > +		      <0 0x11E80000 0 0x1000>,
> > +		      <0 0x11E70000 0 0x1000>,
> > +		      <0 0x11E90000 0 0x1000>,
> > +		      <0 0x11D30000 0 0x1000>,
> > +		      <0 0x11D20000 0 0x1000>,
> > +		      <0 0x11C50000 0 0x1000>,
> > +		      <0 0x11F30000 0 0x1000>;
> > +		reg-names = "iocfg0", "iocfg1", "iocfg2",
> > +			    "iocfg3", "iocfg4", "iocfg5",
> > +			    "iocfg6", "iocfg7", "iocfg8";
> > +		gpio-controller;
> > +		#gpio-cells = <2>;
> > +		gpio-ranges = <&pio 0 0 192>;
> > +		interrupt-controller;
> > +		interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
> > +		interrupt-parent = <&gic>;
> > +		#interrupt-cells = <2>;
> > +
> > +		i2c0_pins_a: i2c0@0 {
> 
> unit-address without reg property is not valid.

==> we will change "i2c0_pins_a: i2c0@0" to "i2c0_pins_a: i2c0" in the
next version.
> 
> > +			pins1 {
> > +				pinmux = <PINMUX_GPIO48__FUNC_SCL5>,
> > +					 <PINMUX_GPIO49__FUNC_SDA5>;
> > +				mediatek,pull-up-adv = <11>;
> > +			};
> > +		};
> > +
> > +		i2c1_pins_a: i2c1@0 {
> > +			pins {
> > +				pinmux = <PINMUX_GPIO50__FUNC_SCL3>,
> > +					 <PINMUX_GPIO51__FUNC_SDA3>;
> > +				mediatek,pull-down-adv = <10>;
> > +			};
> > +		};
> > +		...
> > +	};
> > +};
> > -- 
> > 1.9.1
> > 

^ permalink raw reply

* Re: [PATCH 4/4] tty: serial: qcom_geni_serial: Use u32 for register variables
From: Greg Kroah-Hartman @ 2019-01-04  8:45 UTC (permalink / raw)
  To: Ryan Case
  Cc: Jiri Slaby, Evan Green, Doug Anderson, linux-kernel, linux-serial,
	Stephen Boyd
In-Reply-To: <20190102213636.40866-5-ryandcase@chromium.org>

On Wed, Jan 02, 2019 at 01:36:36PM -0800, Ryan Case wrote:
> Signed-off-by: Ryan Case <ryandcase@chromium.org>
> ---
> 
>  drivers/tty/serial/qcom_geni_serial.c | 22 +++++++++++-----------
>  1 file changed, 11 insertions(+), 11 deletions(-)

I can not take patches without any changelog text, sorry.

greg k-h

^ permalink raw reply

* Re: [PATCH v5 5/6] dt-bindings: pinctrl: mt8183: add binding document
From: Sean Wang @ 2019-01-04  9:14 UTC (permalink / raw)
  To: Zhiyong Tao
  Cc: Rob Herring, Mark Rutland, devicetree@vger.kernel.org,
	Jason Cooper, srv_heupstream, Marc Zyngier, Greg Kroah-Hartman,
	Erin Lo (羅雅齡), Stephen Boyd,
	linux-kernel@vger.kernel.org, linux-mediatek@lists.infradead.org,
	linux-serial@vger.kernel.org,
	Mars Cheng (鄭森友), Matthias Brugger
In-Reply-To: <1546585723.21915.7.camel@mhfsdcap03>

On Thu, Jan 3, 2019 at 11:09 PM Zhiyong Tao <zhiyong.tao@mediatek.com> wrote:
>
> On Sat, 2018-12-29 at 06:04 +0800, Rob Herring wrote:
> > On Fri, Dec 28, 2018 at 04:09:40PM +0800, Erin Lo wrote:
> > > From: Zhiyong Tao <zhiyong.tao@mediatek.com>
> > >
> > > The commit adds mt8183 compatible node in binding document.
> > >
> > > Signed-off-by: Zhiyong Tao <zhiyong.tao@mediatek.com>
> > > Signed-off-by: Erin Lo <erin.lo@mediatek.com>
> > > ---
> > >  .../devicetree/bindings/pinctrl/pinctrl-mt8183.txt | 110 +++++++++++++++++++++
> > >  1 file changed, 110 insertions(+)
> > >  create mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt
> > >
> > > diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt
> > > new file mode 100644
> > > index 0000000..7b5285e
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt
> > > @@ -0,0 +1,110 @@
> > > +* Mediatek MT8183 Pin Controller
> > > +
> > > +The Mediatek's Pin controller is used to control SoC pins.
> > > +
> > > +Required properties:
> > > +- compatible: value should be one of the following.
> > > +   "mediatek,mt8183-pinctrl", compatible with mt8183 pinctrl.
> > > +- gpio-controller : Marks the device node as a gpio controller.
> > > +- #gpio-cells: number of cells in GPIO specifier. Since the generic GPIO
> > > +  binding is used, the amount of cells must be specified as 2. See the below
> > > +  mentioned gpio binding representation for description of particular cells.
> > > +- gpio-ranges : gpio valid number range.
> > > +
> > > +   Eg: <&pio 6 0>
> > > +   <[phandle of the gpio controller node]
> > > +   [line number within the gpio controller]
> > > +   [flags]>
> > > +
> > > +   Values for gpio specifier:
> > > +   - Line number: is a value between 0 to 202.
> > > +   - Flags:  bit field of flags, as defined in <dt-bindings/gpio/gpio.h>.
> > > +            Only the following flags are supported:
> > > +            0 - GPIO_ACTIVE_HIGH
> > > +            1 - GPIO_ACTIVE_LOW
> > > +
> > > +Optional properties:
> > > +- reg: physicall address base for gpio base registers.
> >
> > s/physicall/physical/
> >
> > reg should never be optional.
> >
> > Need to say how many reg entries.
>
> ==> Thanks for your suggestion. We will change 'reg' to Required
> properties and add the reg entries in next version.
> >
> > > +- reg-names: gpio base registers name.
> >
> > Need to say what are the names. However, I don't find the names in the
> > example all that useful, so I'd just drop it.
>
> ==> we will add the reg-names in next version.
> They are used in the sample code, such as:
> > +             reg-names = "iocfg0", "iocfg1", "iocfg2",
> > > +                       "iocfg3", "iocfg4", "iocfg5",
> > > +                       "iocfg6", "iocfg7", "iocfg8";
>
> >
> > > +- interrupt-controller: Marks the device node as an interrupt controller
> > > +- #interrupt-cells: Should be two.
> > > +- interrupts : The interrupt outputs from the controller.
> > > +
> > > +Please refer to pinctrl-bindings.txt in this directory for details of the
> > > +common pinctrl bindings used by client devices.
> > > +
> > > +Subnode format
> > > +A pinctrl node should contain at least one subnodes representing the
> > > +pinctrl groups available on the machine. Each subnode will list the
> > > +pins it needs, and how they should be configured, with regard to muxer
> > > +configuration, pullups, drive strength, input enable/disable and input schmitt.
> > > +
> > > +    node {
> > > +   pinmux = <PIN_NUMBER_PINMUX>;
> > > +   GENERIC_PINCONFIG;
> > > +    };
> > > +
> > > +Required properties:
> > > +- pinmux: integer array, represents gpio pin number and mux setting.
> > > +    Supported pin number and mux varies for different SoCs, and are defined
> > > +    as macros in boot/dts/<soc>-pinfunc.h directly.
> > > +
> > > +Optional properties:
> > > +- GENERIC_PINCONFIG: is the generic pinconfig options to use, bias-disable,
> > > +    bias-pull-down, bias-pull-up, input-enable, input-disable, output-low, output-high,
> > > +    input-schmitt-enable, input-schmitt-disable and drive-strength are valid.
> > > +
> > > +    Some special pins have extra pull up strength, there are R0 and R1 pull-up
> > > +    resistors available, but for user, it's only need to set R1R0 as 00, 01, 10 or 11.
> > > +    So when config mediatek,pull-up-adv or mediatek,pull-down-adv,
> > > +    it support arguments for those special pins.
> > > +
> > > +    When config drive-strength, it can support some arguments, such as
> > > +    MTK_DRIVE_4mA, MTK_DRIVE_6mA, etc. See dt-bindings/pinctrl/mt65xx.h.
> > > +

One point we can fix more is the drive-strength already is supported
as the generic one, not need to depend on a dedicated header file.

> > > +Examples:
> > > +
> > > +#include "mt8183-pinfunc.h"
> > > +
> > > +...
> > > +{
> > > +   pio: pinctrl@10005000 {
> > > +           compatible = "mediatek,mt8183-pinctrl";
> > > +           reg = <0 0x10005000 0 0x1000>,
> > > +                 <0 0x11F20000 0 0x1000>,
> > > +                 <0 0x11E80000 0 0x1000>,
> > > +                 <0 0x11E70000 0 0x1000>,
> > > +                 <0 0x11E90000 0 0x1000>,
> > > +                 <0 0x11D30000 0 0x1000>,
> > > +                 <0 0x11D20000 0 0x1000>,
> > > +                 <0 0x11C50000 0 0x1000>,
> > > +                 <0 0x11F30000 0 0x1000>;
> > > +           reg-names = "iocfg0", "iocfg1", "iocfg2",
> > > +                       "iocfg3", "iocfg4", "iocfg5",
> > > +                       "iocfg6", "iocfg7", "iocfg8";
> > > +           gpio-controller;
> > > +           #gpio-cells = <2>;
> > > +           gpio-ranges = <&pio 0 0 192>;
> > > +           interrupt-controller;
> > > +           interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
> > > +           interrupt-parent = <&gic>;
> > > +           #interrupt-cells = <2>;
> > > +
> > > +           i2c0_pins_a: i2c0@0 {
> >
> > unit-address without reg property is not valid.
>
> ==> we will change "i2c0_pins_a: i2c0@0" to "i2c0_pins_a: i2c0" in the
> next version.
> >
> > > +                   pins1 {
> > > +                           pinmux = <PINMUX_GPIO48__FUNC_SCL5>,
> > > +                                    <PINMUX_GPIO49__FUNC_SDA5>;
> > > +                           mediatek,pull-up-adv = <11>;
> > > +                   };
> > > +           };
> > > +
> > > +           i2c1_pins_a: i2c1@0 {
> > > +                   pins {
> > > +                           pinmux = <PINMUX_GPIO50__FUNC_SCL3>,
> > > +                                    <PINMUX_GPIO51__FUNC_SDA3>;
> > > +                           mediatek,pull-down-adv = <10>;
> > > +                   };
> > > +           };
> > > +           ...
> > > +   };
> > > +};
> > > --
> > > 1.9.1
> > >
>
>
>
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply

* Re: [PATCH v5 5/6] dt-bindings: pinctrl: mt8183: add binding document
From: Zhiyong Tao @ 2019-01-04  9:40 UTC (permalink / raw)
  To: Sean Wang
  Cc: Rob Herring, Mark Rutland, devicetree@vger.kernel.org,
	Jason Cooper, srv_heupstream, Marc Zyngier, Greg Kroah-Hartman,
	Erin Lo (羅雅齡), Stephen Boyd,
	linux-kernel@vger.kernel.org, linux-mediatek@lists.infradead.org,
	linux-serial@vger.kernel.org,
	Mars Cheng (鄭森友), Matthias Brugger
In-Reply-To: <CAGp9LzoAyZqC53eo4JKcouu=pNgsGm9FFm1GaxbH1Jc1OD8Bvw@mail.gmail.com>

On Fri, 2019-01-04 at 01:14 -0800, Sean Wang wrote:
> On Thu, Jan 3, 2019 at 11:09 PM Zhiyong Tao <zhiyong.tao@mediatek.com> wrote:
> >
> > On Sat, 2018-12-29 at 06:04 +0800, Rob Herring wrote:
> > > On Fri, Dec 28, 2018 at 04:09:40PM +0800, Erin Lo wrote:
> > > > From: Zhiyong Tao <zhiyong.tao@mediatek.com>
> > > >
> > > > The commit adds mt8183 compatible node in binding document.
> > > >
> > > > Signed-off-by: Zhiyong Tao <zhiyong.tao@mediatek.com>
> > > > Signed-off-by: Erin Lo <erin.lo@mediatek.com>
> > > > ---
> > > >  .../devicetree/bindings/pinctrl/pinctrl-mt8183.txt | 110 +++++++++++++++++++++
> > > >  1 file changed, 110 insertions(+)
> > > >  create mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt
> > > >
> > > > diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt
> > > > new file mode 100644
> > > > index 0000000..7b5285e
> > > > --- /dev/null
> > > > +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt
> > > > @@ -0,0 +1,110 @@
> > > > +* Mediatek MT8183 Pin Controller
> > > > +
> > > > +The Mediatek's Pin controller is used to control SoC pins.
> > > > +
> > > > +Required properties:
> > > > +- compatible: value should be one of the following.
> > > > +   "mediatek,mt8183-pinctrl", compatible with mt8183 pinctrl.
> > > > +- gpio-controller : Marks the device node as a gpio controller.
> > > > +- #gpio-cells: number of cells in GPIO specifier. Since the generic GPIO
> > > > +  binding is used, the amount of cells must be specified as 2. See the below
> > > > +  mentioned gpio binding representation for description of particular cells.
> > > > +- gpio-ranges : gpio valid number range.
> > > > +
> > > > +   Eg: <&pio 6 0>
> > > > +   <[phandle of the gpio controller node]
> > > > +   [line number within the gpio controller]
> > > > +   [flags]>
> > > > +
> > > > +   Values for gpio specifier:
> > > > +   - Line number: is a value between 0 to 202.
> > > > +   - Flags:  bit field of flags, as defined in <dt-bindings/gpio/gpio.h>.
> > > > +            Only the following flags are supported:
> > > > +            0 - GPIO_ACTIVE_HIGH
> > > > +            1 - GPIO_ACTIVE_LOW
> > > > +
> > > > +Optional properties:
> > > > +- reg: physicall address base for gpio base registers.
> > >
> > > s/physicall/physical/
> > >
> > > reg should never be optional.
> > >
> > > Need to say how many reg entries.
> >
> > ==> Thanks for your suggestion. We will change 'reg' to Required
> > properties and add the reg entries in next version.
> > >
> > > > +- reg-names: gpio base registers name.
> > >
> > > Need to say what are the names. However, I don't find the names in the
> > > example all that useful, so I'd just drop it.
> >
> > ==> we will add the reg-names in next version.
> > They are used in the sample code, such as:
> > > +             reg-names = "iocfg0", "iocfg1", "iocfg2",
> > > > +                       "iocfg3", "iocfg4", "iocfg5",
> > > > +                       "iocfg6", "iocfg7", "iocfg8";
> >
> > >
> > > > +- interrupt-controller: Marks the device node as an interrupt controller
> > > > +- #interrupt-cells: Should be two.
> > > > +- interrupts : The interrupt outputs from the controller.
> > > > +
> > > > +Please refer to pinctrl-bindings.txt in this directory for details of the
> > > > +common pinctrl bindings used by client devices.
> > > > +
> > > > +Subnode format
> > > > +A pinctrl node should contain at least one subnodes representing the
> > > > +pinctrl groups available on the machine. Each subnode will list the
> > > > +pins it needs, and how they should be configured, with regard to muxer
> > > > +configuration, pullups, drive strength, input enable/disable and input schmitt.
> > > > +
> > > > +    node {
> > > > +   pinmux = <PIN_NUMBER_PINMUX>;
> > > > +   GENERIC_PINCONFIG;
> > > > +    };
> > > > +
> > > > +Required properties:
> > > > +- pinmux: integer array, represents gpio pin number and mux setting.
> > > > +    Supported pin number and mux varies for different SoCs, and are defined
> > > > +    as macros in boot/dts/<soc>-pinfunc.h directly.
> > > > +
> > > > +Optional properties:
> > > > +- GENERIC_PINCONFIG: is the generic pinconfig options to use, bias-disable,
> > > > +    bias-pull-down, bias-pull-up, input-enable, input-disable, output-low, output-high,
> > > > +    input-schmitt-enable, input-schmitt-disable and drive-strength are valid.
> > > > +
> > > > +    Some special pins have extra pull up strength, there are R0 and R1 pull-up
> > > > +    resistors available, but for user, it's only need to set R1R0 as 00, 01, 10 or 11.
> > > > +    So when config mediatek,pull-up-adv or mediatek,pull-down-adv,
> > > > +    it support arguments for those special pins.
> > > > +
> > > > +    When config drive-strength, it can support some arguments, such as
> > > > +    MTK_DRIVE_4mA, MTK_DRIVE_6mA, etc. See dt-bindings/pinctrl/mt65xx.h.
> > > > +
> 
> One point we can fix more is the drive-strength already is supported
> as the generic one, not need to depend on a dedicated header file.

==> We think that we use MTK_DRIVE_4mA to set as driving in dts. it it
more clear in v2 common driver for single pin -> single group mode.
How about the idea?

Thanks.
> 
> > > > +Examples:
> > > > +
> > > > +#include "mt8183-pinfunc.h"
> > > > +
> > > > +...
> > > > +{
> > > > +   pio: pinctrl@10005000 {
> > > > +           compatible = "mediatek,mt8183-pinctrl";
> > > > +           reg = <0 0x10005000 0 0x1000>,
> > > > +                 <0 0x11F20000 0 0x1000>,
> > > > +                 <0 0x11E80000 0 0x1000>,
> > > > +                 <0 0x11E70000 0 0x1000>,
> > > > +                 <0 0x11E90000 0 0x1000>,
> > > > +                 <0 0x11D30000 0 0x1000>,
> > > > +                 <0 0x11D20000 0 0x1000>,
> > > > +                 <0 0x11C50000 0 0x1000>,
> > > > +                 <0 0x11F30000 0 0x1000>;
> > > > +           reg-names = "iocfg0", "iocfg1", "iocfg2",
> > > > +                       "iocfg3", "iocfg4", "iocfg5",
> > > > +                       "iocfg6", "iocfg7", "iocfg8";
> > > > +           gpio-controller;
> > > > +           #gpio-cells = <2>;
> > > > +           gpio-ranges = <&pio 0 0 192>;
> > > > +           interrupt-controller;
> > > > +           interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
> > > > +           interrupt-parent = <&gic>;
> > > > +           #interrupt-cells = <2>;
> > > > +
> > > > +           i2c0_pins_a: i2c0@0 {
> > >
> > > unit-address without reg property is not valid.
> >
> > ==> we will change "i2c0_pins_a: i2c0@0" to "i2c0_pins_a: i2c0" in the
> > next version.
> > >
> > > > +                   pins1 {
> > > > +                           pinmux = <PINMUX_GPIO48__FUNC_SCL5>,
> > > > +                                    <PINMUX_GPIO49__FUNC_SDA5>;
> > > > +                           mediatek,pull-up-adv = <11>;
> > > > +                   };
> > > > +           };
> > > > +
> > > > +           i2c1_pins_a: i2c1@0 {
> > > > +                   pins {
> > > > +                           pinmux = <PINMUX_GPIO50__FUNC_SCL3>,
> > > > +                                    <PINMUX_GPIO51__FUNC_SDA3>;
> > > > +                           mediatek,pull-down-adv = <10>;
> > > > +                   };
> > > > +           };
> > > > +           ...
> > > > +   };
> > > > +};
> > > > --
> > > > 1.9.1
> > > >
> >
> >
> >
> > _______________________________________________
> > Linux-mediatek mailing list
> > Linux-mediatek@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply

* Re: [PATCH v5 5/6] dt-bindings: pinctrl: mt8183: add binding document
From: Sean Wang @ 2019-01-04  9:55 UTC (permalink / raw)
  To: Zhiyong Tao
  Cc: Rob Herring, Mark Rutland, devicetree@vger.kernel.org,
	Jason Cooper, srv_heupstream, Marc Zyngier, Greg Kroah-Hartman,
	Erin Lo (羅雅齡), Stephen Boyd,
	linux-kernel@vger.kernel.org, linux-mediatek@lists.infradead.org,
	linux-serial@vger.kernel.org,
	Mars Cheng (鄭森友), Matthias Brugger
In-Reply-To: <1546594814.21915.16.camel@mhfsdcap03>

On Fri, Jan 4, 2019 at 1:40 AM Zhiyong Tao <zhiyong.tao@mediatek.com> wrote:
>
> On Fri, 2019-01-04 at 01:14 -0800, Sean Wang wrote:
> > On Thu, Jan 3, 2019 at 11:09 PM Zhiyong Tao <zhiyong.tao@mediatek.com> wrote:
> > >
> > > On Sat, 2018-12-29 at 06:04 +0800, Rob Herring wrote:
> > > > On Fri, Dec 28, 2018 at 04:09:40PM +0800, Erin Lo wrote:
> > > > > From: Zhiyong Tao <zhiyong.tao@mediatek.com>
> > > > >
> > > > > The commit adds mt8183 compatible node in binding document.
> > > > >
> > > > > Signed-off-by: Zhiyong Tao <zhiyong.tao@mediatek.com>
> > > > > Signed-off-by: Erin Lo <erin.lo@mediatek.com>
> > > > > ---
> > > > >  .../devicetree/bindings/pinctrl/pinctrl-mt8183.txt | 110 +++++++++++++++++++++
> > > > >  1 file changed, 110 insertions(+)
> > > > >  create mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt
> > > > >
> > > > > diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt
> > > > > new file mode 100644
> > > > > index 0000000..7b5285e
> > > > > --- /dev/null
> > > > > +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt
> > > > > @@ -0,0 +1,110 @@
> > > > > +* Mediatek MT8183 Pin Controller
> > > > > +
> > > > > +The Mediatek's Pin controller is used to control SoC pins.
> > > > > +
> > > > > +Required properties:
> > > > > +- compatible: value should be one of the following.
> > > > > +   "mediatek,mt8183-pinctrl", compatible with mt8183 pinctrl.
> > > > > +- gpio-controller : Marks the device node as a gpio controller.
> > > > > +- #gpio-cells: number of cells in GPIO specifier. Since the generic GPIO
> > > > > +  binding is used, the amount of cells must be specified as 2. See the below
> > > > > +  mentioned gpio binding representation for description of particular cells.
> > > > > +- gpio-ranges : gpio valid number range.
> > > > > +
> > > > > +   Eg: <&pio 6 0>
> > > > > +   <[phandle of the gpio controller node]
> > > > > +   [line number within the gpio controller]
> > > > > +   [flags]>
> > > > > +
> > > > > +   Values for gpio specifier:
> > > > > +   - Line number: is a value between 0 to 202.
> > > > > +   - Flags:  bit field of flags, as defined in <dt-bindings/gpio/gpio.h>.
> > > > > +            Only the following flags are supported:
> > > > > +            0 - GPIO_ACTIVE_HIGH
> > > > > +            1 - GPIO_ACTIVE_LOW
> > > > > +
> > > > > +Optional properties:
> > > > > +- reg: physicall address base for gpio base registers.
> > > >
> > > > s/physicall/physical/
> > > >
> > > > reg should never be optional.
> > > >
> > > > Need to say how many reg entries.
> > >
> > > ==> Thanks for your suggestion. We will change 'reg' to Required
> > > properties and add the reg entries in next version.
> > > >
> > > > > +- reg-names: gpio base registers name.
> > > >
> > > > Need to say what are the names. However, I don't find the names in the
> > > > example all that useful, so I'd just drop it.
> > >
> > > ==> we will add the reg-names in next version.
> > > They are used in the sample code, such as:
> > > > +             reg-names = "iocfg0", "iocfg1", "iocfg2",
> > > > > +                       "iocfg3", "iocfg4", "iocfg5",
> > > > > +                       "iocfg6", "iocfg7", "iocfg8";
> > >
> > > >
> > > > > +- interrupt-controller: Marks the device node as an interrupt controller
> > > > > +- #interrupt-cells: Should be two.
> > > > > +- interrupts : The interrupt outputs from the controller.
> > > > > +
> > > > > +Please refer to pinctrl-bindings.txt in this directory for details of the
> > > > > +common pinctrl bindings used by client devices.
> > > > > +
> > > > > +Subnode format
> > > > > +A pinctrl node should contain at least one subnodes representing the
> > > > > +pinctrl groups available on the machine. Each subnode will list the
> > > > > +pins it needs, and how they should be configured, with regard to muxer
> > > > > +configuration, pullups, drive strength, input enable/disable and input schmitt.
> > > > > +
> > > > > +    node {
> > > > > +   pinmux = <PIN_NUMBER_PINMUX>;
> > > > > +   GENERIC_PINCONFIG;
> > > > > +    };
> > > > > +
> > > > > +Required properties:
> > > > > +- pinmux: integer array, represents gpio pin number and mux setting.
> > > > > +    Supported pin number and mux varies for different SoCs, and are defined
> > > > > +    as macros in boot/dts/<soc>-pinfunc.h directly.
> > > > > +
> > > > > +Optional properties:
> > > > > +- GENERIC_PINCONFIG: is the generic pinconfig options to use, bias-disable,
> > > > > +    bias-pull-down, bias-pull-up, input-enable, input-disable, output-low, output-high,
> > > > > +    input-schmitt-enable, input-schmitt-disable and drive-strength are valid.
> > > > > +
> > > > > +    Some special pins have extra pull up strength, there are R0 and R1 pull-up
> > > > > +    resistors available, but for user, it's only need to set R1R0 as 00, 01, 10 or 11.
> > > > > +    So when config mediatek,pull-up-adv or mediatek,pull-down-adv,
> > > > > +    it support arguments for those special pins.
> > > > > +
> > > > > +    When config drive-strength, it can support some arguments, such as
> > > > > +    MTK_DRIVE_4mA, MTK_DRIVE_6mA, etc. See dt-bindings/pinctrl/mt65xx.h.
> > > > > +
> >
> > One point we can fix more is the drive-strength already is supported
> > as the generic one, not need to depend on a dedicated header file.
>
> ==> We think that we use MTK_DRIVE_4mA to set as driving in dts. it it
> more clear in v2 common driver for single pin -> single group mode.
> How about the idea?
>

Sure, thank for post your idea and it sounds not bad to keep the
convention for the single pin -> single group mode binding.

> Thanks.
> >
> > > > > +Examples:
> > > > > +
> > > > > +#include "mt8183-pinfunc.h"
> > > > > +
> > > > > +...
> > > > > +{
> > > > > +   pio: pinctrl@10005000 {
> > > > > +           compatible = "mediatek,mt8183-pinctrl";
> > > > > +           reg = <0 0x10005000 0 0x1000>,
> > > > > +                 <0 0x11F20000 0 0x1000>,
> > > > > +                 <0 0x11E80000 0 0x1000>,
> > > > > +                 <0 0x11E70000 0 0x1000>,
> > > > > +                 <0 0x11E90000 0 0x1000>,
> > > > > +                 <0 0x11D30000 0 0x1000>,
> > > > > +                 <0 0x11D20000 0 0x1000>,
> > > > > +                 <0 0x11C50000 0 0x1000>,
> > > > > +                 <0 0x11F30000 0 0x1000>;
> > > > > +           reg-names = "iocfg0", "iocfg1", "iocfg2",
> > > > > +                       "iocfg3", "iocfg4", "iocfg5",
> > > > > +                       "iocfg6", "iocfg7", "iocfg8";
> > > > > +           gpio-controller;
> > > > > +           #gpio-cells = <2>;
> > > > > +           gpio-ranges = <&pio 0 0 192>;
> > > > > +           interrupt-controller;
> > > > > +           interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
> > > > > +           interrupt-parent = <&gic>;
> > > > > +           #interrupt-cells = <2>;
> > > > > +
> > > > > +           i2c0_pins_a: i2c0@0 {
> > > >
> > > > unit-address without reg property is not valid.
> > >
> > > ==> we will change "i2c0_pins_a: i2c0@0" to "i2c0_pins_a: i2c0" in the
> > > next version.
> > > >
> > > > > +                   pins1 {
> > > > > +                           pinmux = <PINMUX_GPIO48__FUNC_SCL5>,
> > > > > +                                    <PINMUX_GPIO49__FUNC_SDA5>;
> > > > > +                           mediatek,pull-up-adv = <11>;
> > > > > +                   };
> > > > > +           };
> > > > > +
> > > > > +           i2c1_pins_a: i2c1@0 {
> > > > > +                   pins {
> > > > > +                           pinmux = <PINMUX_GPIO50__FUNC_SCL3>,
> > > > > +                                    <PINMUX_GPIO51__FUNC_SDA3>;
> > > > > +                           mediatek,pull-down-adv = <10>;
> > > > > +                   };
> > > > > +           };
> > > > > +           ...
> > > > > +   };
> > > > > +};
> > > > > --
> > > > > 1.9.1
> > > > >
> > >
> > >
> > >
> > > _______________________________________________
> > > Linux-mediatek mailing list
> > > Linux-mediatek@lists.infradead.org
> > > http://lists.infradead.org/mailman/listinfo/linux-mediatek
>
>

^ permalink raw reply

* [PATCH RFC lora-next 0/5] net: lora: sx130x: USB CDC Picocell Gateway serdev driver via fake DT nodes
From: Andreas Färber @ 2019-01-04 11:21 UTC (permalink / raw)
  To: linux-lpwan, linux-serial
  Cc: linux-usb, devicetree, linux-kernel, Johan Hovold, Rob Herring,
	Andreas Färber, Frank Kunz, Oliver Neukum, Andrew Lunn,
	Sebastian Reichel, netdev

Hello everyone,

Following up on a discussion in August 2018 [1] and my ELCE 2018 talk [2, 3],
I have been searching for an easy way to connect kernel network drivers to
a family of cards/adapters that expose a /dev/ttyACMx device today and
with the vendor's reference software would be accessed from userspace.

While a tty obviously works technically, it leaves us with per-vendor forks
of userspace software without a real upstream community (rare code drops).
It also doesn't allow code sharing with in-kernel protocol stacks or with
the SPI and UART based drivers we've already been working on.

One option suggested by Oliver was a line discipline - that would have the
advantage that it could work with virtually any tty, but on the downside
it would not work out-of-the-box and would require some userspace tool to
manually switch the tty into the new mode. Scalability was another concern,
as was duality of ldisc vs. serdev based implementations.

This patchset rather explores the use of Device Tree nodes to load a serdev
driver on top of the cdc-acm driver. By loading a modified cdc-acm module
plus this quickly hacked-together usb driver, I could play with it on 4.20
on an arm based Turris Omnia router with n-fuse mPCIe card, for instance.

I would hope that the shim approach taken here might also work for FTDI
MPSSE based SPI, encountered by Frank. Not with serdev then, of course,
but as pure USB interface/device driver piggy-backing on what exists.

An unsolved problem is that Semtech in version v0.2.1 switched away from
their own VID/PID to a generic STM32 VID/PID (due to Windows drivers...),
with the only distinction in iProduct string that usb_device_id does not
consider for probing. Since I'm reusing the cdc-acm driver, I can't have
it fail in probe, as it would then fail when called from my driver, too.

Various smaller issues are mentioned in the individual commit messages.

This patchset is based on my linux-lora.git lora-next staging branch.
Please consider taking the small usb patch to aid in further evaluating
serdev on cdc-acm and in resolving the remaining issues.
The others are for testing on our staging tree and for discussion.

Have a lot of fun!

Cheers,
Andreas

[1] https://marc.info/?l=linux-serial&m=153421371800416&w=2
[2] https://www.youtube.com/watch?v=Jjel65sZO9M
[3] https://events.linuxfoundation.org/wp-content/uploads/2017/12/ELCE2018_LoRa_final_Andreas-Farber.pdf

Cc: Johan Hovold <johan@kernel.org>
Cc: Rob Herring <robh@kernel.org>
Cc: Frank Kunz <mailinglists@kunz-im-inter.net>
Cc: Oliver Neukum <oneukum@suse.com>
Cc: Andrew Lunn <andrew@lunn.ch>
Cc: Sebastian Reichel <sre@kernel.org>
Cc: devicetree@vger.kernel.org
Cc: linux-lpwan@lists.infradead.org
Cc: linux-serial@vger.kernel.org
Cc: linux-usb@vger.kernel.org
Cc: netdev@vger.kernel.org

Andreas Färber (5):
  net: lora: sx130x: Factor out SPI specific parts
  net: lora: sx130x: Prepare storing driver-specific data
  net: lora: sx130x: Add PicoCell serdev driver
  usb: cdc-acm: Enable serdev support
  HACK: net: lora: sx130x: Add PicoCell gateway shim for cdc-acm

 drivers/net/lora/Makefile        |   4 +
 drivers/net/lora/picogw.c        | 337 ++++++++++++++++++++++++++++
 drivers/net/lora/sx130x.c        | 158 ++++++++-----
 drivers/net/lora/sx130x_picogw.c | 466 +++++++++++++++++++++++++++++++++++++++
 drivers/usb/class/cdc-acm.c      |   8 +-
 include/linux/lora/sx130x.h      |   9 +
 6 files changed, 926 insertions(+), 56 deletions(-)
 create mode 100644 drivers/net/lora/picogw.c
 create mode 100644 drivers/net/lora/sx130x_picogw.c

-- 
2.16.4

^ permalink raw reply

* [PATCH lora-next 1/5] net: lora: sx130x: Factor out SPI specific parts
From: Andreas Färber @ 2019-01-04 11:21 UTC (permalink / raw)
  To: linux-lpwan, linux-serial
  Cc: linux-usb, devicetree, linux-kernel, Johan Hovold, Rob Herring,
	Andreas Färber, David S. Miller, netdev
In-Reply-To: <20190104112131.14451-1-afaerber@suse.de>

Prepare for the picoGW by factoring code out into helpers using device
rather than spi_device.

While touching those lines, clean up the error output.

Split the probe function in two, to allow derived drivers to insert code
before the common probing code. This may need some more work.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 drivers/net/lora/sx130x.c   | 139 +++++++++++++++++++++++++++-----------------
 include/linux/lora/sx130x.h |   7 +++
 2 files changed, 92 insertions(+), 54 deletions(-)

diff --git a/drivers/net/lora/sx130x.c b/drivers/net/lora/sx130x.c
index 9cae9cea195f..840052955874 100644
--- a/drivers/net/lora/sx130x.c
+++ b/drivers/net/lora/sx130x.c
@@ -133,7 +133,7 @@ static bool sx130x_readable_noinc_reg(struct device *dev, unsigned int reg)
 	}
 }
 
-static struct regmap_config sx130x_regmap_config = {
+const struct regmap_config sx130x_regmap_config = {
 	.reg_bits = 8,
 	.val_bits = 8,
 
@@ -151,6 +151,7 @@ static struct regmap_config sx130x_regmap_config = {
 	.num_ranges = ARRAY_SIZE(sx130x_regmap_ranges),
 	.max_register = SX1301_MAX_REGISTER,
 };
+EXPORT_SYMBOL_GPL(sx130x_regmap_config);
 
 static int sx130x_field_write(struct sx130x_priv *priv,
 		enum sx130x_fields field_id, u8 val)
@@ -537,110 +538,98 @@ static const struct net_device_ops sx130x_net_device_ops = {
 	.ndo_start_xmit = sx130x_loradev_start_xmit,
 };
 
-static int sx130x_probe(struct spi_device *spi)
+int sx130x_early_probe(struct regmap *regmap, struct gpio_desc *rst)
 {
+	struct device *dev = regmap_get_device(regmap);
 	struct net_device *netdev;
 	struct sx130x_priv *priv;
-	struct gpio_desc *rst;
 	int ret;
 	int i;
-	unsigned int ver;
-	unsigned int val;
-
-	rst = devm_gpiod_get_optional(&spi->dev, "reset", GPIOD_OUT_LOW);
-	if (IS_ERR(rst)) {
-		if (PTR_ERR(rst) != -EPROBE_DEFER)
-			dev_err(&spi->dev, "Failed to obtain reset GPIO\n");
-		return PTR_ERR(rst);
-	}
-
-	gpiod_set_value_cansleep(rst, 1);
-	msleep(100);
-	gpiod_set_value_cansleep(rst, 0);
-	msleep(100);
-
-	spi->bits_per_word = 8;
-	spi_setup(spi);
 
-	netdev = devm_alloc_loradev(&spi->dev, sizeof(*priv));
+	netdev = devm_alloc_loradev(dev, sizeof(*priv));
 	if (!netdev)
 		return -ENOMEM;
 
 	netdev->netdev_ops = &sx130x_net_device_ops;
-	SET_NETDEV_DEV(netdev, &spi->dev);
+	SET_NETDEV_DEV(netdev, dev);
 
 	priv = netdev_priv(netdev);
+	priv->regmap = regmap;
 	priv->rst_gpio = rst;
 
 	mutex_init(&priv->io_lock);
 
-	spi_set_drvdata(spi, netdev);
-	priv->dev = &spi->dev;
-
-	priv->regmap = devm_regmap_init_spi(spi, &sx130x_regmap_config);
-	if (IS_ERR(priv->regmap)) {
-		ret = PTR_ERR(priv->regmap);
-		dev_err(&spi->dev, "Regmap allocation failed: %d\n", ret);
-		return ret;
-	}
+	dev_set_drvdata(dev, netdev);
+	priv->dev = dev;
 
 	for (i = 0; i < ARRAY_SIZE(sx130x_regmap_fields); i++) {
 		const struct reg_field *reg_fields = sx130x_regmap_fields;
 
-		priv->regmap_fields[i] = devm_regmap_field_alloc(&spi->dev,
+		priv->regmap_fields[i] = devm_regmap_field_alloc(dev,
 				priv->regmap,
 				reg_fields[i]);
 		if (IS_ERR(priv->regmap_fields[i])) {
 			ret = PTR_ERR(priv->regmap_fields[i]);
-			dev_err(&spi->dev, "Cannot allocate regmap field: %d\n", ret);
+			dev_err(dev, "Cannot allocate regmap field (%d)\n", ret);
 			return ret;
 		}
 	}
+	return 0;
+}
+EXPORT_SYMBOL_GPL(sx130x_early_probe);
+
+int sx130x_probe(struct device *dev)
+{
+	struct net_device *netdev = dev_get_drvdata(dev);
+	struct sx130x_priv *priv = netdev_priv(netdev);
+	unsigned int ver;
+	unsigned int val;
+	int ret;
 
 	ret = regmap_read(priv->regmap, SX1301_VER, &ver);
 	if (ret) {
-		dev_err(&spi->dev, "version read failed\n");
+		dev_err(dev, "version read failed (%d)\n", ret);
 		return ret;
 	}
 
 	if (ver != SX1301_CHIP_VERSION) {
-		dev_err(&spi->dev, "unexpected version: %u\n", ver);
+		dev_err(dev, "unexpected version: %u\n", ver);
 		return -ENXIO;
 	}
 
 	ret = regmap_write(priv->regmap, SX1301_PAGE, 0);
 	if (ret) {
-		dev_err(&spi->dev, "page/reset write failed\n");
+		dev_err(dev, "page/reset write failed (%d)\n", ret);
 		return ret;
 	}
 
 	ret = sx130x_field_write(priv, F_SOFT_RESET, 1);
 	if (ret) {
-		dev_err(&spi->dev, "soft reset failed\n");
+		dev_err(dev, "soft reset failed (%d)\n", ret);
 		return ret;
 	}
 
 	ret = sx130x_field_write(priv, F_GLOBAL_EN, 0);
 	if (ret) {
-		dev_err(&spi->dev, "gate global clocks failed\n");
+		dev_err(dev, "gate global clocks failed (%d)\n", ret);
 		return ret;
 	}
 
 	ret = sx130x_field_write(priv, F_CLK32M_EN, 0);
 	if (ret) {
-		dev_err(&spi->dev, "gate 32M clock failed\n");
+		dev_err(dev, "gate 32M clock failed (%d)\n", ret);
 		return ret;
 	}
 
 	ret = sx130x_field_write(priv, F_RADIO_A_EN, 1);
 	if (ret) {
-		dev_err(&spi->dev, "radio a enable failed\n");
+		dev_err(dev, "radio A enable failed (%d)\n", ret);
 		return ret;
 	}
 
 	ret = sx130x_field_write(priv, F_RADIO_B_EN, 1);
 	if (ret) {
-		dev_err(&spi->dev, "radio b enable failed\n");
+		dev_err(dev, "radio B enable failed (%d)\n", ret);
 		return ret;
 	}
 
@@ -648,7 +637,7 @@ static int sx130x_probe(struct spi_device *spi)
 
 	ret = sx130x_field_write(priv, F_RADIO_RST, 1);
 	if (ret) {
-		dev_err(&spi->dev, "radio asert reset failed\n");
+		dev_err(dev, "radio assert reset failed (%d)\n", ret);
 		return ret;
 	}
 
@@ -656,13 +645,13 @@ static int sx130x_probe(struct spi_device *spi)
 
 	ret = sx130x_field_write(priv, F_RADIO_RST, 0);
 	if (ret) {
-		dev_err(&spi->dev, "radio deasert reset failed\n");
+		dev_err(dev, "radio deassert reset failed (%d)\n", ret);
 		return ret;
 	}
 
 	/* radio */
 
-	ret = devm_sx130x_register_radio_devices(&spi->dev);
+	ret = devm_sx130x_register_radio_devices(dev);
 	if (ret)
 		return ret;
 
@@ -672,7 +661,7 @@ static int sx130x_probe(struct spi_device *spi)
 
 	ret = regmap_read(priv->regmap, SX1301_GPMODE, &val);
 	if (ret) {
-		dev_err(&spi->dev, "GPIO mode read failed\n");
+		dev_err(dev, "GPIO mode read failed (%d)\n", ret);
 		goto out;
 	}
 
@@ -680,13 +669,13 @@ static int sx130x_probe(struct spi_device *spi)
 
 	ret = regmap_write(priv->regmap, SX1301_GPMODE, val);
 	if (ret) {
-		dev_err(&spi->dev, "GPIO mode write failed\n");
+		dev_err(dev, "GPIO mode write failed (%d)\n", ret);
 		goto out;
 	}
 
 	ret = regmap_read(priv->regmap, SX1301_GPSO, &val);
 	if (ret) {
-		dev_err(&spi->dev, "GPIO select output read failed\n");
+		dev_err(dev, "GPIO select output read failed (%d)\n", ret);
 		goto out;
 	}
 
@@ -695,7 +684,7 @@ static int sx130x_probe(struct spi_device *spi)
 
 	ret = regmap_write(priv->regmap, SX1301_GPSO, val);
 	if (ret) {
-		dev_err(&spi->dev, "GPIO select output write failed\n");
+		dev_err(dev, "GPIO select output write failed (%d)\n", ret);
 		goto out;
 	}
 
@@ -705,24 +694,66 @@ static int sx130x_probe(struct spi_device *spi)
 	if (ret)
 		goto out;
 
-	dev_info(&spi->dev, "SX1301 module probed\n");
+	dev_info(dev, "SX1301 module probed\n");
 
 out:
 	mutex_unlock(&priv->io_lock);
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(sx130x_probe);
 
-static int sx130x_remove(struct spi_device *spi)
+int sx130x_remove(struct device *dev)
 {
-	struct net_device *netdev = spi_get_drvdata(spi);
+	struct net_device *netdev = dev_get_drvdata(dev);
 
 	unregister_loradev(netdev);
 
-	dev_info(&spi->dev, "SX1301 module removed\n");
+	dev_info(dev, "SX1301 module removed\n");
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(sx130x_remove);
+
+static int sx130x_spi_probe(struct spi_device *spi)
+{
+	struct gpio_desc *rst;
+	struct regmap *regmap;
+	int ret;
+
+	rst = devm_gpiod_get_optional(&spi->dev, "reset", GPIOD_OUT_LOW);
+	if (IS_ERR(rst)) {
+		if (PTR_ERR(rst) != -EPROBE_DEFER)
+			dev_err(&spi->dev, "Failed to obtain reset GPIO\n");
+		return PTR_ERR(rst);
+	}
+
+	gpiod_set_value_cansleep(rst, 1);
+	msleep(100);
+	gpiod_set_value_cansleep(rst, 0);
+	msleep(100);
+
+	spi->bits_per_word = 8;
+	spi_setup(spi);
+
+	regmap = devm_regmap_init_spi(spi, &sx130x_regmap_config);
+	if (IS_ERR(regmap)) {
+		ret = PTR_ERR(regmap);
+		dev_err(&spi->dev, "Regmap allocation failed: %d\n", ret);
+		return ret;
+	}
+
+	ret = sx130x_early_probe(regmap, rst);
+	if (ret)
+		return ret;
+
+	return sx130x_probe(&spi->dev);
+}
+
+static int sx130x_spi_remove(struct spi_device *spi)
+{
+	return sx130x_remove(&spi->dev);;
+}
 
 #ifdef CONFIG_OF
 static const struct of_device_id sx130x_dt_ids[] = {
@@ -737,8 +768,8 @@ static struct spi_driver sx130x_spi_driver = {
 		.name = "sx130x",
 		.of_match_table = of_match_ptr(sx130x_dt_ids),
 	},
-	.probe = sx130x_probe,
-	.remove = sx130x_remove,
+	.probe = sx130x_spi_probe,
+	.remove = sx130x_spi_remove,
 };
 
 static int __init sx130x_init(void)
diff --git a/include/linux/lora/sx130x.h b/include/linux/lora/sx130x.h
index ac4e2e7ae18a..d6f027ef283f 100644
--- a/include/linux/lora/sx130x.h
+++ b/include/linux/lora/sx130x.h
@@ -9,9 +9,16 @@
 #define LORA_SX130X_H
 
 #include <linux/device.h>
+#include <linux/gpio/consumer.h>
 #include <linux/module.h>
 #include <linux/regmap.h>
 
+extern const struct regmap_config sx130x_regmap_config;
+int sx130x_early_probe(struct regmap *regmap, struct gpio_desc *rst);
+int sx130x_probe(struct device *dev);
+int sx130x_remove(struct device *dev);
+
+
 struct sx130x_radio_device {
 	struct device dev;
 	struct device *concentrator;
-- 
2.16.4

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox