[U-Boot] [PATCH 00/26] Add and update drivers for MediaTek MT76x8 SoCs

This patch series have the following changes:
- Add pinctrl(both pinmux and pinconf) driver, reset controller driver and clock gating driver for mt7628. - Add mt7628 platform to mtk-sd driver. - Modify mt7628's ethernet & usb phy driver to take advantages from the new drivers. - Update mt7621-spi driver with a new transfer method. - Enable fifo, disable flow control, and enable non-DM implementation for mtk hsuart driver. - Enanble the new drivers for currently existed mt7628 boards.
Weijie Gao (26): serial: serial_mtk: enable FIFO and disable flow control serial: serial_mtk: add non-DM version for SPL dts: mtmips: move uart property clock-frequency into mt7628an.dtsi dts: mtmips: enable high-speed UART support for mt7628 spi: mt7621-spi: remove data cache and rewrite its xfer function spi: mt7621-spi: restore default register value after each xfer pinctrl: add support for MediaTek MT7628 dts: mtmips: add pinctrl node for mt7628 dts: mtmips: add default pinctrl for uart nodes reset: add reset controller driver for MediaTek MIPS platform dts: mtmips: update reset controller node for mt7628 clk: add clock gating driver for MediaTek MIPS platform dts: mtmips: add gate clock node for mt7628 phy: mt76x8-usb-phy: add slew rate calibration and remove non-mt7628 part net: mt7628-eth: remove hardcoded gpio settings and regmap-based phy reset net: mt7628-eth: remove phy link up detection net: mt7628-eth: free rx descriptor on receiving failure net: mt7628-eth: add support to isolate LAN/WAN ports dts: mtmips: enable eth port0 led function for all boards mmc: mtk-sd: add support for MediaTek MT7620/MT7628 SoCs mmc: mtk-sd: add a dts property cd-active-high for builtin-cd mode dts: mtmips: add mmc related nodes for mt7628an.dtsi dts: mtmips: add default pinctrl for gardena-smart-gateway-mt7688 dts: mtmips: add default pinctrl to eth nodes for all boards configs: mtmips: change all boards to use mtk high-speed uart driver configs: mtmips: add necessary drivers for mtmips boards
.../mips/dts/gardena-smart-gateway-mt7688.dts | 18 +- arch/mips/dts/linkit-smart-7688.dts | 15 +- arch/mips/dts/mt7628a.dtsi | 241 +++++++- ...gardena-smart-gateway-mt7688-ram_defconfig | 2 +- .../gardena-smart-gateway-mt7688_defconfig | 8 +- configs/linkit-smart-7688-ram_defconfig | 2 +- configs/linkit-smart-7688_defconfig | 8 +- drivers/clk/Kconfig | 8 + drivers/clk/Makefile | 1 + drivers/clk/clk-mtmips-cg.c | 63 ++ drivers/mmc/Kconfig | 2 +- drivers/mmc/mtk-sd.c | 32 +- drivers/net/mt7628-eth.c | 108 ++-- drivers/phy/Kconfig | 2 + drivers/phy/mt76x8-usb-phy.c | 225 +++++-- drivers/pinctrl/Kconfig | 1 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/mtmips/Kconfig | 13 + drivers/pinctrl/mtmips/Makefile | 7 + drivers/pinctrl/mtmips/pinctrl-mt7628.c | 585 ++++++++++++++++++ .../pinctrl/mtmips/pinctrl-mtmips-common.c | 87 +++ .../pinctrl/mtmips/pinctrl-mtmips-common.h | 53 ++ drivers/reset/Kconfig | 7 + drivers/reset/Makefile | 1 + drivers/reset/reset-mtmips.c | 82 +++ drivers/serial/serial.c | 2 + drivers/serial/serial_mtk.c | 223 ++++++- drivers/spi/mt7621_spi.c | 227 ++++--- .../configs/gardena-smart-gateway-mt7688.h | 2 +- include/configs/linkit-smart-7688.h | 2 +- include/dt-bindings/clk/mt7628-clk.h | 31 + include/dt-bindings/reset/mt7628-reset.h | 36 ++ 32 files changed, 1795 insertions(+), 300 deletions(-) create mode 100644 drivers/clk/clk-mtmips-cg.c create mode 100644 drivers/pinctrl/mtmips/Kconfig create mode 100644 drivers/pinctrl/mtmips/Makefile create mode 100644 drivers/pinctrl/mtmips/pinctrl-mt7628.c create mode 100644 drivers/pinctrl/mtmips/pinctrl-mtmips-common.c create mode 100644 drivers/pinctrl/mtmips/pinctrl-mtmips-common.h create mode 100644 drivers/reset/reset-mtmips.c create mode 100644 include/dt-bindings/clk/mt7628-clk.h create mode 100644 include/dt-bindings/reset/mt7628-reset.h

This patch adds codes to enable FIFO and disable flow control taken from ns16550 driver.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- drivers/serial/serial_mtk.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
diff --git a/drivers/serial/serial_mtk.c b/drivers/serial/serial_mtk.c index bce1be8227..11892a8740 100644 --- a/drivers/serial/serial_mtk.c +++ b/drivers/serial/serial_mtk.c @@ -46,6 +46,22 @@ struct mtk_serial_regs {
#define UART_LSR_DR 0x01 /* Data ready */ #define UART_LSR_THRE 0x20 /* Xmit holding register empty */ +#define UART_LSR_TEMT 0x40 /* Xmitter empty */ + +#define UART_MCR_DTR 0x01 /* DTR */ +#define UART_MCR_RTS 0x02 /* RTS */ + +#define UART_FCR_FIFO_EN 0x01 /* Fifo enable */ +#define UART_FCR_RXSR 0x02 /* Receiver soft reset */ +#define UART_FCR_TXSR 0x04 /* Transmitter soft reset */ + +#define UART_MCRVAL (UART_MCR_DTR | \ + UART_MCR_RTS) + +/* Clear & enable FIFOs */ +#define UART_FCRVAL (UART_FCR_FIFO_EN | \ + UART_FCR_RXSR | \ + UART_FCR_TXSR)
/* the data is correct if the real baud is within 3%. */ #define BAUD_ALLOW_MAX(baud) ((baud) + (baud) * 3 / 100) @@ -175,6 +191,9 @@ static int mtk_serial_probe(struct udevice *dev) /* Disable interrupt */ writel(0, &priv->regs->ier);
+ writel(UART_MCRVAL, &priv->regs->mcr); + writel(UART_FCRVAL, &priv->regs->fcr); + return 0; }
@@ -248,6 +267,8 @@ static inline void _debug_uart_init(void) priv.clock = CONFIG_DEBUG_UART_CLOCK;
writel(0, &priv.regs->ier); + writel(UART_MCRVAL, &priv.regs->mcr); + writel(UART_FCRVAL, &priv.regs->fcr);
_mtk_serial_setbrg(&priv, CONFIG_BAUDRATE); }

This patch adds non-DM version for mtk hsuart driver and makes it compatible with ns16550a driver in configuration. This is needed in SPL with CONFIG_SPL_DM disabled for reducing size.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- drivers/serial/serial.c | 2 + drivers/serial/serial_mtk.c | 202 +++++++++++++++++++++++++++++++++--- 2 files changed, 187 insertions(+), 17 deletions(-)
diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c index b907508dbe..bf5f39215d 100644 --- a/drivers/serial/serial.c +++ b/drivers/serial/serial.c @@ -124,6 +124,7 @@ serial_initfunc(ns16550_serial_initialize); serial_initfunc(pl01x_serial_initialize); serial_initfunc(pxa_serial_initialize); serial_initfunc(sh_serial_initialize); +serial_initfunc(mtk_serial_initialize);
/** * serial_register() - Register serial driver with serial driver core @@ -177,6 +178,7 @@ void serial_initialize(void) pl01x_serial_initialize(); pxa_serial_initialize(); sh_serial_initialize(); + mtk_serial_initialize();
serial_assign(default_serial_console()->name); } diff --git a/drivers/serial/serial_mtk.c b/drivers/serial/serial_mtk.c index 11892a8740..18530a4fd1 100644 --- a/drivers/serial/serial_mtk.c +++ b/drivers/serial/serial_mtk.c @@ -140,6 +140,37 @@ static void _mtk_serial_setbrg(struct mtk_serial_priv *priv, int baud) } }
+static int _mtk_serial_putc(struct mtk_serial_priv *priv, const char ch) +{ + if (!(readl(&priv->regs->lsr) & UART_LSR_THRE)) + return -EAGAIN; + + writel(ch, &priv->regs->thr); + + if (ch == '\n') + WATCHDOG_RESET(); + + return 0; +} + +static int _mtk_serial_getc(struct mtk_serial_priv *priv) +{ + if (!(readl(&priv->regs->lsr) & UART_LSR_DR)) + return -EAGAIN; + + return readl(&priv->regs->rbr); +} + +static int _mtk_serial_pending(struct mtk_serial_priv *priv, bool input) +{ + if (input) + return (readl(&priv->regs->lsr) & UART_LSR_DR) ? 1 : 0; + else + return (readl(&priv->regs->lsr) & UART_LSR_THRE) ? 0 : 1; +} + +#if defined(CONFIG_DM_SERIAL) && \ + (!defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_DM)) static int mtk_serial_setbrg(struct udevice *dev, int baudrate) { struct mtk_serial_priv *priv = dev_get_priv(dev); @@ -153,35 +184,21 @@ static int mtk_serial_putc(struct udevice *dev, const char ch) { struct mtk_serial_priv *priv = dev_get_priv(dev);
- if (!(readl(&priv->regs->lsr) & UART_LSR_THRE)) - return -EAGAIN; - - writel(ch, &priv->regs->thr); - - if (ch == '\n') - WATCHDOG_RESET(); - - return 0; + return _mtk_serial_putc(priv, ch); }
static int mtk_serial_getc(struct udevice *dev) { struct mtk_serial_priv *priv = dev_get_priv(dev);
- if (!(readl(&priv->regs->lsr) & UART_LSR_DR)) - return -EAGAIN; - - return readl(&priv->regs->rbr); + return _mtk_serial_getc(priv); }
static int mtk_serial_pending(struct udevice *dev, bool input) { struct mtk_serial_priv *priv = dev_get_priv(dev);
- if (input) - return (readl(&priv->regs->lsr) & UART_LSR_DR) ? 1 : 0; - else - return (readl(&priv->regs->lsr) & UART_LSR_THRE) ? 0 : 1; + return _mtk_serial_pending(priv, input); }
static int mtk_serial_probe(struct udevice *dev) @@ -254,6 +271,157 @@ U_BOOT_DRIVER(serial_mtk) = { .ops = &mtk_serial_ops, .flags = DM_FLAG_PRE_RELOC, }; +#else + +DECLARE_GLOBAL_DATA_PTR; + +#define DECLARE_HSUART_PRIV(port) \ + static struct mtk_serial_priv mtk_hsuart##port = { \ + .regs = (struct mtk_serial_regs *)CONFIG_SYS_NS16550_COM##port, \ + .clock = CONFIG_SYS_NS16550_CLK \ +}; + +#define DECLARE_HSUART_FUNCTIONS(port) \ + static int mtk_serial##port##_init(void) \ + { \ + writel(0, &mtk_hsuart##port.regs->ier); \ + writel(UART_MCRVAL, &mtk_hsuart##port.regs->mcr); \ + writel(UART_FCRVAL, &mtk_hsuart##port.regs->fcr); \ + _mtk_serial_setbrg(&mtk_hsuart##port, gd->baudrate); \ + return 0 ; \ + } \ + static void mtk_serial##port##_setbrg(void) \ + { \ + _mtk_serial_setbrg(&mtk_hsuart##port, gd->baudrate); \ + } \ + static int mtk_serial##port##_getc(void) \ + { \ + int err; \ + do { \ + err = _mtk_serial_getc(&mtk_hsuart##port); \ + if (err == -EAGAIN) \ + WATCHDOG_RESET(); \ + } while (err == -EAGAIN); \ + return err >= 0 ? err : 0; \ + } \ + static int mtk_serial##port##_tstc(void) \ + { \ + return _mtk_serial_pending(&mtk_hsuart##port, true); \ + } \ + static void mtk_serial##port##_putc(const char c) \ + { \ + int err; \ + if (c == '\n') \ + mtk_serial##port##_putc('\r'); \ + do { \ + err = _mtk_serial_putc(&mtk_hsuart##port, c); \ + } while (err == -EAGAIN); \ + } \ + static void mtk_serial##port##_puts(const char *s) \ + { \ + while (*s) { \ + mtk_serial##port##_putc(*s++); \ + } \ + } + +/* Serial device descriptor */ +#define INIT_HSUART_STRUCTURE(port, __name) { \ + .name = __name, \ + .start = mtk_serial##port##_init, \ + .stop = NULL, \ + .setbrg = mtk_serial##port##_setbrg, \ + .getc = mtk_serial##port##_getc, \ + .tstc = mtk_serial##port##_tstc, \ + .putc = mtk_serial##port##_putc, \ + .puts = mtk_serial##port##_puts, \ +} + +#define DECLARE_HSUART(port, __name) \ + DECLARE_HSUART_PRIV(port); \ + DECLARE_HSUART_FUNCTIONS(port); \ + struct serial_device mtk_hsuart##port##_device = \ + INIT_HSUART_STRUCTURE(port, __name); + +#if !defined(CONFIG_CONS_INDEX) +#elif (CONFIG_CONS_INDEX < 1) || (CONFIG_CONS_INDEX > 6) +#error "Invalid console index value." +#endif + +#if CONFIG_CONS_INDEX == 1 && !defined(CONFIG_SYS_NS16550_COM1) +#error "Console port 1 defined but not configured." +#elif CONFIG_CONS_INDEX == 2 && !defined(CONFIG_SYS_NS16550_COM2) +#error "Console port 2 defined but not configured." +#elif CONFIG_CONS_INDEX == 3 && !defined(CONFIG_SYS_NS16550_COM3) +#error "Console port 3 defined but not configured." +#elif CONFIG_CONS_INDEX == 4 && !defined(CONFIG_SYS_NS16550_COM4) +#error "Console port 4 defined but not configured." +#elif CONFIG_CONS_INDEX == 5 && !defined(CONFIG_SYS_NS16550_COM5) +#error "Console port 5 defined but not configured." +#elif CONFIG_CONS_INDEX == 6 && !defined(CONFIG_SYS_NS16550_COM6) +#error "Console port 6 defined but not configured." +#endif + +#if defined(CONFIG_SYS_NS16550_COM1) +DECLARE_HSUART(1, "mtk-hsuart0"); +#endif +#if defined(CONFIG_SYS_NS16550_COM2) +DECLARE_HSUART(2, "mtk-hsuart1"); +#endif +#if defined(CONFIG_SYS_NS16550_COM3) +DECLARE_HSUART(3, "mtk-hsuart2"); +#endif +#if defined(CONFIG_SYS_NS16550_COM4) +DECLARE_HSUART(4, "mtk-hsuart3"); +#endif +#if defined(CONFIG_SYS_NS16550_COM5) +DECLARE_HSUART(5, "mtk-hsuart4"); +#endif +#if defined(CONFIG_SYS_NS16550_COM6) +DECLARE_HSUART(6, "mtk-hsuart5"); +#endif + +__weak struct serial_device *default_serial_console(void) +{ +#if CONFIG_CONS_INDEX == 1 + return &mtk_hsuart1_device; +#elif CONFIG_CONS_INDEX == 2 + return &mtk_hsuart2_device; +#elif CONFIG_CONS_INDEX == 3 + return &mtk_hsuart3_device; +#elif CONFIG_CONS_INDEX == 4 + return &mtk_hsuart4_device; +#elif CONFIG_CONS_INDEX == 5 + return &mtk_hsuart5_device; +#elif CONFIG_CONS_INDEX == 6 + return &mtk_hsuart6_device; +#else +#error "Bad CONFIG_CONS_INDEX." +#endif +} + +void mtk_serial_initialize(void) +{ +#if defined(CONFIG_SYS_NS16550_COM1) + serial_register(&mtk_hsuart1_device); +#endif +#if defined(CONFIG_SYS_NS16550_COM2) + serial_register(&mtk_hsuart2_device); +#endif +#if defined(CONFIG_SYS_NS16550_COM3) + serial_register(&mtk_hsuart3_device); +#endif +#if defined(CONFIG_SYS_NS16550_COM4) + serial_register(&mtk_hsuart4_device); +#endif +#if defined(CONFIG_SYS_NS16550_COM5) + serial_register(&mtk_hsuart5_device); +#endif +#if defined(CONFIG_SYS_NS16550_COM6) + serial_register(&mtk_hsuart6_device); +#endif +} + +#endif
#ifdef CONFIG_DEBUG_UART_MTK

The UART of MT7628 has fixed 40MHz input clock so there is no need to put clock-frequency in every dts files. Just put it into the common dtsi file.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- arch/mips/dts/gardena-smart-gateway-mt7688.dts | 1 - arch/mips/dts/linkit-smart-7688.dts | 1 - arch/mips/dts/mt7628a.dtsi | 6 ++++++ 3 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/arch/mips/dts/gardena-smart-gateway-mt7688.dts b/arch/mips/dts/gardena-smart-gateway-mt7688.dts index eedde89dfd..95675a3947 100644 --- a/arch/mips/dts/gardena-smart-gateway-mt7688.dts +++ b/arch/mips/dts/gardena-smart-gateway-mt7688.dts @@ -87,7 +87,6 @@
&uart0 { status = "okay"; - clock-frequency = <40000000>; };
&spi0 { diff --git a/arch/mips/dts/linkit-smart-7688.dts b/arch/mips/dts/linkit-smart-7688.dts index bb10402174..935315743c 100644 --- a/arch/mips/dts/linkit-smart-7688.dts +++ b/arch/mips/dts/linkit-smart-7688.dts @@ -28,7 +28,6 @@
&uart2 { status = "okay"; - clock-frequency = <40000000>; };
&spi0 { diff --git a/arch/mips/dts/mt7628a.dtsi b/arch/mips/dts/mt7628a.dtsi index 1e7d0a6ec5..6bc0722b07 100644 --- a/arch/mips/dts/mt7628a.dtsi +++ b/arch/mips/dts/mt7628a.dtsi @@ -127,6 +127,8 @@ compatible = "ns16550a"; reg = <0xc00 0x100>;
+ clock-frequency = <40000000>; + resets = <&resetc 12>; reset-names = "uart0";
@@ -140,6 +142,8 @@ compatible = "ns16550a"; reg = <0xd00 0x100>;
+ clock-frequency = <40000000>; + resets = <&resetc 19>; reset-names = "uart1";
@@ -153,6 +157,8 @@ compatible = "ns16550a"; reg = <0xe00 0x100>;
+ clock-frequency = <40000000>; + resets = <&resetc 20>; reset-names = "uart2";

On 28.08.19 08:37, Weijie Gao wrote:
The UART of MT7628 has fixed 40MHz input clock so there is no need to put clock-frequency in every dts files. Just put it into the common dtsi file.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com
Reviewed-by: Stefan Roese sr@denx.de
Thanks, Stefan

All three UARTs of mt7628 are actually MediaTek's high-speed UARTs which support baudrate up to 921600. The high-speed UART is compatible with ns16550 when baudrate <= 115200.
Add compatible string to dtsi file so u-boot can use it when serial_mtk driver is built in.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- arch/mips/dts/mt7628a.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/mips/dts/mt7628a.dtsi b/arch/mips/dts/mt7628a.dtsi index 6bc0722b07..e9241a0737 100644 --- a/arch/mips/dts/mt7628a.dtsi +++ b/arch/mips/dts/mt7628a.dtsi @@ -124,7 +124,7 @@ };
uart0: uartlite@c00 { - compatible = "ns16550a"; + compatible = "mediatek,hsuart", "ns16550a"; reg = <0xc00 0x100>;
clock-frequency = <40000000>; @@ -139,7 +139,7 @@ };
uart1: uart1@d00 { - compatible = "ns16550a"; + compatible = "mediatek,hsuart", "ns16550a"; reg = <0xd00 0x100>;
clock-frequency = <40000000>; @@ -154,7 +154,7 @@ };
uart2: uart2@e00 { - compatible = "ns16550a"; + compatible = "mediatek,hsuart", "ns16550a"; reg = <0xe00 0x100>;
clock-frequency = <40000000>;

On 28.08.19 08:37, Weijie Gao wrote:
All three UARTs of mt7628 are actually MediaTek's high-speed UARTs which support baudrate up to 921600. The high-speed UART is compatible with ns16550 when baudrate <= 115200.
Add compatible string to dtsi file so u-boot can use it when serial_mtk driver is built in.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com
Reviewed-by: Stefan Roese sr@denx.de
Thanks, Stefan

The mt7621 spi controller supports continuous generic half-duplex spi transaction. There is no need to cache xfer data at all.
To achieve this goal, the OPADDR register must be used as the first data to be sent. And follows the eight generic DIDO registers. But one thing different between OPADDR and DIDO registers is OPADDR has a reversed byte order.
With this patch, any amount of data can be read/written in a single xfer function call.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- drivers/spi/mt7621_spi.c | 197 ++++++++++++++++++--------------------- 1 file changed, 91 insertions(+), 106 deletions(-)
diff --git a/drivers/spi/mt7621_spi.c b/drivers/spi/mt7621_spi.c index 107e58f657..20fe93d416 100644 --- a/drivers/spi/mt7621_spi.c +++ b/drivers/spi/mt7621_spi.c @@ -14,9 +14,8 @@ #include <wait_bit.h> #include <linux/io.h>
-#define SPI_MSG_SIZE_MAX 32 /* SPI message chunk size */ -/* Enough for SPI NAND page read / write with page size 2048 bytes */ -#define SPI_MSG_SIZE_OVERALL (2048 + 16) +#define MT7621_RX_FIFO_LEN 32 +#define MT7621_TX_FIFO_LEN 36
#define MT7621_SPI_TRANS 0x00 #define MT7621_SPI_TRANS_START BIT(8) @@ -38,11 +37,16 @@ #define MASTER_RS_CLK_SEL_SHIFT 16 #define MASTER_RS_SLAVE_SEL GENMASK(31, 29)
+#define MOREBUF_CMD_CNT GENMASK(29, 24) +#define MOREBUF_CMD_CNT_SHIFT 24 +#define MOREBUF_MISO_CNT GENMASK(20, 12) +#define MOREBUF_MISO_CNT_SHIFT 12 +#define MOREBUF_MOSI_CNT GENMASK(8, 0) +#define MOREBUF_MOSI_CNT_SHIFT 0 + struct mt7621_spi { void __iomem *base; unsigned int sys_freq; - u32 data[(SPI_MSG_SIZE_OVERALL / 4) + 1]; - int tx_len; };
static void mt7621_spi_reset(struct mt7621_spi *rs, int duplex) @@ -128,20 +132,89 @@ static inline int mt7621_spi_wait_till_ready(struct mt7621_spi *rs) return ret; }
+static int mt7621_spi_read(struct mt7621_spi *rs, u8 *buf, size_t len) +{ + size_t rx_len; + int i, ret; + u32 val = 0; + + while (len) { + rx_len = min_t(size_t, len, MT7621_RX_FIFO_LEN); + + iowrite32((rx_len * 8) << MOREBUF_MISO_CNT_SHIFT, + rs->base + MT7621_SPI_MOREBUF); + iowrite32(MT7621_SPI_TRANS_START, rs->base + MT7621_SPI_TRANS); + + ret = mt7621_spi_wait_till_ready(rs); + if (ret) + return ret; + + for (i = 0; i < rx_len; i++) { + if ((i % 4) == 0) + val = ioread32(rs->base + MT7621_SPI_DATA0 + i); + *buf++ = val & 0xff; + val >>= 8; + } + + len -= rx_len; + } + + return ret; +} + +static int mt7621_spi_write(struct mt7621_spi *rs, const u8 *buf, size_t len) +{ + size_t tx_len, opcode_len, dido_len; + int i, ret; + u32 val; + + while (len) { + tx_len = min_t(size_t, len, MT7621_TX_FIFO_LEN); + + opcode_len = min_t(size_t, tx_len, 4); + dido_len = tx_len - opcode_len; + + val = 0; + for (i = 0; i < opcode_len; i++) { + val <<= 8; + val |= *buf++; + } + + iowrite32(val, rs->base + MT7621_SPI_OPCODE); + + val = 0; + for (i = 0; i < dido_len; i++) { + val |= (*buf++) << ((i % 4) * 8); + + if ((i % 4 == 3) || (i == dido_len - 1)) { + iowrite32(val, rs->base + MT7621_SPI_DATA0 + + (i & ~3)); + val = 0; + } + } + + iowrite32(((opcode_len * 8) << MOREBUF_CMD_CNT_SHIFT) | + ((dido_len * 8) << MOREBUF_MOSI_CNT_SHIFT), + rs->base + MT7621_SPI_MOREBUF); + iowrite32(MT7621_SPI_TRANS_START, rs->base + MT7621_SPI_TRANS); + + ret = mt7621_spi_wait_till_ready(rs); + if (ret) + return ret; + + len -= tx_len; + } + + return 0; +} + static int mt7621_spi_xfer(struct udevice *dev, unsigned int bitlen, const void *dout, void *din, unsigned long flags) { struct udevice *bus = dev->parent; struct mt7621_spi *rs = dev_get_priv(bus); - const u8 *tx_buf = dout; - u8 *ptr = (u8 *)dout; - u8 *rx_buf = din; int total_size = bitlen >> 3; - int chunk_size; - int rx_len = 0; - u32 data[(SPI_MSG_SIZE_MAX / 4) + 1] = { 0 }; - u32 val; - int i; + int ret = 0;
debug("%s: dout=%p, din=%p, len=%x, flags=%lx\n", __func__, dout, din, total_size, flags); @@ -155,13 +228,6 @@ static int mt7621_spi_xfer(struct udevice *dev, unsigned int bitlen, return -EIO; }
- if (dout) { - debug("TX-DATA: "); - for (i = 0; i < total_size; i++) - debug("%02x ", *ptr++); - debug("\n"); - } - mt7621_spi_wait_till_ready(rs);
/* @@ -171,96 +237,15 @@ static int mt7621_spi_xfer(struct udevice *dev, unsigned int bitlen, if (flags & SPI_XFER_BEGIN) mt7621_spi_set_cs(rs, spi_chip_select(dev), 1);
- while (total_size > 0) { - /* Don't exceed the max xfer size */ - chunk_size = min_t(int, total_size, SPI_MSG_SIZE_MAX); - - /* - * We might have some TX data buffered from the last xfer - * message. Make sure, that this does not exceed the max - * xfer size - */ - if (rs->tx_len > 4) - chunk_size -= rs->tx_len; - if (din) - rx_len = chunk_size; - - if (tx_buf) { - /* Check if this message does not exceed the buffer */ - if ((chunk_size + rs->tx_len) > SPI_MSG_SIZE_OVERALL) { - printf("TX message size too big (%d)\n", - chunk_size + rs->tx_len); - return -EMSGSIZE; - } - - /* - * Write all TX data into internal buffer to collect - * all TX messages into one buffer (might be split into - * multiple calls to this function) - */ - for (i = 0; i < chunk_size; i++, rs->tx_len++) { - rs->data[rs->tx_len / 4] |= - tx_buf[i] << (8 * (rs->tx_len & 3)); - } - } - - if (flags & SPI_XFER_END) { - /* Write TX data into controller */ - if (rs->tx_len) { - rs->data[0] = swab32(rs->data[0]); - if (rs->tx_len < 4) - rs->data[0] >>= (4 - rs->tx_len) * 8; - - for (i = 0; i < rs->tx_len; i += 4) { - iowrite32(rs->data[i / 4], rs->base + - MT7621_SPI_OPCODE + i); - } - } - - /* Write length into controller */ - val = (min_t(int, rs->tx_len, 4) * 8) << 24; - if (rs->tx_len > 4) - val |= (rs->tx_len - 4) * 8; - val |= (rx_len * 8) << 12; - iowrite32(val, rs->base + MT7621_SPI_MOREBUF); - - /* Start the xfer */ - setbits_le32(rs->base + MT7621_SPI_TRANS, - MT7621_SPI_TRANS_START); - - /* Wait until xfer is finished on bus */ - mt7621_spi_wait_till_ready(rs); - - /* Reset TX length and TX buffer for next xfer */ - rs->tx_len = 0; - memset(rs->data, 0, sizeof(rs->data)); - } - - for (i = 0; i < rx_len; i += 4) - data[i / 4] = ioread32(rs->base + MT7621_SPI_DATA0 + i); - - if (rx_len) { - debug("RX-DATA: "); - for (i = 0; i < rx_len; i++) { - rx_buf[i] = data[i / 4] >> (8 * (i & 3)); - debug("%02x ", rx_buf[i]); - } - debug("\n"); - } - - if (tx_buf) - tx_buf += chunk_size; - if (rx_buf) - rx_buf += chunk_size; - total_size -= chunk_size; - } + if (din) + ret = mt7621_spi_read(rs, din, total_size); + else if (dout) + ret = mt7621_spi_write(rs, dout, total_size);
- /* Wait until xfer is finished on bus and de-assert CS */ - mt7621_spi_wait_till_ready(rs); if (flags & SPI_XFER_END) mt7621_spi_set_cs(rs, spi_chip_select(dev), 0);
- return 0; + return ret; }
static int mt7621_spi_probe(struct udevice *dev)

On 28.08.19 08:37, Weijie Gao wrote:
The mt7621 spi controller supports continuous generic half-duplex spi transaction. There is no need to cache xfer data at all.
To achieve this goal, the OPADDR register must be used as the first data to be sent. And follows the eight generic DIDO registers. But one thing different between OPADDR and DIDO registers is OPADDR has a reversed byte order.
With this patch, any amount of data can be read/written in a single xfer function call.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com
Very nice, thanks for all your work here.
Reviewed-by: Stefan Roese sr@denx.de
Thanks, Stefan

Currently this driver uses a different way to implement the spi xfer, by modifying some fields of two registers, which is incompatible with the MTK's original SDK linux driver. This will cause the flash data being damaged by the SDK driver.
This patch lets the mt7621_spi_set_cs() restore the original register fields after cs deactivated.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- drivers/spi/mt7621_spi.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-)
diff --git a/drivers/spi/mt7621_spi.c b/drivers/spi/mt7621_spi.c index 20fe93d416..06484e7abe 100644 --- a/drivers/spi/mt7621_spi.c +++ b/drivers/spi/mt7621_spi.c @@ -20,6 +20,10 @@ #define MT7621_SPI_TRANS 0x00 #define MT7621_SPI_TRANS_START BIT(8) #define MT7621_SPI_TRANS_BUSY BIT(16) +#define TRANS_ADDR_SZ GENMASK(20, 19) +#define TRANS_ADDR_SZ_SHIFT 19 +#define TRANS_MOSI_BCNT GENMASK(3, 0) +#define TRANS_MOSI_BCNT_SHIFT 0
#define MT7621_SPI_OPCODE 0x04 #define MT7621_SPI_DATA0 0x08 @@ -49,20 +53,22 @@ struct mt7621_spi { unsigned int sys_freq; };
-static void mt7621_spi_reset(struct mt7621_spi *rs, int duplex) -{ - setbits_le32(rs->base + MT7621_SPI_MASTER, - MASTER_RS_SLAVE_SEL | MASTER_MORE_BUFMODE); -} - static void mt7621_spi_set_cs(struct mt7621_spi *rs, int cs, int enable) { - u32 val = 0; - debug("%s: cs#%d -> %s\n", __func__, cs, enable ? "enable" : "disable"); - if (enable) - val = BIT(cs); - iowrite32(val, rs->base + MT7621_SPI_POLAR); + + if (enable) { + setbits_le32(rs->base + MT7621_SPI_MASTER, + MASTER_RS_SLAVE_SEL | MASTER_MORE_BUFMODE); + iowrite32(BIT(cs), rs->base + MT7621_SPI_POLAR); + } else { + iowrite32(0, rs->base + MT7621_SPI_POLAR); + iowrite32((2 << TRANS_ADDR_SZ_SHIFT) | + (1 << TRANS_MOSI_BCNT_SHIFT), + rs->base + MT7621_SPI_TRANS); + clrbits_le32(rs->base + MT7621_SPI_MASTER, + MASTER_RS_SLAVE_SEL | MASTER_MORE_BUFMODE); + } }
static int mt7621_spi_set_mode(struct udevice *bus, uint mode) @@ -267,8 +273,6 @@ static int mt7621_spi_probe(struct udevice *dev) return -EINVAL; }
- mt7621_spi_reset(rs, 0); - return 0; }

On 28.08.19 08:37, Weijie Gao wrote:
Currently this driver uses a different way to implement the spi xfer, by modifying some fields of two registers, which is incompatible with the MTK's original SDK linux driver. This will cause the flash data being damaged by the SDK driver.
This patch lets the mt7621_spi_set_cs() restore the original register fields after cs deactivated.
What is this "MTK's original SDK Linux driver"? It's not the mainline Linux SPI driver, correct? Which platforms / boards are using it?
Please note that in general, drivers in Linux should not make any assumptions about prior register setup. So the driver you are referring to should configure all registers correctly for its setup.
But I don't object to this patch, so if this is really needed for some of your customers, please go ahead:
Reviewed-by: Stefan Roese sr@denx.de
Thanks, Stefan
Signed-off-by: Weijie Gao weijie.gao@mediatek.com
drivers/spi/mt7621_spi.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-)
diff --git a/drivers/spi/mt7621_spi.c b/drivers/spi/mt7621_spi.c index 20fe93d416..06484e7abe 100644 --- a/drivers/spi/mt7621_spi.c +++ b/drivers/spi/mt7621_spi.c @@ -20,6 +20,10 @@ #define MT7621_SPI_TRANS 0x00 #define MT7621_SPI_TRANS_START BIT(8) #define MT7621_SPI_TRANS_BUSY BIT(16) +#define TRANS_ADDR_SZ GENMASK(20, 19) +#define TRANS_ADDR_SZ_SHIFT 19 +#define TRANS_MOSI_BCNT GENMASK(3, 0) +#define TRANS_MOSI_BCNT_SHIFT 0
#define MT7621_SPI_OPCODE 0x04 #define MT7621_SPI_DATA0 0x08 @@ -49,20 +53,22 @@ struct mt7621_spi { unsigned int sys_freq; };
-static void mt7621_spi_reset(struct mt7621_spi *rs, int duplex) -{
- setbits_le32(rs->base + MT7621_SPI_MASTER,
MASTER_RS_SLAVE_SEL | MASTER_MORE_BUFMODE);
-}
- static void mt7621_spi_set_cs(struct mt7621_spi *rs, int cs, int enable) {
- u32 val = 0;
- debug("%s: cs#%d -> %s\n", __func__, cs, enable ? "enable" : "disable");
- if (enable)
val = BIT(cs);
- iowrite32(val, rs->base + MT7621_SPI_POLAR);
if (enable) {
setbits_le32(rs->base + MT7621_SPI_MASTER,
MASTER_RS_SLAVE_SEL | MASTER_MORE_BUFMODE);
iowrite32(BIT(cs), rs->base + MT7621_SPI_POLAR);
} else {
iowrite32(0, rs->base + MT7621_SPI_POLAR);
iowrite32((2 << TRANS_ADDR_SZ_SHIFT) |
(1 << TRANS_MOSI_BCNT_SHIFT),
rs->base + MT7621_SPI_TRANS);
clrbits_le32(rs->base + MT7621_SPI_MASTER,
MASTER_RS_SLAVE_SEL | MASTER_MORE_BUFMODE);
} }
static int mt7621_spi_set_mode(struct udevice *bus, uint mode)
@@ -267,8 +273,6 @@ static int mt7621_spi_probe(struct udevice *dev) return -EINVAL; }
- mt7621_spi_reset(rs, 0);
- return 0; }
Viele Grüße, Stefan

This patch adds pinctrl support for mt7628, with a file for common pinmux functions and a file for mt7628 which has additional support for pinconf.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- drivers/pinctrl/Kconfig | 1 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/mtmips/Kconfig | 13 + drivers/pinctrl/mtmips/Makefile | 7 + drivers/pinctrl/mtmips/pinctrl-mt7628.c | 585 ++++++++++++++++++ .../pinctrl/mtmips/pinctrl-mtmips-common.c | 87 +++ .../pinctrl/mtmips/pinctrl-mtmips-common.h | 53 ++ 7 files changed, 747 insertions(+) create mode 100644 drivers/pinctrl/mtmips/Kconfig create mode 100644 drivers/pinctrl/mtmips/Makefile create mode 100644 drivers/pinctrl/mtmips/pinctrl-mt7628.c create mode 100644 drivers/pinctrl/mtmips/pinctrl-mtmips-common.c create mode 100644 drivers/pinctrl/mtmips/pinctrl-mtmips-common.h
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index a0ac167d14..1634dffb35 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -244,6 +244,7 @@ source "drivers/pinctrl/exynos/Kconfig" source "drivers/pinctrl/mediatek/Kconfig" source "drivers/pinctrl/meson/Kconfig" source "drivers/pinctrl/mscc/Kconfig" +source "drivers/pinctrl/mtmips/Kconfig" source "drivers/pinctrl/mvebu/Kconfig" source "drivers/pinctrl/nxp/Kconfig" source "drivers/pinctrl/renesas/Kconfig" diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 4b080b74dc..ce0879a2b7 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -9,6 +9,7 @@ obj-y += nxp/ obj-$(CONFIG_$(SPL_)PINCTRL_ROCKCHIP) += rockchip/ obj-$(CONFIG_ARCH_ASPEED) += aspeed/ obj-$(CONFIG_ARCH_ATH79) += ath79/ +obj-$(CONFIG_ARCH_MTMIPS) += mtmips/ obj-$(CONFIG_ARCH_RMOBILE) += renesas/ obj-$(CONFIG_PINCTRL_SANDBOX) += pinctrl-sandbox.o
diff --git a/drivers/pinctrl/mtmips/Kconfig b/drivers/pinctrl/mtmips/Kconfig new file mode 100644 index 0000000000..8482a38ebc --- /dev/null +++ b/drivers/pinctrl/mtmips/Kconfig @@ -0,0 +1,13 @@ + +config PINCTRL_MTMIPS + depends on ARCH_MTMIPS + bool + +config PINCTRL_MT7628 + bool "MediaTek MT7628 pin control driver" + select PINCTRL_MTMIPS + depends on SOC_MT7628 && PINCTRL_GENERIC + help + Support pin multiplexing control on MediaTek MT7628. + The driver is controlled by a device tree node which contains + the pin mux functions for each available pin groups. diff --git a/drivers/pinctrl/mtmips/Makefile b/drivers/pinctrl/mtmips/Makefile new file mode 100644 index 0000000000..3ba5c0c66d --- /dev/null +++ b/drivers/pinctrl/mtmips/Makefile @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0 + +# Core +obj-$(CONFIG_PINCTRL_MTMIPS) += pinctrl-mtmips-common.o + +# SoC Drivers +obj-$(CONFIG_PINCTRL_MT7628) += pinctrl-mt7628.o diff --git a/drivers/pinctrl/mtmips/pinctrl-mt7628.c b/drivers/pinctrl/mtmips/pinctrl-mt7628.c new file mode 100644 index 0000000000..6883450a09 --- /dev/null +++ b/drivers/pinctrl/mtmips/pinctrl-mt7628.c @@ -0,0 +1,585 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 MediaTek Inc. All Rights Reserved. + * + * Author: Weijie Gao weijie.gao@mediatek.com + */ + +#include <common.h> +#include <dm.h> +#include <dm/pinctrl.h> +#include <linux/bitops.h> +#include <linux/io.h> + +#include "pinctrl-mtmips-common.h" + +DECLARE_GLOBAL_DATA_PTR; + +#define AGPIO_OFS 0 +#define GPIOMODE1_OFS 0x24 +#define GPIOMODE2_OFS 0x28 + +#define EPHY4_1_PAD_SHIFT 17 +#define EPHY4_1_PAD_MASK 0x0f +#define EPHY0_SHIFT 16 +#define RF_OLT_MODE_SHIFT 12 +#define N9_EINT_SRC_SHIFT 9 +#define WLED_OD_SHIFT 8 +#define REF_CLKO_PAD_SHIFT 4 +#define I2S_CLK_PAD_SHIFT 3 +#define I2S_WS_PAD_SHIFT 2 +#define I2S_SDO_PAD_SHIFT 1 +#define I2S_SDI_PAD_SHIFT 0 + +#define GM4_MASK 3 + +#define P4LED_K_SHIFT 26 +#define P3LED_K_SHIFT 24 +#define P2LED_K_SHIFT 22 +#define P1LED_K_SHIFT 20 +#define P0LED_K_SHIFT 18 +#define WLED_K_SHIFT 16 +#define P4LED_A_SHIFT 10 +#define P3LED_A_SHIFT 8 +#define P2LED_A_SHIFT 6 +#define P1LED_A_SHIFT 4 +#define P0LED_A_SHIFT 2 +#define WLED_A_SHIFT 0 + +#define PWM1_SHIFT 30 +#define PWM0_SHIFT 28 +#define UART2_SHIFT 26 +#define UART1_SHIFT 24 +#define I2C_SHIFT 20 +#define REFCLK_SHIFT 18 +#define PERST_SHIFT 16 +#define ESD_SHIFT 15 +#define WDT_SHIFT 14 +#define SPI_SHIFT 12 +#define SDMODE_SHIFT 10 +#define UART0_SHIFT 8 +#define I2S_SHIFT 6 +#define SPI_CS1_SHIFT 4 +#define SPIS_SHIFT 2 +#define GPIO0_SHIFT 0 + +#define PAD_PU_G0_REG 0x00 +#define PAD_PU_G1_REG 0x04 +#define PAD_PD_G0_REG 0x10 +#define PAD_PD_G1_REG 0x14 +#define PAD_SR_G0_REG 0x20 +#define PAD_SR_G1_REG 0x24 +#define PAD_SMT_G0_REG 0x30 +#define PAD_SMT_G1_REG 0x34 +#define PAD_E2_G0_REG 0x40 +#define PAD_E2_G1_REG 0x44 +#define PAD_E4_G0_REG 0x50 +#define PAD_E4_G1_REG 0x54 +#define PAD_E8_G0_REG 0x60 +#define PAD_E8_G1_REG 0x64 + +#define PIN_CONFIG_DRIVE_STRENGTH_28 (PIN_CONFIG_END + 1) +#define PIN_CONFIG_DRIVE_STRENGTH_4G (PIN_CONFIG_END + 2) + +struct mt7628_pinctrl_priv { + struct mtmips_pinctrl_priv mp; + + void __iomem *pcbase; +}; + +#if CONFIG_IS_ENABLED(PINMUX) +static struct mtmips_pmx_func ephy4_1_pad_grp[] = { + FUNC("digital", 0xf), + FUNC("analog", 0), +}; + +static struct mtmips_pmx_func ephy0_grp[] = { + FUNC("disable", 1), + FUNC("enable", 0), +}; + +static struct mtmips_pmx_func rf_olt_grp[] = { + FUNC("enable", 1), + FUNC("disable", 0), +}; + +static struct mtmips_pmx_func n9_eint_src_grp[] = { + FUNC("gpio", 1), + FUNC("utif", 0), +}; + +static struct mtmips_pmx_func wlen_od_grp[] = { + FUNC("enable", 1), + FUNC("disable", 0), +}; + +static struct mtmips_pmx_func ref_clko_grp[] = { + FUNC("digital", 1), + FUNC("analog", 0), +}; + +static struct mtmips_pmx_func i2s_clk_grp[] = { + FUNC("digital", 1), + FUNC("analog", 0), +}; + +static struct mtmips_pmx_func i2s_ws_grp[] = { + FUNC("digital", 1), + FUNC("analog", 0), +}; + +static struct mtmips_pmx_func i2s_sdo_grp[] = { + FUNC("digital", 1), + FUNC("analog", 0), +}; + +static struct mtmips_pmx_func i2s_sdi_grp[] = { + FUNC("digital", 1), + FUNC("analog", 0), +}; + +static struct mtmips_pmx_func pwm1_grp[] = { + FUNC("sdxc d6", 3), + FUNC("utif", 2), + FUNC("gpio", 1), + FUNC("pwm1", 0), +}; + +static struct mtmips_pmx_func pwm0_grp[] = { + FUNC("sdxc d7", 3), + FUNC("utif", 2), + FUNC("gpio", 1), + FUNC("pwm0", 0), +}; + +static struct mtmips_pmx_func uart2_grp[] = { + FUNC("sdxc d5 d4", 3), + FUNC("pwm", 2), + FUNC("gpio", 1), + FUNC("uart2", 0), +}; + +static struct mtmips_pmx_func uart1_grp[] = { + FUNC("sw_r", 3), + FUNC("pwm", 2), + FUNC("gpio", 1), + FUNC("uart1", 0), +}; + +static struct mtmips_pmx_func i2c_grp[] = { + FUNC("-", 3), + FUNC("debug", 2), + FUNC("gpio", 1), + FUNC("i2c", 0), +}; + +static struct mtmips_pmx_func refclk_grp[] = { + FUNC("gpio", 1), + FUNC("refclk", 0), +}; + +static struct mtmips_pmx_func perst_grp[] = { + FUNC("gpio", 1), + FUNC("perst", 0), +}; + +static struct mtmips_pmx_func esd_grp[] = { + FUNC("router", 1), + FUNC("iot", 0), +}; + +static struct mtmips_pmx_func wdt_grp[] = { + FUNC("gpio", 1), + FUNC("wdt", 0), +}; + +static struct mtmips_pmx_func spi_grp[] = { + FUNC("gpio", 1), + FUNC("spi", 0), +}; + +static struct mtmips_pmx_func sd_mode_grp[] = { + FUNC("n9 jtag", 3), + FUNC("utif1", 2), + FUNC("gpio", 1), + FUNC("sdxc", 0), +}; + +static struct mtmips_pmx_func uart0_grp[] = { + FUNC("-", 3), + FUNC("-", 2), + FUNC("gpio", 1), + FUNC("uart0", 0), +}; + +static struct mtmips_pmx_func i2s_grp[] = { + FUNC("antenna", 3), + FUNC("pcm", 2), + FUNC("gpio", 1), + FUNC("i2s", 0), +}; + +static struct mtmips_pmx_func spi_cs1_grp[] = { + FUNC("-", 3), + FUNC("refclk", 2), + FUNC("gpio", 1), + FUNC("spi cs1", 0), +}; + +static struct mtmips_pmx_func spis_grp[] = { + FUNC("pwm_uart2", 3), + FUNC("utif", 2), + FUNC("gpio", 1), + FUNC("spis", 0), +}; + +static struct mtmips_pmx_func gpio0_grp[] = { + FUNC("perst", 3), + FUNC("refclk", 2), + FUNC("gpio", 1), + FUNC("gpio0", 0), +}; + +static struct mtmips_pmx_func wled_a_grp[] = { + FUNC("-", 3), + FUNC("-", 2), + FUNC("gpio", 1), + FUNC("led", 0), +}; + +static struct mtmips_pmx_func p0led_a_grp[] = { + FUNC("jtag", 3), + FUNC("rsvd", 2), + FUNC("gpio", 1), + FUNC("led", 0), +}; + +static struct mtmips_pmx_func p1led_a_grp[] = { + FUNC("jtag", 3), + FUNC("utif", 2), + FUNC("gpio", 1), + FUNC("led", 0), +}; + +static struct mtmips_pmx_func p2led_a_grp[] = { + FUNC("jtag", 3), + FUNC("utif", 2), + FUNC("gpio", 1), + FUNC("led", 0), +}; + +static struct mtmips_pmx_func p3led_a_grp[] = { + FUNC("jtag", 3), + FUNC("utif", 2), + FUNC("gpio", 1), + FUNC("led", 0), +}; + +static struct mtmips_pmx_func p4led_a_grp[] = { + FUNC("jtag", 3), + FUNC("utif", 2), + FUNC("gpio", 1), + FUNC("led", 0), +}; + +static struct mtmips_pmx_func wled_k_grp[] = { + FUNC("-", 3), + FUNC("-", 2), + FUNC("gpio", 1), + FUNC("led", 0), +}; + +static struct mtmips_pmx_func p0led_k_grp[] = { + FUNC("jtag", 3), + FUNC("rsvd", 2), + FUNC("gpio", 1), + FUNC("led", 0), +}; + +static struct mtmips_pmx_func p1led_k_grp[] = { + FUNC("jtag", 3), + FUNC("utif", 2), + FUNC("gpio", 1), + FUNC("led", 0), +}; + +static struct mtmips_pmx_func p2led_k_grp[] = { + FUNC("jtag", 3), + FUNC("utif", 2), + FUNC("gpio", 1), + FUNC("led", 0), +}; + +static struct mtmips_pmx_func p3led_k_grp[] = { + FUNC("jtag", 3), + FUNC("utif", 2), + FUNC("gpio", 1), + FUNC("led", 0), +}; + +static struct mtmips_pmx_func p4led_k_grp[] = { + FUNC("jtag", 3), + FUNC("utif", 2), + FUNC("gpio", 1), + FUNC("led", 0), +}; + +static struct mtmips_pmx_group mt7628_pinmux_data[] = { + GRP("ephy4_1_pad", ephy4_1_pad_grp, AGPIO_OFS, EPHY4_1_PAD_SHIFT, + EPHY4_1_PAD_MASK), + GRP("ephy0", ephy0_grp, AGPIO_OFS, EPHY0_SHIFT, 1), + GRP("rf_olt", rf_olt_grp, AGPIO_OFS, RF_OLT_MODE_SHIFT, 1), + GRP("n9_eint_src", n9_eint_src_grp, AGPIO_OFS, N9_EINT_SRC_SHIFT, 1), + GRP("wlen_od", wlen_od_grp, AGPIO_OFS, WLED_OD_SHIFT, 1), + GRP("ref_clko_pad", ref_clko_grp, AGPIO_OFS, REF_CLKO_PAD_SHIFT, 1), + GRP("i2s_clk_pad", i2s_clk_grp, AGPIO_OFS, I2S_CLK_PAD_SHIFT, 1), + GRP("i2s_ws_pad", i2s_ws_grp, AGPIO_OFS, I2S_WS_PAD_SHIFT, 1), + GRP("i2s_sdo_pad", i2s_sdo_grp, AGPIO_OFS, I2S_SDO_PAD_SHIFT, 1), + GRP("i2s_sdi_pad", i2s_sdi_grp, AGPIO_OFS, I2S_SDI_PAD_SHIFT, 1), + GRP("pwm1", pwm1_grp, GPIOMODE1_OFS, PWM1_SHIFT, GM4_MASK), + GRP("pwm0", pwm0_grp, GPIOMODE1_OFS, PWM0_SHIFT, GM4_MASK), + GRP("uart2", uart2_grp, GPIOMODE1_OFS, UART2_SHIFT, GM4_MASK), + GRP("uart1", uart1_grp, GPIOMODE1_OFS, UART1_SHIFT, GM4_MASK), + GRP("i2c", i2c_grp, GPIOMODE1_OFS, I2C_SHIFT, GM4_MASK), + GRP("refclk", refclk_grp, GPIOMODE1_OFS, REFCLK_SHIFT, 1), + GRP("perst", perst_grp, GPIOMODE1_OFS, PERST_SHIFT, 1), + GRP("sd router", esd_grp, GPIOMODE1_OFS, ESD_SHIFT, 1), + GRP("wdt", wdt_grp, GPIOMODE1_OFS, WDT_SHIFT, 1), + GRP("spi", spi_grp, GPIOMODE1_OFS, SPI_SHIFT, 1), + GRP("sdmode", sd_mode_grp, GPIOMODE1_OFS, SDMODE_SHIFT, GM4_MASK), + GRP("uart0", uart0_grp, GPIOMODE1_OFS, UART0_SHIFT, GM4_MASK), + GRP("i2s", i2s_grp, GPIOMODE1_OFS, I2S_SHIFT, GM4_MASK), + GRP("spi cs1", spi_cs1_grp, GPIOMODE1_OFS, SPI_CS1_SHIFT, GM4_MASK), + GRP("spis", spis_grp, GPIOMODE1_OFS, SPIS_SHIFT, GM4_MASK), + GRP("gpio0", gpio0_grp, GPIOMODE1_OFS, GPIO0_SHIFT, GM4_MASK), + GRP("wled_a", wled_a_grp, GPIOMODE2_OFS, WLED_A_SHIFT, GM4_MASK), + GRP("p0led_a", p0led_a_grp, GPIOMODE2_OFS, P0LED_A_SHIFT, GM4_MASK), + GRP("p1led_a", p1led_a_grp, GPIOMODE2_OFS, P1LED_A_SHIFT, GM4_MASK), + GRP("p2led_a", p2led_a_grp, GPIOMODE2_OFS, P2LED_A_SHIFT, GM4_MASK), + GRP("p3led_a", p3led_a_grp, GPIOMODE2_OFS, P3LED_A_SHIFT, GM4_MASK), + GRP("p4led_a", p4led_a_grp, GPIOMODE2_OFS, P4LED_A_SHIFT, GM4_MASK), + GRP("wled_k", wled_k_grp, GPIOMODE2_OFS, WLED_K_SHIFT, GM4_MASK), + GRP("p0led_k", p0led_k_grp, GPIOMODE2_OFS, P0LED_K_SHIFT, GM4_MASK), + GRP("p1led_k", p1led_k_grp, GPIOMODE2_OFS, P1LED_K_SHIFT, GM4_MASK), + GRP("p2led_k", p2led_k_grp, GPIOMODE2_OFS, P2LED_K_SHIFT, GM4_MASK), + GRP("p3led_k", p3led_k_grp, GPIOMODE2_OFS, P3LED_K_SHIFT, GM4_MASK), + GRP("p4led_k", p4led_k_grp, GPIOMODE2_OFS, P4LED_K_SHIFT, GM4_MASK), +}; + +static int mt7628_get_groups_count(struct udevice *dev) +{ + return ARRAY_SIZE(mt7628_pinmux_data); +} + +static const char *mt7628_get_group_name(struct udevice *dev, + unsigned int selector) +{ + return mt7628_pinmux_data[selector].name; +} +#endif /* CONFIG_IS_ENABLED(PINMUX) */ + +#if CONFIG_IS_ENABLED(PINCONF) +static const struct pinconf_param mt7628_conf_params[] = { + { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 }, + { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 }, + { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 }, + { "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 }, + { "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 }, + { "drive-strength-28", PIN_CONFIG_DRIVE_STRENGTH_28, 0 }, + { "drive-strength-4g", PIN_CONFIG_DRIVE_STRENGTH_4G, 0 }, + { "slew-rate", PIN_CONFIG_SLEW_RATE, 0 }, +}; + +static const char *const mt7628_pins[] = { + "i2s_sdi", + "i2s_sdo", + "i2s_ws", + "i2s_clk", + "i2s_sclk", + "i2c_sd", + "spi_cs1", + "spi_clk", + "spi_mosi", + "spi_miso", + "spi_cs0", + "gpio0", + "uart0_txd", + "uart0_rxd", + "spis_cs", + "spis_clk", + "spis_miso", + "spis_mosi", + "pwm_ch0", + "pwm_ch1", + "uart2_txd", + "uart2_rxd", + "sd_wp", + "sd_cd", + "sd_d1", + "sd_d0", + "sd_clk", + "sd_cmd", + "sd_d3", + "sd_d2", + "ephy_led4_k", + "ephy_led3_k", + "ephy_led2_k", + "ephy_led1_k", + "ephy_led0_k", + "wled_k", + "perst_n", + "co_clko", + "wdt", + "ephy_led4_a", + "ephy_led3_a", + "ephy_led2_a", + "ephy_led1_a", + "ephy_led0_a", + "wled_a", + "uart1_txd", + "uart1_rxd", +}; + +static const u32 mt7628_drv_strength_28_tbl[] = {2, 4, 6, 8}; +static const u32 mt7628_drv_strength_4g_tbl[] = {4, 8, 12, 16}; + +static int mt7628_set_drv_strength(void __iomem *base, u32 val, u32 bit, + const u32 tbl[], u32 reg_lo, u32 reg_hi) +{ + int i; + + for (i = 0; i < 4; i++) + if (tbl[i] == val) + break; + + if (i >= 4) + return -EINVAL; + + clrsetbits_32(base + reg_lo, BIT(bit), (i & 1) << bit); + clrsetbits_32(base + reg_hi, BIT(bit), ((i >> 1) & 1) << bit); + + return 0; +} + +static int mt7628_get_pins_count(struct udevice *dev) +{ + return ARRAY_SIZE(mt7628_pins); +} + +static const char *mt7628_get_pin_name(struct udevice *dev, + unsigned int selector) +{ + return mt7628_pins[selector]; +} + +static int mt7628_pinconf_set(struct udevice *dev, unsigned int pin_selector, + unsigned int param, unsigned int argument) +{ + struct mt7628_pinctrl_priv *priv = dev_get_priv(dev); + u32 offs, bit; + int ret = 0; + + offs = (pin_selector / 32) * 4; + bit = pin_selector % 32; + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + clrbits_32(priv->pcbase + offs + PAD_PU_G0_REG, BIT(bit)); + clrbits_32(priv->pcbase + offs + PAD_PD_G0_REG, BIT(bit)); + break; + case PIN_CONFIG_BIAS_PULL_UP: + setbits_32(priv->pcbase + offs + PAD_PU_G0_REG, BIT(bit)); + clrbits_32(priv->pcbase + offs + PAD_PD_G0_REG, BIT(bit)); + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + clrbits_32(priv->pcbase + offs + PAD_PU_G0_REG, BIT(bit)); + setbits_32(priv->pcbase + offs + PAD_PD_G0_REG, BIT(bit)); + break; + case PIN_CONFIG_INPUT_SCHMITT_ENABLE: + clrsetbits_32(priv->pcbase + offs + PAD_SMT_G0_REG, + BIT(bit), (!!argument) << bit); + break; + case PIN_CONFIG_DRIVE_STRENGTH_28: + ret = mt7628_set_drv_strength(priv->pcbase + offs, argument, + bit, mt7628_drv_strength_28_tbl, + PAD_E2_G0_REG, PAD_E4_G0_REG); + break; + case PIN_CONFIG_DRIVE_STRENGTH_4G: + ret = mt7628_set_drv_strength(priv->pcbase + offs, argument, + bit, mt7628_drv_strength_4g_tbl, + PAD_E4_G0_REG, PAD_E8_G0_REG); + break; + case PIN_CONFIG_SLEW_RATE: + clrsetbits_32(priv->pcbase + offs + PAD_SR_G0_REG, + BIT(bit), (!!argument) << bit); + break; + default: + ret = -EINVAL; + } + + return ret; +} +#endif + +static int mt7628_pinctrl_probe(struct udevice *dev) +{ + struct mt7628_pinctrl_priv *priv = dev_get_priv(dev); + int ret = 0; + +#if CONFIG_IS_ENABLED(PINMUX) + ret = mtmips_pinctrl_probe(&priv->mp, ARRAY_SIZE(mt7628_pinmux_data), + mt7628_pinmux_data); +#endif /* CONFIG_IS_ENABLED(PINMUX) */ + + return ret; +} + +static int mt7628_pinctrl_ofdata_to_platdata(struct udevice *dev) +{ + struct mt7628_pinctrl_priv *priv = dev_get_priv(dev); + + priv->mp.base = (void __iomem *)dev_remap_addr_index(dev, 0); + + if (!priv->mp.base) + return -EINVAL; + + priv->pcbase = (void __iomem *)dev_remap_addr_index(dev, 1); + + if (!priv->pcbase) + return -EINVAL; + + return 0; +} + +static struct pinctrl_ops mt7628_pinctrl_ops = { +#if CONFIG_IS_ENABLED(PINMUX) + .get_groups_count = mt7628_get_groups_count, + .get_group_name = mt7628_get_group_name, + .get_functions_count = mtmips_get_functions_count, + .get_function_name = mtmips_get_function_name, + .pinmux_group_set = mtmips_pinmux_group_set, +#endif /* CONFIG_IS_ENABLED(PINMUX) */ +#if CONFIG_IS_ENABLED(PINCONF) + .pinconf_num_params = ARRAY_SIZE(mt7628_conf_params), + .pinconf_params = mt7628_conf_params, + .get_pins_count = mt7628_get_pins_count, + .get_pin_name = mt7628_get_pin_name, + .pinconf_set = mt7628_pinconf_set, +#endif /* CONFIG_IS_ENABLED(PINCONF) */ + .set_state = pinctrl_generic_set_state, +}; + +static const struct udevice_id mt7628_pinctrl_ids[] = { + { .compatible = "mediatek,mt7628-pinctrl" }, + { } +}; + +U_BOOT_DRIVER(mt7628_pinctrl) = { + .name = "mt7628-pinctrl", + .id = UCLASS_PINCTRL, + .of_match = mt7628_pinctrl_ids, + .ofdata_to_platdata = mt7628_pinctrl_ofdata_to_platdata, + .ops = &mt7628_pinctrl_ops, + .probe = mt7628_pinctrl_probe, + .priv_auto_alloc_size = sizeof(struct mt7628_pinctrl_priv), +}; diff --git a/drivers/pinctrl/mtmips/pinctrl-mtmips-common.c b/drivers/pinctrl/mtmips/pinctrl-mtmips-common.c new file mode 100644 index 0000000000..ee6a9d1fc8 --- /dev/null +++ b/drivers/pinctrl/mtmips/pinctrl-mtmips-common.c @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 MediaTek Inc. All Rights Reserved. + * + * Author: Weijie Gao weijie.gao@mediatek.com + */ + +#include <common.h> +#include <dm.h> +#include <dm/pinctrl.h> +#include <linux/io.h> + +#include "pinctrl-mtmips-common.h" + +static void mtmips_pinctrl_reg_set(struct mtmips_pinctrl_priv *priv, + u32 reg, u32 shift, u32 mask, u32 value) +{ + u32 val; + + val = readl(priv->base + reg); + val &= ~(mask << shift); + val |= value << shift; + writel(val, priv->base + reg); +} + +int mtmips_get_functions_count(struct udevice *dev) +{ + struct mtmips_pinctrl_priv *priv = dev_get_priv(dev); + + return priv->nfuncs; +} + +const char *mtmips_get_function_name(struct udevice *dev, unsigned int selector) +{ + struct mtmips_pinctrl_priv *priv = dev_get_priv(dev); + + return priv->funcs[selector]->name; +} + +int mtmips_pinmux_group_set(struct udevice *dev, unsigned int group_selector, + unsigned int func_selector) +{ + struct mtmips_pinctrl_priv *priv = dev_get_priv(dev); + const struct mtmips_pmx_group *grp = &priv->groups[group_selector]; + const struct mtmips_pmx_func *func = priv->funcs[func_selector]; + int i; + + if (!grp->nfuncs) + return 0; + + for (i = 0; i < grp->nfuncs; i++) { + if (!strcmp(grp->funcs[i].name, func->name)) { + mtmips_pinctrl_reg_set(priv, grp->reg, grp->shift, + grp->mask, grp->funcs[i].value); + return 0; + } + } + + return -EINVAL; +} + +int mtmips_pinctrl_probe(struct mtmips_pinctrl_priv *priv, u32 ngroups, + const struct mtmips_pmx_group *groups) +{ + int i, j, n; + + priv->ngroups = ngroups; + priv->groups = groups; + + priv->nfuncs = 0; + + for (i = 0; i < ngroups; i++) + priv->nfuncs += groups[i].nfuncs; + + priv->funcs = malloc(priv->nfuncs * sizeof(*priv->funcs)); + if (!priv->funcs) + return -ENOMEM; + + n = 0; + + for (i = 0; i < ngroups; i++) { + for (j = 0; j < groups[i].nfuncs; j++) + priv->funcs[n++] = &groups[i].funcs[j]; + } + + return 0; +} diff --git a/drivers/pinctrl/mtmips/pinctrl-mtmips-common.h b/drivers/pinctrl/mtmips/pinctrl-mtmips-common.h new file mode 100644 index 0000000000..b51d8f009c --- /dev/null +++ b/drivers/pinctrl/mtmips/pinctrl-mtmips-common.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2019 MediaTek Inc. All Rights Reserved. + * + * Author: Weijie Gao weijie.gao@mediatek.com + */ + +#ifndef _PINCTRL_MTMIPS_COMMON_H_ +#define _PINCTRL_MTMIPS_COMMON_H_ + +#include <common.h> + +struct mtmips_pmx_func { + const char *name; + int value; +}; + +struct mtmips_pmx_group { + const char *name; + + u32 reg; + u32 shift; + char mask; + + int nfuncs; + const struct mtmips_pmx_func *funcs; +}; + +struct mtmips_pinctrl_priv { + void __iomem *base; + + u32 ngroups; + const struct mtmips_pmx_group *groups; + + u32 nfuncs; + const struct mtmips_pmx_func **funcs; +}; + +#define FUNC(name, value) { name, value } + +#define GRP(_name, _funcs, _reg, _shift, _mask) \ + { .name = (_name), .reg = (_reg), .shift = (_shift), .mask = (_mask), \ + .funcs = (_funcs), .nfuncs = ARRAY_SIZE(_funcs) } + +int mtmips_get_functions_count(struct udevice *dev); +const char *mtmips_get_function_name(struct udevice *dev, + unsigned int selector); +int mtmips_pinmux_group_set(struct udevice *dev, unsigned int group_selector, + unsigned int func_selector); +int mtmips_pinctrl_probe(struct mtmips_pinctrl_priv *priv, u32 ngroups, + const struct mtmips_pmx_group *groups); + +#endif /* _PINCTRL_MTMIPS_COMMON_H_ */

On 28.08.19 08:37, Weijie Gao wrote:
This patch adds pinctrl support for mt7628, with a file for common pinmux functions and a file for mt7628 which has additional support for pinconf.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com
drivers/pinctrl/Kconfig | 1 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/mtmips/Kconfig | 13 + drivers/pinctrl/mtmips/Makefile | 7 + drivers/pinctrl/mtmips/pinctrl-mt7628.c | 585 ++++++++++++++++++ .../pinctrl/mtmips/pinctrl-mtmips-common.c | 87 +++ .../pinctrl/mtmips/pinctrl-mtmips-common.h | 53 ++ 7 files changed, 747 insertions(+) create mode 100644 drivers/pinctrl/mtmips/Kconfig create mode 100644 drivers/pinctrl/mtmips/Makefile create mode 100644 drivers/pinctrl/mtmips/pinctrl-mt7628.c create mode 100644 drivers/pinctrl/mtmips/pinctrl-mtmips-common.c create mode 100644 drivers/pinctrl/mtmips/pinctrl-mtmips-common.h
Nice patch. I do have 2 questions though:
a) Why are you introducing a new "mtmips" directory and don't re-use the already available "mediatek" directory? Is there nothing in common with these "mediatek" drivers?
b) Somewhat related: You introduce a mtmips-common file. For which platforms is this targeted (non-mt7628)? Is there nothing in common with the "mediatek" files already available?
Other than that I've tested this on my MT7688 board and it works just fine. Thanks a lot!
Thanks, Stefan
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index a0ac167d14..1634dffb35 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -244,6 +244,7 @@ source "drivers/pinctrl/exynos/Kconfig" source "drivers/pinctrl/mediatek/Kconfig" source "drivers/pinctrl/meson/Kconfig" source "drivers/pinctrl/mscc/Kconfig" +source "drivers/pinctrl/mtmips/Kconfig" source "drivers/pinctrl/mvebu/Kconfig" source "drivers/pinctrl/nxp/Kconfig" source "drivers/pinctrl/renesas/Kconfig" diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 4b080b74dc..ce0879a2b7 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -9,6 +9,7 @@ obj-y += nxp/ obj-$(CONFIG_$(SPL_)PINCTRL_ROCKCHIP) += rockchip/ obj-$(CONFIG_ARCH_ASPEED) += aspeed/ obj-$(CONFIG_ARCH_ATH79) += ath79/ +obj-$(CONFIG_ARCH_MTMIPS) += mtmips/ obj-$(CONFIG_ARCH_RMOBILE) += renesas/ obj-$(CONFIG_PINCTRL_SANDBOX) += pinctrl-sandbox.o
diff --git a/drivers/pinctrl/mtmips/Kconfig b/drivers/pinctrl/mtmips/Kconfig new file mode 100644 index 0000000000..8482a38ebc --- /dev/null +++ b/drivers/pinctrl/mtmips/Kconfig @@ -0,0 +1,13 @@
+config PINCTRL_MTMIPS
- depends on ARCH_MTMIPS
- bool
+config PINCTRL_MT7628
- bool "MediaTek MT7628 pin control driver"
- select PINCTRL_MTMIPS
- depends on SOC_MT7628 && PINCTRL_GENERIC
- help
Support pin multiplexing control on MediaTek MT7628.
The driver is controlled by a device tree node which contains
the pin mux functions for each available pin groups.
diff --git a/drivers/pinctrl/mtmips/Makefile b/drivers/pinctrl/mtmips/Makefile new file mode 100644 index 0000000000..3ba5c0c66d --- /dev/null +++ b/drivers/pinctrl/mtmips/Makefile @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0
+# Core +obj-$(CONFIG_PINCTRL_MTMIPS) += pinctrl-mtmips-common.o
+# SoC Drivers +obj-$(CONFIG_PINCTRL_MT7628) += pinctrl-mt7628.o diff --git a/drivers/pinctrl/mtmips/pinctrl-mt7628.c b/drivers/pinctrl/mtmips/pinctrl-mt7628.c new file mode 100644 index 0000000000..6883450a09 --- /dev/null +++ b/drivers/pinctrl/mtmips/pinctrl-mt7628.c @@ -0,0 +1,585 @@ +// SPDX-License-Identifier: GPL-2.0 +/*
- Copyright (C) 2019 MediaTek Inc. All Rights Reserved.
- Author: Weijie Gao weijie.gao@mediatek.com
- */
+#include <common.h> +#include <dm.h> +#include <dm/pinctrl.h> +#include <linux/bitops.h> +#include <linux/io.h>
+#include "pinctrl-mtmips-common.h"
+DECLARE_GLOBAL_DATA_PTR;
+#define AGPIO_OFS 0 +#define GPIOMODE1_OFS 0x24 +#define GPIOMODE2_OFS 0x28
+#define EPHY4_1_PAD_SHIFT 17 +#define EPHY4_1_PAD_MASK 0x0f +#define EPHY0_SHIFT 16 +#define RF_OLT_MODE_SHIFT 12 +#define N9_EINT_SRC_SHIFT 9 +#define WLED_OD_SHIFT 8 +#define REF_CLKO_PAD_SHIFT 4 +#define I2S_CLK_PAD_SHIFT 3 +#define I2S_WS_PAD_SHIFT 2 +#define I2S_SDO_PAD_SHIFT 1 +#define I2S_SDI_PAD_SHIFT 0
+#define GM4_MASK 3
+#define P4LED_K_SHIFT 26 +#define P3LED_K_SHIFT 24 +#define P2LED_K_SHIFT 22 +#define P1LED_K_SHIFT 20 +#define P0LED_K_SHIFT 18 +#define WLED_K_SHIFT 16 +#define P4LED_A_SHIFT 10 +#define P3LED_A_SHIFT 8 +#define P2LED_A_SHIFT 6 +#define P1LED_A_SHIFT 4 +#define P0LED_A_SHIFT 2 +#define WLED_A_SHIFT 0
+#define PWM1_SHIFT 30 +#define PWM0_SHIFT 28 +#define UART2_SHIFT 26 +#define UART1_SHIFT 24 +#define I2C_SHIFT 20 +#define REFCLK_SHIFT 18 +#define PERST_SHIFT 16 +#define ESD_SHIFT 15 +#define WDT_SHIFT 14 +#define SPI_SHIFT 12 +#define SDMODE_SHIFT 10 +#define UART0_SHIFT 8 +#define I2S_SHIFT 6 +#define SPI_CS1_SHIFT 4 +#define SPIS_SHIFT 2 +#define GPIO0_SHIFT 0
+#define PAD_PU_G0_REG 0x00 +#define PAD_PU_G1_REG 0x04 +#define PAD_PD_G0_REG 0x10 +#define PAD_PD_G1_REG 0x14 +#define PAD_SR_G0_REG 0x20 +#define PAD_SR_G1_REG 0x24 +#define PAD_SMT_G0_REG 0x30 +#define PAD_SMT_G1_REG 0x34 +#define PAD_E2_G0_REG 0x40 +#define PAD_E2_G1_REG 0x44 +#define PAD_E4_G0_REG 0x50 +#define PAD_E4_G1_REG 0x54 +#define PAD_E8_G0_REG 0x60 +#define PAD_E8_G1_REG 0x64
+#define PIN_CONFIG_DRIVE_STRENGTH_28 (PIN_CONFIG_END + 1) +#define PIN_CONFIG_DRIVE_STRENGTH_4G (PIN_CONFIG_END + 2)
+struct mt7628_pinctrl_priv {
- struct mtmips_pinctrl_priv mp;
- void __iomem *pcbase;
+};
+#if CONFIG_IS_ENABLED(PINMUX) +static struct mtmips_pmx_func ephy4_1_pad_grp[] = {
- FUNC("digital", 0xf),
- FUNC("analog", 0),
+};
+static struct mtmips_pmx_func ephy0_grp[] = {
- FUNC("disable", 1),
- FUNC("enable", 0),
+};
+static struct mtmips_pmx_func rf_olt_grp[] = {
- FUNC("enable", 1),
- FUNC("disable", 0),
+};
+static struct mtmips_pmx_func n9_eint_src_grp[] = {
- FUNC("gpio", 1),
- FUNC("utif", 0),
+};
+static struct mtmips_pmx_func wlen_od_grp[] = {
- FUNC("enable", 1),
- FUNC("disable", 0),
+};
+static struct mtmips_pmx_func ref_clko_grp[] = {
- FUNC("digital", 1),
- FUNC("analog", 0),
+};
+static struct mtmips_pmx_func i2s_clk_grp[] = {
- FUNC("digital", 1),
- FUNC("analog", 0),
+};
+static struct mtmips_pmx_func i2s_ws_grp[] = {
- FUNC("digital", 1),
- FUNC("analog", 0),
+};
+static struct mtmips_pmx_func i2s_sdo_grp[] = {
- FUNC("digital", 1),
- FUNC("analog", 0),
+};
+static struct mtmips_pmx_func i2s_sdi_grp[] = {
- FUNC("digital", 1),
- FUNC("analog", 0),
+};
+static struct mtmips_pmx_func pwm1_grp[] = {
- FUNC("sdxc d6", 3),
- FUNC("utif", 2),
- FUNC("gpio", 1),
- FUNC("pwm1", 0),
+};
+static struct mtmips_pmx_func pwm0_grp[] = {
- FUNC("sdxc d7", 3),
- FUNC("utif", 2),
- FUNC("gpio", 1),
- FUNC("pwm0", 0),
+};
+static struct mtmips_pmx_func uart2_grp[] = {
- FUNC("sdxc d5 d4", 3),
- FUNC("pwm", 2),
- FUNC("gpio", 1),
- FUNC("uart2", 0),
+};
+static struct mtmips_pmx_func uart1_grp[] = {
- FUNC("sw_r", 3),
- FUNC("pwm", 2),
- FUNC("gpio", 1),
- FUNC("uart1", 0),
+};
+static struct mtmips_pmx_func i2c_grp[] = {
- FUNC("-", 3),
- FUNC("debug", 2),
- FUNC("gpio", 1),
- FUNC("i2c", 0),
+};
+static struct mtmips_pmx_func refclk_grp[] = {
- FUNC("gpio", 1),
- FUNC("refclk", 0),
+};
+static struct mtmips_pmx_func perst_grp[] = {
- FUNC("gpio", 1),
- FUNC("perst", 0),
+};
+static struct mtmips_pmx_func esd_grp[] = {
- FUNC("router", 1),
- FUNC("iot", 0),
+};
+static struct mtmips_pmx_func wdt_grp[] = {
- FUNC("gpio", 1),
- FUNC("wdt", 0),
+};
+static struct mtmips_pmx_func spi_grp[] = {
- FUNC("gpio", 1),
- FUNC("spi", 0),
+};
+static struct mtmips_pmx_func sd_mode_grp[] = {
- FUNC("n9 jtag", 3),
- FUNC("utif1", 2),
- FUNC("gpio", 1),
- FUNC("sdxc", 0),
+};
+static struct mtmips_pmx_func uart0_grp[] = {
- FUNC("-", 3),
- FUNC("-", 2),
- FUNC("gpio", 1),
- FUNC("uart0", 0),
+};
+static struct mtmips_pmx_func i2s_grp[] = {
- FUNC("antenna", 3),
- FUNC("pcm", 2),
- FUNC("gpio", 1),
- FUNC("i2s", 0),
+};
+static struct mtmips_pmx_func spi_cs1_grp[] = {
- FUNC("-", 3),
- FUNC("refclk", 2),
- FUNC("gpio", 1),
- FUNC("spi cs1", 0),
+};
+static struct mtmips_pmx_func spis_grp[] = {
- FUNC("pwm_uart2", 3),
- FUNC("utif", 2),
- FUNC("gpio", 1),
- FUNC("spis", 0),
+};
+static struct mtmips_pmx_func gpio0_grp[] = {
- FUNC("perst", 3),
- FUNC("refclk", 2),
- FUNC("gpio", 1),
- FUNC("gpio0", 0),
+};
+static struct mtmips_pmx_func wled_a_grp[] = {
- FUNC("-", 3),
- FUNC("-", 2),
- FUNC("gpio", 1),
- FUNC("led", 0),
+};
+static struct mtmips_pmx_func p0led_a_grp[] = {
- FUNC("jtag", 3),
- FUNC("rsvd", 2),
- FUNC("gpio", 1),
- FUNC("led", 0),
+};
+static struct mtmips_pmx_func p1led_a_grp[] = {
- FUNC("jtag", 3),
- FUNC("utif", 2),
- FUNC("gpio", 1),
- FUNC("led", 0),
+};
+static struct mtmips_pmx_func p2led_a_grp[] = {
- FUNC("jtag", 3),
- FUNC("utif", 2),
- FUNC("gpio", 1),
- FUNC("led", 0),
+};
+static struct mtmips_pmx_func p3led_a_grp[] = {
- FUNC("jtag", 3),
- FUNC("utif", 2),
- FUNC("gpio", 1),
- FUNC("led", 0),
+};
+static struct mtmips_pmx_func p4led_a_grp[] = {
- FUNC("jtag", 3),
- FUNC("utif", 2),
- FUNC("gpio", 1),
- FUNC("led", 0),
+};
+static struct mtmips_pmx_func wled_k_grp[] = {
- FUNC("-", 3),
- FUNC("-", 2),
- FUNC("gpio", 1),
- FUNC("led", 0),
+};
+static struct mtmips_pmx_func p0led_k_grp[] = {
- FUNC("jtag", 3),
- FUNC("rsvd", 2),
- FUNC("gpio", 1),
- FUNC("led", 0),
+};
+static struct mtmips_pmx_func p1led_k_grp[] = {
- FUNC("jtag", 3),
- FUNC("utif", 2),
- FUNC("gpio", 1),
- FUNC("led", 0),
+};
+static struct mtmips_pmx_func p2led_k_grp[] = {
- FUNC("jtag", 3),
- FUNC("utif", 2),
- FUNC("gpio", 1),
- FUNC("led", 0),
+};
+static struct mtmips_pmx_func p3led_k_grp[] = {
- FUNC("jtag", 3),
- FUNC("utif", 2),
- FUNC("gpio", 1),
- FUNC("led", 0),
+};
+static struct mtmips_pmx_func p4led_k_grp[] = {
- FUNC("jtag", 3),
- FUNC("utif", 2),
- FUNC("gpio", 1),
- FUNC("led", 0),
+};
+static struct mtmips_pmx_group mt7628_pinmux_data[] = {
- GRP("ephy4_1_pad", ephy4_1_pad_grp, AGPIO_OFS, EPHY4_1_PAD_SHIFT,
EPHY4_1_PAD_MASK),
- GRP("ephy0", ephy0_grp, AGPIO_OFS, EPHY0_SHIFT, 1),
- GRP("rf_olt", rf_olt_grp, AGPIO_OFS, RF_OLT_MODE_SHIFT, 1),
- GRP("n9_eint_src", n9_eint_src_grp, AGPIO_OFS, N9_EINT_SRC_SHIFT, 1),
- GRP("wlen_od", wlen_od_grp, AGPIO_OFS, WLED_OD_SHIFT, 1),
- GRP("ref_clko_pad", ref_clko_grp, AGPIO_OFS, REF_CLKO_PAD_SHIFT, 1),
- GRP("i2s_clk_pad", i2s_clk_grp, AGPIO_OFS, I2S_CLK_PAD_SHIFT, 1),
- GRP("i2s_ws_pad", i2s_ws_grp, AGPIO_OFS, I2S_WS_PAD_SHIFT, 1),
- GRP("i2s_sdo_pad", i2s_sdo_grp, AGPIO_OFS, I2S_SDO_PAD_SHIFT, 1),
- GRP("i2s_sdi_pad", i2s_sdi_grp, AGPIO_OFS, I2S_SDI_PAD_SHIFT, 1),
- GRP("pwm1", pwm1_grp, GPIOMODE1_OFS, PWM1_SHIFT, GM4_MASK),
- GRP("pwm0", pwm0_grp, GPIOMODE1_OFS, PWM0_SHIFT, GM4_MASK),
- GRP("uart2", uart2_grp, GPIOMODE1_OFS, UART2_SHIFT, GM4_MASK),
- GRP("uart1", uart1_grp, GPIOMODE1_OFS, UART1_SHIFT, GM4_MASK),
- GRP("i2c", i2c_grp, GPIOMODE1_OFS, I2C_SHIFT, GM4_MASK),
- GRP("refclk", refclk_grp, GPIOMODE1_OFS, REFCLK_SHIFT, 1),
- GRP("perst", perst_grp, GPIOMODE1_OFS, PERST_SHIFT, 1),
- GRP("sd router", esd_grp, GPIOMODE1_OFS, ESD_SHIFT, 1),
- GRP("wdt", wdt_grp, GPIOMODE1_OFS, WDT_SHIFT, 1),
- GRP("spi", spi_grp, GPIOMODE1_OFS, SPI_SHIFT, 1),
- GRP("sdmode", sd_mode_grp, GPIOMODE1_OFS, SDMODE_SHIFT, GM4_MASK),
- GRP("uart0", uart0_grp, GPIOMODE1_OFS, UART0_SHIFT, GM4_MASK),
- GRP("i2s", i2s_grp, GPIOMODE1_OFS, I2S_SHIFT, GM4_MASK),
- GRP("spi cs1", spi_cs1_grp, GPIOMODE1_OFS, SPI_CS1_SHIFT, GM4_MASK),
- GRP("spis", spis_grp, GPIOMODE1_OFS, SPIS_SHIFT, GM4_MASK),
- GRP("gpio0", gpio0_grp, GPIOMODE1_OFS, GPIO0_SHIFT, GM4_MASK),
- GRP("wled_a", wled_a_grp, GPIOMODE2_OFS, WLED_A_SHIFT, GM4_MASK),
- GRP("p0led_a", p0led_a_grp, GPIOMODE2_OFS, P0LED_A_SHIFT, GM4_MASK),
- GRP("p1led_a", p1led_a_grp, GPIOMODE2_OFS, P1LED_A_SHIFT, GM4_MASK),
- GRP("p2led_a", p2led_a_grp, GPIOMODE2_OFS, P2LED_A_SHIFT, GM4_MASK),
- GRP("p3led_a", p3led_a_grp, GPIOMODE2_OFS, P3LED_A_SHIFT, GM4_MASK),
- GRP("p4led_a", p4led_a_grp, GPIOMODE2_OFS, P4LED_A_SHIFT, GM4_MASK),
- GRP("wled_k", wled_k_grp, GPIOMODE2_OFS, WLED_K_SHIFT, GM4_MASK),
- GRP("p0led_k", p0led_k_grp, GPIOMODE2_OFS, P0LED_K_SHIFT, GM4_MASK),
- GRP("p1led_k", p1led_k_grp, GPIOMODE2_OFS, P1LED_K_SHIFT, GM4_MASK),
- GRP("p2led_k", p2led_k_grp, GPIOMODE2_OFS, P2LED_K_SHIFT, GM4_MASK),
- GRP("p3led_k", p3led_k_grp, GPIOMODE2_OFS, P3LED_K_SHIFT, GM4_MASK),
- GRP("p4led_k", p4led_k_grp, GPIOMODE2_OFS, P4LED_K_SHIFT, GM4_MASK),
+};
+static int mt7628_get_groups_count(struct udevice *dev) +{
- return ARRAY_SIZE(mt7628_pinmux_data);
+}
+static const char *mt7628_get_group_name(struct udevice *dev,
unsigned int selector)
+{
- return mt7628_pinmux_data[selector].name;
+} +#endif /* CONFIG_IS_ENABLED(PINMUX) */
+#if CONFIG_IS_ENABLED(PINCONF) +static const struct pinconf_param mt7628_conf_params[] = {
- { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
- { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
- { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
- { "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
- { "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 },
- { "drive-strength-28", PIN_CONFIG_DRIVE_STRENGTH_28, 0 },
- { "drive-strength-4g", PIN_CONFIG_DRIVE_STRENGTH_4G, 0 },
- { "slew-rate", PIN_CONFIG_SLEW_RATE, 0 },
+};
+static const char *const mt7628_pins[] = {
- "i2s_sdi",
- "i2s_sdo",
- "i2s_ws",
- "i2s_clk",
- "i2s_sclk",
- "i2c_sd",
- "spi_cs1",
- "spi_clk",
- "spi_mosi",
- "spi_miso",
- "spi_cs0",
- "gpio0",
- "uart0_txd",
- "uart0_rxd",
- "spis_cs",
- "spis_clk",
- "spis_miso",
- "spis_mosi",
- "pwm_ch0",
- "pwm_ch1",
- "uart2_txd",
- "uart2_rxd",
- "sd_wp",
- "sd_cd",
- "sd_d1",
- "sd_d0",
- "sd_clk",
- "sd_cmd",
- "sd_d3",
- "sd_d2",
- "ephy_led4_k",
- "ephy_led3_k",
- "ephy_led2_k",
- "ephy_led1_k",
- "ephy_led0_k",
- "wled_k",
- "perst_n",
- "co_clko",
- "wdt",
- "ephy_led4_a",
- "ephy_led3_a",
- "ephy_led2_a",
- "ephy_led1_a",
- "ephy_led0_a",
- "wled_a",
- "uart1_txd",
- "uart1_rxd",
+};
+static const u32 mt7628_drv_strength_28_tbl[] = {2, 4, 6, 8}; +static const u32 mt7628_drv_strength_4g_tbl[] = {4, 8, 12, 16};
+static int mt7628_set_drv_strength(void __iomem *base, u32 val, u32 bit,
const u32 tbl[], u32 reg_lo, u32 reg_hi)
+{
- int i;
- for (i = 0; i < 4; i++)
if (tbl[i] == val)
break;
- if (i >= 4)
return -EINVAL;
- clrsetbits_32(base + reg_lo, BIT(bit), (i & 1) << bit);
- clrsetbits_32(base + reg_hi, BIT(bit), ((i >> 1) & 1) << bit);
- return 0;
+}
+static int mt7628_get_pins_count(struct udevice *dev) +{
- return ARRAY_SIZE(mt7628_pins);
+}
+static const char *mt7628_get_pin_name(struct udevice *dev,
unsigned int selector)
+{
- return mt7628_pins[selector];
+}
+static int mt7628_pinconf_set(struct udevice *dev, unsigned int pin_selector,
unsigned int param, unsigned int argument)
+{
- struct mt7628_pinctrl_priv *priv = dev_get_priv(dev);
- u32 offs, bit;
- int ret = 0;
- offs = (pin_selector / 32) * 4;
- bit = pin_selector % 32;
- switch (param) {
- case PIN_CONFIG_BIAS_DISABLE:
clrbits_32(priv->pcbase + offs + PAD_PU_G0_REG, BIT(bit));
clrbits_32(priv->pcbase + offs + PAD_PD_G0_REG, BIT(bit));
break;
- case PIN_CONFIG_BIAS_PULL_UP:
setbits_32(priv->pcbase + offs + PAD_PU_G0_REG, BIT(bit));
clrbits_32(priv->pcbase + offs + PAD_PD_G0_REG, BIT(bit));
break;
- case PIN_CONFIG_BIAS_PULL_DOWN:
clrbits_32(priv->pcbase + offs + PAD_PU_G0_REG, BIT(bit));
setbits_32(priv->pcbase + offs + PAD_PD_G0_REG, BIT(bit));
break;
- case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
clrsetbits_32(priv->pcbase + offs + PAD_SMT_G0_REG,
BIT(bit), (!!argument) << bit);
break;
- case PIN_CONFIG_DRIVE_STRENGTH_28:
ret = mt7628_set_drv_strength(priv->pcbase + offs, argument,
bit, mt7628_drv_strength_28_tbl,
PAD_E2_G0_REG, PAD_E4_G0_REG);
break;
- case PIN_CONFIG_DRIVE_STRENGTH_4G:
ret = mt7628_set_drv_strength(priv->pcbase + offs, argument,
bit, mt7628_drv_strength_4g_tbl,
PAD_E4_G0_REG, PAD_E8_G0_REG);
break;
- case PIN_CONFIG_SLEW_RATE:
clrsetbits_32(priv->pcbase + offs + PAD_SR_G0_REG,
BIT(bit), (!!argument) << bit);
break;
- default:
ret = -EINVAL;
- }
- return ret;
+} +#endif
+static int mt7628_pinctrl_probe(struct udevice *dev) +{
- struct mt7628_pinctrl_priv *priv = dev_get_priv(dev);
- int ret = 0;
+#if CONFIG_IS_ENABLED(PINMUX)
- ret = mtmips_pinctrl_probe(&priv->mp, ARRAY_SIZE(mt7628_pinmux_data),
mt7628_pinmux_data);
+#endif /* CONFIG_IS_ENABLED(PINMUX) */
- return ret;
+}
+static int mt7628_pinctrl_ofdata_to_platdata(struct udevice *dev) +{
- struct mt7628_pinctrl_priv *priv = dev_get_priv(dev);
- priv->mp.base = (void __iomem *)dev_remap_addr_index(dev, 0);
- if (!priv->mp.base)
return -EINVAL;
- priv->pcbase = (void __iomem *)dev_remap_addr_index(dev, 1);
- if (!priv->pcbase)
return -EINVAL;
- return 0;
+}
+static struct pinctrl_ops mt7628_pinctrl_ops = { +#if CONFIG_IS_ENABLED(PINMUX)
- .get_groups_count = mt7628_get_groups_count,
- .get_group_name = mt7628_get_group_name,
- .get_functions_count = mtmips_get_functions_count,
- .get_function_name = mtmips_get_function_name,
- .pinmux_group_set = mtmips_pinmux_group_set,
+#endif /* CONFIG_IS_ENABLED(PINMUX) */ +#if CONFIG_IS_ENABLED(PINCONF)
- .pinconf_num_params = ARRAY_SIZE(mt7628_conf_params),
- .pinconf_params = mt7628_conf_params,
- .get_pins_count = mt7628_get_pins_count,
- .get_pin_name = mt7628_get_pin_name,
- .pinconf_set = mt7628_pinconf_set,
+#endif /* CONFIG_IS_ENABLED(PINCONF) */
- .set_state = pinctrl_generic_set_state,
+};
+static const struct udevice_id mt7628_pinctrl_ids[] = {
- { .compatible = "mediatek,mt7628-pinctrl" },
- { }
+};
+U_BOOT_DRIVER(mt7628_pinctrl) = {
- .name = "mt7628-pinctrl",
- .id = UCLASS_PINCTRL,
- .of_match = mt7628_pinctrl_ids,
- .ofdata_to_platdata = mt7628_pinctrl_ofdata_to_platdata,
- .ops = &mt7628_pinctrl_ops,
- .probe = mt7628_pinctrl_probe,
- .priv_auto_alloc_size = sizeof(struct mt7628_pinctrl_priv),
+}; diff --git a/drivers/pinctrl/mtmips/pinctrl-mtmips-common.c b/drivers/pinctrl/mtmips/pinctrl-mtmips-common.c new file mode 100644 index 0000000000..ee6a9d1fc8 --- /dev/null +++ b/drivers/pinctrl/mtmips/pinctrl-mtmips-common.c @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: GPL-2.0 +/*
- Copyright (C) 2019 MediaTek Inc. All Rights Reserved.
- Author: Weijie Gao weijie.gao@mediatek.com
- */
+#include <common.h> +#include <dm.h> +#include <dm/pinctrl.h> +#include <linux/io.h>
+#include "pinctrl-mtmips-common.h"
+static void mtmips_pinctrl_reg_set(struct mtmips_pinctrl_priv *priv,
u32 reg, u32 shift, u32 mask, u32 value)
+{
- u32 val;
- val = readl(priv->base + reg);
- val &= ~(mask << shift);
- val |= value << shift;
- writel(val, priv->base + reg);
+}
+int mtmips_get_functions_count(struct udevice *dev) +{
- struct mtmips_pinctrl_priv *priv = dev_get_priv(dev);
- return priv->nfuncs;
+}
+const char *mtmips_get_function_name(struct udevice *dev, unsigned int selector) +{
- struct mtmips_pinctrl_priv *priv = dev_get_priv(dev);
- return priv->funcs[selector]->name;
+}
+int mtmips_pinmux_group_set(struct udevice *dev, unsigned int group_selector,
unsigned int func_selector)
+{
- struct mtmips_pinctrl_priv *priv = dev_get_priv(dev);
- const struct mtmips_pmx_group *grp = &priv->groups[group_selector];
- const struct mtmips_pmx_func *func = priv->funcs[func_selector];
- int i;
- if (!grp->nfuncs)
return 0;
- for (i = 0; i < grp->nfuncs; i++) {
if (!strcmp(grp->funcs[i].name, func->name)) {
mtmips_pinctrl_reg_set(priv, grp->reg, grp->shift,
grp->mask, grp->funcs[i].value);
return 0;
}
- }
- return -EINVAL;
+}
+int mtmips_pinctrl_probe(struct mtmips_pinctrl_priv *priv, u32 ngroups,
const struct mtmips_pmx_group *groups)
+{
- int i, j, n;
- priv->ngroups = ngroups;
- priv->groups = groups;
- priv->nfuncs = 0;
- for (i = 0; i < ngroups; i++)
priv->nfuncs += groups[i].nfuncs;
- priv->funcs = malloc(priv->nfuncs * sizeof(*priv->funcs));
- if (!priv->funcs)
return -ENOMEM;
- n = 0;
- for (i = 0; i < ngroups; i++) {
for (j = 0; j < groups[i].nfuncs; j++)
priv->funcs[n++] = &groups[i].funcs[j];
- }
- return 0;
+} diff --git a/drivers/pinctrl/mtmips/pinctrl-mtmips-common.h b/drivers/pinctrl/mtmips/pinctrl-mtmips-common.h new file mode 100644 index 0000000000..b51d8f009c --- /dev/null +++ b/drivers/pinctrl/mtmips/pinctrl-mtmips-common.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/*
- Copyright (C) 2019 MediaTek Inc. All Rights Reserved.
- Author: Weijie Gao weijie.gao@mediatek.com
- */
+#ifndef _PINCTRL_MTMIPS_COMMON_H_ +#define _PINCTRL_MTMIPS_COMMON_H_
+#include <common.h>
+struct mtmips_pmx_func {
- const char *name;
- int value;
+};
+struct mtmips_pmx_group {
- const char *name;
- u32 reg;
- u32 shift;
- char mask;
- int nfuncs;
- const struct mtmips_pmx_func *funcs;
+};
+struct mtmips_pinctrl_priv {
- void __iomem *base;
- u32 ngroups;
- const struct mtmips_pmx_group *groups;
- u32 nfuncs;
- const struct mtmips_pmx_func **funcs;
+};
+#define FUNC(name, value) { name, value }
+#define GRP(_name, _funcs, _reg, _shift, _mask) \
- { .name = (_name), .reg = (_reg), .shift = (_shift), .mask = (_mask), \
.funcs = (_funcs), .nfuncs = ARRAY_SIZE(_funcs) }
+int mtmips_get_functions_count(struct udevice *dev); +const char *mtmips_get_function_name(struct udevice *dev,
unsigned int selector);
+int mtmips_pinmux_group_set(struct udevice *dev, unsigned int group_selector,
unsigned int func_selector);
+int mtmips_pinctrl_probe(struct mtmips_pinctrl_priv *priv, u32 ngroups,
const struct mtmips_pmx_group *groups);
+#endif /* _PINCTRL_MTMIPS_COMMON_H_ */
Viele Grüße, Stefan

On 28.08.19 14:26, Stefan Roese wrote:
On 28.08.19 08:37, Weijie Gao wrote:
This patch adds pinctrl support for mt7628, with a file for common pinmux functions and a file for mt7628 which has additional support for pinconf.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com
drivers/pinctrl/Kconfig | 1 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/mtmips/Kconfig | 13 + drivers/pinctrl/mtmips/Makefile | 7 + drivers/pinctrl/mtmips/pinctrl-mt7628.c | 585 ++++++++++++++++++ .../pinctrl/mtmips/pinctrl-mtmips-common.c | 87 +++ .../pinctrl/mtmips/pinctrl-mtmips-common.h | 53 ++ 7 files changed, 747 insertions(+) create mode 100644 drivers/pinctrl/mtmips/Kconfig create mode 100644 drivers/pinctrl/mtmips/Makefile create mode 100644 drivers/pinctrl/mtmips/pinctrl-mt7628.c create mode 100644 drivers/pinctrl/mtmips/pinctrl-mtmips-common.c create mode 100644 drivers/pinctrl/mtmips/pinctrl-mtmips-common.h
Nice patch. I do have 2 questions though:
a) Why are you introducing a new "mtmips" directory and don't re-use the already available "mediatek" directory? Is there nothing in common with these "mediatek" drivers?
b) Somewhat related: You introduce a mtmips-common file. For which platforms is this targeted (non-mt7628)? Is there nothing in common with the "mediatek" files already available?
Other than that I've tested this on my MT7688 board and it works just fine. Thanks a lot!
I do have another comment though:
I've used the common "pinctrl-single" driver in Linux a few weeks ago as there is no need for a separate MT7628 specific pin-mux driver [1][2] etc. Frankly, I don't know that status of the "pinctrl-single" U-Boot driver in depth. If its compatible with the Linux one (which I really hope), then we don't need a MT7628 specific pinctrl driver but can use the "pinctrl-single" driver as I've done in the Linux [1][2].
It would be great if you could check this and change this pinctrl support to the common "single" driver is possible.
Thanks, Stefan
[1] https://github.com/torvalds/linux/commit/380f072c57a590d7593050b8533d88e18b6... [2] https://github.com/torvalds/linux/commit/6394de396ed36f3e8043734676eaa9c26f8...

On Wed, 2019-08-28 at 14:37 +0200, Stefan Roese wrote:
On 28.08.19 14:26, Stefan Roese wrote:
On 28.08.19 08:37, Weijie Gao wrote:
This patch adds pinctrl support for mt7628, with a file for common pinmux functions and a file for mt7628 which has additional support for pinconf.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com
drivers/pinctrl/Kconfig | 1 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/mtmips/Kconfig | 13 + drivers/pinctrl/mtmips/Makefile | 7 + drivers/pinctrl/mtmips/pinctrl-mt7628.c | 585 ++++++++++++++++++ .../pinctrl/mtmips/pinctrl-mtmips-common.c | 87 +++ .../pinctrl/mtmips/pinctrl-mtmips-common.h | 53 ++ 7 files changed, 747 insertions(+) create mode 100644 drivers/pinctrl/mtmips/Kconfig create mode 100644 drivers/pinctrl/mtmips/Makefile create mode 100644 drivers/pinctrl/mtmips/pinctrl-mt7628.c create mode 100644 drivers/pinctrl/mtmips/pinctrl-mtmips-common.c create mode 100644 drivers/pinctrl/mtmips/pinctrl-mtmips-common.h
Nice patch. I do have 2 questions though:
a) Why are you introducing a new "mtmips" directory and don't re-use the already available "mediatek" directory? Is there nothing in common with these "mediatek" drivers?
b) Somewhat related: You introduce a mtmips-common file. For which platforms is this targeted (non-mt7628)? Is there nothing in common with the "mediatek" files already available?
Other than that I've tested this on my MT7688 board and it works just fine. Thanks a lot!
I do have another comment though:
I've used the common "pinctrl-single" driver in Linux a few weeks ago as there is no need for a separate MT7628 specific pin-mux driver [1][2] etc. Frankly, I don't know that status of the "pinctrl-single" U-Boot driver in depth. If its compatible with the Linux one (which I really hope), then we don't need a MT7628 specific pinctrl driver but can use the "pinctrl-single" driver as I've done in the Linux [1][2].
It would be great if you could check this and change this pinctrl support to the common "single" driver is possible.
Thanks, Stefan
[1] https://github.com/torvalds/linux/commit/380f072c57a590d7593050b8533d88e18b6... [2] https://github.com/torvalds/linux/commit/6394de396ed36f3e8043734676eaa9c26f8...
Although I am trying to write the pinctrl driver to be similar with the "mediatek" one, they cannot share the same codebase because the register map and definition are totally different. The "mtmips" chips have separate pinmux registers, pinconf registers and gpio registers, while the "mediatek" chips have uniformed registers for all these three functionalities.
I introduced the common file to reserve space for mt7620.
If I use pinctrl-single, I still have to write a new driver for the pinconf function and I'd rather just write them into one driver.
Besides the pinmux function takes advantages from the OpenWrt source. Since some pinmux groups have 4 different function, I think is more readable using the string configuration. And the users don't need to read the programming guide to set the registers/shift/mask for a single pinmux function.
Please see https://github.com/torvalds/linux/blob/master/arch/mips/ralink/mt7620.c
Best Regards,
Weijie

This patch adds pinctrl node with default pin state for mt7628an.dtsi.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- arch/mips/dts/mt7628a.dtsi | 150 +++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+)
diff --git a/arch/mips/dts/mt7628a.dtsi b/arch/mips/dts/mt7628a.dtsi index e9241a0737..be9ab50931 100644 --- a/arch/mips/dts/mt7628a.dtsi +++ b/arch/mips/dts/mt7628a.dtsi @@ -48,6 +48,156 @@ mask = <0x1>; };
+ pinctrl: pinctrl@60 { + compatible = "mediatek,mt7628-pinctrl"; + reg = <0x3c 0x2c>, <0x1300 0x100>; + reg-names = "gpiomode", "padconf"; + + pinctrl-names = "default"; + pinctrl-0 = <&state_default>; + + state_default: pin_state { + }; + + spi_single_pins: spi_single_pins { + groups = "spi"; + function = "spi"; + }; + + spi_dual_pins: spi_dual_pins { + spi_master_pins { + groups = "spi"; + function = "spi"; + }; + + spi_cs1_pin { + groups = "spi cs1"; + function = "spi cs1"; + }; + }; + + uart0_pins: uart0_pins { + groups = "uart0"; + function = "uart0"; + }; + + uart1_pins: uart1_pins { + groups = "uart1"; + function = "uart1"; + }; + + uart2_pins: uart2_pins { + groups = "uart2"; + function = "uart2"; + }; + + i2c_pins: i2c_pins { + groups = "i2c"; + function = "i2c"; + }; + + ephy_iot_mode: ephy_iot_mode { + ephy4_1_dis { + groups = "ephy4_1_pad"; + function = "digital"; + }; + + ephy0_en { + groups = "ephy0"; + function = "enable"; + }; + }; + + ephy_router_mode: ephy_router_mode { + ephy4_1_en { + groups = "ephy4_1_pad"; + function = "analog"; + }; + + ephy0_en { + groups = "ephy0"; + function = "enable"; + }; + }; + + sd_iot_mode: sd_iot_mode { + ephy4_1_dis { + groups = "ephy4_1_pad"; + function = "digital"; + }; + + sdxc_en { + groups = "sdmode"; + function = "sdxc"; + }; + + sdxc_iot_mode { + groups = "sd router"; + function = "iot"; + }; + + sd_clk_pad { + pins = "sd_clk"; + drive-strength-4g = <8>; + }; + }; + + sd_router_mode: sd_router_mode { + sdxc_router_mode { + groups = "sd router"; + function = "router"; + }; + + sdxc_map_pins { + groups = "gpio0", "i2s", "sdmode", \ + "i2c", "uart1"; + function = "gpio"; + }; + + sd_clk_pad { + pins = "gpio0"; + drive-strength-28 = <8>; + }; + }; + + emmc_iot_8bit_mode: emmc_iot_8bit_mode { + ephy4_1_dis { + groups = "ephy4_1_pad"; + function = "digital"; + }; + + emmc_en { + groups = "sdmode"; + function = "sdxc"; + }; + + emmc_iot_mode { + groups = "sd router"; + function = "iot"; + }; + + emmc_d4_d5 { + groups = "uart2"; + function = "sdxc d5 d4"; + }; + + emmc_d6 { + groups = "pwm1"; + function = "sdxc d6"; + }; + + emmc_d7 { + groups = "pwm0"; + function = "sdxc d7"; + }; + + sd_clk_pad { + pins = "sd_clk"; + drive-strength-4g = <8>; + }; + }; + }; + watchdog: watchdog@100 { compatible = "ralink,mt7628a-wdt", "mediatek,mt7621-wdt"; reg = <0x100 0x30>;

This patch adds default pinctrl for uart nodes
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- arch/mips/dts/mt7628a.dtsi | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/arch/mips/dts/mt7628a.dtsi b/arch/mips/dts/mt7628a.dtsi index be9ab50931..f07de1b611 100644 --- a/arch/mips/dts/mt7628a.dtsi +++ b/arch/mips/dts/mt7628a.dtsi @@ -277,6 +277,9 @@ compatible = "mediatek,hsuart", "ns16550a"; reg = <0xc00 0x100>;
+ pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; + clock-frequency = <40000000>;
resets = <&resetc 12>; @@ -292,6 +295,9 @@ compatible = "mediatek,hsuart", "ns16550a"; reg = <0xd00 0x100>;
+ pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; + clock-frequency = <40000000>;
resets = <&resetc 19>; @@ -307,6 +313,9 @@ compatible = "mediatek,hsuart", "ns16550a"; reg = <0xe00 0x100>;
+ pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; + clock-frequency = <40000000>;
resets = <&resetc 20>;

This patch adds reset controller driver for MediaTek MIPS platform and header file for mt7628.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- drivers/reset/Kconfig | 7 ++ drivers/reset/Makefile | 1 + drivers/reset/reset-mtmips.c | 82 ++++++++++++++++++++++++ include/dt-bindings/reset/mt7628-reset.h | 36 +++++++++++ 4 files changed, 126 insertions(+) create mode 100644 drivers/reset/reset-mtmips.c create mode 100644 include/dt-bindings/reset/mt7628-reset.h
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 6ec6f39c85..76866a2e90 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -113,6 +113,13 @@ config RESET_MEDIATEK help Support for reset controller on MediaTek SoCs.
+config RESET_MTMIPS + bool "Reset controller driver for MediaTek MIPS platform" + depends on DM_RESET && ARCH_MTMIPS + default y + help + Support for reset controller on MediaTek MIPS platform. + config RESET_SUNXI bool "RESET support for Allwinner SoCs" depends on DM_RESET && ARCH_SUNXI diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 7fec75bb49..87d2bc4f18 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -18,5 +18,6 @@ obj-$(CONFIG_RESET_ROCKCHIP) += reset-rockchip.o obj-$(CONFIG_RESET_MESON) += reset-meson.o obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o obj-$(CONFIG_RESET_MEDIATEK) += reset-mediatek.o +obj-$(CONFIG_RESET_MTMIPS) += reset-mtmips.o obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o obj-$(CONFIG_RESET_HISILICON) += reset-hisilicon.o diff --git a/drivers/reset/reset-mtmips.c b/drivers/reset/reset-mtmips.c new file mode 100644 index 0000000000..59734565d7 --- /dev/null +++ b/drivers/reset/reset-mtmips.c @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 MediaTek Inc. All Rights Reserved. + * + * Author: Weijie Gao weijie.gao@mediatek.com + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <reset-uclass.h> +#include <linux/io.h> + +struct mtmips_reset_priv { + void __iomem *base; +}; + +static int mtmips_reset_request(struct reset_ctl *reset_ctl) +{ + return 0; +} + +static int mtmips_reset_free(struct reset_ctl *reset_ctl) +{ + return 0; +} + +static int mtmips_reset_assert(struct reset_ctl *reset_ctl) +{ + struct mtmips_reset_priv *priv = dev_get_priv(reset_ctl->dev); + + setbits_32(priv->base, BIT(reset_ctl->id)); + + return 0; +} + +static int mtmips_reset_deassert(struct reset_ctl *reset_ctl) +{ + struct mtmips_reset_priv *priv = dev_get_priv(reset_ctl->dev); + + clrbits_32(priv->base, BIT(reset_ctl->id)); + + return 0; +} + +static const struct reset_ops mtmips_reset_ops = { + .request = mtmips_reset_request, + .free = mtmips_reset_free, + .rst_assert = mtmips_reset_assert, + .rst_deassert = mtmips_reset_deassert, +}; + +static int mtmips_reset_probe(struct udevice *dev) +{ + return 0; +} + +static int mtmips_reset_ofdata_to_platdata(struct udevice *dev) +{ + struct mtmips_reset_priv *priv = dev_get_priv(dev); + + priv->base = (void __iomem *)dev_remap_addr_index(dev, 0); + if (!priv->base) + return -EINVAL; + + return 0; +} + +static const struct udevice_id mtmips_reset_ids[] = { + { .compatible = "mediatek,mtmips-reset" }, + { } +}; + +U_BOOT_DRIVER(mtmips_reset) = { + .name = "mtmips-reset", + .id = UCLASS_RESET, + .of_match = mtmips_reset_ids, + .ofdata_to_platdata = mtmips_reset_ofdata_to_platdata, + .probe = mtmips_reset_probe, + .priv_auto_alloc_size = sizeof(struct mtmips_reset_priv), + .ops = &mtmips_reset_ops, +}; diff --git a/include/dt-bindings/reset/mt7628-reset.h b/include/dt-bindings/reset/mt7628-reset.h new file mode 100644 index 0000000000..2a674c1ea7 --- /dev/null +++ b/include/dt-bindings/reset/mt7628-reset.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * Author: Weijie Gao weijie.gao@mediatek.com + */ + +#ifndef _DT_BINDINGS_MT7628_RESET_H_ +#define _DT_BINDINGS_MT7628_RESET_H_ + +#define MT7628_PWM_RST 31 +#define MT7628_SDXC_RST 30 +#define MT7628_CRYPTO_RST 29 +#define MT7628_AUX_STCK_RST 28 +#define MT7628_PCIE_RST 26 +#define MT7628_EPHY_RST 24 +#define MT7628_ETH_RST 23 +#define MT7628_UPHY_RST 22 +#define MT7628_UART2_RST 20 +#define MT7628_UART1_RST 19 +#define MT7628_SPI_RST 18 +#define MT7628_I2S_RST 17 +#define MT7628_I2C_RST 16 +#define MT7628_GDMA_RST 14 +#define MT7628_PIO_RST 13 +#define MT7628_UART0_RST 12 +#define MT7628_PCM_RST 11 +#define MT7628_MC_RST 10 +#define MT7628_INT_RST 9 +#define MT7628_TIMER_RST 8 +#define MT7628_HIF_RST 5 +#define MT7628_WIFI_RST 4 +#define MT7628_SPIS_RST 3 +#define MT7628_SYS_RST 0 + +#endif /* _DT_BINDINGS_MT7628_RESET_H_ */

This patch updates reset controller node for mt7628
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- arch/mips/dts/mt7628a.dtsi | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-)
diff --git a/arch/mips/dts/mt7628a.dtsi b/arch/mips/dts/mt7628a.dtsi index f07de1b611..0e2b6598ea 100644 --- a/arch/mips/dts/mt7628a.dtsi +++ b/arch/mips/dts/mt7628a.dtsi @@ -1,4 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 +#include <dt-bindings/reset/mt7628-reset.h>
/ { #address-cells = <1>; @@ -16,11 +17,6 @@ }; };
- resetc: reset-controller { - compatible = "ralink,rt2880-reset"; - #reset-cells = <1>; - }; - cpuintc: interrupt-controller { #address-cells = <0>; #interrupt-cells = <1>; @@ -48,6 +44,12 @@ mask = <0x1>; };
+ rstctrl: rstctrl@0x34 { + reg = <0x34 0x4>; + compatible = "mediatek,mtmips-reset"; + #reset-cells = <1>; + }; + pinctrl: pinctrl@60 { compatible = "mediatek,mt7628-pinctrl"; reg = <0x3c 0x2c>, <0x1300 0x100>; @@ -202,7 +204,7 @@ compatible = "ralink,mt7628a-wdt", "mediatek,mt7621-wdt"; reg = <0x100 0x30>;
- resets = <&resetc 8>; + resets = <&rstctrl MT7628_TIMER_RST>; reset-names = "wdt";
interrupt-parent = <&intc>; @@ -216,7 +218,7 @@ interrupt-controller; #interrupt-cells = <1>;
- resets = <&resetc 9>; + resets = <&rstctrl MT7628_INT_RST>; reset-names = "intc";
interrupt-parent = <&cpuintc>; @@ -239,6 +241,9 @@ compatible = "mtk,mt7628-gpio", "mtk,mt7621-gpio"; reg = <0x600 0x100>;
+ resets = <&rstctrl MT7628_PIO_RST>; + reset-names = "pio"; + interrupt-parent = <&intc>; interrupts = <6>;
@@ -267,6 +272,10 @@ spi0: spi@b00 { compatible = "ralink,mt7621-spi"; reg = <0xb00 0x40>; + + resets = <&rstctrl MT7628_SPI_RST>; + reset-names = "spi"; + #address-cells = <1>; #size-cells = <0>;
@@ -282,7 +291,7 @@
clock-frequency = <40000000>;
- resets = <&resetc 12>; + resets = <&rstctrl MT7628_UART0_RST>; reset-names = "uart0";
interrupt-parent = <&intc>; @@ -300,7 +309,7 @@
clock-frequency = <40000000>;
- resets = <&resetc 19>; + resets = <&rstctrl MT7628_UART1_RST>; reset-names = "uart1";
interrupt-parent = <&intc>; @@ -318,7 +327,7 @@
clock-frequency = <40000000>;
- resets = <&resetc 20>; + resets = <&rstctrl MT7628_UART2_RST>; reset-names = "uart2";
interrupt-parent = <&intc>; @@ -333,6 +342,9 @@ reg = <0x10100000 0x10000 0x10110000 0x8000>;
+ resets = <&rstctrl MT7628_EPHY_RST>; + reset-names = "ephy"; + syscon = <&sysc>; };
@@ -343,8 +355,8 @@ #phy-cells = <0>;
ralink,sysctl = <&sysc>; - resets = <&resetc 22 &resetc 25>; - reset-names = "host", "device"; + resets = <&rstctrl MT7628_UPHY_RST>; + reset-names = "phy"; };
ehci@101c0000 {

On 28.08.19 08:37, Weijie Gao wrote:
This patch updates reset controller node for mt7628
Signed-off-by: Weijie Gao weijie.gao@mediatek.com
arch/mips/dts/mt7628a.dtsi | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-)
diff --git a/arch/mips/dts/mt7628a.dtsi b/arch/mips/dts/mt7628a.dtsi index f07de1b611..0e2b6598ea 100644 --- a/arch/mips/dts/mt7628a.dtsi +++ b/arch/mips/dts/mt7628a.dtsi @@ -1,4 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 +#include <dt-bindings/reset/mt7628-reset.h>
/ { #address-cells = <1>; @@ -16,11 +17,6 @@ }; };
- resetc: reset-controller {
compatible = "ralink,rt2880-reset";
#reset-cells = <1>;
- };
- cpuintc: interrupt-controller { #address-cells = <0>; #interrupt-cells = <1>;
@@ -48,6 +44,12 @@ mask = <0x1>; };
rstctrl: rstctrl@0x34 {
reg = <0x34 0x4>;
compatible = "mediatek,mtmips-reset";
#reset-cells = <1>;
};
- pinctrl: pinctrl@60 { compatible = "mediatek,mt7628-pinctrl"; reg = <0x3c 0x2c>, <0x1300 0x100>;
@@ -202,7 +204,7 @@ compatible = "ralink,mt7628a-wdt", "mediatek,mt7621-wdt"; reg = <0x100 0x30>;
resets = <&resetc 8>;
resets = <&rstctrl MT7628_TIMER_RST>;
I like this patch. But we should always keep in mind to stay in sync (or sync in the future) with the Linux DT sources. And in Linux currently, its the "old" syntax that you are removing with this patch.
Do you plan to update the Linux DT as well, so that the bindings match again?
Thanks, Stefan

On Wed, 2019-08-28 at 15:18 +0200, Stefan Roese wrote:
On 28.08.19 08:37, Weijie Gao wrote:
This patch updates reset controller node for mt7628
Signed-off-by: Weijie Gao weijie.gao@mediatek.com
arch/mips/dts/mt7628a.dtsi | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-)
diff --git a/arch/mips/dts/mt7628a.dtsi b/arch/mips/dts/mt7628a.dtsi index f07de1b611..0e2b6598ea 100644 --- a/arch/mips/dts/mt7628a.dtsi +++ b/arch/mips/dts/mt7628a.dtsi @@ -1,4 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 +#include <dt-bindings/reset/mt7628-reset.h>
/ { #address-cells = <1>; @@ -16,11 +17,6 @@ }; };
- resetc: reset-controller {
compatible = "ralink,rt2880-reset";
#reset-cells = <1>;
- };
- cpuintc: interrupt-controller { #address-cells = <0>; #interrupt-cells = <1>;
@@ -48,6 +44,12 @@ mask = <0x1>; };
rstctrl: rstctrl@0x34 {
reg = <0x34 0x4>;
compatible = "mediatek,mtmips-reset";
#reset-cells = <1>;
};
- pinctrl: pinctrl@60 { compatible = "mediatek,mt7628-pinctrl"; reg = <0x3c 0x2c>, <0x1300 0x100>;
@@ -202,7 +204,7 @@ compatible = "ralink,mt7628a-wdt", "mediatek,mt7621-wdt"; reg = <0x100 0x30>;
resets = <&resetc 8>;
resets = <&rstctrl MT7628_TIMER_RST>;
I like this patch. But we should always keep in mind to stay in sync (or sync in the future) with the Linux DT sources. And in Linux currently, its the "old" syntax that you are removing with this patch.
Do you plan to update the Linux DT as well, so that the bindings match again?
Thanks, Stefan
I agree with that. At lease a reset controller won't make things complex.

I am having problems with this patch.
Problem is "reset"command fails (for my board) with:
=> reset resetting ... ### ERROR ### Please RESET the board ###
I traced down problem to "drivers/sysreset/sysreset-uclass.c" requesting "uclass_first_device(UCLASS_SYSRESET, &dev)", while "drivers/reset/reset-mips.c" defines:
static const struct udevice_id mtmips_reset_ids[] = { { .compatible = "mediatek,mtmips-reset" }, { } };
U_BOOT_DRIVER(mtmips_reset) = { .name = "mtmips-reset", .id = UCLASS_RESET,
... so UCLASS_SYSRESET list is empty.
What am I doing wrong? TiA! Mauro

Am 30.12.19 um 10:19 schrieb Mauro Condarelli:
I am having problems with this patch.
Problem is "reset"command fails (for my board) with:
=> reset resetting ... ### ERROR ### Please RESET the board ###
I traced down problem to "drivers/sysreset/sysreset-uclass.c" requesting "uclass_first_device(UCLASS_SYSRESET, &dev)", while "drivers/reset/reset-mips.c" defines:
static const struct udevice_id mtmips_reset_ids[] = { { .compatible = "mediatek,mtmips-reset" }, { } };
U_BOOT_DRIVER(mtmips_reset) = { .name = "mtmips-reset", .id = UCLASS_RESET,
... so UCLASS_SYSRESET list is empty.
What am I doing wrong? TiA! Mauro
do you have the according node with compatible string "mediatek,mtmips-reset" in your device-tree?

On 12/30/19 11:22 AM, Daniel Schwierzeck wrote:
Am 30.12.19 um 10:19 schrieb Mauro Condarelli:
I am having problems with this patch.
Problem is "reset"command fails (for my board) with:
=> reset resetting ... ### ERROR ### Please RESET the board ###
I traced down problem to "drivers/sysreset/sysreset-uclass.c" requesting "uclass_first_device(UCLASS_SYSRESET, &dev)", while "drivers/reset/reset-mips.c" defines:
static const struct udevice_id mtmips_reset_ids[] = { { .compatible = "mediatek,mtmips-reset" }, { } };
U_BOOT_DRIVER(mtmips_reset) = { .name = "mtmips-reset", .id = UCLASS_RESET,
... so UCLASS_SYSRESET list is empty.
What am I doing wrong? TiA! Mauro
do you have the according node with compatible string "mediatek,mtmips-reset" in your device-tree?
I have the standard mt7628a.dtsi contents:
... palmbus@10000000 { compatible = "palmbus", "simple-bus"; reg = <0x10000000 0x200000>; ranges = <0x0 0x10000000 0x1FFFFF>; ... rstctrl: rstctrl@0x34 { reg = <0x34 0x4>; compatible = "mediatek,mtmips-reset"; #reset-cells = <1>; }; ...
I tried adding the "old-style": ... resetc: reset-controller { compatible = "ralink,rt2880-reset"; #reset-cells = <1>; }; ... but, apparently, it makes no difference.
Shouldn't that be enough?
TiA MAuro

On 12/30/19 11:22 AM, Daniel Schwierzeck wrote:
Am 30.12.19 um 10:19 schrieb Mauro Condarelli:
I am having problems with this patch.
Problem is "reset"command fails (for my board) with:
=> reset resetting ... ### ERROR ### Please RESET the board ###
I traced down problem to "drivers/sysreset/sysreset-uclass.c" requesting "uclass_first_device(UCLASS_SYSRESET, &dev)", while "drivers/reset/reset-mips.c" defines:
static const struct udevice_id mtmips_reset_ids[] = { { .compatible = "mediatek,mtmips-reset" }, { } };
U_BOOT_DRIVER(mtmips_reset) = { .name = "mtmips-reset", .id = UCLASS_RESET,
... so UCLASS_SYSRESET list is empty.
What am I doing wrong? TiA! Mauro
do you have the according node with compatible string "mediatek,mtmips-reset" in your device-tree?
Yes, I do, but problem is elsewhere: "reset" command looks for a UCLASS_SYSRESET while drivers/reset/reset-mips.c (implementing "mediatek,mtmips-reset") provides a UCLASS_RESET.
I know too little about u-boot internals to understand which one I should "fix" (if any).
Thanks Mauro

Hi Mauro,
On 30.12.19 13:14, Mauro Condarelli wrote:
On 12/30/19 11:22 AM, Daniel Schwierzeck wrote:
Am 30.12.19 um 10:19 schrieb Mauro Condarelli:
I am having problems with this patch.
Problem is "reset"command fails (for my board) with:
=> reset resetting ... ### ERROR ### Please RESET the board ###
I traced down problem to "drivers/sysreset/sysreset-uclass.c" requesting "uclass_first_device(UCLASS_SYSRESET, &dev)", while "drivers/reset/reset-mips.c" defines:
static const struct udevice_id mtmips_reset_ids[] = { { .compatible = "mediatek,mtmips-reset" }, { } };
U_BOOT_DRIVER(mtmips_reset) = { .name = "mtmips-reset", .id = UCLASS_RESET,
... so UCLASS_SYSRESET list is empty.
What am I doing wrong? TiA! Mauro
do you have the according node with compatible string "mediatek,mtmips-reset" in your device-tree?
Yes, I do, but problem is elsewhere: "reset" command looks for a UCLASS_SYSRESET while drivers/reset/reset-mips.c (implementing "mediatek,mtmips-reset") provides a UCLASS_RESET.
I know too little about u-boot internals to understand which one I should "fix" (if any).
I just tested current mainline U-Boot (top-of-tree) on the GARDENA board and the reset works just fine:
=> reset resetting ...
U-Boot 2020.01-rc5-00042-g6cb87cbb14 (Jan 02 2020 - 13:27:15 +0100)
CPU: MT7628 Rev 1.2 - Boot from XTAL (3-Byte SPI Addr) Model: GARDENA smart Gateway (MT7688) DRAM: 128 MiB WDT: Started with servicing (60s timeout) Loading Environment from SPI Flash... SF: Detected XM25QH64A with page size 256 Bytes, erase size 4 KiB, total 8 MiB OK F-Data:factory-data version 1 detected Net: eth0: eth@10110000 Hit any key to stop autoboot: 0
I didn't check the details of this mail thread, so I can't really comment on this. Your board is so similar to the GARDENA one (LinkIt) that it should work there as well. Do you gave some differences in your defconfig?
Thanks, Stefan

On 1/2/20 1:30 PM, Stefan Roese wrote:
Hi Mauro,
On 30.12.19 13:14, Mauro Condarelli wrote:
On 12/30/19 11:22 AM, Daniel Schwierzeck wrote:
Am 30.12.19 um 10:19 schrieb Mauro Condarelli:
I am having problems with this patch.
Problem is "reset"command fails (for my board) with:
=> reset resetting ... ### ERROR ### Please RESET the board ###
I traced down problem to "drivers/sysreset/sysreset-uclass.c" requesting "uclass_first_device(UCLASS_SYSRESET, &dev)", while "drivers/reset/reset-mips.c" defines:
static const struct udevice_id mtmips_reset_ids[] = { { .compatible = "mediatek,mtmips-reset" }, { } };
U_BOOT_DRIVER(mtmips_reset) = { .name = "mtmips-reset", .id = UCLASS_RESET,
... so UCLASS_SYSRESET list is empty.
What am I doing wrong? TiA! Mauro
do you have the according node with compatible string "mediatek,mtmips-reset" in your device-tree?
Yes, I do, but problem is elsewhere: "reset" command looks for a UCLASS_SYSRESET while drivers/reset/reset-mips.c (implementing "mediatek,mtmips-reset") provides a UCLASS_RESET.
I know too little about u-boot internals to understand which one I should "fix" (if any).
I just tested current mainline U-Boot (top-of-tree) on the GARDENA board and the reset works just fine:
=> reset resetting ...
U-Boot 2020.01-rc5-00042-g6cb87cbb14 (Jan 02 2020 - 13:27:15 +0100)
CPU: MT7628 Rev 1.2 - Boot from XTAL (3-Byte SPI Addr) Model: GARDENA smart Gateway (MT7688) DRAM: 128 MiB WDT: Started with servicing (60s timeout) Loading Environment from SPI Flash... SF: Detected XM25QH64A with page size 256 Bytes, erase size 4 KiB, total 8 MiB OK F-Data:factory-data version 1 detected Net: eth0: eth@10110000 Hit any key to stop autoboot: 0
I didn't check the details of this mail thread, so I can't really comment on this. Your board is so similar to the GARDENA one (LinkIt) that it should work there as well. Do you gave some differences in your defconfig?
My defconfig looks very different, mainly due to not having (currently) any network in u-boot, but I have USB strorage. I attach the whole vocore2_defconfig. To me it seems the only difference that *might* be relevant is I don't have CONFIG_SYSRESET_SYSCON=y. ... enable... compile... load... test... SUCCESS!! That was it. I was thinking reset should have been handled by "reset-mtmips.c" but apparently "mfd syscon reboot driver" is needed. THANKS. I'll send another iteration of my patches soon after a bit of testing.
Thanks, Stefan
Regards Mauro

This patch adds clock gating driver for MediaTek MIPS platform
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- drivers/clk/Kconfig | 8 ++++ drivers/clk/Makefile | 1 + drivers/clk/clk-mtmips-cg.c | 63 ++++++++++++++++++++++++++++ include/dt-bindings/clk/mt7628-clk.h | 31 ++++++++++++++ 4 files changed, 103 insertions(+) create mode 100644 drivers/clk/clk-mtmips-cg.c create mode 100644 include/dt-bindings/clk/mt7628-clk.h
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 95fe0aea2c..0762a42476 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -160,4 +160,12 @@ config SANDBOX_CLK_CCF Enable this option if you want to test the Linux kernel's Common Clock Framework [CCF] code in U-Boot's Sandbox clock driver.
+config CLK_MTMIPS_GATE + bool "Enable clock gating driver for MediaTek MIPS platform" + depends on CLK && ARCH_MTMIPS + default y + help + Enable clock gating driver for MediaTek MIPS platform. + This driver supports only clock enable and disable. + endmenu diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 68aabe1ca9..353974d784 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_CLK_BOSTON) += clk_boston.o obj-$(CONFIG_CLK_EXYNOS) += exynos/ obj-$(CONFIG_CLK_HSDK) += clk-hsdk-cgu.o obj-$(CONFIG_CLK_MPC83XX) += mpc83xx_clk.o +obj-$(CONFIG_CLK_MTMIPS_GATE) += clk-mtmips-cg.o obj-$(CONFIG_CLK_OWL) += owl/ obj-$(CONFIG_CLK_RENESAS) += renesas/ obj-$(CONFIG_CLK_SIFIVE) += sifive/ diff --git a/drivers/clk/clk-mtmips-cg.c b/drivers/clk/clk-mtmips-cg.c new file mode 100644 index 0000000000..0221d95aed --- /dev/null +++ b/drivers/clk/clk-mtmips-cg.c @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 MediaTek Inc. All Rights Reserved. + * + * Author: Weijie Gao weijie.gao@mediatek.com + */ + +#include <common.h> +#include <clk-uclass.h> +#include <dm.h> +#include <asm/io.h> + +struct mtmips_clk_gate_priv { + void __iomem *base; +}; + +static int mtmips_clk_gate_enable(struct clk *clk) +{ + struct mtmips_clk_gate_priv *priv = dev_get_priv(clk->dev); + + setbits_32(priv->base, BIT(clk->id)); + + return 0; +} + +static int mtmips_clk_gate_disable(struct clk *clk) +{ + struct mtmips_clk_gate_priv *priv = dev_get_priv(clk->dev); + + clrbits_32(priv->base, BIT(clk->id)); + + return 0; +} + +const struct clk_ops mtmips_clk_gate_ops = { + .enable = mtmips_clk_gate_enable, + .disable = mtmips_clk_gate_disable, +}; + +static int mtmips_clk_gate_probe(struct udevice *dev) +{ + struct mtmips_clk_gate_priv *priv = dev_get_priv(dev); + + priv->base = (void __iomem *)dev_remap_addr_index(dev, 0); + if (!priv->base) + return -EINVAL; + + return 0; +} + +static const struct udevice_id mtmips_clk_gate_ids[] = { + { .compatible = "mediatek,mtmips-clk-gate" }, + { } +}; + +U_BOOT_DRIVER(mtmips_clk_gate) = { + .name = "mtmips-clk-gate", + .id = UCLASS_CLK, + .of_match = mtmips_clk_gate_ids, + .probe = mtmips_clk_gate_probe, + .priv_auto_alloc_size = sizeof(struct mtmips_clk_gate_priv), + .ops = &mtmips_clk_gate_ops, +}; diff --git a/include/dt-bindings/clk/mt7628-clk.h b/include/dt-bindings/clk/mt7628-clk.h new file mode 100644 index 0000000000..6784d6e50b --- /dev/null +++ b/include/dt-bindings/clk/mt7628-clk.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * Author: Weijie Gao weijie.gao@mediatek.com + */ + +#ifndef _DT_BINDINGS_MT7628_CLK_H_ +#define _DT_BINDINGS_MT7628_CLK_H_ + +#define MT7628_PWM_CLK 31 +#define MT7628_SDXC_CLK 30 +#define MT7628_CRYPTO_CLK 29 +#define MT7628_MIPS_CNT_CLK 28 +#define MT7628_PCIE_CLK 26 +#define MT7628_UPHY_CLK 25 +#define MT7628_ETH_CLK 23 +#define MT7628_UART2_CLK 20 +#define MT7628_UART1_CLK 19 +#define MT7628_SPI_CLK 18 +#define MT7628_I2S_CLK 17 +#define MT7628_I2C_CLK 16 +#define MT7628_GDMA_CLK 14 +#define MT7628_PIO_CLK 13 +#define MT7628_UART0_CLK 12 +#define MT7628_PCM_CLK 11 +#define MT7628_MC_CLK 10 +#define MT7628_INT_CLK 9 +#define MT7628_TIMER_CLK 8 + +#endif /* _DT_BINDINGS_MT7628_CLK_H_ */

Am 28.08.19 um 08:37 schrieb Weijie Gao:
This patch adds clock gating driver for MediaTek MIPS platform
Signed-off-by: Weijie Gao weijie.gao@mediatek.com
drivers/clk/Kconfig | 8 ++++ drivers/clk/Makefile | 1 + drivers/clk/clk-mtmips-cg.c | 63 ++++++++++++++++++++++++++++ include/dt-bindings/clk/mt7628-clk.h | 31 ++++++++++++++ 4 files changed, 103 insertions(+) create mode 100644 drivers/clk/clk-mtmips-cg.c create mode 100644 include/dt-bindings/clk/mt7628-clk.h
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 95fe0aea2c..0762a42476 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -160,4 +160,12 @@ config SANDBOX_CLK_CCF Enable this option if you want to test the Linux kernel's Common Clock Framework [CCF] code in U-Boot's Sandbox clock driver.
+config CLK_MTMIPS_GATE
- bool "Enable clock gating driver for MediaTek MIPS platform"
- depends on CLK && ARCH_MTMIPS
- default y
- help
Enable clock gating driver for MediaTek MIPS platform.
This driver supports only clock enable and disable.
endmenu diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 68aabe1ca9..353974d784 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_CLK_BOSTON) += clk_boston.o obj-$(CONFIG_CLK_EXYNOS) += exynos/ obj-$(CONFIG_CLK_HSDK) += clk-hsdk-cgu.o obj-$(CONFIG_CLK_MPC83XX) += mpc83xx_clk.o +obj-$(CONFIG_CLK_MTMIPS_GATE) += clk-mtmips-cg.o obj-$(CONFIG_CLK_OWL) += owl/ obj-$(CONFIG_CLK_RENESAS) += renesas/ obj-$(CONFIG_CLK_SIFIVE) += sifive/ diff --git a/drivers/clk/clk-mtmips-cg.c b/drivers/clk/clk-mtmips-cg.c new file mode 100644 index 0000000000..0221d95aed --- /dev/null +++ b/drivers/clk/clk-mtmips-cg.c @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-2.0 +/*
- Copyright (C) 2019 MediaTek Inc. All Rights Reserved.
- Author: Weijie Gao weijie.gao@mediatek.com
- */
+#include <common.h> +#include <clk-uclass.h> +#include <dm.h> +#include <asm/io.h>
+struct mtmips_clk_gate_priv {
- void __iomem *base;
+};
+static int mtmips_clk_gate_enable(struct clk *clk) +{
- struct mtmips_clk_gate_priv *priv = dev_get_priv(clk->dev);
- setbits_32(priv->base, BIT(clk->id));
- return 0;
+}
+static int mtmips_clk_gate_disable(struct clk *clk) +{
- struct mtmips_clk_gate_priv *priv = dev_get_priv(clk->dev);
- clrbits_32(priv->base, BIT(clk->id));
- return 0;
+}
+const struct clk_ops mtmips_clk_gate_ops = {
- .enable = mtmips_clk_gate_enable,
- .disable = mtmips_clk_gate_disable,
+};
the generic clk-gate.c driver already supports this simple register bit toggling. Why don't you use that one?
+static int mtmips_clk_gate_probe(struct udevice *dev) +{
- struct mtmips_clk_gate_priv *priv = dev_get_priv(dev);
- priv->base = (void __iomem *)dev_remap_addr_index(dev, 0);
- if (!priv->base)
return -EINVAL;
- return 0;
+}
+static const struct udevice_id mtmips_clk_gate_ids[] = {
- { .compatible = "mediatek,mtmips-clk-gate" },
- { }
+};
+U_BOOT_DRIVER(mtmips_clk_gate) = {
- .name = "mtmips-clk-gate",
- .id = UCLASS_CLK,
- .of_match = mtmips_clk_gate_ids,
- .probe = mtmips_clk_gate_probe,
- .priv_auto_alloc_size = sizeof(struct mtmips_clk_gate_priv),
- .ops = &mtmips_clk_gate_ops,
+}; diff --git a/include/dt-bindings/clk/mt7628-clk.h b/include/dt-bindings/clk/mt7628-clk.h new file mode 100644 index 0000000000..6784d6e50b --- /dev/null +++ b/include/dt-bindings/clk/mt7628-clk.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/*
- Copyright (C) 2019 MediaTek Inc.
- Author: Weijie Gao weijie.gao@mediatek.com
- */
+#ifndef _DT_BINDINGS_MT7628_CLK_H_ +#define _DT_BINDINGS_MT7628_CLK_H_
+#define MT7628_PWM_CLK 31 +#define MT7628_SDXC_CLK 30 +#define MT7628_CRYPTO_CLK 29 +#define MT7628_MIPS_CNT_CLK 28 +#define MT7628_PCIE_CLK 26 +#define MT7628_UPHY_CLK 25 +#define MT7628_ETH_CLK 23 +#define MT7628_UART2_CLK 20 +#define MT7628_UART1_CLK 19 +#define MT7628_SPI_CLK 18 +#define MT7628_I2S_CLK 17 +#define MT7628_I2C_CLK 16 +#define MT7628_GDMA_CLK 14 +#define MT7628_PIO_CLK 13 +#define MT7628_UART0_CLK 12 +#define MT7628_PCM_CLK 11 +#define MT7628_MC_CLK 10 +#define MT7628_INT_CLK 9 +#define MT7628_TIMER_CLK 8
+#endif /* _DT_BINDINGS_MT7628_CLK_H_ */

On Wed, 2019-08-28 at 15:24 +0200, Daniel Schwierzeck wrote:
Am 28.08.19 um 08:37 schrieb Weijie Gao:
This patch adds clock gating driver for MediaTek MIPS platform
Signed-off-by: Weijie Gao weijie.gao@mediatek.com
drivers/clk/Kconfig | 8 ++++ drivers/clk/Makefile | 1 + drivers/clk/clk-mtmips-cg.c | 63 ++++++++++++++++++++++++++++ include/dt-bindings/clk/mt7628-clk.h | 31 ++++++++++++++ 4 files changed, 103 insertions(+) create mode 100644 drivers/clk/clk-mtmips-cg.c create mode 100644 include/dt-bindings/clk/mt7628-clk.h
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 95fe0aea2c..0762a42476 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -160,4 +160,12 @@ config SANDBOX_CLK_CCF Enable this option if you want to test the Linux kernel's Common Clock Framework [CCF] code in U-Boot's Sandbox clock driver.
+config CLK_MTMIPS_GATE
- bool "Enable clock gating driver for MediaTek MIPS platform"
- depends on CLK && ARCH_MTMIPS
- default y
- help
Enable clock gating driver for MediaTek MIPS platform.
This driver supports only clock enable and disable.
endmenu diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 68aabe1ca9..353974d784 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_CLK_BOSTON) += clk_boston.o obj-$(CONFIG_CLK_EXYNOS) += exynos/ obj-$(CONFIG_CLK_HSDK) += clk-hsdk-cgu.o obj-$(CONFIG_CLK_MPC83XX) += mpc83xx_clk.o +obj-$(CONFIG_CLK_MTMIPS_GATE) += clk-mtmips-cg.o obj-$(CONFIG_CLK_OWL) += owl/ obj-$(CONFIG_CLK_RENESAS) += renesas/ obj-$(CONFIG_CLK_SIFIVE) += sifive/ diff --git a/drivers/clk/clk-mtmips-cg.c b/drivers/clk/clk-mtmips-cg.c new file mode 100644 index 0000000000..0221d95aed --- /dev/null +++ b/drivers/clk/clk-mtmips-cg.c @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-2.0 +/*
- Copyright (C) 2019 MediaTek Inc. All Rights Reserved.
- Author: Weijie Gao weijie.gao@mediatek.com
- */
+#include <common.h> +#include <clk-uclass.h> +#include <dm.h> +#include <asm/io.h>
+struct mtmips_clk_gate_priv {
- void __iomem *base;
+};
+static int mtmips_clk_gate_enable(struct clk *clk) +{
- struct mtmips_clk_gate_priv *priv = dev_get_priv(clk->dev);
- setbits_32(priv->base, BIT(clk->id));
- return 0;
+}
+static int mtmips_clk_gate_disable(struct clk *clk) +{
- struct mtmips_clk_gate_priv *priv = dev_get_priv(clk->dev);
- clrbits_32(priv->base, BIT(clk->id));
- return 0;
+}
+const struct clk_ops mtmips_clk_gate_ops = {
- .enable = mtmips_clk_gate_enable,
- .disable = mtmips_clk_gate_disable,
+};
the generic clk-gate.c driver already supports this simple register bit toggling. Why don't you use that one?
+static int mtmips_clk_gate_probe(struct udevice *dev) +{
- struct mtmips_clk_gate_priv *priv = dev_get_priv(dev);
- priv->base = (void __iomem *)dev_remap_addr_index(dev, 0);
- if (!priv->base)
return -EINVAL;
- return 0;
+}
+static const struct udevice_id mtmips_clk_gate_ids[] = {
- { .compatible = "mediatek,mtmips-clk-gate" },
- { }
+};
+U_BOOT_DRIVER(mtmips_clk_gate) = {
- .name = "mtmips-clk-gate",
- .id = UCLASS_CLK,
- .of_match = mtmips_clk_gate_ids,
- .probe = mtmips_clk_gate_probe,
- .priv_auto_alloc_size = sizeof(struct mtmips_clk_gate_priv),
- .ops = &mtmips_clk_gate_ops,
+}; diff --git a/include/dt-bindings/clk/mt7628-clk.h b/include/dt-bindings/clk/mt7628-clk.h new file mode 100644 index 0000000000..6784d6e50b --- /dev/null +++ b/include/dt-bindings/clk/mt7628-clk.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/*
- Copyright (C) 2019 MediaTek Inc.
- Author: Weijie Gao weijie.gao@mediatek.com
- */
+#ifndef _DT_BINDINGS_MT7628_CLK_H_ +#define _DT_BINDINGS_MT7628_CLK_H_
+#define MT7628_PWM_CLK 31 +#define MT7628_SDXC_CLK 30 +#define MT7628_CRYPTO_CLK 29 +#define MT7628_MIPS_CNT_CLK 28 +#define MT7628_PCIE_CLK 26 +#define MT7628_UPHY_CLK 25 +#define MT7628_ETH_CLK 23 +#define MT7628_UART2_CLK 20 +#define MT7628_UART1_CLK 19 +#define MT7628_SPI_CLK 18 +#define MT7628_I2S_CLK 17 +#define MT7628_I2C_CLK 16 +#define MT7628_GDMA_CLK 14 +#define MT7628_PIO_CLK 13 +#define MT7628_UART0_CLK 12 +#define MT7628_PCM_CLK 11 +#define MT7628_MC_CLK 10 +#define MT7628_INT_CLK 9 +#define MT7628_TIMER_CLK 8
+#endif /* _DT_BINDINGS_MT7628_CLK_H_ */
I've written this driver in the early July, before clk-gate was added. I didn't notice this driver yesterday. I will try to switch to clk-gate.

This patch adds clkgate node for mt7628 and adds clock gate property for usb phy node.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- arch/mips/dts/mt7628a.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/arch/mips/dts/mt7628a.dtsi b/arch/mips/dts/mt7628a.dtsi index 0e2b6598ea..dd11cac28c 100644 --- a/arch/mips/dts/mt7628a.dtsi +++ b/arch/mips/dts/mt7628a.dtsi @@ -1,4 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 +#include <dt-bindings/clk/mt7628-clk.h> #include <dt-bindings/reset/mt7628-reset.h>
/ { @@ -44,6 +45,12 @@ mask = <0x1>; };
+ clkgate: clkgate@0x30 { + reg = <0x30 0x4>; + compatible = "mediatek,mtmips-clk-gate"; + #clock-cells = <1>; + }; + rstctrl: rstctrl@0x34 { reg = <0x34 0x4>; compatible = "mediatek,mtmips-reset"; @@ -357,6 +364,9 @@ ralink,sysctl = <&sysc>; resets = <&rstctrl MT7628_UPHY_RST>; reset-names = "phy"; + + clocks = <&clkgate MT7628_UPHY_CLK>; + clock-names = "cg"; };
ehci@101c0000 {

This patch adds slew rate calibration for mt76x8-usb-phy, removes code which belongs to mt7620, and gets rid of using syscon and regmap by using clock driver and reset controller.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- drivers/phy/Kconfig | 2 + drivers/phy/mt76x8-usb-phy.c | 225 ++++++++++++++++++++++++----------- 2 files changed, 159 insertions(+), 68 deletions(-)
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 02312273e2..5c7b221431 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -200,6 +200,8 @@ config KEYSTONE_USB_PHY config MT76X8_USB_PHY bool "MediaTek MT76x8 (7628/88) USB PHY support" depends on PHY + select CLK + select DM_RESET help Support the USB PHY in MT76x8 SoCs
diff --git a/drivers/phy/mt76x8-usb-phy.c b/drivers/phy/mt76x8-usb-phy.c index 268da8ef6c..1e7c5f334b 100644 --- a/drivers/phy/mt76x8-usb-phy.c +++ b/drivers/phy/mt76x8-usb-phy.c @@ -6,93 +6,185 @@ * Copyright (C) 2017 John Crispin john@phrozen.org */
+#include <clk.h> #include <common.h> #include <dm.h> #include <generic-phy.h> -#include <regmap.h> -#include <reset-uclass.h> -#include <syscon.h> +#include <reset.h> #include <asm/io.h> - -#define RT_SYSC_REG_SYSCFG1 0x014 -#define RT_SYSC_REG_CLKCFG1 0x030 -#define RT_SYSC_REG_USB_PHY_CFG 0x05c +#include <linux/bitops.h>
#define OFS_U2_PHY_AC0 0x800 +#define USBPLL_FBDIV_S 16 +#define USBPLL_FBDIV_M GENMASK(22, 16) +#define BG_TRIM_S 8 +#define BG_TRIM_M GENMASK(11, 8) +#define BG_RBSEL_S 6 +#define BG_RBSEL_M GENMASK(7, 6) +#define BG_RASEL_S 4 +#define BG_RASEL_M GENMASK(5, 4) +#define BGR_DIV_S 2 +#define BGR_DIV_M GENMASK(3, 2) +#define CHP_EN BIT(1) + #define OFS_U2_PHY_AC1 0x804 +#define VRT_VREF_SEL_S 28 +#define VRT_VREF_SEL_M GENMASK(30, 28) +#define TERM_VREF_SEL_S 24 +#define TERM_VREF_SEL_M GENMASK(26, 24) +#define USBPLL_RSVD BIT(4) +#define USBPLL_ACCEN BIT(3) +#define USBPLL_LF BIT(2) + #define OFS_U2_PHY_AC2 0x808 + #define OFS_U2_PHY_ACR0 0x810 -#define OFS_U2_PHY_ACR1 0x814 -#define OFS_U2_PHY_ACR2 0x818 +#define HSTX_SRCAL_EN BIT(23) +#define HSTX_SRCTRL_S 16 +#define HSTX_SRCTRL_M GENMASK(18, 16) + #define OFS_U2_PHY_ACR3 0x81C -#define OFS_U2_PHY_ACR4 0x820 -#define OFS_U2_PHY_AMON0 0x824 +#define HSTX_DBIST_S 28 +#define HSTX_DBIST_M GENMASK(31, 28) +#define HSRX_BIAS_EN_SEL_S 20 +#define HSRX_BIAS_EN_SEL_M GENMASK(21, 20) + #define OFS_U2_PHY_DCR0 0x860 -#define OFS_U2_PHY_DCR1 0x864 +#define PHYD_RESERVE_S 8 +#define PHYD_RESERVE_M GENMASK(23, 8) +#define CDR_FILT_S 0 +#define CDR_FILT_M GENMASK(3, 0) + #define OFS_U2_PHY_DTM0 0x868 -#define OFS_U2_PHY_DTM1 0x86C +#define FORCE_USB_CLKEN BIT(25) + +#define OFS_FM_CR0 0xf00 +#define FREQDET_EN BIT(24) +#define CYCLECNT_S 0 +#define CYCLECNT_M GENMASK(23, 0)
-#define RT_RSTCTRL_UDEV BIT(25) -#define RT_RSTCTRL_UHST BIT(22) -#define RT_SYSCFG1_USB0_HOST_MODE BIT(10) +#define OFS_FM_MONR0 0xf0c
-#define MT7620_CLKCFG1_UPHY0_CLK_EN BIT(25) -#define MT7620_CLKCFG1_UPHY1_CLK_EN BIT(22) -#define RT_CLKCFG1_UPHY1_CLK_EN BIT(20) -#define RT_CLKCFG1_UPHY0_CLK_EN BIT(18) +#define OFS_FM_MONR1 0xf10 +#define FRCK_EN BIT(8)
-#define USB_PHY_UTMI_8B60M BIT(1) -#define UDEV_WAKEUP BIT(0) +#define U2_SR_COEF_7628 32
struct mt76x8_usb_phy { - u32 clk; void __iomem *base; - struct regmap *sysctl; + struct clk cg; /* for clock gating */ + struct reset_ctl rst_phy; };
-static void u2_phy_w32(struct mt76x8_usb_phy *phy, u32 val, u32 reg) +static void phy_w32(struct mt76x8_usb_phy *phy, u32 reg, u32 val) { writel(val, phy->base + reg); }
-static u32 u2_phy_r32(struct mt76x8_usb_phy *phy, u32 reg) +static u32 phy_r32(struct mt76x8_usb_phy *phy, u32 reg) { return readl(phy->base + reg); }
+static void phy_rmw32(struct mt76x8_usb_phy *phy, u32 reg, u32 clr, u32 set) +{ + clrsetbits_32(phy->base + reg, clr, set); +} + static void mt76x8_usb_phy_init(struct mt76x8_usb_phy *phy) { - u2_phy_r32(phy, OFS_U2_PHY_AC2); - u2_phy_r32(phy, OFS_U2_PHY_ACR0); - u2_phy_r32(phy, OFS_U2_PHY_DCR0); - - u2_phy_w32(phy, 0x00ffff02, OFS_U2_PHY_DCR0); - u2_phy_r32(phy, OFS_U2_PHY_DCR0); - u2_phy_w32(phy, 0x00555502, OFS_U2_PHY_DCR0); - u2_phy_r32(phy, OFS_U2_PHY_DCR0); - u2_phy_w32(phy, 0x00aaaa02, OFS_U2_PHY_DCR0); - u2_phy_r32(phy, OFS_U2_PHY_DCR0); - u2_phy_w32(phy, 0x00000402, OFS_U2_PHY_DCR0); - u2_phy_r32(phy, OFS_U2_PHY_DCR0); - u2_phy_w32(phy, 0x0048086a, OFS_U2_PHY_AC0); - u2_phy_w32(phy, 0x4400001c, OFS_U2_PHY_AC1); - u2_phy_w32(phy, 0xc0200000, OFS_U2_PHY_ACR3); - u2_phy_w32(phy, 0x02000000, OFS_U2_PHY_DTM0); + phy_r32(phy, OFS_U2_PHY_AC2); + phy_r32(phy, OFS_U2_PHY_ACR0); + phy_r32(phy, OFS_U2_PHY_DCR0); + + phy_w32(phy, OFS_U2_PHY_DCR0, + (0xffff << PHYD_RESERVE_S) | (2 << CDR_FILT_S)); + phy_r32(phy, OFS_U2_PHY_DCR0); + + phy_w32(phy, OFS_U2_PHY_DCR0, + (0x5555 << PHYD_RESERVE_S) | (2 << CDR_FILT_S)); + phy_r32(phy, OFS_U2_PHY_DCR0); + + phy_w32(phy, OFS_U2_PHY_DCR0, + (0xaaaa << PHYD_RESERVE_S) | (2 << CDR_FILT_S)); + phy_r32(phy, OFS_U2_PHY_DCR0); + + phy_w32(phy, OFS_U2_PHY_DCR0, + (4 << PHYD_RESERVE_S) | (2 << CDR_FILT_S)); + phy_r32(phy, OFS_U2_PHY_DCR0); + + phy_w32(phy, OFS_U2_PHY_AC0, + (0x48 << USBPLL_FBDIV_S) | (8 << BG_TRIM_S) | + (1 << BG_RBSEL_S) | (2 << BG_RASEL_S) | (2 << BGR_DIV_S) | + CHP_EN); + + phy_w32(phy, OFS_U2_PHY_AC1, + (4 << VRT_VREF_SEL_S) | (4 << TERM_VREF_SEL_S) | USBPLL_RSVD | + USBPLL_ACCEN | USBPLL_LF); + + phy_w32(phy, OFS_U2_PHY_ACR3, + (12 << HSTX_DBIST_S) | (2 << HSRX_BIAS_EN_SEL_S)); + + phy_w32(phy, OFS_U2_PHY_DTM0, FORCE_USB_CLKEN); +} + +static void mt76x8_usb_phy_sr_calibrate(struct mt76x8_usb_phy *phy) +{ + u32 fmout, tmp = 4; + int i; + + /* Enable HS TX SR calibration */ + phy_rmw32(phy, OFS_U2_PHY_ACR0, 0, HSTX_SRCAL_EN); + mdelay(1); + + /* Enable free run clock */ + phy_rmw32(phy, OFS_FM_MONR1, 0, FRCK_EN); + + /* Set cycle count = 0x400 */ + phy_rmw32(phy, OFS_FM_CR0, CYCLECNT_M, 0x400 << CYCLECNT_S); + + /* Enable frequency meter */ + phy_rmw32(phy, OFS_FM_CR0, 0, FREQDET_EN); + + /* Wait for FM detection done, set timeout to 10ms */ + for (i = 0; i < 10; i++) { + fmout = phy_r32(phy, OFS_FM_MONR0); + + if (fmout) + break; + + mdelay(1); + } + + /* Disable frequency meter */ + phy_rmw32(phy, OFS_FM_CR0, FREQDET_EN, 0); + + /* Disable free run clock */ + phy_rmw32(phy, OFS_FM_MONR1, FRCK_EN, 0); + + /* Disable HS TX SR calibration */ + phy_rmw32(phy, OFS_U2_PHY_ACR0, HSTX_SRCAL_EN, 0); + mdelay(1); + + if (fmout) { + /* + * set reg = (1024 / FM_OUT) * 25 * 0.028 + * (round to the nearest digits) + */ + tmp = (((1024 * 25 * U2_SR_COEF_7628) / fmout) + 500) / 1000; + } + + phy_rmw32(phy, OFS_U2_PHY_ACR0, HSTX_SRCTRL_M, + (tmp << HSTX_SRCTRL_S) & HSTX_SRCTRL_M); }
static int mt76x8_usb_phy_power_on(struct phy *_phy) { struct mt76x8_usb_phy *phy = dev_get_priv(_phy->dev); - u32 t;
- /* enable the phy */ - regmap_update_bits(phy->sysctl, RT_SYSC_REG_CLKCFG1, - phy->clk, phy->clk); + clk_enable(&phy->cg);
- /* setup host mode */ - regmap_update_bits(phy->sysctl, RT_SYSC_REG_SYSCFG1, - RT_SYSCFG1_USB0_HOST_MODE, - RT_SYSCFG1_USB0_HOST_MODE); + reset_deassert(&phy->rst_phy);
/* * The SDK kernel had a delay of 100ms. however on device @@ -100,17 +192,8 @@ static int mt76x8_usb_phy_power_on(struct phy *_phy) */ mdelay(10);
- if (phy->base) - mt76x8_usb_phy_init(phy); - - /* print some status info */ - regmap_read(phy->sysctl, RT_SYSC_REG_USB_PHY_CFG, &t); - printf("remote usb device wakeup %s\n", - (t & UDEV_WAKEUP) ? "enabled" : "disabled"); - if (t & USB_PHY_UTMI_8B60M) - printf("UTMI 8bit 60MHz\n"); - else - printf("UTMI 16bit 30MHz\n"); + mt76x8_usb_phy_init(phy); + mt76x8_usb_phy_sr_calibrate(phy);
return 0; } @@ -119,9 +202,9 @@ static int mt76x8_usb_phy_power_off(struct phy *_phy) { struct mt76x8_usb_phy *phy = dev_get_priv(_phy->dev);
- /* disable the phy */ - regmap_update_bits(phy->sysctl, RT_SYSC_REG_CLKCFG1, - phy->clk, 0); + clk_disable(&phy->cg); + + reset_assert(&phy->rst_phy);
return 0; } @@ -129,15 +212,21 @@ static int mt76x8_usb_phy_power_off(struct phy *_phy) static int mt76x8_usb_phy_probe(struct udevice *dev) { struct mt76x8_usb_phy *phy = dev_get_priv(dev); - - phy->sysctl = syscon_regmap_lookup_by_phandle(dev, "ralink,sysctl"); - if (IS_ERR(phy->sysctl)) - return PTR_ERR(phy->sysctl); + int ret;
phy->base = dev_read_addr_ptr(dev); if (!phy->base) return -EINVAL;
+ /* clock gate */ + ret = clk_get_by_name(dev, "cg", &phy->cg); + if (ret) + return ret; + + ret = reset_get_by_name(dev, "phy", &phy->rst_phy); + if (ret) + return ret; + return 0; }

This patch removes hardcoded gpio settings as they have been replaced by pinctrl in dts, and also replaces regmap-based phy reset with a more generic reset controller.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- drivers/net/mt7628-eth.c | 45 +++++++--------------------------------- 1 file changed, 8 insertions(+), 37 deletions(-)
diff --git a/drivers/net/mt7628-eth.c b/drivers/net/mt7628-eth.c index 7833b2f47a..4675b0f003 100644 --- a/drivers/net/mt7628-eth.c +++ b/drivers/net/mt7628-eth.c @@ -18,23 +18,12 @@ #include <malloc.h> #include <miiphy.h> #include <net.h> -#include <regmap.h> -#include <syscon.h> +#include <reset.h> #include <wait_bit.h> #include <asm/io.h> #include <linux/bitfield.h> #include <linux/err.h>
-/* System controller register */ -#define MT7628_RSTCTRL_REG 0x34 -#define RSTCTRL_EPHY_RST BIT(24) - -#define MT7628_AGPIO_CFG_REG 0x3c -#define MT7628_EPHY_GPIO_AIO_EN GENMASK(20, 17) -#define MT7628_EPHY_P0_DIS BIT(16) - -#define MT7628_GPIO2_MODE_REG 0x64 - /* Ethernet frame engine register */ #define PDMA_RELATED 0x0800
@@ -137,7 +126,6 @@ struct fe_tx_dma { struct mt7628_eth_dev { void __iomem *base; /* frame engine base address */ void __iomem *eth_sw_base; /* switch base address */ - struct regmap *sysctrl_regmap; /* system-controller reg-map */
struct mii_dev *bus;
@@ -150,6 +138,8 @@ struct mt7628_eth_dev { int rx_dma_idx; /* Point to the next TXD in TXD Ring0 CPU wants to use */ int tx_dma_idx; + + struct reset_ctl rst_ephy; };
static int mdio_wait_read(struct mt7628_eth_dev *priv, u32 mask, bool mask_set) @@ -301,20 +291,9 @@ static void rt305x_esw_init(struct mt7628_eth_dev *priv) /* 1us cycle number=125 (FE's clock=125Mhz) */ writel(0x7d000000, base + MT7628_SWITCH_BMU_CTRL);
- /* Configure analog GPIO setup */ - regmap_update_bits(priv->sysctrl_regmap, MT7628_AGPIO_CFG_REG, - MT7628_EPHY_P0_DIS, MT7628_EPHY_GPIO_AIO_EN); - /* Reset PHY */ - regmap_update_bits(priv->sysctrl_regmap, MT7628_RSTCTRL_REG, - 0, RSTCTRL_EPHY_RST); - regmap_update_bits(priv->sysctrl_regmap, MT7628_RSTCTRL_REG, - RSTCTRL_EPHY_RST, 0); - mdelay(10); - - /* Set P0 EPHY LED mode */ - regmap_update_bits(priv->sysctrl_regmap, MT7628_GPIO2_MODE_REG, - 0x0ffc0ffc, 0x05540554); + reset_assert(&priv->rst_ephy); + reset_deassert(&priv->rst_ephy); mdelay(10);
mt7628_ephy_init(priv); @@ -558,7 +537,6 @@ static void mt7628_eth_stop(struct udevice *dev) static int mt7628_eth_probe(struct udevice *dev) { struct mt7628_eth_dev *priv = dev_get_priv(dev); - struct udevice *syscon; struct mii_dev *bus; int ret; int i; @@ -573,20 +551,13 @@ static int mt7628_eth_probe(struct udevice *dev) if (IS_ERR(priv->eth_sw_base)) return PTR_ERR(priv->eth_sw_base);
- /* Get system controller regmap */ - ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, - "syscon", &syscon); + /* Reset controller */ + ret = reset_get_by_name(dev, "ephy", &priv->rst_ephy); if (ret) { - pr_err("unable to find syscon device\n"); + pr_err("unable to find reset controller for ethernet PHYs\n"); return ret; }
- priv->sysctrl_regmap = syscon_get_regmap(syscon); - if (!priv->sysctrl_regmap) { - pr_err("unable to find regmap\n"); - return -ENODEV; - } - /* Put rx and tx rings into KSEG1 area (uncached) */ priv->tx_ring = (struct fe_tx_dma *) KSEG1ADDR(memalign(ARCH_DMA_MINALIGN,

On 28.08.19 08:38, Weijie Gao wrote:
This patch removes hardcoded gpio settings as they have been replaced by pinctrl in dts, and also replaces regmap-based phy reset with a more generic reset controller.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com
drivers/net/mt7628-eth.c | 45 +++++++--------------------------------- 1 file changed, 8 insertions(+), 37 deletions(-)
Very nice diffstat with this patch. :)
Reviewed-by: Stefan Roese sr@denx.de
Thanks, Stefan
diff --git a/drivers/net/mt7628-eth.c b/drivers/net/mt7628-eth.c index 7833b2f47a..4675b0f003 100644 --- a/drivers/net/mt7628-eth.c +++ b/drivers/net/mt7628-eth.c @@ -18,23 +18,12 @@ #include <malloc.h> #include <miiphy.h> #include <net.h> -#include <regmap.h> -#include <syscon.h> +#include <reset.h> #include <wait_bit.h> #include <asm/io.h> #include <linux/bitfield.h> #include <linux/err.h>
-/* System controller register */ -#define MT7628_RSTCTRL_REG 0x34 -#define RSTCTRL_EPHY_RST BIT(24)
-#define MT7628_AGPIO_CFG_REG 0x3c -#define MT7628_EPHY_GPIO_AIO_EN GENMASK(20, 17) -#define MT7628_EPHY_P0_DIS BIT(16)
-#define MT7628_GPIO2_MODE_REG 0x64
- /* Ethernet frame engine register */ #define PDMA_RELATED 0x0800
@@ -137,7 +126,6 @@ struct fe_tx_dma { struct mt7628_eth_dev { void __iomem *base; /* frame engine base address */ void __iomem *eth_sw_base; /* switch base address */
struct regmap *sysctrl_regmap; /* system-controller reg-map */
struct mii_dev *bus;
@@ -150,6 +138,8 @@ struct mt7628_eth_dev { int rx_dma_idx; /* Point to the next TXD in TXD Ring0 CPU wants to use */ int tx_dma_idx;
struct reset_ctl rst_ephy; };
static int mdio_wait_read(struct mt7628_eth_dev *priv, u32 mask, bool mask_set)
@@ -301,20 +291,9 @@ static void rt305x_esw_init(struct mt7628_eth_dev *priv) /* 1us cycle number=125 (FE's clock=125Mhz) */ writel(0x7d000000, base + MT7628_SWITCH_BMU_CTRL);
- /* Configure analog GPIO setup */
- regmap_update_bits(priv->sysctrl_regmap, MT7628_AGPIO_CFG_REG,
MT7628_EPHY_P0_DIS, MT7628_EPHY_GPIO_AIO_EN);
- /* Reset PHY */
- regmap_update_bits(priv->sysctrl_regmap, MT7628_RSTCTRL_REG,
0, RSTCTRL_EPHY_RST);
- regmap_update_bits(priv->sysctrl_regmap, MT7628_RSTCTRL_REG,
RSTCTRL_EPHY_RST, 0);
- mdelay(10);
- /* Set P0 EPHY LED mode */
- regmap_update_bits(priv->sysctrl_regmap, MT7628_GPIO2_MODE_REG,
0x0ffc0ffc, 0x05540554);
reset_assert(&priv->rst_ephy);
reset_deassert(&priv->rst_ephy); mdelay(10);
mt7628_ephy_init(priv);
@@ -558,7 +537,6 @@ static void mt7628_eth_stop(struct udevice *dev) static int mt7628_eth_probe(struct udevice *dev) { struct mt7628_eth_dev *priv = dev_get_priv(dev);
- struct udevice *syscon; struct mii_dev *bus; int ret; int i;
@@ -573,20 +551,13 @@ static int mt7628_eth_probe(struct udevice *dev) if (IS_ERR(priv->eth_sw_base)) return PTR_ERR(priv->eth_sw_base);
- /* Get system controller regmap */
- ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev,
"syscon", &syscon);
- /* Reset controller */
- ret = reset_get_by_name(dev, "ephy", &priv->rst_ephy); if (ret) {
pr_err("unable to find syscon device\n");
return ret; }pr_err("unable to find reset controller for ethernet PHYs\n");
- priv->sysctrl_regmap = syscon_get_regmap(syscon);
- if (!priv->sysctrl_regmap) {
pr_err("unable to find regmap\n");
return -ENODEV;
- }
- /* Put rx and tx rings into KSEG1 area (uncached) */ priv->tx_ring = (struct fe_tx_dma *) KSEG1ADDR(memalign(ARCH_DMA_MINALIGN,
Viele Grüße, Stefan

The mt7628 has an embedded ethernet switch (5 phy ports + 1 cpu port). Although in IOT mode only port0 is usable, the phy0 is still connected to the switch, not the ethernet gmac directly.
This patch removes these codes as we should not check only the status of phy0 because phy0 may not be linked up in router mode which has all 5 phy ports working.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- drivers/net/mt7628-eth.c | 32 -------------------------------- 1 file changed, 32 deletions(-)
diff --git a/drivers/net/mt7628-eth.c b/drivers/net/mt7628-eth.c index 4675b0f003..eef25da8a8 100644 --- a/drivers/net/mt7628-eth.c +++ b/drivers/net/mt7628-eth.c @@ -120,9 +120,6 @@ struct fe_tx_dma { #define CONFIG_DMA_STOP_TIMEOUT 100 #define CONFIG_TX_DMA_TIMEOUT 100
-#define LINK_DELAY_TIME 500 /* 500 ms */ -#define LINK_TIMEOUT 10000 /* 10 seconds */ - struct mt7628_eth_dev { void __iomem *base; /* frame engine base address */ void __iomem *eth_sw_base; /* switch base address */ @@ -437,14 +434,6 @@ static int mt7628_eth_free_pkt(struct udevice *dev, uchar *packet, int length) return 0; }
-static int phy_link_up(struct mt7628_eth_dev *priv) -{ - u32 val; - - mii_mgr_read(priv, 0x00, MII_BMSR, &val); - return !!(val & BMSR_LSTATUS); -} - static int mt7628_eth_start(struct udevice *dev) { struct mt7628_eth_dev *priv = dev_get_priv(dev); @@ -493,27 +482,6 @@ static int mt7628_eth_start(struct udevice *dev) wmb(); eth_dma_start(priv);
- /* Check if link is not up yet */ - if (!phy_link_up(priv)) { - /* Wait for link to come up */ - - printf("Waiting for link to come up ."); - for (i = 0; i < (LINK_TIMEOUT / LINK_DELAY_TIME); i++) { - mdelay(LINK_DELAY_TIME); - if (phy_link_up(priv)) { - mdelay(100); /* Ensure all is ready */ - break; - } - - printf("."); - } - - if (phy_link_up(priv)) - printf(" done\n"); - else - printf(" timeout! Trying anyways\n"); - } - /* * The integrated switch seems to queue some received ethernet * packets in some FIFO. Lets read the already queued packets

On 28.08.19 08:38, Weijie Gao wrote:
The mt7628 has an embedded ethernet switch (5 phy ports + 1 cpu port). Although in IOT mode only port0 is usable, the phy0 is still connected to the switch, not the ethernet gmac directly.
This patch removes these codes as we should not check only the status of phy0 because phy0 may not be linked up in router mode which has all 5 phy ports working.
I understand. But for those embedded targets that use the mainline code right now, this setup is exactly the one that's used. With this patch applied this "feature" of link detection of the only ethernet port is removed.
Can't we somehow change this code, that it supports both operations modes? So targets without switch functionality and targets with multiple ports (with switch functionality) can be supported? Perhaps via some DT property or at least a Kconfig option?
BTW: Do you plan to add support for a target with switch functionality? That would be just great.
Thanks, Stefan
Signed-off-by: Weijie Gao weijie.gao@mediatek.com
drivers/net/mt7628-eth.c | 32 -------------------------------- 1 file changed, 32 deletions(-)
diff --git a/drivers/net/mt7628-eth.c b/drivers/net/mt7628-eth.c index 4675b0f003..eef25da8a8 100644 --- a/drivers/net/mt7628-eth.c +++ b/drivers/net/mt7628-eth.c @@ -120,9 +120,6 @@ struct fe_tx_dma { #define CONFIG_DMA_STOP_TIMEOUT 100 #define CONFIG_TX_DMA_TIMEOUT 100
-#define LINK_DELAY_TIME 500 /* 500 ms */ -#define LINK_TIMEOUT 10000 /* 10 seconds */
- struct mt7628_eth_dev { void __iomem *base; /* frame engine base address */ void __iomem *eth_sw_base; /* switch base address */
@@ -437,14 +434,6 @@ static int mt7628_eth_free_pkt(struct udevice *dev, uchar *packet, int length) return 0; }
-static int phy_link_up(struct mt7628_eth_dev *priv) -{
- u32 val;
- mii_mgr_read(priv, 0x00, MII_BMSR, &val);
- return !!(val & BMSR_LSTATUS);
-}
- static int mt7628_eth_start(struct udevice *dev) { struct mt7628_eth_dev *priv = dev_get_priv(dev);
@@ -493,27 +482,6 @@ static int mt7628_eth_start(struct udevice *dev) wmb(); eth_dma_start(priv);
- /* Check if link is not up yet */
- if (!phy_link_up(priv)) {
/* Wait for link to come up */
printf("Waiting for link to come up .");
for (i = 0; i < (LINK_TIMEOUT / LINK_DELAY_TIME); i++) {
mdelay(LINK_DELAY_TIME);
if (phy_link_up(priv)) {
mdelay(100); /* Ensure all is ready */
break;
}
printf(".");
}
if (phy_link_up(priv))
printf(" done\n");
else
printf(" timeout! Trying anyways\n");
- }
- /*
- The integrated switch seems to queue some received ethernet
- packets in some FIFO. Lets read the already queued packets
Viele Grüße, Stefan

On Wed, 2019-08-28 at 15:37 +0200, Stefan Roese wrote:
On 28.08.19 08:38, Weijie Gao wrote:
The mt7628 has an embedded ethernet switch (5 phy ports + 1 cpu port). Although in IOT mode only port0 is usable, the phy0 is still connected to the switch, not the ethernet gmac directly.
This patch removes these codes as we should not check only the status of phy0 because phy0 may not be linked up in router mode which has all 5 phy ports working.
I understand. But for those embedded targets that use the mainline code right now, this setup is exactly the one that's used. With this patch applied this "feature" of link detection of the only ethernet port is removed.
Can't we somehow change this code, that it supports both operations modes? So targets without switch functionality and targets with multiple ports (with switch functionality) can be supported? Perhaps via some DT property or at least a Kconfig option?
BTW: Do you plan to add support for a target with switch functionality? That would be just great.
Thanks, Stefan
Signed-off-by: Weijie Gao weijie.gao@mediatek.com
drivers/net/mt7628-eth.c | 32 -------------------------------- 1 file changed, 32 deletions(-)
diff --git a/drivers/net/mt7628-eth.c b/drivers/net/mt7628-eth.c index 4675b0f003..eef25da8a8 100644 --- a/drivers/net/mt7628-eth.c +++ b/drivers/net/mt7628-eth.c @@ -120,9 +120,6 @@ struct fe_tx_dma { #define CONFIG_DMA_STOP_TIMEOUT 100 #define CONFIG_TX_DMA_TIMEOUT 100
-#define LINK_DELAY_TIME 500 /* 500 ms */ -#define LINK_TIMEOUT 10000 /* 10 seconds */
- struct mt7628_eth_dev { void __iomem *base; /* frame engine base address */ void __iomem *eth_sw_base; /* switch base address */
@@ -437,14 +434,6 @@ static int mt7628_eth_free_pkt(struct udevice *dev, uchar *packet, int length) return 0; }
-static int phy_link_up(struct mt7628_eth_dev *priv) -{
- u32 val;
- mii_mgr_read(priv, 0x00, MII_BMSR, &val);
- return !!(val & BMSR_LSTATUS);
-}
- static int mt7628_eth_start(struct udevice *dev) { struct mt7628_eth_dev *priv = dev_get_priv(dev);
@@ -493,27 +482,6 @@ static int mt7628_eth_start(struct udevice *dev) wmb(); eth_dma_start(priv);
- /* Check if link is not up yet */
- if (!phy_link_up(priv)) {
/* Wait for link to come up */
printf("Waiting for link to come up .");
for (i = 0; i < (LINK_TIMEOUT / LINK_DELAY_TIME); i++) {
mdelay(LINK_DELAY_TIME);
if (phy_link_up(priv)) {
mdelay(100); /* Ensure all is ready */
break;
}
printf(".");
}
if (phy_link_up(priv))
printf(" done\n");
else
printf(" timeout! Trying anyways\n");
- }
- /*
- The integrated switch seems to queue some received ethernet
- packets in some FIFO. Lets read the already queued packets
Viele Grüße, Stefan
I think adding a phy interface should do. I'll try to implement this.

When received a packet with an invalid length recorded in rx descriptor, we should free this rx descriptor to allow us to continue to receive following packets. Without doing so, u-boot will stuck in a dead loop trying to process this invalid rx descriptor.
This patch adds a call to mt7628_eth_free_pkt() after received an invalid packet length.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- drivers/net/mt7628-eth.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/net/mt7628-eth.c b/drivers/net/mt7628-eth.c index eef25da8a8..8ca2c66edb 100644 --- a/drivers/net/mt7628-eth.c +++ b/drivers/net/mt7628-eth.c @@ -139,6 +139,8 @@ struct mt7628_eth_dev { struct reset_ctl rst_ephy; };
+static int mt7628_eth_free_pkt(struct udevice *dev, uchar *packet, int length); + static int mdio_wait_read(struct mt7628_eth_dev *priv, u32 mask, bool mask_set) { void __iomem *base = priv->eth_sw_base; @@ -400,6 +402,7 @@ static int mt7628_eth_recv(struct udevice *dev, int flags, uchar **packetp) length = FIELD_GET(RX_DMA_PLEN0, priv->rx_ring[idx].rxd2); if (length == 0 || length > MTK_QDMA_PAGE_SIZE) { printf("%s: invalid length (%d bytes)\n", __func__, length); + mt7628_eth_free_pkt(dev, NULL, 0); return -EIO; }

On 28.08.19 08:38, Weijie Gao wrote:
When received a packet with an invalid length recorded in rx descriptor, we should free this rx descriptor to allow us to continue to receive following packets. Without doing so, u-boot will stuck in a dead loop trying to process this invalid rx descriptor.
This patch adds a call to mt7628_eth_free_pkt() after received an invalid packet length.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com
Good catch.
Reviewed-by: Stefan Roese sr@denx.de
Thanks, Stefan

This patch add support for mt7628-eth to isolate LAN/WAN ports mainly to prevent LAN devices from getting IP address from WAN.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- drivers/net/mt7628-eth.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)
diff --git a/drivers/net/mt7628-eth.c b/drivers/net/mt7628-eth.c index 8ca2c66edb..1215b24eaf 100644 --- a/drivers/net/mt7628-eth.c +++ b/drivers/net/mt7628-eth.c @@ -57,6 +57,11 @@ /* Ethernet switch register */ #define MT7628_SWITCH_FCT0 0x0008 #define MT7628_SWITCH_PFC1 0x0014 +#define MT7628_SWITCH_PVIDC0 0x0040 +#define MT7628_SWITCH_PVIDC1 0x0044 +#define MT7628_SWITCH_PVIDC2 0x0048 +#define MT7628_SWITCH_PVIDC3 0x004c +#define MT7628_SWITCH_VMSC0 0x0070 #define MT7628_SWITCH_FPA 0x0084 #define MT7628_SWITCH_SOCPC 0x008c #define MT7628_SWITCH_POC0 0x0090 @@ -137,6 +142,8 @@ struct mt7628_eth_dev { int tx_dma_idx;
struct reset_ctl rst_ephy; + + int wan_port; };
static int mt7628_eth_free_pkt(struct udevice *dev, uchar *packet, int length); @@ -269,6 +276,9 @@ static void mt7628_ephy_init(struct mt7628_eth_dev *priv) static void rt305x_esw_init(struct mt7628_eth_dev *priv) { void __iomem *base = priv->eth_sw_base; + void __iomem *reg; + u32 val = 0, pvid; + int i;
/* * FC_RLS_TH=200, FC_SET_TH=160 @@ -290,6 +300,25 @@ static void rt305x_esw_init(struct mt7628_eth_dev *priv) /* 1us cycle number=125 (FE's clock=125Mhz) */ writel(0x7d000000, base + MT7628_SWITCH_BMU_CTRL);
+ /* LAN/WAN partition, WAN port will be unusable in u-boot network */ + if (priv->wan_port >= 0 && priv->wan_port < 6) { + for (i = 0; i < 8; i++) { + pvid = i == priv->wan_port ? 2 : 1; + reg = base + MT7628_SWITCH_PVIDC0 + (i / 2) * 4; + if (i % 2 == 0) { + val = pvid; + } else { + val |= (pvid << 12); + writel(val, reg); + } + } + + val = 0xffff407f; + val |= 1 << (8 + priv->wan_port); + val &= ~(1 << priv->wan_port); + writel(val, base + MT7628_SWITCH_VMSC0); + } + /* Reset PHY */ reset_assert(&priv->rst_ephy); reset_deassert(&priv->rst_ephy); @@ -529,6 +558,9 @@ static int mt7628_eth_probe(struct udevice *dev) return ret; }
+ /* WAN port will be isolated from LAN ports */ + priv->wan_port = dev_read_u32_default(dev, "mediatek,wan-port", -1); + /* Put rx and tx rings into KSEG1 area (uncached) */ priv->tx_ring = (struct fe_tx_dma *) KSEG1ADDR(memalign(ARCH_DMA_MINALIGN,

On 28.08.19 08:38, Weijie Gao wrote:
This patch add support for mt7628-eth to isolate LAN/WAN ports mainly to
Nitpicking:
s/add/adds
prevent LAN devices from getting IP address from WAN.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com
drivers/net/mt7628-eth.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)
diff --git a/drivers/net/mt7628-eth.c b/drivers/net/mt7628-eth.c index 8ca2c66edb..1215b24eaf 100644 --- a/drivers/net/mt7628-eth.c +++ b/drivers/net/mt7628-eth.c @@ -57,6 +57,11 @@ /* Ethernet switch register */ #define MT7628_SWITCH_FCT0 0x0008 #define MT7628_SWITCH_PFC1 0x0014 +#define MT7628_SWITCH_PVIDC0 0x0040 +#define MT7628_SWITCH_PVIDC1 0x0044 +#define MT7628_SWITCH_PVIDC2 0x0048 +#define MT7628_SWITCH_PVIDC3 0x004c +#define MT7628_SWITCH_VMSC0 0x0070 #define MT7628_SWITCH_FPA 0x0084 #define MT7628_SWITCH_SOCPC 0x008c #define MT7628_SWITCH_POC0 0x0090 @@ -137,6 +142,8 @@ struct mt7628_eth_dev { int tx_dma_idx;
struct reset_ctl rst_ephy;
int wan_port; };
static int mt7628_eth_free_pkt(struct udevice *dev, uchar *packet, int length);
@@ -269,6 +276,9 @@ static void mt7628_ephy_init(struct mt7628_eth_dev *priv) static void rt305x_esw_init(struct mt7628_eth_dev *priv) { void __iomem *base = priv->eth_sw_base;
void __iomem *reg;
u32 val = 0, pvid;
int i;
/*
- FC_RLS_TH=200, FC_SET_TH=160
@@ -290,6 +300,25 @@ static void rt305x_esw_init(struct mt7628_eth_dev *priv) /* 1us cycle number=125 (FE's clock=125Mhz) */ writel(0x7d000000, base + MT7628_SWITCH_BMU_CTRL);
- /* LAN/WAN partition, WAN port will be unusable in u-boot network */
- if (priv->wan_port >= 0 && priv->wan_port < 6) {
for (i = 0; i < 8; i++) {
pvid = i == priv->wan_port ? 2 : 1;
reg = base + MT7628_SWITCH_PVIDC0 + (i / 2) * 4;
if (i % 2 == 0) {
val = pvid;
} else {
val |= (pvid << 12);
writel(val, reg);
}
}
val = 0xffff407f;
val |= 1 << (8 + priv->wan_port);
val &= ~(1 << priv->wan_port);
writel(val, base + MT7628_SWITCH_VMSC0);
- }
- /* Reset PHY */ reset_assert(&priv->rst_ephy); reset_deassert(&priv->rst_ephy);
@@ -529,6 +558,9 @@ static int mt7628_eth_probe(struct udevice *dev) return ret; }
- /* WAN port will be isolated from LAN ports */
- priv->wan_port = dev_read_u32_default(dev, "mediatek,wan-port", -1);
Where is this DT property documented? I can't find it in Linux either. We should find some other way to reference the ports. Perhaps something like done in Linux DSA?
What is your reasoning for this change? Which board / target are you supporting with this new code?
Thanks, Stefan

On Wed, 2019-08-28 at 15:46 +0200, Stefan Roese wrote:
On 28.08.19 08:38, Weijie Gao wrote:
This patch add support for mt7628-eth to isolate LAN/WAN ports mainly to
Nitpicking:
s/add/adds
prevent LAN devices from getting IP address from WAN.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com
drivers/net/mt7628-eth.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)
diff --git a/drivers/net/mt7628-eth.c b/drivers/net/mt7628-eth.c index 8ca2c66edb..1215b24eaf 100644 --- a/drivers/net/mt7628-eth.c +++ b/drivers/net/mt7628-eth.c @@ -57,6 +57,11 @@ /* Ethernet switch register */ #define MT7628_SWITCH_FCT0 0x0008 #define MT7628_SWITCH_PFC1 0x0014 +#define MT7628_SWITCH_PVIDC0 0x0040 +#define MT7628_SWITCH_PVIDC1 0x0044 +#define MT7628_SWITCH_PVIDC2 0x0048 +#define MT7628_SWITCH_PVIDC3 0x004c +#define MT7628_SWITCH_VMSC0 0x0070 #define MT7628_SWITCH_FPA 0x0084 #define MT7628_SWITCH_SOCPC 0x008c #define MT7628_SWITCH_POC0 0x0090 @@ -137,6 +142,8 @@ struct mt7628_eth_dev { int tx_dma_idx;
struct reset_ctl rst_ephy;
int wan_port; };
static int mt7628_eth_free_pkt(struct udevice *dev, uchar *packet, int length);
@@ -269,6 +276,9 @@ static void mt7628_ephy_init(struct mt7628_eth_dev *priv) static void rt305x_esw_init(struct mt7628_eth_dev *priv) { void __iomem *base = priv->eth_sw_base;
void __iomem *reg;
u32 val = 0, pvid;
int i;
/*
- FC_RLS_TH=200, FC_SET_TH=160
@@ -290,6 +300,25 @@ static void rt305x_esw_init(struct mt7628_eth_dev *priv) /* 1us cycle number=125 (FE's clock=125Mhz) */ writel(0x7d000000, base + MT7628_SWITCH_BMU_CTRL);
- /* LAN/WAN partition, WAN port will be unusable in u-boot network */
- if (priv->wan_port >= 0 && priv->wan_port < 6) {
for (i = 0; i < 8; i++) {
pvid = i == priv->wan_port ? 2 : 1;
reg = base + MT7628_SWITCH_PVIDC0 + (i / 2) * 4;
if (i % 2 == 0) {
val = pvid;
} else {
val |= (pvid << 12);
writel(val, reg);
}
}
val = 0xffff407f;
val |= 1 << (8 + priv->wan_port);
val &= ~(1 << priv->wan_port);
writel(val, base + MT7628_SWITCH_VMSC0);
- }
- /* Reset PHY */ reset_assert(&priv->rst_ephy); reset_deassert(&priv->rst_ephy);
@@ -529,6 +558,9 @@ static int mt7628_eth_probe(struct udevice *dev) return ret; }
- /* WAN port will be isolated from LAN ports */
- priv->wan_port = dev_read_u32_default(dev, "mediatek,wan-port", -1);
Where is this DT property documented? I can't find it in Linux either. We should find some other way to reference the ports. Perhaps something like done in Linux DSA?
What is your reasoning for this change? Which board / target are you supporting with this new code?
Thanks, Stefan
This is for the situation mt76x8 used as a router with more than one ethernet ports.
The mt76x8 has one switch, both LAN ports and WAN port come from it. By default the switch is in dumb switch mode after power on, which means any packet can be broadcast to any port with out restriction.
If a router powered on with both LAN cable and WAN cable plugged in, the LAN device may get IP address from upstream before the kernel setting the correct VLAN. However the IP address which is supposed to be get by the router itself. This is what we don't want to be happened.
If we're using a switch like mt7530, we can use the port matrix to isolate each port to solve this problem perfectly. You can refer to mtk_eth.c, at the end of mt7530_setup().
However mt76x8 switch core does not have the port matrix functionality, that means the VLAN must be used.
Considering you are using OpenWrt. The switch registers a switch object to swconfig (OpenWrt's switch framework). So the VLAN is set by swconfig, not the ethernet driver.
However u-boot does not have a switch framework, I have to add this directly to the ethernet driver.
The WAN port, depending on the design of the router, can be any ports from 0 to 4. So I use "mediatek,wan-port" to specify the WAN port.
If "mediatek,wan-port" is set, the WAN port is isolated from the switch. Otherwise all ports are interconnected.
Weijie

This patch adds default p0led status for all boards.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- arch/mips/dts/gardena-smart-gateway-mt7688.dts | 9 +++++++++ arch/mips/dts/linkit-smart-7688.dts | 9 +++++++++ 2 files changed, 18 insertions(+)
diff --git a/arch/mips/dts/gardena-smart-gateway-mt7688.dts b/arch/mips/dts/gardena-smart-gateway-mt7688.dts index 95675a3947..821e5bcdf8 100644 --- a/arch/mips/dts/gardena-smart-gateway-mt7688.dts +++ b/arch/mips/dts/gardena-smart-gateway-mt7688.dts @@ -85,6 +85,15 @@ }; };
+&pinctrl { + state_default: pin_state { + p0led { + groups = "p0led_a"; + function = "led"; + }; + }; +}; + &uart0 { status = "okay"; }; diff --git a/arch/mips/dts/linkit-smart-7688.dts b/arch/mips/dts/linkit-smart-7688.dts index 935315743c..7dbd909d00 100644 --- a/arch/mips/dts/linkit-smart-7688.dts +++ b/arch/mips/dts/linkit-smart-7688.dts @@ -26,6 +26,15 @@ }; };
+&pinctrl { + state_default: pin_state { + p0led { + groups = "p0led_a"; + function = "led"; + }; + }; +}; + &uart2 { status = "okay"; };

On 28.08.19 08:38, Weijie Gao wrote:
This patch adds default p0led status for all boards.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com
Reviewed-by: Stefan Roese sr@denx.de
Thanks, Stefan

This patch adds mmc support for MediaTek MT7620/MT7628 SoCs.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- drivers/mmc/Kconfig | 2 +- drivers/mmc/mtk-sd.c | 23 ++++++++++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 0ccb1ea701..564310b293 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -671,7 +671,7 @@ config FTSDC010_SDIO
config MMC_MTK bool "MediaTek SD/MMC Card Interface support" - depends on ARCH_MEDIATEK + depends on (ARCH_MEDIATEK || ARCH_MTMIPS) depends on BLK && DM_MMC depends on OF_CONTROL help diff --git a/drivers/mmc/mtk-sd.c b/drivers/mmc/mtk-sd.c index f555357af2..7069fe8948 100644 --- a/drivers/mmc/mtk-sd.c +++ b/drivers/mmc/mtk-sd.c @@ -217,6 +217,7 @@ struct mtk_sd_regs {
struct msdc_compatible { u8 clk_div_bits; + u8 sclk_cycle_shift; bool pad_tune0; bool async_fifo; bool data_tune; @@ -664,7 +665,7 @@ static int msdc_ops_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
static void msdc_set_timeout(struct msdc_host *host, u32 ns, u32 clks) { - u32 timeout, clk_ns; + u32 timeout, clk_ns, shift; u32 mode = 0;
host->timeout_ns = ns; @@ -673,10 +674,11 @@ static void msdc_set_timeout(struct msdc_host *host, u32 ns, u32 clks) if (host->sclk == 0) { timeout = 0; } else { + shift = host->dev_comp->sclk_cycle_shift; clk_ns = 1000000000UL / host->sclk; timeout = (ns + clk_ns - 1) / clk_ns + clks; /* unit is 1048576 sclk cycles */ - timeout = (timeout + (0x1 << 20) - 1) >> 20; + timeout = (timeout + (0x1 << shift) - 1) >> shift; if (host->dev_comp->clk_div_bits == 8) mode = (readl(&host->base->msdc_cfg) & MSDC_CFG_CKMOD_M) >> MSDC_CFG_CKMOD_S; @@ -1301,7 +1303,7 @@ static int msdc_drv_probe(struct udevice *dev)
host->mmc = &plat->mmc; host->timeout_ns = 100000000; - host->timeout_clks = 3 * 1048576; + host->timeout_clks = 3 * (1 << host->dev_comp->sclk_cycle_shift);
#ifdef CONFIG_PINCTRL pinctrl_select_state(dev, "default"); @@ -1374,8 +1376,20 @@ static const struct dm_mmc_ops msdc_ops = { #endif };
+static const struct msdc_compatible mt7620_compat = { + .clk_div_bits = 8, + .sclk_cycle_shift = 16, + .pad_tune0 = false, + .async_fifo = false, + .data_tune = false, + .busy_check = false, + .stop_clk_fix = false, + .enhance_rx = false +}; + static const struct msdc_compatible mt7623_compat = { .clk_div_bits = 12, + .sclk_cycle_shift = 20, .pad_tune0 = true, .async_fifo = true, .data_tune = true, @@ -1386,6 +1400,7 @@ static const struct msdc_compatible mt7623_compat = {
static const struct msdc_compatible mt8516_compat = { .clk_div_bits = 12, + .sclk_cycle_shift = 20, .pad_tune0 = true, .async_fifo = true, .data_tune = true, @@ -1395,6 +1410,7 @@ static const struct msdc_compatible mt8516_compat = {
static const struct msdc_compatible mt8183_compat = { .clk_div_bits = 12, + .sclk_cycle_shift = 20, .pad_tune0 = true, .async_fifo = true, .data_tune = true, @@ -1403,6 +1419,7 @@ static const struct msdc_compatible mt8183_compat = { };
static const struct udevice_id msdc_ids[] = { + { .compatible = "mediatek,mt7620-mmc", .data = (ulong)&mt7620_compat }, { .compatible = "mediatek,mt7623-mmc", .data = (ulong)&mt7623_compat }, { .compatible = "mediatek,mt8516-mmc", .data = (ulong)&mt8516_compat }, { .compatible = "mediatek,mt8183-mmc", .data = (ulong)&mt8183_compat },

On 28.08.19 08:38, Weijie Gao wrote:
This patch adds mmc support for MediaTek MT7620/MT7628 SoCs.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com
drivers/mmc/Kconfig | 2 +- drivers/mmc/mtk-sd.c | 23 ++++++++++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 0ccb1ea701..564310b293 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -671,7 +671,7 @@ config FTSDC010_SDIO
config MMC_MTK bool "MediaTek SD/MMC Card Interface support"
- depends on ARCH_MEDIATEK
- depends on (ARCH_MEDIATEK || ARCH_MTMIPS)
AFAIK, the braces are not necessary.
Thanks, Stefan
depends on BLK && DM_MMC depends on OF_CONTROL help diff --git a/drivers/mmc/mtk-sd.c b/drivers/mmc/mtk-sd.c index f555357af2..7069fe8948 100644 --- a/drivers/mmc/mtk-sd.c +++ b/drivers/mmc/mtk-sd.c @@ -217,6 +217,7 @@ struct mtk_sd_regs {
struct msdc_compatible { u8 clk_div_bits;
- u8 sclk_cycle_shift; bool pad_tune0; bool async_fifo; bool data_tune;
@@ -664,7 +665,7 @@ static int msdc_ops_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
static void msdc_set_timeout(struct msdc_host *host, u32 ns, u32 clks) {
- u32 timeout, clk_ns;
u32 timeout, clk_ns, shift; u32 mode = 0;
host->timeout_ns = ns;
@@ -673,10 +674,11 @@ static void msdc_set_timeout(struct msdc_host *host, u32 ns, u32 clks) if (host->sclk == 0) { timeout = 0; } else {
clk_ns = 1000000000UL / host->sclk; timeout = (ns + clk_ns - 1) / clk_ns + clks; /* unit is 1048576 sclk cycles */shift = host->dev_comp->sclk_cycle_shift;
timeout = (timeout + (0x1 << 20) - 1) >> 20;
if (host->dev_comp->clk_div_bits == 8) mode = (readl(&host->base->msdc_cfg) & MSDC_CFG_CKMOD_M) >> MSDC_CFG_CKMOD_S;timeout = (timeout + (0x1 << shift) - 1) >> shift;
@@ -1301,7 +1303,7 @@ static int msdc_drv_probe(struct udevice *dev)
host->mmc = &plat->mmc; host->timeout_ns = 100000000;
- host->timeout_clks = 3 * 1048576;
host->timeout_clks = 3 * (1 << host->dev_comp->sclk_cycle_shift);
#ifdef CONFIG_PINCTRL pinctrl_select_state(dev, "default");
@@ -1374,8 +1376,20 @@ static const struct dm_mmc_ops msdc_ops = { #endif };
+static const struct msdc_compatible mt7620_compat = {
- .clk_div_bits = 8,
- .sclk_cycle_shift = 16,
- .pad_tune0 = false,
- .async_fifo = false,
- .data_tune = false,
- .busy_check = false,
- .stop_clk_fix = false,
- .enhance_rx = false
+};
- static const struct msdc_compatible mt7623_compat = { .clk_div_bits = 12,
- .sclk_cycle_shift = 20, .pad_tune0 = true, .async_fifo = true, .data_tune = true,
@@ -1386,6 +1400,7 @@ static const struct msdc_compatible mt7623_compat = {
static const struct msdc_compatible mt8516_compat = { .clk_div_bits = 12,
- .sclk_cycle_shift = 20, .pad_tune0 = true, .async_fifo = true, .data_tune = true,
@@ -1395,6 +1410,7 @@ static const struct msdc_compatible mt8516_compat = {
static const struct msdc_compatible mt8183_compat = { .clk_div_bits = 12,
- .sclk_cycle_shift = 20, .pad_tune0 = true, .async_fifo = true, .data_tune = true,
@@ -1403,6 +1419,7 @@ static const struct msdc_compatible mt8183_compat = { };
static const struct udevice_id msdc_ids[] = {
- { .compatible = "mediatek,mt7620-mmc", .data = (ulong)&mt7620_compat }, { .compatible = "mediatek,mt7623-mmc", .data = (ulong)&mt7623_compat }, { .compatible = "mediatek,mt8516-mmc", .data = (ulong)&mt8516_compat }, { .compatible = "mediatek,mt8183-mmc", .data = (ulong)&mt8183_compat },
Viele Grüße, Stefan

On Wed, 2019-08-28 at 15:50 +0200, Stefan Roese wrote:
On 28.08.19 08:38, Weijie Gao wrote:
This patch adds mmc support for MediaTek MT7620/MT7628 SoCs.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com
drivers/mmc/Kconfig | 2 +- drivers/mmc/mtk-sd.c | 23 ++++++++++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 0ccb1ea701..564310b293 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -671,7 +671,7 @@ config FTSDC010_SDIO
config MMC_MTK bool "MediaTek SD/MMC Card Interface support"
- depends on ARCH_MEDIATEK
- depends on (ARCH_MEDIATEK || ARCH_MTMIPS)
AFAIK, the braces are not necessary.
Thanks, Stefan
depends on BLK && DM_MMC depends on OF_CONTROL help diff --git a/drivers/mmc/mtk-sd.c b/drivers/mmc/mtk-sd.c index f555357af2..7069fe8948 100644 --- a/drivers/mmc/mtk-sd.c +++ b/drivers/mmc/mtk-sd.c @@ -217,6 +217,7 @@ struct mtk_sd_regs {
struct msdc_compatible { u8 clk_div_bits;
- u8 sclk_cycle_shift; bool pad_tune0; bool async_fifo; bool data_tune;
@@ -664,7 +665,7 @@ static int msdc_ops_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
static void msdc_set_timeout(struct msdc_host *host, u32 ns, u32 clks) {
- u32 timeout, clk_ns;
u32 timeout, clk_ns, shift; u32 mode = 0;
host->timeout_ns = ns;
@@ -673,10 +674,11 @@ static void msdc_set_timeout(struct msdc_host *host, u32 ns, u32 clks) if (host->sclk == 0) { timeout = 0; } else {
clk_ns = 1000000000UL / host->sclk; timeout = (ns + clk_ns - 1) / clk_ns + clks; /* unit is 1048576 sclk cycles */shift = host->dev_comp->sclk_cycle_shift;
timeout = (timeout + (0x1 << 20) - 1) >> 20;
if (host->dev_comp->clk_div_bits == 8) mode = (readl(&host->base->msdc_cfg) & MSDC_CFG_CKMOD_M) >> MSDC_CFG_CKMOD_S;timeout = (timeout + (0x1 << shift) - 1) >> shift;
@@ -1301,7 +1303,7 @@ static int msdc_drv_probe(struct udevice *dev)
host->mmc = &plat->mmc; host->timeout_ns = 100000000;
- host->timeout_clks = 3 * 1048576;
host->timeout_clks = 3 * (1 << host->dev_comp->sclk_cycle_shift);
#ifdef CONFIG_PINCTRL pinctrl_select_state(dev, "default");
@@ -1374,8 +1376,20 @@ static const struct dm_mmc_ops msdc_ops = { #endif };
+static const struct msdc_compatible mt7620_compat = {
- .clk_div_bits = 8,
- .sclk_cycle_shift = 16,
- .pad_tune0 = false,
- .async_fifo = false,
- .data_tune = false,
- .busy_check = false,
- .stop_clk_fix = false,
- .enhance_rx = false
+};
- static const struct msdc_compatible mt7623_compat = { .clk_div_bits = 12,
- .sclk_cycle_shift = 20, .pad_tune0 = true, .async_fifo = true, .data_tune = true,
@@ -1386,6 +1400,7 @@ static const struct msdc_compatible mt7623_compat = {
static const struct msdc_compatible mt8516_compat = { .clk_div_bits = 12,
- .sclk_cycle_shift = 20, .pad_tune0 = true, .async_fifo = true, .data_tune = true,
@@ -1395,6 +1410,7 @@ static const struct msdc_compatible mt8516_compat = {
static const struct msdc_compatible mt8183_compat = { .clk_div_bits = 12,
- .sclk_cycle_shift = 20, .pad_tune0 = true, .async_fifo = true, .data_tune = true,
@@ -1403,6 +1419,7 @@ static const struct msdc_compatible mt8183_compat = { };
static const struct udevice_id msdc_ids[] = {
- { .compatible = "mediatek,mt7620-mmc", .data = (ulong)&mt7620_compat }, { .compatible = "mediatek,mt7623-mmc", .data = (ulong)&mt7623_compat }, { .compatible = "mediatek,mt8516-mmc", .data = (ulong)&mt8516_compat }, { .compatible = "mediatek,mt8183-mmc", .data = (ulong)&mt8183_compat },
Viele Grüße, Stefan
I'll remove these braces.

This patch adds a dts property cd-active-high for builtin-cd mode to make it configurable instead of using hardcoded active-low.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- drivers/mmc/mtk-sd.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/mtk-sd.c b/drivers/mmc/mtk-sd.c index 7069fe8948..814a1b5fe9 100644 --- a/drivers/mmc/mtk-sd.c +++ b/drivers/mmc/mtk-sd.c @@ -270,6 +270,7 @@ struct msdc_host {
/* whether to use gpio detection or built-in hw detection */ bool builtin_cd; + bool cd_active_high;
/* card detection / write protection GPIOs */ #if CONFIG_IS_ENABLED(DM_GPIO) @@ -852,7 +853,12 @@ static int msdc_ops_get_cd(struct udevice *dev)
if (host->builtin_cd) { val = readl(&host->base->msdc_ps); - return !(val & MSDC_PS_CDSTS); + val &= MSDC_PS_CDSTS; + + if (!host->cd_active_high) + val = !val; + + return val; }
#if CONFIG_IS_ENABLED(DM_GPIO) @@ -1355,6 +1361,7 @@ static int msdc_ofdata_to_platdata(struct udevice *dev) host->latch_ck = dev_read_u32_default(dev, "latch-ck", 0); host->r_smpl = dev_read_u32_default(dev, "r_smpl", 0); host->builtin_cd = dev_read_u32_default(dev, "builtin-cd", 0); + host->cd_active_high = dev_read_bool(dev, "cd-active-high");
return 0; }

This patch adds mmc related nodes for mt7628an.dtsi
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- arch/mips/dts/mt7628a.dtsi | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
diff --git a/arch/mips/dts/mt7628a.dtsi b/arch/mips/dts/mt7628a.dtsi index dd11cac28c..929397c729 100644 --- a/arch/mips/dts/mt7628a.dtsi +++ b/arch/mips/dts/mt7628a.dtsi @@ -25,6 +25,14 @@ compatible = "mti,cpu-interrupt-controller"; };
+ clk48m: clk48m@0 { + compatible = "fixed-clock"; + + clock-frequency = <48000000>; + + #clock-cells = <0>; + }; + palmbus@10000000 { compatible = "palmbus", "simple-bus"; reg = <0x10000000 0x200000>; @@ -379,4 +387,18 @@ interrupt-parent = <&intc>; interrupts = <18>; }; + + mmc: mmc@10130000 { + compatible = "mediatek,mt7620-mmc"; + reg = <0x10130000 0x4000>; + builtin-cd = <1>; + r_smpl = <1>; + + clocks = <&clk48m>, <&clk48m>; + clock-names = "source", "hclk"; + + resets = <&rstctrl MT7628_SDXC_RST>; + + status = "disabled"; + }; };

This adds default pinctrl (dual SPI chip select) for gardena smart gateway
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- arch/mips/dts/gardena-smart-gateway-mt7688.dts | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/arch/mips/dts/gardena-smart-gateway-mt7688.dts b/arch/mips/dts/gardena-smart-gateway-mt7688.dts index 821e5bcdf8..8a9b8227b7 100644 --- a/arch/mips/dts/gardena-smart-gateway-mt7688.dts +++ b/arch/mips/dts/gardena-smart-gateway-mt7688.dts @@ -102,6 +102,9 @@ status = "okay"; num-cs = <2>;
+ pinctrl-names = "default"; + pinctrl-0 = <&spi_dual_pins>; + spi-flash@0 { #address-cells = <1>; #size-cells = <1>;

On 28.08.19 08:38, Weijie Gao wrote:
This adds default pinctrl (dual SPI chip select) for gardena smart gateway
Signed-off-by: Weijie Gao weijie.gao@mediatek.com
Please see my comment about the pinctrl-single driver usage in Linux. And my patch to add support to the mt7628.dtsi file as well. We should stay in sync with the Linux DT bindings here.
Other than that:
Reviewed-by: Stefan Roese sr@denx.de
Thanks, Stefan

This patch adds a referenceable name to eth node, and adds default pinctrl for all boards.
There are two pinctrl nodes used for two scenarios: ephy_iot_mode - for IOT boards which have only one port (PHY0) ephy_router_mode - For routers which have more than one ports
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- arch/mips/dts/gardena-smart-gateway-mt7688.dts | 5 +++++ arch/mips/dts/linkit-smart-7688.dts | 5 +++++ arch/mips/dts/mt7628a.dtsi | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/arch/mips/dts/gardena-smart-gateway-mt7688.dts b/arch/mips/dts/gardena-smart-gateway-mt7688.dts index 8a9b8227b7..1a2629ad9d 100644 --- a/arch/mips/dts/gardena-smart-gateway-mt7688.dts +++ b/arch/mips/dts/gardena-smart-gateway-mt7688.dts @@ -121,3 +121,8 @@ reg = <1>; }; }; + +ð { + pinctrl-names = "default"; + pinctrl-0 = <&ephy_iot_mode>; +}; diff --git a/arch/mips/dts/linkit-smart-7688.dts b/arch/mips/dts/linkit-smart-7688.dts index 7dbd909d00..aca1ec8c70 100644 --- a/arch/mips/dts/linkit-smart-7688.dts +++ b/arch/mips/dts/linkit-smart-7688.dts @@ -51,3 +51,8 @@ reg = <0>; }; }; + +ð { + pinctrl-names = "default"; + pinctrl-0 = <&ephy_iot_mode>; +}; diff --git a/arch/mips/dts/mt7628a.dtsi b/arch/mips/dts/mt7628a.dtsi index 929397c729..f13b539242 100644 --- a/arch/mips/dts/mt7628a.dtsi +++ b/arch/mips/dts/mt7628a.dtsi @@ -352,7 +352,7 @@ }; };
- eth@10110000 { + eth: eth@10110000 { compatible = "mediatek,mt7628-eth"; reg = <0x10100000 0x10000 0x10110000 0x8000>;

On 28.08.19 08:38, Weijie Gao wrote:
This patch adds a referenceable name to eth node, and adds default pinctrl for all boards.
There are two pinctrl nodes used for two scenarios: ephy_iot_mode - for IOT boards which have only one port (PHY0) ephy_router_mode - For routers which have more than one ports
Signed-off-by: Weijie Gao weijie.gao@mediatek.com
Again my comment about staying in sync with the Linux DT bindings. It might be that case, that Linux is still missing some defines for the pinctrl (like this IOT one).
Reviewed-by: Stefan Roese sr@denx.de
Thanks, Stefan
arch/mips/dts/gardena-smart-gateway-mt7688.dts | 5 +++++ arch/mips/dts/linkit-smart-7688.dts | 5 +++++ arch/mips/dts/mt7628a.dtsi | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/arch/mips/dts/gardena-smart-gateway-mt7688.dts b/arch/mips/dts/gardena-smart-gateway-mt7688.dts index 8a9b8227b7..1a2629ad9d 100644 --- a/arch/mips/dts/gardena-smart-gateway-mt7688.dts +++ b/arch/mips/dts/gardena-smart-gateway-mt7688.dts @@ -121,3 +121,8 @@ reg = <1>; }; };
+ð {
- pinctrl-names = "default";
- pinctrl-0 = <&ephy_iot_mode>;
+}; diff --git a/arch/mips/dts/linkit-smart-7688.dts b/arch/mips/dts/linkit-smart-7688.dts index 7dbd909d00..aca1ec8c70 100644 --- a/arch/mips/dts/linkit-smart-7688.dts +++ b/arch/mips/dts/linkit-smart-7688.dts @@ -51,3 +51,8 @@ reg = <0>; }; };
+ð {
- pinctrl-names = "default";
- pinctrl-0 = <&ephy_iot_mode>;
+}; diff --git a/arch/mips/dts/mt7628a.dtsi b/arch/mips/dts/mt7628a.dtsi index 929397c729..f13b539242 100644 --- a/arch/mips/dts/mt7628a.dtsi +++ b/arch/mips/dts/mt7628a.dtsi @@ -352,7 +352,7 @@ }; };
- eth@10110000 {
- eth: eth@10110000 { compatible = "mediatek,mt7628-eth"; reg = <0x10100000 0x10000 0x10110000 0x8000>;
Viele Grüße, Stefan

This patch changes all defconfig files of mtmips to use mtk high-speed uart driver.
This driver is compatible with ns16550a when baudrate <= 115200.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- configs/gardena-smart-gateway-mt7688-ram_defconfig | 2 +- configs/gardena-smart-gateway-mt7688_defconfig | 2 +- configs/linkit-smart-7688-ram_defconfig | 2 +- configs/linkit-smart-7688_defconfig | 2 +- include/configs/gardena-smart-gateway-mt7688.h | 2 +- include/configs/linkit-smart-7688.h | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/configs/gardena-smart-gateway-mt7688-ram_defconfig b/configs/gardena-smart-gateway-mt7688-ram_defconfig index 1a1167b2a6..99010289e9 100644 --- a/configs/gardena-smart-gateway-mt7688-ram_defconfig +++ b/configs/gardena-smart-gateway-mt7688-ram_defconfig @@ -68,7 +68,7 @@ CONFIG_POWER_DOMAIN=y CONFIG_RAM=y CONFIG_DM_RESET=y # CONFIG_SPL_SERIAL_PRESENT is not set -CONFIG_SYS_NS16550=y +CONFIG_MTK_SERIAL=y CONFIG_SPI=y CONFIG_MT7621_SPI=y CONFIG_SYSRESET_SYSCON=y diff --git a/configs/gardena-smart-gateway-mt7688_defconfig b/configs/gardena-smart-gateway-mt7688_defconfig index a456e3b575..1e270cb61d 100644 --- a/configs/gardena-smart-gateway-mt7688_defconfig +++ b/configs/gardena-smart-gateway-mt7688_defconfig @@ -71,7 +71,7 @@ CONFIG_POWER_DOMAIN=y CONFIG_RAM=y CONFIG_DM_RESET=y # CONFIG_SPL_SERIAL_PRESENT is not set -CONFIG_SYS_NS16550=y +CONFIG_MTK_SERIAL=y CONFIG_SPI=y CONFIG_MT7621_SPI=y CONFIG_SYSRESET_SYSCON=y diff --git a/configs/linkit-smart-7688-ram_defconfig b/configs/linkit-smart-7688-ram_defconfig index aa76633802..1e9cac5596 100644 --- a/configs/linkit-smart-7688-ram_defconfig +++ b/configs/linkit-smart-7688-ram_defconfig @@ -55,7 +55,7 @@ CONFIG_POWER_DOMAIN=y CONFIG_RAM=y CONFIG_DM_RESET=y # CONFIG_SPL_SERIAL_PRESENT is not set -CONFIG_SYS_NS16550=y +CONFIG_MTK_SERIAL=y CONFIG_SPI=y CONFIG_MT7621_SPI=y CONFIG_SYSRESET_SYSCON=y diff --git a/configs/linkit-smart-7688_defconfig b/configs/linkit-smart-7688_defconfig index 3750e59a4b..743cc48166 100644 --- a/configs/linkit-smart-7688_defconfig +++ b/configs/linkit-smart-7688_defconfig @@ -59,7 +59,7 @@ CONFIG_POWER_DOMAIN=y CONFIG_RAM=y CONFIG_DM_RESET=y # CONFIG_SPL_SERIAL_PRESENT is not set -CONFIG_SYS_NS16550=y +CONFIG_MTK_SERIAL=y CONFIG_SPI=y CONFIG_MT7621_SPI=y CONFIG_SYSRESET_SYSCON=y diff --git a/include/configs/gardena-smart-gateway-mt7688.h b/include/configs/gardena-smart-gateway-mt7688.h index b3b89d2ab9..e83a96ad5e 100644 --- a/include/configs/gardena-smart-gateway-mt7688.h +++ b/include/configs/gardena-smart-gateway-mt7688.h @@ -22,7 +22,7 @@
/* UART */ #define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \ - 230400, 500000, 1500000 } + 230400, 460800, 921600 }
/* RAM */ #define CONFIG_SYS_MEMTEST_START 0x80100000 diff --git a/include/configs/linkit-smart-7688.h b/include/configs/linkit-smart-7688.h index 2adf38545a..4d30d98abf 100644 --- a/include/configs/linkit-smart-7688.h +++ b/include/configs/linkit-smart-7688.h @@ -22,7 +22,7 @@
/* UART */ #define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \ - 230400, 500000, 1500000 } + 230400, 460800, 921600 }
/* RAM */ #define CONFIG_SYS_MEMTEST_START 0x80100000

On 28.08.19 08:38, Weijie Gao wrote:
This patch changes all defconfig files of mtmips to use mtk high-speed uart driver.
This driver is compatible with ns16550a when baudrate <= 115200.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com
As already suggested by Daniel, please move this change into a Kconfig "select" instead in the arch/mips platform.
Thanks, Stefan
configs/gardena-smart-gateway-mt7688-ram_defconfig | 2 +- configs/gardena-smart-gateway-mt7688_defconfig | 2 +- configs/linkit-smart-7688-ram_defconfig | 2 +- configs/linkit-smart-7688_defconfig | 2 +- include/configs/gardena-smart-gateway-mt7688.h | 2 +- include/configs/linkit-smart-7688.h | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/configs/gardena-smart-gateway-mt7688-ram_defconfig b/configs/gardena-smart-gateway-mt7688-ram_defconfig index 1a1167b2a6..99010289e9 100644 --- a/configs/gardena-smart-gateway-mt7688-ram_defconfig +++ b/configs/gardena-smart-gateway-mt7688-ram_defconfig @@ -68,7 +68,7 @@ CONFIG_POWER_DOMAIN=y CONFIG_RAM=y CONFIG_DM_RESET=y # CONFIG_SPL_SERIAL_PRESENT is not set -CONFIG_SYS_NS16550=y +CONFIG_MTK_SERIAL=y CONFIG_SPI=y CONFIG_MT7621_SPI=y CONFIG_SYSRESET_SYSCON=y diff --git a/configs/gardena-smart-gateway-mt7688_defconfig b/configs/gardena-smart-gateway-mt7688_defconfig index a456e3b575..1e270cb61d 100644 --- a/configs/gardena-smart-gateway-mt7688_defconfig +++ b/configs/gardena-smart-gateway-mt7688_defconfig @@ -71,7 +71,7 @@ CONFIG_POWER_DOMAIN=y CONFIG_RAM=y CONFIG_DM_RESET=y # CONFIG_SPL_SERIAL_PRESENT is not set -CONFIG_SYS_NS16550=y +CONFIG_MTK_SERIAL=y CONFIG_SPI=y CONFIG_MT7621_SPI=y CONFIG_SYSRESET_SYSCON=y diff --git a/configs/linkit-smart-7688-ram_defconfig b/configs/linkit-smart-7688-ram_defconfig index aa76633802..1e9cac5596 100644 --- a/configs/linkit-smart-7688-ram_defconfig +++ b/configs/linkit-smart-7688-ram_defconfig @@ -55,7 +55,7 @@ CONFIG_POWER_DOMAIN=y CONFIG_RAM=y CONFIG_DM_RESET=y # CONFIG_SPL_SERIAL_PRESENT is not set -CONFIG_SYS_NS16550=y +CONFIG_MTK_SERIAL=y CONFIG_SPI=y CONFIG_MT7621_SPI=y CONFIG_SYSRESET_SYSCON=y diff --git a/configs/linkit-smart-7688_defconfig b/configs/linkit-smart-7688_defconfig index 3750e59a4b..743cc48166 100644 --- a/configs/linkit-smart-7688_defconfig +++ b/configs/linkit-smart-7688_defconfig @@ -59,7 +59,7 @@ CONFIG_POWER_DOMAIN=y CONFIG_RAM=y CONFIG_DM_RESET=y # CONFIG_SPL_SERIAL_PRESENT is not set -CONFIG_SYS_NS16550=y +CONFIG_MTK_SERIAL=y CONFIG_SPI=y CONFIG_MT7621_SPI=y CONFIG_SYSRESET_SYSCON=y diff --git a/include/configs/gardena-smart-gateway-mt7688.h b/include/configs/gardena-smart-gateway-mt7688.h index b3b89d2ab9..e83a96ad5e 100644 --- a/include/configs/gardena-smart-gateway-mt7688.h +++ b/include/configs/gardena-smart-gateway-mt7688.h @@ -22,7 +22,7 @@
/* UART */ #define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \
230400, 500000, 1500000 }
230400, 460800, 921600 }
/* RAM */ #define CONFIG_SYS_MEMTEST_START 0x80100000
diff --git a/include/configs/linkit-smart-7688.h b/include/configs/linkit-smart-7688.h index 2adf38545a..4d30d98abf 100644 --- a/include/configs/linkit-smart-7688.h +++ b/include/configs/linkit-smart-7688.h @@ -22,7 +22,7 @@
/* UART */ #define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \
230400, 500000, 1500000 }
230400, 460800, 921600 }
/* RAM */ #define CONFIG_SYS_MEMTEST_START 0x80100000
Viele Grüße, Stefan

On Wed, 2019-08-28 at 15:57 +0200, Stefan Roese wrote:
On 28.08.19 08:38, Weijie Gao wrote:
This patch changes all defconfig files of mtmips to use mtk high-speed uart driver.
This driver is compatible with ns16550a when baudrate <= 115200.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com
As already suggested by Daniel, please move this change into a Kconfig "select" instead in the arch/mips platform.
Thanks, Stefan
configs/gardena-smart-gateway-mt7688-ram_defconfig | 2 +- configs/gardena-smart-gateway-mt7688_defconfig | 2 +- configs/linkit-smart-7688-ram_defconfig | 2 +- configs/linkit-smart-7688_defconfig | 2 +- include/configs/gardena-smart-gateway-mt7688.h | 2 +- include/configs/linkit-smart-7688.h | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/configs/gardena-smart-gateway-mt7688-ram_defconfig b/configs/gardena-smart-gateway-mt7688-ram_defconfig index 1a1167b2a6..99010289e9 100644 --- a/configs/gardena-smart-gateway-mt7688-ram_defconfig +++ b/configs/gardena-smart-gateway-mt7688-ram_defconfig @@ -68,7 +68,7 @@ CONFIG_POWER_DOMAIN=y CONFIG_RAM=y CONFIG_DM_RESET=y # CONFIG_SPL_SERIAL_PRESENT is not set -CONFIG_SYS_NS16550=y +CONFIG_MTK_SERIAL=y CONFIG_SPI=y CONFIG_MT7621_SPI=y CONFIG_SYSRESET_SYSCON=y diff --git a/configs/gardena-smart-gateway-mt7688_defconfig b/configs/gardena-smart-gateway-mt7688_defconfig index a456e3b575..1e270cb61d 100644 --- a/configs/gardena-smart-gateway-mt7688_defconfig +++ b/configs/gardena-smart-gateway-mt7688_defconfig @@ -71,7 +71,7 @@ CONFIG_POWER_DOMAIN=y CONFIG_RAM=y CONFIG_DM_RESET=y # CONFIG_SPL_SERIAL_PRESENT is not set -CONFIG_SYS_NS16550=y +CONFIG_MTK_SERIAL=y CONFIG_SPI=y CONFIG_MT7621_SPI=y CONFIG_SYSRESET_SYSCON=y diff --git a/configs/linkit-smart-7688-ram_defconfig b/configs/linkit-smart-7688-ram_defconfig index aa76633802..1e9cac5596 100644 --- a/configs/linkit-smart-7688-ram_defconfig +++ b/configs/linkit-smart-7688-ram_defconfig @@ -55,7 +55,7 @@ CONFIG_POWER_DOMAIN=y CONFIG_RAM=y CONFIG_DM_RESET=y # CONFIG_SPL_SERIAL_PRESENT is not set -CONFIG_SYS_NS16550=y +CONFIG_MTK_SERIAL=y CONFIG_SPI=y CONFIG_MT7621_SPI=y CONFIG_SYSRESET_SYSCON=y diff --git a/configs/linkit-smart-7688_defconfig b/configs/linkit-smart-7688_defconfig index 3750e59a4b..743cc48166 100644 --- a/configs/linkit-smart-7688_defconfig +++ b/configs/linkit-smart-7688_defconfig @@ -59,7 +59,7 @@ CONFIG_POWER_DOMAIN=y CONFIG_RAM=y CONFIG_DM_RESET=y # CONFIG_SPL_SERIAL_PRESENT is not set -CONFIG_SYS_NS16550=y +CONFIG_MTK_SERIAL=y CONFIG_SPI=y CONFIG_MT7621_SPI=y CONFIG_SYSRESET_SYSCON=y diff --git a/include/configs/gardena-smart-gateway-mt7688.h b/include/configs/gardena-smart-gateway-mt7688.h index b3b89d2ab9..e83a96ad5e 100644 --- a/include/configs/gardena-smart-gateway-mt7688.h +++ b/include/configs/gardena-smart-gateway-mt7688.h @@ -22,7 +22,7 @@
/* UART */ #define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \
230400, 500000, 1500000 }
230400, 460800, 921600 }
/* RAM */ #define CONFIG_SYS_MEMTEST_START 0x80100000
diff --git a/include/configs/linkit-smart-7688.h b/include/configs/linkit-smart-7688.h index 2adf38545a..4d30d98abf 100644 --- a/include/configs/linkit-smart-7688.h +++ b/include/configs/linkit-smart-7688.h @@ -22,7 +22,7 @@
/* UART */ #define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \
230400, 500000, 1500000 }
230400, 460800, 921600 }
/* RAM */ #define CONFIG_SYS_MEMTEST_START 0x80100000
Viele Grüße, Stefan
Actually both ns16550a and mtk-hsuart can be used. But it's OK to force to use mtk-hsuart.

This patch adds pinctrl driver, clock gate driver and reset controller support for defconfig files of mtmips boards.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- configs/gardena-smart-gateway-mt7688_defconfig | 6 ++++++ configs/linkit-smart-7688_defconfig | 6 ++++++ 2 files changed, 12 insertions(+)
diff --git a/configs/gardena-smart-gateway-mt7688_defconfig b/configs/gardena-smart-gateway-mt7688_defconfig index 1e270cb61d..83e793042a 100644 --- a/configs/gardena-smart-gateway-mt7688_defconfig +++ b/configs/gardena-smart-gateway-mt7688_defconfig @@ -49,6 +49,7 @@ CONFIG_NET_RANDOM_ETHADDR=y CONFIG_HAVE_BLOCK_DEVICE=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_CLK=y +CONFIG_CLK_MTMIPS_GATE=y CONFIG_LED=y CONFIG_LED_BLINK=y CONFIG_LED_GPIO=y @@ -67,10 +68,15 @@ CONFIG_PHYLIB=y CONFIG_PHY_FIXED=y CONFIG_MT7628_ETH=y CONFIG_PHY=y +CONFIG_PINCTRL=y +CONFIG_PINMUX=y +CONFIG_PINCONF=y +CONFIG_PINCTRL_MT7628=y CONFIG_POWER_DOMAIN=y CONFIG_RAM=y CONFIG_DM_RESET=y # CONFIG_SPL_SERIAL_PRESENT is not set +CONFIG_RESET_MTMIPS=y CONFIG_MTK_SERIAL=y CONFIG_SPI=y CONFIG_MT7621_SPI=y diff --git a/configs/linkit-smart-7688_defconfig b/configs/linkit-smart-7688_defconfig index 743cc48166..13f5cf8a21 100644 --- a/configs/linkit-smart-7688_defconfig +++ b/configs/linkit-smart-7688_defconfig @@ -40,6 +40,7 @@ CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set CONFIG_BLK=y CONFIG_CLK=y +CONFIG_CLK_MTMIPS_GATE=y CONFIG_LED=y CONFIG_LED_BLINK=y CONFIG_LED_GPIO=y @@ -55,10 +56,15 @@ CONFIG_PHY_FIXED=y CONFIG_MT7628_ETH=y CONFIG_PHY=y CONFIG_MT76X8_USB_PHY=y +CONFIG_PINCTRL=y +CONFIG_PINMUX=y +CONFIG_PINCONF=y +CONFIG_PINCTRL_MT7628=y CONFIG_POWER_DOMAIN=y CONFIG_RAM=y CONFIG_DM_RESET=y # CONFIG_SPL_SERIAL_PRESENT is not set +CONFIG_RESET_MTMIPS=y CONFIG_MTK_SERIAL=y CONFIG_SPI=y CONFIG_MT7621_SPI=y

Am 28.08.19 um 08:38 schrieb Weijie Gao:
This patch adds pinctrl driver, clock gate driver and reset controller support for defconfig files of mtmips boards.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com
configs/gardena-smart-gateway-mt7688_defconfig | 6 ++++++ configs/linkit-smart-7688_defconfig | 6 ++++++ 2 files changed, 12 insertions(+)
diff --git a/configs/gardena-smart-gateway-mt7688_defconfig b/configs/gardena-smart-gateway-mt7688_defconfig index 1e270cb61d..83e793042a 100644 --- a/configs/gardena-smart-gateway-mt7688_defconfig +++ b/configs/gardena-smart-gateway-mt7688_defconfig @@ -49,6 +49,7 @@ CONFIG_NET_RANDOM_ETHADDR=y CONFIG_HAVE_BLOCK_DEVICE=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_CLK=y +CONFIG_CLK_MTMIPS_GATE=y CONFIG_LED=y CONFIG_LED_BLINK=y CONFIG_LED_GPIO=y @@ -67,10 +68,15 @@ CONFIG_PHYLIB=y CONFIG_PHY_FIXED=y CONFIG_MT7628_ETH=y CONFIG_PHY=y +CONFIG_PINCTRL=y +CONFIG_PINMUX=y +CONFIG_PINCONF=y +CONFIG_PINCTRL_MT7628=y CONFIG_POWER_DOMAIN=y CONFIG_RAM=y CONFIG_DM_RESET=y # CONFIG_SPL_SERIAL_PRESENT is not set +CONFIG_RESET_MTMIPS=y
if the SoC only works with those drivers enabled, you should consider to select all according Kconfig symbols in arch/mips/mach-mtmips/Kconfig so an user can't configure a non-working board config by mistake.
CONFIG_MTK_SERIAL=y CONFIG_SPI=y CONFIG_MT7621_SPI=y diff --git a/configs/linkit-smart-7688_defconfig b/configs/linkit-smart-7688_defconfig index 743cc48166..13f5cf8a21 100644 --- a/configs/linkit-smart-7688_defconfig +++ b/configs/linkit-smart-7688_defconfig @@ -40,6 +40,7 @@ CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set CONFIG_BLK=y CONFIG_CLK=y +CONFIG_CLK_MTMIPS_GATE=y CONFIG_LED=y CONFIG_LED_BLINK=y CONFIG_LED_GPIO=y @@ -55,10 +56,15 @@ CONFIG_PHY_FIXED=y CONFIG_MT7628_ETH=y CONFIG_PHY=y CONFIG_MT76X8_USB_PHY=y +CONFIG_PINCTRL=y +CONFIG_PINMUX=y +CONFIG_PINCONF=y +CONFIG_PINCTRL_MT7628=y CONFIG_POWER_DOMAIN=y CONFIG_RAM=y CONFIG_DM_RESET=y # CONFIG_SPL_SERIAL_PRESENT is not set +CONFIG_RESET_MTMIPS=y CONFIG_MTK_SERIAL=y CONFIG_SPI=y CONFIG_MT7621_SPI=y

On 28.08.19 15:35, Daniel Schwierzeck wrote:
Am 28.08.19 um 08:38 schrieb Weijie Gao:
This patch adds pinctrl driver, clock gate driver and reset controller support for defconfig files of mtmips boards.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com
configs/gardena-smart-gateway-mt7688_defconfig | 6 ++++++ configs/linkit-smart-7688_defconfig | 6 ++++++ 2 files changed, 12 insertions(+)
diff --git a/configs/gardena-smart-gateway-mt7688_defconfig b/configs/gardena-smart-gateway-mt7688_defconfig index 1e270cb61d..83e793042a 100644 --- a/configs/gardena-smart-gateway-mt7688_defconfig +++ b/configs/gardena-smart-gateway-mt7688_defconfig @@ -49,6 +49,7 @@ CONFIG_NET_RANDOM_ETHADDR=y CONFIG_HAVE_BLOCK_DEVICE=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_CLK=y +CONFIG_CLK_MTMIPS_GATE=y CONFIG_LED=y CONFIG_LED_BLINK=y CONFIG_LED_GPIO=y @@ -67,10 +68,15 @@ CONFIG_PHYLIB=y CONFIG_PHY_FIXED=y CONFIG_MT7628_ETH=y CONFIG_PHY=y +CONFIG_PINCTRL=y +CONFIG_PINMUX=y +CONFIG_PINCONF=y +CONFIG_PINCTRL_MT7628=y CONFIG_POWER_DOMAIN=y CONFIG_RAM=y CONFIG_DM_RESET=y # CONFIG_SPL_SERIAL_PRESENT is not set +CONFIG_RESET_MTMIPS=y
if the SoC only works with those drivers enabled, you should consider to select all according Kconfig symbols in arch/mips/mach-mtmips/Kconfig so an user can't configure a non-working board config by mistake.
I agree. Please move those selections to Kconfig (select XXX).
And please re-think about using the generic drivers for pinctrl and clock (as also remarked by Daniel).
Thanks, Stefan
CONFIG_MTK_SERIAL=y CONFIG_SPI=y CONFIG_MT7621_SPI=y diff --git a/configs/linkit-smart-7688_defconfig b/configs/linkit-smart-7688_defconfig index 743cc48166..13f5cf8a21 100644 --- a/configs/linkit-smart-7688_defconfig +++ b/configs/linkit-smart-7688_defconfig @@ -40,6 +40,7 @@ CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set CONFIG_BLK=y CONFIG_CLK=y +CONFIG_CLK_MTMIPS_GATE=y CONFIG_LED=y CONFIG_LED_BLINK=y CONFIG_LED_GPIO=y @@ -55,10 +56,15 @@ CONFIG_PHY_FIXED=y CONFIG_MT7628_ETH=y CONFIG_PHY=y CONFIG_MT76X8_USB_PHY=y +CONFIG_PINCTRL=y +CONFIG_PINMUX=y +CONFIG_PINCONF=y +CONFIG_PINCTRL_MT7628=y CONFIG_POWER_DOMAIN=y CONFIG_RAM=y CONFIG_DM_RESET=y # CONFIG_SPL_SERIAL_PRESENT is not set +CONFIG_RESET_MTMIPS=y CONFIG_MTK_SERIAL=y CONFIG_SPI=y CONFIG_MT7621_SPI=y
Viele Grüße, Stefan

On Wed, 2019-08-28 at 15:40 +0200, Stefan Roese wrote:
On 28.08.19 15:35, Daniel Schwierzeck wrote:
Am 28.08.19 um 08:38 schrieb Weijie Gao:
This patch adds pinctrl driver, clock gate driver and reset controller support for defconfig files of mtmips boards.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com
configs/gardena-smart-gateway-mt7688_defconfig | 6 ++++++ configs/linkit-smart-7688_defconfig | 6 ++++++ 2 files changed, 12 insertions(+)
diff --git a/configs/gardena-smart-gateway-mt7688_defconfig b/configs/gardena-smart-gateway-mt7688_defconfig index 1e270cb61d..83e793042a 100644 --- a/configs/gardena-smart-gateway-mt7688_defconfig +++ b/configs/gardena-smart-gateway-mt7688_defconfig @@ -49,6 +49,7 @@ CONFIG_NET_RANDOM_ETHADDR=y CONFIG_HAVE_BLOCK_DEVICE=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_CLK=y +CONFIG_CLK_MTMIPS_GATE=y CONFIG_LED=y CONFIG_LED_BLINK=y CONFIG_LED_GPIO=y @@ -67,10 +68,15 @@ CONFIG_PHYLIB=y CONFIG_PHY_FIXED=y CONFIG_MT7628_ETH=y CONFIG_PHY=y +CONFIG_PINCTRL=y +CONFIG_PINMUX=y +CONFIG_PINCONF=y +CONFIG_PINCTRL_MT7628=y CONFIG_POWER_DOMAIN=y CONFIG_RAM=y CONFIG_DM_RESET=y # CONFIG_SPL_SERIAL_PRESENT is not set +CONFIG_RESET_MTMIPS=y
if the SoC only works with those drivers enabled, you should consider to select all according Kconfig symbols in arch/mips/mach-mtmips/Kconfig so an user can't configure a non-working board config by mistake.
I agree. Please move those selections to Kconfig (select XXX).
And please re-think about using the generic drivers for pinctrl and clock (as also remarked by Daniel).
Thanks, Stefan
CONFIG_MTK_SERIAL=y CONFIG_SPI=y CONFIG_MT7621_SPI=y diff --git a/configs/linkit-smart-7688_defconfig b/configs/linkit-smart-7688_defconfig index 743cc48166..13f5cf8a21 100644 --- a/configs/linkit-smart-7688_defconfig +++ b/configs/linkit-smart-7688_defconfig @@ -40,6 +40,7 @@ CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set CONFIG_BLK=y CONFIG_CLK=y +CONFIG_CLK_MTMIPS_GATE=y CONFIG_LED=y CONFIG_LED_BLINK=y CONFIG_LED_GPIO=y @@ -55,10 +56,15 @@ CONFIG_PHY_FIXED=y CONFIG_MT7628_ETH=y CONFIG_PHY=y CONFIG_MT76X8_USB_PHY=y +CONFIG_PINCTRL=y +CONFIG_PINMUX=y +CONFIG_PINCONF=y +CONFIG_PINCTRL_MT7628=y CONFIG_POWER_DOMAIN=y CONFIG_RAM=y CONFIG_DM_RESET=y # CONFIG_SPL_SERIAL_PRESENT is not set +CONFIG_RESET_MTMIPS=y CONFIG_MTK_SERIAL=y CONFIG_SPI=y CONFIG_MT7621_SPI=y
Viele Grüße, Stefan
I'll move them to mach-mtmips/Kconfig.
participants (4)
-
Daniel Schwierzeck
-
Mauro Condarelli
-
Stefan Roese
-
Weijie Gao