All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs
@ 2022-08-04  3:34 Weijie Gao
  2022-08-04  3:34 ` [PATCH 01/31] arm: mediatek: add support for MediaTek MT7986 SoC Weijie Gao
                   ` (30 more replies)
  0 siblings, 31 replies; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:34 UTC (permalink / raw)
  To: u-boot; +Cc: GSS_MTK_Uboot_upstream, Weijie Gao

This patch series add support for MediaTek MT7981/MT7986 SoCs with their
reference boards and related drivers.

This patch series add basic boot support on eMMC/SD/SPI-NOR/SPI-NAND for
 these
boards. The clock, pinctrl drivers and the SoC initializaton code are also
included.

Product spec for MT7986:
https://www.mediatek.com/products/home-networking/mediatek-filogic-830

Weijie Gao (31):
  arm: mediatek: add support for MediaTek MT7986 SoC
  arm: mediatek: add support for MediaTek MT7981 SoC
  board: mediatek: add MT7986 reference boards
  board: mediatek: add MT7981 reference boards
  mmc: mediatek: add support for MediaTek MT7891/MT7986 SoCs
  net: mediatek: use a struct to cover variations of all SoCs
  net: mediatek: stop using bitfileds for DMA descriptors
  net: mediatek: add support for PDMA v2
  net: mediatek: add support for MediaTek MT7981/MT7986
  serial: mtk: add support for using dynamic baud clock souce
  arm: dts: mt7622: force high-speed mode for uart
  pwm: mtk: add support for MediaTek MT7986 SoC
  pwm: mtk: add support for MediaTek MT7981 SoC
  timer: mtk: add support for MediaTek MT7981/MT7986 SoCs
  watchdog: mediatek: add support for MediaTek MT7986 SoC
  spi: add support for MediaTek spi-mem controller
  i2c: add support for MediaTek I2C interface
  arm: dts: mt7622: add i2c support
  dt-bindings: pinctrl: mediatek: add a header for common pinconf
    parameters
  pinctrl: mediatek: add pinctrl driver for MT7981 SoC
  pinctrl: mediatek: add pinctrl driver for MT7986 SoC
  clk: mediatek: add CLK_BYPASS_XTAL flag to allow bypassing searching
    clock parent of xtal clock
  clk: mediatek: add support to configure clock driver parent
  clk: mediatek: add infrasys clock mux support
  clk: mediatek: add CLK_XTAL support for clock driver
  clk: mediatek: add clock driver support for MediaTek MT7986 SoC
  clk: mediatek: add clock driver support for MediaTek MT7981 SoC
  tools: mtk_image: split gfh header verification into a new function
  tools: mtk_image: split the code of generating NAND header into a new
    file
  tools: mtk_image: add support for nand headers used by newer chips
  MAINTAINERS: update maintainer for MediaTek ARM platform

 MAINTAINERS                                   |    5 +
 arch/arm/dts/Makefile                         |    9 +
 arch/arm/dts/mt7622-rfb.dts                   |   18 +
 arch/arm/dts/mt7622.dtsi                      |   25 +
 arch/arm/dts/mt7981-emmc-rfb.dts              |  139 +++
 arch/arm/dts/mt7981-rfb.dts                   |  133 +++
 arch/arm/dts/mt7981-sd-rfb.dts                |  139 +++
 arch/arm/dts/mt7981-spim-nand-rfb.dts         |  138 +++
 arch/arm/dts/mt7981-spim-nor-rfb.dts          |  133 +++
 arch/arm/dts/mt7981.dtsi                      |  288 +++++
 arch/arm/dts/mt7986-u-boot.dtsi               |   33 +
 arch/arm/dts/mt7986.dtsi                      |  341 ++++++
 arch/arm/dts/mt7986a-rfb.dts                  |  218 ++++
 arch/arm/dts/mt7986a-sd-rfb.dts               |  177 +++
 arch/arm/dts/mt7986b-rfb.dts                  |  204 ++++
 arch/arm/dts/mt7986b-sd-rfb.dts               |  173 +++
 arch/arm/mach-mediatek/Kconfig                |   21 +
 arch/arm/mach-mediatek/Makefile               |    2 +
 arch/arm/mach-mediatek/mt7981/Makefile        |    4 +
 arch/arm/mach-mediatek/mt7981/init.c          |   52 +
 arch/arm/mach-mediatek/mt7981/lowlevel_init.S |   30 +
 arch/arm/mach-mediatek/mt7986/Makefile        |    4 +
 arch/arm/mach-mediatek/mt7986/init.c          |   53 +
 arch/arm/mach-mediatek/mt7986/lowlevel_init.S |   30 +
 board/mediatek/mt7981/MAINTAINERS             |   10 +
 board/mediatek/mt7981/Makefile                |    3 +
 board/mediatek/mt7981/mt7981_rfb.c            |   10 +
 board/mediatek/mt7986/MAINTAINERS             |   10 +
 board/mediatek/mt7986/Makefile                |    3 +
 board/mediatek/mt7986/mt7986_rfb.c            |   10 +
 configs/mt7981_emmc_rfb_defconfig             |   64 +
 configs/mt7981_rfb_defconfig                  |   65 +
 configs/mt7981_sd_rfb_defconfig               |   64 +
 configs/mt7981_spim_nand_rfb_defconfig        |   59 +
 configs/mt7981_spim_nor_rfb_defconfig         |   70 ++
 configs/mt7986_rfb_defconfig                  |   66 ++
 configs/mt7986a_emmc_rfb_defconfig            |   64 +
 configs/mt7986a_sd_rfb_defconfig              |   64 +
 configs/mt7986b_emmc_rfb_defconfig            |   64 +
 configs/mt7986b_sd_rfb_defconfig              |   64 +
 drivers/clk/mediatek/Makefile                 |    2 +
 drivers/clk/mediatek/clk-mt7981.c             |  682 +++++++++++
 drivers/clk/mediatek/clk-mt7986.c             |  671 +++++++++++
 drivers/clk/mediatek/clk-mtk.c                |  157 ++-
 drivers/clk/mediatek/clk-mtk.h                |   10 +-
 drivers/i2c/Kconfig                           |    9 +
 drivers/i2c/Makefile                          |    1 +
 drivers/i2c/mtk_i2c.c                         |  822 +++++++++++++
 drivers/mmc/mtk-sd.c                          |   68 +-
 drivers/net/mtk_eth.c                         |  252 ++--
 drivers/net/mtk_eth.h                         |  101 +-
 drivers/pinctrl/mediatek/Kconfig              |    8 +
 drivers/pinctrl/mediatek/Makefile             |    2 +
 drivers/pinctrl/mediatek/pinctrl-mt7981.c     | 1049 +++++++++++++++++
 drivers/pinctrl/mediatek/pinctrl-mt7986.c     |  775 ++++++++++++
 drivers/pwm/pwm-mtk.c                         |   40 +-
 drivers/serial/serial_mtk.c                   |   72 +-
 drivers/spi/Kconfig                           |    8 +
 drivers/spi/Makefile                          |    1 +
 drivers/spi/mtk_spim.c                        |  705 +++++++++++
 drivers/timer/mtk_timer.c                     |   59 +-
 drivers/watchdog/mtk_wdt.c                    |    1 +
 include/configs/mt7981.h                      |   26 +
 include/configs/mt7986.h                      |   26 +
 include/dt-bindings/clock/mt7981-clk.h        |  267 +++++
 include/dt-bindings/clock/mt7986-clk.h        |  249 ++++
 include/dt-bindings/pinctrl/mt65xx.h          |   41 +
 tools/Makefile                                |    1 +
 tools/mtk_image.c                             |  376 ++----
 tools/mtk_image.h                             |   25 -
 tools/mtk_nand_headers.c                      |  668 +++++++++++
 tools/mtk_nand_headers.h                      |  156 +++
 72 files changed, 9841 insertions(+), 548 deletions(-)
 create mode 100644 arch/arm/dts/mt7981-emmc-rfb.dts
 create mode 100644 arch/arm/dts/mt7981-rfb.dts
 create mode 100644 arch/arm/dts/mt7981-sd-rfb.dts
 create mode 100644 arch/arm/dts/mt7981-spim-nand-rfb.dts
 create mode 100644 arch/arm/dts/mt7981-spim-nor-rfb.dts
 create mode 100644 arch/arm/dts/mt7981.dtsi
 create mode 100644 arch/arm/dts/mt7986-u-boot.dtsi
 create mode 100644 arch/arm/dts/mt7986.dtsi
 create mode 100644 arch/arm/dts/mt7986a-rfb.dts
 create mode 100644 arch/arm/dts/mt7986a-sd-rfb.dts
 create mode 100644 arch/arm/dts/mt7986b-rfb.dts
 create mode 100644 arch/arm/dts/mt7986b-sd-rfb.dts
 create mode 100644 arch/arm/mach-mediatek/mt7981/Makefile
 create mode 100644 arch/arm/mach-mediatek/mt7981/init.c
 create mode 100644 arch/arm/mach-mediatek/mt7981/lowlevel_init.S
 create mode 100644 arch/arm/mach-mediatek/mt7986/Makefile
 create mode 100644 arch/arm/mach-mediatek/mt7986/init.c
 create mode 100644 arch/arm/mach-mediatek/mt7986/lowlevel_init.S
 create mode 100644 board/mediatek/mt7981/MAINTAINERS
 create mode 100644 board/mediatek/mt7981/Makefile
 create mode 100644 board/mediatek/mt7981/mt7981_rfb.c
 create mode 100644 board/mediatek/mt7986/MAINTAINERS
 create mode 100644 board/mediatek/mt7986/Makefile
 create mode 100644 board/mediatek/mt7986/mt7986_rfb.c
 create mode 100644 configs/mt7981_emmc_rfb_defconfig
 create mode 100644 configs/mt7981_rfb_defconfig
 create mode 100644 configs/mt7981_sd_rfb_defconfig
 create mode 100644 configs/mt7981_spim_nand_rfb_defconfig
 create mode 100644 configs/mt7981_spim_nor_rfb_defconfig
 create mode 100644 configs/mt7986_rfb_defconfig
 create mode 100644 configs/mt7986a_emmc_rfb_defconfig
 create mode 100644 configs/mt7986a_sd_rfb_defconfig
 create mode 100644 configs/mt7986b_emmc_rfb_defconfig
 create mode 100644 configs/mt7986b_sd_rfb_defconfig
 create mode 100644 drivers/clk/mediatek/clk-mt7981.c
 create mode 100644 drivers/clk/mediatek/clk-mt7986.c
 create mode 100644 drivers/i2c/mtk_i2c.c
 create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt7981.c
 create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt7986.c
 create mode 100644 drivers/spi/mtk_spim.c
 create mode 100644 include/configs/mt7981.h
 create mode 100644 include/configs/mt7986.h
 create mode 100644 include/dt-bindings/clock/mt7981-clk.h
 create mode 100644 include/dt-bindings/clock/mt7986-clk.h
 create mode 100644 include/dt-bindings/pinctrl/mt65xx.h
 create mode 100644 tools/mtk_nand_headers.c
 create mode 100644 tools/mtk_nand_headers.h

-- 
2.17.1


^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 01/31] arm: mediatek: add support for MediaTek MT7986 SoC
  2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
@ 2022-08-04  3:34 ` Weijie Gao
  2022-08-04  8:37   ` Daniel Golle
  2022-08-04  3:34 ` [PATCH 02/31] arm: mediatek: add support for MediaTek MT7981 SoC Weijie Gao
                   ` (29 subsequent siblings)
  30 siblings, 1 reply; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:34 UTC (permalink / raw)
  To: u-boot; +Cc: GSS_MTK_Uboot_upstream, Weijie Gao

This patch adds basic support for MediaTek MT7986 SoC.
This include the file that will initialize the SoC after boot and its
device tree.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 arch/arm/dts/mt7986-u-boot.dtsi               |  33 ++
 arch/arm/dts/mt7986.dtsi                      | 341 ++++++++++++++++++
 arch/arm/mach-mediatek/Kconfig                |  11 +
 arch/arm/mach-mediatek/Makefile               |   1 +
 arch/arm/mach-mediatek/mt7986/Makefile        |   4 +
 arch/arm/mach-mediatek/mt7986/init.c          |  53 +++
 arch/arm/mach-mediatek/mt7986/lowlevel_init.S |  30 ++
 7 files changed, 473 insertions(+)
 create mode 100644 arch/arm/dts/mt7986-u-boot.dtsi
 create mode 100644 arch/arm/dts/mt7986.dtsi
 create mode 100644 arch/arm/mach-mediatek/mt7986/Makefile
 create mode 100644 arch/arm/mach-mediatek/mt7986/init.c
 create mode 100644 arch/arm/mach-mediatek/mt7986/lowlevel_init.S

diff --git a/arch/arm/dts/mt7986-u-boot.dtsi
 b/arch/arm/dts/mt7986-u-boot.dtsi
new file mode 100644
index 0000000000..95671f8afa
--- /dev/null
+++ b/arch/arm/dts/mt7986-u-boot.dtsi
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+&topckgen {
+	u-boot,dm-pre-reloc;
+};
+
+&pericfg {
+	u-boot,dm-pre-reloc;
+};
+
+&apmixedsys {
+	u-boot,dm-pre-reloc;
+};
+
+&timer0 {
+	u-boot,dm-pre-reloc;
+};
+
+&uart0 {
+	u-boot,dm-pre-reloc;
+};
+
+&snand {
+	u-boot,dm-pre-reloc;
+};
+
+&pinctrl {
+	u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/mt7986.dtsi b/arch/arm/dts/mt7986.dtsi
new file mode 100644
index 0000000000..f235bd8b8c
--- /dev/null
+++ b/arch/arm/dts/mt7986.dtsi
@@ -0,0 +1,341 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/clock/mt7986-clk.h>
+#include <dt-bindings/reset/mt7629-reset.h>
+#include <dt-bindings/pinctrl/mt65xx.h>
+
+/ {
+	compatible = "mediatek,mt7986";
+	interrupt-parent = <&gic>;
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	config {
+		u-boot,mmc-env-partition = "u-boot-env";
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0x0>;
+		};
+		cpu1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0x1>;
+		};
+		cpu2: cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0x1>;
+		};
+		cpu3: cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0x1>;
+		};
+	};
+
+	dummy_clk: dummy12m {
+		compatible = "fixed-clock";
+		clock-frequency = <12000000>;
+		#clock-cells = <0>;
+		/* must need this line, or uart uanable to get dummy_clk */
+		u-boot,dm-pre-reloc;
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupt-parent = <&gic>;
+		clock-frequency = <13000000>;
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+		arm,cpu-registers-not-fw-configured;
+	};
+
+	timer0: timer@10008000 {
+		compatible = "mediatek,mt7986-timer";
+		reg = <0x10008000 0x1000>;
+		interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&infracfg CK_INFRA_CK_F26M>;
+		clock-names = "gpt-clk";
+		u-boot,dm-pre-reloc;
+	};
+
+	watchdog: watchdog@1001c000 {
+		compatible = "mediatek,mt7986-wdt";
+		reg = <0x1001c000 0x1000>;
+		interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+		#reset-cells = <1>;
+		status = "disabled";
+	};
+
+	gic: interrupt-controller@c000000 {
+		compatible = "arm,gic-v3";
+		#interrupt-cells = <3>;
+		interrupt-parent = <&gic>;
+		interrupt-controller;
+		reg = <0x0c000000 0x40000>,  /* GICD */
+		      <0x0c080000 0x200000>; /* GICR */
+
+		interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	fixed_plls: apmixedsys@1001E000 {
+		compatible = "mediatek,mt7986-fixed-plls";
+		reg = <0x1001E000 0x1000>;
+		#clock-cells = <1>;
+	};
+
+	topckgen: topckgen@1001B000 {
+		compatible = "mediatek,mt7986-topckgen";
+		reg = <0x1001B000 0x1000>;
+		clock-parent = <&fixed_plls>;
+		#clock-cells = <1>;
+	};
+
+	infracfg_ao: infracfg_ao@10001000 {
+		compatible = "mediatek,mt7986-infracfg_ao";
+		reg = <0x10001000 0x68>;
+		clock-parent = <&infracfg>;
+		#clock-cells = <1>;
+	};
+
+	infracfg: infracfg@10001040 {
+		compatible = "mediatek,mt7986-infracfg";
+		reg = <0x10001000 0x1000>;
+		clock-parent = <&topckgen>;
+		#clock-cells = <1>;
+	};
+
+	pinctrl: pinctrl@1001f000 {
+		compatible = "mediatek,mt7986-pinctrl";
+		reg = <0x1001f000 0x1000>,
+		      <0x11c30000 0x1000>,
+		      <0x11c40000 0x1000>,
+		      <0x11e20000 0x1000>,
+		      <0x11e30000 0x1000>,
+		      <0x11f00000 0x1000>,
+		      <0x11f10000 0x1000>,
+		      <0x1000b000 0x1000>;
+		reg-names = "gpio_base", "iocfg_rt_base", "iocfg_rb_base",
+			    "iocfg_lt_base", "iocfg_lb_base", "iocfg_tr_base",
+			    "iocfg_tl_base", "eint";
+		gpio: gpio-controller {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+	};
+
+	pwm: pwm@10048000 {
+		compatible = "mediatek,mt7986-pwm";
+		reg = <0x10048000 0x1000>;
+		#clock-cells = <1>;
+		#pwm-cells = <2>;
+		interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&infracfg CK_INFRA_PWM>,
+			 <&infracfg_ao CK_INFRA_PWM_BSEL>,
+			 <&infracfg_ao CK_INFRA_PWM1_CK>,
+			 <&infracfg_ao CK_INFRA_PWM2_CK>;
+		assigned-clocks = <&topckgen CK_TOP_PWM_SEL>,
+				  <&infracfg CK_INFRA_PWM_BSEL>,
+				  <&infracfg CK_INFRA_PWM1_SEL>,
+				  <&infracfg CK_INFRA_PWM2_SEL>;
+		assigned-clock-parents = <&topckgen CK_TOP_CB_M_D4>,
+					 <&infracfg CK_INFRA_PWM>,
+					 <&infracfg CK_INFRA_PWM>,
+					 <&infracfg CK_INFRA_PWM>;
+		clock-names = "top", "main", "pwm1", "pwm2";
+		status = "disabled";
+		u-boot,dm-pre-reloc;
+	};
+
+	uart0: serial@11002000 {
+		compatible = "mediatek,hsuart";
+		reg = <0x11002000 0x400>;
+		interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&infracfg_ao CK_INFRA_UART0_CK>;
+		assigned-clocks = <&topckgen CK_TOP_UART_SEL>,
+				  <&infracfg_ao CK_INFRA_UART0_SEL>;
+		assigned-clock-parents = <&topckgen CK_TOP_CB_CKSQ_40M>,
+					 <&infracfg CK_INFRA_UART>;
+		mediatek,force-highspeed;
+		status = "disabled";
+		u-boot,dm-pre-reloc;
+	};
+
+	uart1: serial@11003000 {
+		compatible = "mediatek,hsuart";
+		reg = <0x11003000 0x400>;
+		interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&infracfg_ao CK_INFRA_UART1_CK>;
+		assigned-clocks = <&infracfg CK_INFRA_UART1_SEL>;
+		assigned-clock-parents = <&infracfg CK_INFRA_CK_F26M>;
+		mediatek,force-highspeed;
+		status = "disabled";
+	};
+
+	uart2: serial@11004000 {
+		compatible = "mediatek,hsuart";
+		reg = <0x11004000 0x400>;
+		interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&infracfg_ao CK_INFRA_UART2_CK>;
+		assigned-clocks = <&infracfg CK_INFRA_UART2_SEL>;
+		assigned-clock-parents = <&infracfg CK_INFRA_CK_F26M>;
+		mediatek,force-highspeed;
+		status = "disabled";
+	};
+
+	snand: snand@11005000 {
+		compatible = "mediatek,mt7986-snand";
+		reg = <0x11005000 0x1000>,
+		      <0x11006000 0x1000>;
+		reg-names = "nfi", "ecc";
+		clocks = <&infracfg_ao CK_INFRA_SPINFI1_CK>,
+			 <&infracfg_ao CK_INFRA_NFI1_CK>,
+			 <&infracfg_ao CK_INFRA_NFI_HCK_CK>;
+		clock-names = "pad_clk", "nfi_clk", "nfi_hclk";
+		assigned-clocks = <&topckgen CK_TOP_SPINFI_SEL>,
+				  <&topckgen CK_TOP_NFI1X_SEL>;
+		assigned-clock-parents = <&topckgen CK_TOP_CB_M_D8>,
+					 <&topckgen CK_TOP_CB_M_D8>;
+		status = "disabled";
+	};
+
+	ethsys: syscon@15000000 {
+		compatible = "mediatek,mt7986-ethsys", "syscon";
+		reg = <0x15000000 0x1000>;
+		clock-parent = <&topckgen>;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+	};
+
+	eth: ethernet@15100000 {
+		compatible = "mediatek,mt7986-eth", "syscon";
+		reg = <0x15100000 0x20000>;
+		resets = <&ethsys ETHSYS_FE_RST>;
+		reset-names = "fe";
+		mediatek,ethsys = <&ethsys>;
+		mediatek,sgmiisys = <&sgmiisys0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	sgmiisys0: syscon@10060000 {
+		compatible = "mediatek,mt7986-sgmiisys", "syscon";
+		reg = <0x10060000 0x1000>;
+		#clock-cells = <1>;
+	};
+
+	sgmiisys1: syscon@10070000 {
+		compatible = "mediatek,mt7986-sgmiisys", "syscon";
+		reg = <0x10070000 0x1000>;
+		#clock-cells = <1>;
+	};
+
+	spi0: spi@1100a000 {
+		compatible = "mediatek,ipm-spi";
+		reg = <0x1100a000 0x100>;
+		clocks = <&infracfg_ao CK_INFRA_SPI0_CK>,
+			 <&topckgen CK_TOP_SPI_SEL>;
+		assigned-clocks = <&topckgen CK_TOP_SPI_SEL>,
+				  <&infracfg CK_INFRA_SPI0_SEL>;
+		assigned-clock-parents = <&topckgen CK_TOP_CB_M_D2>,
+					 <&topckgen CK_INFRA_ISPI0>;
+		clock-names = "sel-clk", "spi-clk";
+		interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
+		status = "disabled";
+	};
+
+	spi1: spi@1100b000 {
+		compatible = "mediatek,ipm-spi";
+		reg = <0x1100b000 0x100>;
+		interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
+		status = "disabled";
+	};
+
+	mmc0: mmc@11230000 {
+		compatible = "mediatek,mt7986-mmc";
+		reg = <0x11230000 0x1000>,
+		      <0x11C20000 0x1000>;
+		interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&topckgen CK_TOP_EMMC_416M>,
+			<&topckgen CK_TOP_EMMC_250M>,
+			<&infracfg_ao CK_INFRA_MSDC_CK>;
+		assigned-clocks = <&topckgen CK_TOP_EMMC_416M_SEL>,
+				  <&topckgen CK_TOP_EMMC_250M_SEL>;
+		assigned-clock-parents = <&topckgen CK_TOP_CB_M_416M>,
+					 <&topckgen CK_TOP_NET1_D5_D2>;
+		clock-names = "source", "hclk", "source_cg";
+		status = "disabled";
+	};
+
+	xhci: xhci@11200000 {
+		compatible = "mediatek,mt7986-xhci",
+			     "mediatek,mtk-xhci";
+		reg = <0x11200000 0x2e00>,
+		      <0x11203e00 0x0100>;
+		reg-names = "mac", "ippc";
+		interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
+		phys = <&u2port0 PHY_TYPE_USB2>,
+		       <&u3port0 PHY_TYPE_USB3>,
+		       <&u2port1 PHY_TYPE_USB2>;
+		clocks = <&dummy_clk>,
+			 <&dummy_clk>,
+			 <&dummy_clk>,
+			 <&dummy_clk>,
+			 <&dummy_clk>;
+		clock-names = "sys_ck",
+			      "xhci_ck",
+			      "ref_ck",
+			      "mcu_ck",
+			      "dma_ck";
+		tpl-support;
+		status = "okay";
+	};
+
+	usbtphy: usb-phy@11e10000 {
+		compatible = "mediatek,mt7986",
+			     "mediatek,generic-tphy-v2";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		status = "okay";
+
+		u2port0: usb-phy@11e10000 {
+			reg = <0x11e10000 0x700>;
+			clocks = <&dummy_clk>;
+			clock-names = "ref";
+			#phy-cells = <1>;
+			status = "okay";
+		};
+
+		u3port0: usb-phy@11e10700 {
+			reg = <0x11e10700 0x900>;
+			clocks = <&dummy_clk>;
+			clock-names = "ref";
+			#phy-cells = <1>;
+			status = "okay";
+		};
+
+		u2port1: usb-phy@11e11000 {
+			reg = <0x11e11000 0x700>;
+			clocks = <&dummy_clk>;
+			clock-names = "ref";
+			#phy-cells = <1>;
+			status = "okay";
+		};
+	};
+};
diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
index f79a5c62cd..e059a013db 100644
--- a/arch/arm/mach-mediatek/Kconfig
+++ b/arch/arm/mach-mediatek/Kconfig
@@ -40,6 +40,14 @@ config TARGET_MT7629
 	  including DDR3, crypto engine, 3x3 11n/ac Wi-Fi, Gigabit Ethernet,
 	  switch, USB3.0, PCIe, UART, SPI, I2C and PWM.
 
+config TARGET_MT7986
+	bool "MediaTek MT7986 SoC"
+	select ARM64
+	help
+	  The MediaTek MT7986 is a ARM64-based SoC with a quad-core Cortex-A53.
+	  including UART, SPI, SPI flash, USB3.0, MMC, NAND, SNFI, PWM, PCIe,
+	  Gigabit Ethernet, I2C, built-in 4x4 Wi-Fi, and PCIe.
+
 config TARGET_MT8183
 	bool "MediaTek MT8183 SoC"
 	select ARM64
@@ -84,6 +92,7 @@ config SYS_BOARD
 	default "mt7622" if TARGET_MT7622
 	default "mt7623" if TARGET_MT7623
 	default "mt7629" if TARGET_MT7629
+	default "mt7986" if TARGET_MT7986
 	default "mt8183" if TARGET_MT8183
 	default "mt8512" if TARGET_MT8512
 	default "mt8516" if TARGET_MT8516
@@ -99,6 +108,7 @@ config SYS_CONFIG_NAME
 	default "mt7622" if TARGET_MT7622
 	default "mt7623" if TARGET_MT7623
 	default "mt7629" if TARGET_MT7629
+	default "mt7986" if TARGET_MT7986
 	default "mt8183" if TARGET_MT8183
 	default "mt8512" if TARGET_MT8512
 	default "mt8516" if TARGET_MT8516
@@ -113,6 +123,7 @@ config MTK_BROM_HEADER_INFO
 	string
 	default "media=nor" if TARGET_MT8518 || TARGET_MT8512 || TARGET_MT7629 ||
 TARGET_MT7622
 	default "media=emmc" if TARGET_MT8516 || TARGET_MT8365 || TARGET_MT8183
+	default "media=snand;nandinfo=2k+64" if TARGET_MT7986
 	default "lk=1" if TARGET_MT7623
 
 endif
diff --git a/arch/arm/mach-mediatek/Makefile
 b/arch/arm/mach-mediatek/Makefile
index 0f5b0c16d2..fe5c3a837c 100644
--- a/arch/arm/mach-mediatek/Makefile
+++ b/arch/arm/mach-mediatek/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_MT8512) += mt8512/
 obj-$(CONFIG_TARGET_MT7622) += mt7622/
 obj-$(CONFIG_TARGET_MT7623) += mt7623/
 obj-$(CONFIG_TARGET_MT7629) += mt7629/
+obj-$(CONFIG_TARGET_MT7986) += mt7986/
 obj-$(CONFIG_TARGET_MT8183) += mt8183/
 obj-$(CONFIG_TARGET_MT8516) += mt8516/
 obj-$(CONFIG_TARGET_MT8518) += mt8518/
diff --git a/arch/arm/mach-mediatek/mt7986/Makefile
 b/arch/arm/mach-mediatek/mt7986/Makefile
new file mode 100644
index 0000000000..007eb4a367
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7986/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier:	GPL-2.0
+
+obj-y += init.o
+obj-y += lowlevel_init.o
diff --git a/arch/arm/mach-mediatek/mt7986/init.c
 b/arch/arm/mach-mediatek/mt7986/init.c
new file mode 100644
index 0000000000..4884cbdc67
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7986/init.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+#include <fdtdec.h>
+#include <asm/armv8/mmu.h>
+#include <init.h>
+#include <asm/system.h>
+#include <asm/global_data.h>
+#include <linux/sizes.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int print_cpuinfo(void)
+{
+	printf("CPU:   MediaTek MT7986\n");
+	return 0;
+}
+
+int dram_init(void)
+{
+	gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, SZ_2G);
+
+	return 0;
+}
+
+void reset_cpu(ulong addr)
+{
+	psci_system_reset();
+}
+
+static struct mm_region mt7986_mem_map[] = {
+	{
+		/* DDR */
+		.virt = 0x40000000UL,
+		.phys = 0x40000000UL,
+		.size = 0x80000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE,
+	}, {
+		.virt = 0x00000000UL,
+		.phys = 0x00000000UL,
+		.size = 0x40000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}, {
+		0,
+	}
+};
+
+struct mm_region *mem_map = mt7986_mem_map;
diff --git a/arch/arm/mach-mediatek/mt7986/lowlevel_init.S
 b/arch/arm/mach-mediatek/mt7986/lowlevel_init.S
new file mode 100644
index 0000000000..244d2c1385
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7986/lowlevel_init.S
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+/*
+ * Switch from AArch64 EL2 to AArch32 EL2
+ * @param inputs:
+ * x0: argument, zero
+ * x1: machine nr
+ * x2: fdt address
+ * x3: input argument
+ * x4: kernel entry point
+ * @param outputs for secure firmware:
+ * x0: function id
+ * x1: kernel entry point
+ * x2: machine nr
+ * x3: fdt address
+*/
+
+.global armv8_el2_to_aarch32
+armv8_el2_to_aarch32:
+	mov     x3, x2
+	mov     x2, x1
+	mov     x1, x4
+	mov	x4, #0
+	ldr x0, =0x82000200
+	SMC #0
+	ret
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 02/31] arm: mediatek: add support for MediaTek MT7981 SoC
  2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
  2022-08-04  3:34 ` [PATCH 01/31] arm: mediatek: add support for MediaTek MT7986 SoC Weijie Gao
@ 2022-08-04  3:34 ` Weijie Gao
  2022-08-04 13:57   ` Simon Glass
  2022-08-04  3:35 ` [PATCH 03/31] board: mediatek: add MT7986 reference boards Weijie Gao
                   ` (28 subsequent siblings)
  30 siblings, 1 reply; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:34 UTC (permalink / raw)
  To: u-boot; +Cc: GSS_MTK_Uboot_upstream, Weijie Gao

This patch adds basic support for MediaTek MT7981 SoC.
This include the file that will initialize the SoC after boot and its
device tree.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 arch/arm/dts/mt7981.dtsi                      | 288 ++++++++++++++++++
 arch/arm/mach-mediatek/Kconfig                |  12 +-
 arch/arm/mach-mediatek/Makefile               |   1 +
 arch/arm/mach-mediatek/mt7981/Makefile        |   4 +
 arch/arm/mach-mediatek/mt7981/init.c          |  52 ++++
 arch/arm/mach-mediatek/mt7981/lowlevel_init.S |  30 ++
 6 files changed, 386 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/dts/mt7981.dtsi
 create mode 100644 arch/arm/mach-mediatek/mt7981/Makefile
 create mode 100644 arch/arm/mach-mediatek/mt7981/init.c
 create mode 100644 arch/arm/mach-mediatek/mt7981/lowlevel_init.S

diff --git a/arch/arm/dts/mt7981.dtsi b/arch/arm/dts/mt7981.dtsi
new file mode 100644
index 0000000000..11609dc484
--- /dev/null
+++ b/arch/arm/dts/mt7981.dtsi
@@ -0,0 +1,288 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/mt7981-clk.h>
+#include <dt-bindings/reset/mt7629-reset.h>
+#include <dt-bindings/pinctrl/mt65xx.h>
+
+/ {
+	compatible = "mediatek,mt7981";
+	interrupt-parent = <&gic>;
+	#address-cells = <1>;
+	#size-cells = <1>;
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0x0>;
+		};
+		cpu1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0x1>;
+		};
+	};
+
+	gpt_clk: gpt_dummy20m {
+		compatible = "fixed-clock";
+		clock-frequency = <13000000>;
+		#clock-cells = <0>;
+		u-boot,dm-pre-reloc;
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupt-parent = <&gic>;
+		clock-frequency = <13000000>;
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+		arm,cpu-registers-not-fw-configured;
+	};
+
+	timer0: timer@10008000 {
+		compatible = "mediatek,mt7986-timer";
+		reg = <0x10008000 0x1000>;
+		interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&gpt_clk>;
+		clock-names = "gpt-clk";
+		u-boot,dm-pre-reloc;
+	};
+
+	watchdog: watchdog@1001c000 {
+		compatible = "mediatek,mt7986-wdt";
+		reg = <0x1001c000 0x1000>;
+		interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+		#reset-cells = <1>;
+		status = "disabled";
+	};
+
+	gic: interrupt-controller@c000000 {
+		compatible = "arm,gic-v3";
+		#interrupt-cells = <3>;
+		interrupt-parent = <&gic>;
+		interrupt-controller;
+		reg = <0x0c000000 0x40000>,  /* GICD */
+		      <0x0c080000 0x200000>; /* GICR */
+
+		interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	fixed_plls: apmixedsys@1001e000 {
+		compatible = "mediatek,mt7981-fixed-plls";
+		reg = <0x1001e000 0x1000>;
+		#clock-cells = <1>;
+		u-boot,dm-pre-reloc;
+	};
+
+	topckgen: topckgen@1001b000 {
+		compatible = "mediatek,mt7981-topckgen";
+		reg = <0x1001b000 0x1000>;
+		clock-parent = <&fixed_plls>;
+		#clock-cells = <1>;
+		u-boot,dm-pre-reloc;
+	};
+
+	infracfg_ao: infracfg_ao@10001000 {
+		compatible = "mediatek,mt7981-infracfg_ao";
+		reg = <0x10001000 0x80>;
+		clock-parent = <&infracfg>;
+		#clock-cells = <1>;
+		u-boot,dm-pre-reloc;
+	};
+
+	infracfg: infracfg@10001000 {
+		compatible = "mediatek,mt7981-infracfg";
+		reg = <0x10001000 0x30>;
+		clock-parent = <&topckgen>;
+		#clock-cells = <1>;
+		u-boot,dm-pre-reloc;
+	};
+
+	pinctrl: pinctrl@11d00000 {
+		compatible = "mediatek,mt7981-pinctrl";
+		reg = <0x11d00000 0x1000>,
+		      <0x11c00000 0x1000>,
+		      <0x11c10000 0x1000>,
+		      <0x11d20000 0x1000>,
+		      <0x11e00000 0x1000>,
+		      <0x11e20000 0x1000>,
+		      <0x11f00000 0x1000>,
+		      <0x11f10000 0x1000>,
+		      <0x1000b000 0x1000>;
+		reg-names = "gpio_base", "iocfg_rt_base", "iocfg_rm_base",
+			    "iocfg_rb_base", "iocfg_lb_base", "iocfg_bl_base",
+			    "iocfg_tm_base", "iocfg_tl_base", "eint";
+		gpio: gpio-controller {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+	};
+
+	pwm: pwm@10048000 {
+		compatible = "mediatek,mt7981-pwm";
+		reg = <0x10048000 0x1000>;
+		#clock-cells = <1>;
+		#pwm-cells = <2>;
+		interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&infracfg CK_INFRA_PWM>,
+			 <&infracfg_ao CK_INFRA_PWM_BSEL>,
+			 <&infracfg_ao CK_INFRA_PWM1_CK>,
+			 <&infracfg_ao CK_INFRA_PWM2_CK>,
+			 /* FIXME */
+			 <&infracfg_ao CK_INFRA_PWM2_CK>;
+		assigned-clocks = <&topckgen CK_TOP_PWM_SEL>;
+		assigned-clock-parents = <&topckgen CK_TOP_CB_CKSQ_40M>;
+		clock-names = "top", "main", "pwm1", "pwm2", "pwm3";
+		status = "disabled";
+	};
+
+	uart0: serial@11002000 {
+		compatible = "mediatek,hsuart";
+		reg = <0x11002000 0x400>;
+		interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&infracfg_ao CK_INFRA_UART0_CK>;
+		assigned-clocks = <&topckgen CK_TOP_UART_SEL>,
+				  <&infracfg_ao CK_INFRA_UART0_SEL>;
+		assigned-clock-parents = <&topckgen CK_TOP_CB_CKSQ_40M>,
+					 <&infracfg CK_INFRA_UART>;
+		mediatek,force-highspeed;
+		status = "disabled";
+		u-boot,dm-pre-reloc;
+	};
+
+	uart1: serial@11003000 {
+		compatible = "mediatek,hsuart";
+		reg = <0x11003000 0x400>;
+		interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&infracfg_ao CK_INFRA_UART1_CK>;
+		assigned-clocks = <&topckgen CK_TOP_UART_SEL>,
+				  <&infracfg_ao CK_INFRA_UART1_SEL>;
+		assigned-clock-parents = <&topckgen CK_TOP_CB_CKSQ_40M>,
+					 <&infracfg CK_INFRA_UART>;
+		mediatek,force-highspeed;
+		status = "disabled";
+	};
+
+	uart2: serial@11004000 {
+		compatible = "mediatek,hsuart";
+		reg = <0x11004000 0x400>;
+		interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&infracfg_ao CK_INFRA_UART2_CK>;
+		assigned-clocks = <&topckgen CK_TOP_UART_SEL>,
+				  <&infracfg_ao CK_INFRA_UART2_SEL>;
+		assigned-clock-parents = <&topckgen CK_TOP_CB_CKSQ_40M>,
+					 <&infracfg CK_INFRA_UART>;
+		mediatek,force-highspeed;
+		status = "disabled";
+	};
+
+	snand: snand@11005000 {
+		compatible = "mediatek,mt7986-snand";
+		reg = <0x11005000 0x1000>,
+		      <0x11006000 0x1000>;
+		reg-names = "nfi", "ecc";
+		clocks = <&infracfg_ao CK_INFRA_SPINFI1_CK>,
+			 <&infracfg_ao CK_INFRA_NFI1_CK>,
+			 <&infracfg_ao CK_INFRA_NFI_HCK_CK>;
+		clock-names = "pad_clk", "nfi_clk", "nfi_hclk";
+		assigned-clocks = <&topckgen CK_TOP_SPINFI_SEL>,
+				  <&topckgen CK_TOP_NFI1X_SEL>;
+		assigned-clock-parents = <&topckgen CK_TOP_CB_M_D8>,
+					 <&topckgen CK_TOP_CB_M_D8>;
+		status = "disabled";
+	};
+
+	ethsys: syscon@15000000 {
+		compatible = "mediatek,mt7981-ethsys", "syscon";
+		reg = <0x15000000 0x1000>;
+		clock-parent = <&topckgen>;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+	};
+
+	eth: ethernet@15100000 {
+		compatible = "mediatek,mt7981-eth", "syscon";
+		reg = <0x15100000 0x20000>;
+		resets = <&ethsys ETHSYS_FE_RST>;
+		reset-names = "fe";
+		mediatek,ethsys = <&ethsys>;
+		mediatek,sgmiisys = <&sgmiisys0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	sgmiisys0: syscon@10060000 {
+		compatible = "mediatek,mt7986-sgmiisys", "syscon";
+		reg = <0x10060000 0x1000>;
+		pn_swap;
+		#clock-cells = <1>;
+	};
+
+	sgmiisys1: syscon@10070000 {
+		compatible = "mediatek,mt7986-sgmiisys", "syscon";
+		reg = <0x10070000 0x1000>;
+		#clock-cells = <1>;
+	};
+
+	spi0: spi@1100a000 {
+		compatible = "mediatek,ipm-spi";
+		reg = <0x1100a000 0x100>;
+		clocks = <&infracfg_ao CK_INFRA_SPI0_CK>,
+			 <&topckgen CK_TOP_SPI_SEL>;
+		assigned-clocks = <&topckgen CK_TOP_SPI_SEL>,
+				  <&infracfg CK_INFRA_SPI0_SEL>;
+		assigned-clock-parents = <&topckgen CK_TOP_CB_M_D2>,
+					 <&topckgen CK_INFRA_ISPI0>;
+		clock-names = "sel-clk", "spi-clk";
+		interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
+		status = "disabled";
+	};
+
+	spi1: spi@1100b000 {
+		compatible = "mediatek,ipm-spi";
+		reg = <0x1100b000 0x100>;
+		interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
+		status = "disabled";
+	};
+
+	spi2: spi@11009000 {
+		compatible = "mediatek,ipm-spi";
+		reg = <0x11009000 0x100>;
+		clocks = <&infracfg_ao CK_INFRA_SPI0_CK>,
+			 <&topckgen CK_TOP_SPI_SEL>;
+		assigned-clocks = <&topckgen CK_TOP_SPI_SEL>,
+				  <&infracfg CK_INFRA_SPI0_SEL>;
+		assigned-clock-parents = <&topckgen CK_TOP_CB_M_D2>,
+					 <&topckgen CK_INFRA_ISPI0>;
+		clock-names = "sel-clk", "spi-clk";
+		interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>;
+		status = "disabled";
+	};
+
+	mmc0: mmc@11230000 {
+		compatible = "mediatek,mt7981-mmc";
+		reg = <0x11230000 0x1000>,
+		      <0x11C20000 0x1000>;
+		interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&topckgen CK_TOP_EMMC_400M>,
+			 <&topckgen CK_TOP_EMMC_208M>,
+			 <&infracfg_ao CK_INFRA_MSDC_CK>;
+		assigned-clocks = <&topckgen CK_TOP_EMMC_400M_SEL>,
+				  <&topckgen CK_TOP_EMMC_208M_SEL>;
+		assigned-clock-parents = <&topckgen CK_TOP_CB_NET2_D2>,
+					 <&topckgen CK_TOP_CB_M_D2>;
+		clock-names = "source", "hclk", "source_cg";
+		status = "disabled";
+	};
+
+};
diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
index e059a013db..a5fc6e0978 100644
--- a/arch/arm/mach-mediatek/Kconfig
+++ b/arch/arm/mach-mediatek/Kconfig
@@ -40,6 +40,14 @@ config TARGET_MT7629
 	  including DDR3, crypto engine, 3x3 11n/ac Wi-Fi, Gigabit Ethernet,
 	  switch, USB3.0, PCIe, UART, SPI, I2C and PWM.
 
+config TARGET_MT7981
+	bool "MediaTek MT7981 SoC"
+	select ARM64
+	help
+	  The MediaTek MT7981 is a ARM64-based SoC with a dual-core Cortex-A53.
+	  including UART, SPI, USB, NAND, SNFI, PWM, Gigabit Ethernet, I2C,
+          built-in Wi-Fi, and PCIe.
+
 config TARGET_MT7986
 	bool "MediaTek MT7986 SoC"
 	select ARM64
@@ -92,6 +100,7 @@ config SYS_BOARD
 	default "mt7622" if TARGET_MT7622
 	default "mt7623" if TARGET_MT7623
 	default "mt7629" if TARGET_MT7629
+	default "mt7981" if TARGET_MT7981
 	default "mt7986" if TARGET_MT7986
 	default "mt8183" if TARGET_MT8183
 	default "mt8512" if TARGET_MT8512
@@ -108,6 +117,7 @@ config SYS_CONFIG_NAME
 	default "mt7622" if TARGET_MT7622
 	default "mt7623" if TARGET_MT7623
 	default "mt7629" if TARGET_MT7629
+	default "mt7981" if TARGET_MT7981
 	default "mt7986" if TARGET_MT7986
 	default "mt8183" if TARGET_MT8183
 	default "mt8512" if TARGET_MT8512
@@ -123,7 +133,7 @@ config MTK_BROM_HEADER_INFO
 	string
 	default "media=nor" if TARGET_MT8518 || TARGET_MT8512 || TARGET_MT7629 ||
 TARGET_MT7622
 	default "media=emmc" if TARGET_MT8516 || TARGET_MT8365 || TARGET_MT8183
-	default "media=snand;nandinfo=2k+64" if TARGET_MT7986
+	default "media=snand;nandinfo=2k+64" if TARGET_MT7981 || TARGET_MT7986
 	default "lk=1" if TARGET_MT7623
 
 endif
diff --git a/arch/arm/mach-mediatek/Makefile
 b/arch/arm/mach-mediatek/Makefile
index fe5c3a837c..fc85293f71 100644
--- a/arch/arm/mach-mediatek/Makefile
+++ b/arch/arm/mach-mediatek/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_MT8512) += mt8512/
 obj-$(CONFIG_TARGET_MT7622) += mt7622/
 obj-$(CONFIG_TARGET_MT7623) += mt7623/
 obj-$(CONFIG_TARGET_MT7629) += mt7629/
+obj-$(CONFIG_TARGET_MT7981) += mt7981/
 obj-$(CONFIG_TARGET_MT7986) += mt7986/
 obj-$(CONFIG_TARGET_MT8183) += mt8183/
 obj-$(CONFIG_TARGET_MT8516) += mt8516/
diff --git a/arch/arm/mach-mediatek/mt7981/Makefile
 b/arch/arm/mach-mediatek/mt7981/Makefile
new file mode 100644
index 0000000000..007eb4a367
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7981/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier:	GPL-2.0
+
+obj-y += init.o
+obj-y += lowlevel_init.o
diff --git a/arch/arm/mach-mediatek/mt7981/init.c
 b/arch/arm/mach-mediatek/mt7981/init.c
new file mode 100644
index 0000000000..f503bb804b
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7981/init.c
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+#include <fdtdec.h>
+#include <asm/armv8/mmu.h>
+#include <init.h>
+#include <asm/system.h>
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int print_cpuinfo(void)
+{
+	printf("CPU:   MediaTek MT7981\n");
+	return 0;
+}
+
+int dram_init(void)
+{
+	gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, SZ_2G);
+
+	return 0;
+}
+
+void reset_cpu(ulong addr)
+{
+	psci_system_reset();
+}
+
+static struct mm_region mt7981_mem_map[] = {
+	{
+		/* DDR */
+		.virt = 0x40000000UL,
+		.phys = 0x40000000UL,
+		.size = 0x80000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE,
+	}, {
+		.virt = 0x00000000UL,
+		.phys = 0x00000000UL,
+		.size = 0x40000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}, {
+		0,
+	}
+};
+
+struct mm_region *mem_map = mt7981_mem_map;
diff --git a/arch/arm/mach-mediatek/mt7981/lowlevel_init.S
 b/arch/arm/mach-mediatek/mt7981/lowlevel_init.S
new file mode 100644
index 0000000000..244d2c1385
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7981/lowlevel_init.S
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+/*
+ * Switch from AArch64 EL2 to AArch32 EL2
+ * @param inputs:
+ * x0: argument, zero
+ * x1: machine nr
+ * x2: fdt address
+ * x3: input argument
+ * x4: kernel entry point
+ * @param outputs for secure firmware:
+ * x0: function id
+ * x1: kernel entry point
+ * x2: machine nr
+ * x3: fdt address
+*/
+
+.global armv8_el2_to_aarch32
+armv8_el2_to_aarch32:
+	mov     x3, x2
+	mov     x2, x1
+	mov     x1, x4
+	mov	x4, #0
+	ldr x0, =0x82000200
+	SMC #0
+	ret
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 03/31] board: mediatek: add MT7986 reference boards
  2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
  2022-08-04  3:34 ` [PATCH 01/31] arm: mediatek: add support for MediaTek MT7986 SoC Weijie Gao
  2022-08-04  3:34 ` [PATCH 02/31] arm: mediatek: add support for MediaTek MT7981 SoC Weijie Gao
@ 2022-08-04  3:35 ` Weijie Gao
  2022-08-04 13:57   ` Simon Glass
  2022-08-09  9:10   ` Daniel Golle
  2022-08-04  3:35 ` [PATCH 04/31] board: mediatek: add MT7981 " Weijie Gao
                   ` (27 subsequent siblings)
  30 siblings, 2 replies; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:35 UTC (permalink / raw)
  To: u-boot
  Cc: GSS_MTK_Uboot_upstream, Simon Glass, Marcel Ziswiler,
	Andre Przywara, Fabio Estevam, Samuel Holland, Marek Vasut,
	Ying-Chun Liu (PaulLiu),
	Christian Hewitt, Weijie Gao

This patch adds general board files based on MT7986 SoCs.

The SD/eMMC controller on MT7986A and MT7986B have different pin
configurations so that four different reference board configs has to be
added.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 arch/arm/dts/Makefile              |   4 +
 arch/arm/dts/mt7986a-rfb.dts       | 218 +++++++++++++++++++++++++++++
 arch/arm/dts/mt7986a-sd-rfb.dts    | 177 +++++++++++++++++++++++
 arch/arm/dts/mt7986b-rfb.dts       | 204 +++++++++++++++++++++++++++
 arch/arm/dts/mt7986b-sd-rfb.dts    | 173 +++++++++++++++++++++++
 board/mediatek/mt7986/MAINTAINERS  |  10 ++
 board/mediatek/mt7986/Makefile     |   3 +
 board/mediatek/mt7986/mt7986_rfb.c |  10 ++
 configs/mt7986_rfb_defconfig       |  66 +++++++++
 configs/mt7986a_emmc_rfb_defconfig |  64 +++++++++
 configs/mt7986a_sd_rfb_defconfig   |  64 +++++++++
 configs/mt7986b_emmc_rfb_defconfig |  64 +++++++++
 configs/mt7986b_sd_rfb_defconfig   |  64 +++++++++
 include/configs/mt7986.h           |  26 ++++
 14 files changed, 1147 insertions(+)
 create mode 100644 arch/arm/dts/mt7986a-rfb.dts
 create mode 100644 arch/arm/dts/mt7986a-sd-rfb.dts
 create mode 100644 arch/arm/dts/mt7986b-rfb.dts
 create mode 100644 arch/arm/dts/mt7986b-sd-rfb.dts
 create mode 100644 board/mediatek/mt7986/MAINTAINERS
 create mode 100644 board/mediatek/mt7986/Makefile
 create mode 100644 board/mediatek/mt7986/mt7986_rfb.c
 create mode 100644 configs/mt7986_rfb_defconfig
 create mode 100644 configs/mt7986a_emmc_rfb_defconfig
 create mode 100644 configs/mt7986a_sd_rfb_defconfig
 create mode 100644 configs/mt7986b_emmc_rfb_defconfig
 create mode 100644 configs/mt7986b_sd_rfb_defconfig
 create mode 100644 include/configs/mt7986.h

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index ceaa39e4b4..eeb08116c0 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -1226,6 +1226,10 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \
 	mt7622-bananapi-bpi-r64.dtb \
 	mt7623n-bananapi-bpi-r2.dtb \
 	mt7629-rfb.dtb \
+	mt7986a-rfb.dtb \
+	mt7986b-rfb.dtb \
+	mt7986a-sd-rfb.dtb \
+	mt7986b-sd-rfb.dtb \
 	mt8183-pumpkin.dtb \
 	mt8512-bm1-emmc.dtb \
 	mt8516-pumpkin.dtb \
diff --git a/arch/arm/dts/mt7986a-rfb.dts b/arch/arm/dts/mt7986a-rfb.dts
new file mode 100644
index 0000000000..80def57e1a
--- /dev/null
+++ b/arch/arm/dts/mt7986a-rfb.dts
@@ -0,0 +1,218 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+/dts-v1/;
+#include "mt7986.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	model = "mt7986-rfb";
+	compatible = "mediatek,mt7986", "mediatek,mt7986-rfb";
+	chosen {
+		stdout-path = &uart0;
+		tick-timer = &timer0;
+	};
+
+	reg_1p8v: regulator-1p8v {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-1.8V";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	reg_3p3v: regulator-3p3v {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-3.3V";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins>;
+	status = "disabled";
+};
+
+&eth {
+	status = "okay";
+	mediatek,gmac-id = <0>;
+	phy-mode = "sgmii";
+	mediatek,switch = "mt7531";
+	reset-gpios = <&gpio 5 GPIO_ACTIVE_HIGH>;
+
+	fixed-link {
+		speed = <1000>;
+		full-duplex;
+	};
+};
+
+&pinctrl {
+	spi_flash_pins: spi0-pins-func-1 {
+		mux {
+			function = "flash";
+			groups = "spi0", "spi0_wp_hold";
+		};
+
+		conf-pu {
+			pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP";
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_11>;
+		};
+
+		conf-pd {
+			pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO";
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_11>;
+		};
+	};
+
+	snfi_pins: snfi-pins-func-1 {
+		mux {
+			function = "flash";
+			groups = "snfi";
+		};
+
+		clk {
+			pins = "SPI0_CLK";
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_00>;
+		};
+
+		conf-pu {
+			pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP";
+			drive-strength = <MTK_DRIVE_6mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_00>;
+		};
+
+		conf-pd {
+			pins = "SPI0_MOSI", "SPI0_MISO";
+			drive-strength = <MTK_DRIVE_6mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_00>;
+		};
+	};
+
+	spic_pins: spi1-pins-func-1 {
+		mux {
+			function = "spi";
+			groups = "spi1_2";
+		};
+	};
+
+	uart1_pins: spi1-pins-func-3 {
+		mux {
+			function = "uart";
+			groups = "uart1_2";
+		};
+	};
+
+	pwm_pins: pwm0-pins-func-1 {
+		mux {
+			function = "pwm";
+			groups = "pwm0";
+		};
+	};
+
+	mmc0_pins_default: mmc0default {
+		mux {
+			function = "flash";
+			groups =  "emmc_51";
+		};
+
+		conf-cmd-dat {
+			pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2",
+			       "EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5",
+			       "EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD";
+			input-enable;
+			drive-strength = <MTK_DRIVE_4mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+
+		conf-clk {
+			pins = "EMMC_CK";
+			drive-strength = <MTK_DRIVE_6mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+		};
+
+		conf-dsl {
+			pins = "EMMC_DSL";
+			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+		};
+
+		conf-rst {
+			pins = "EMMC_RSTB";
+			drive-strength = <MTK_DRIVE_4mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+	};
+};
+
+&snand {
+	pinctrl-names = "default";
+	pinctrl-0 = <&snfi_pins>;
+	status = "okay";
+	quad-spi;
+};
+
+&spi0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi_flash_pins>;
+	status = "okay";
+	must_tx;
+	enhance_timing;
+	dma_ext;
+	ipm_design;
+	support_quad;
+	tick_dly = <2>;
+	sample_sel = <0>;
+
+	spi_nor@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <52000000>;
+	};
+
+	spi_nand@1 {
+		compatible = "spi-nand";
+		reg = <1>;
+		spi-max-frequency = <52000000>;
+	};
+};
+
+&pwm {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pwm_pins>;
+	status = "okay";
+};
+
+&watchdog {
+	status = "disabled";
+};
+
+&mmc0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc0_pins_default>;
+	bus-width = <8>;
+	max-frequency = <52000000>;
+	cap-mmc-highspeed;
+	cap-mmc-hw-reset;
+	vmmc-supply = <&reg_3p3v>;
+	vqmmc-supply = <&reg_1p8v>;
+	non-removable;
+	status = "okay";
+};
diff --git a/arch/arm/dts/mt7986a-sd-rfb.dts
 b/arch/arm/dts/mt7986a-sd-rfb.dts
new file mode 100644
index 0000000000..5807c5d5cc
--- /dev/null
+++ b/arch/arm/dts/mt7986a-sd-rfb.dts
@@ -0,0 +1,177 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+/dts-v1/;
+#include "mt7986.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	model = "mt7986-rfb";
+	compatible = "mediatek,mt7986", "mediatek,mt7986-rfb",
+		     "mediatek,mt7986-sd-rfb";
+	chosen {
+		stdout-path = &uart0;
+		tick-timer = &timer0;
+	};
+
+	reg_3p3v: regulator-3p3v {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-3.3V";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins>;
+	status = "disabled";
+};
+
+&eth {
+	status = "okay";
+	mediatek,gmac-id = <0>;
+	phy-mode = "sgmii";
+	mediatek,switch = "mt7531";
+	reset-gpios = <&gpio 5 GPIO_ACTIVE_HIGH>;
+
+	fixed-link {
+		speed = <1000>;
+		full-duplex;
+	};
+};
+
+&pinctrl {
+	spi_flash_pins: spi0-pins-func-1 {
+		mux {
+			function = "flash";
+			groups = "spi0", "spi0_wp_hold";
+		};
+
+		conf-pu {
+			pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP";
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_11>;
+		};
+
+		conf-pd {
+			pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO";
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_11>;
+		};
+	};
+
+	spic_pins: spi1-pins-func-1 {
+		mux {
+			function = "spi";
+			groups = "spi1_2";
+		};
+	};
+
+	uart1_pins: spi1-pins-func-3 {
+		mux {
+			function = "uart";
+			groups = "uart1_2";
+		};
+	};
+
+	pwm_pins: pwm0-pins-func-1 {
+		mux {
+			function = "pwm";
+			groups = "pwm0";
+		};
+	};
+
+	mmc0_pins_default: mmc0default {
+		mux {
+			function = "flash";
+			groups =  "emmc_51";
+		};
+
+		conf-cmd-dat {
+			pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2",
+			       "EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5",
+			       "EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD";
+			input-enable;
+			drive-strength = <MTK_DRIVE_4mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+
+		conf-clk {
+			pins = "EMMC_CK";
+			drive-strength = <MTK_DRIVE_6mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+		};
+
+		conf-dsl {
+			pins = "EMMC_DSL";
+			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+		};
+
+		conf-rst {
+			pins = "EMMC_RSTB";
+			drive-strength = <MTK_DRIVE_4mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+	};
+};
+
+&spi0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi_flash_pins>;
+	status = "okay";
+	must_tx;
+	enhance_timing;
+	dma_ext;
+	ipm_design;
+	support_quad;
+	tick_dly = <2>;
+	sample_sel = <0>;
+
+	spi_nor@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <52000000>;
+	};
+
+	spi_nand@1 {
+		compatible = "spi-nand";
+		reg = <1>;
+		spi-max-frequency = <52000000>;
+	};
+};
+
+&pwm {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pwm_pins>;
+	status = "okay";
+};
+
+&watchdog {
+	status = "disabled";
+};
+
+&mmc0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc0_pins_default>;
+	bus-width = <4>;
+	max-frequency = <52000000>;
+	cap-sd-highspeed;
+	r_smpl = <1>;
+	vmmc-supply = <&reg_3p3v>;
+	vqmmc-supply = <&reg_3p3v>;
+	status = "okay";
+};
diff --git a/arch/arm/dts/mt7986b-rfb.dts b/arch/arm/dts/mt7986b-rfb.dts
new file mode 100644
index 0000000000..0c4e3e878f
--- /dev/null
+++ b/arch/arm/dts/mt7986b-rfb.dts
@@ -0,0 +1,204 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+/dts-v1/;
+#include "mt7986.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	model = "mt7986-rfb";
+	compatible = "mediatek,mt7986", "mediatek,mt7986-rfb";
+	chosen {
+		stdout-path = &uart0;
+		tick-timer = &timer0;
+	};
+
+	reg_3p3v: regulator-3p3v {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-3.3V";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins>;
+	status = "disabled";
+};
+
+&eth {
+	status = "okay";
+	mediatek,gmac-id = <0>;
+	phy-mode = "sgmii";
+	mediatek,switch = "mt7531";
+	reset-gpios = <&gpio 5 GPIO_ACTIVE_HIGH>;
+
+	fixed-link {
+		speed = <1000>;
+		full-duplex;
+	};
+};
+
+&pinctrl {
+	spi_flash_pins: spi0-pins-func-1 {
+		mux {
+			function = "flash";
+			groups = "spi0", "spi0_wp_hold";
+		};
+
+		conf-pu {
+			pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP";
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_11>;
+		};
+
+		conf-pd {
+			pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO";
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_11>;
+		};
+	};
+
+	snfi_pins: snfi-pins-func-1 {
+		mux {
+			function = "flash";
+			groups = "snfi";
+		};
+
+		clk {
+			pins = "SPI0_CLK";
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_00>;
+		};
+
+		conf-pu {
+			pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP";
+			drive-strength = <MTK_DRIVE_6mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_00>;
+		};
+
+		conf-pd {
+			pins = "SPI0_MOSI", "SPI0_MISO";
+			drive-strength = <MTK_DRIVE_6mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_00>;
+		};
+	};
+
+	spic_pins: spi1-pins-func-1 {
+		mux {
+			function = "spi";
+			groups = "spi1_2";
+		};
+	};
+
+	uart1_pins: spi1-pins-func-3 {
+		mux {
+			function = "uart";
+			groups = "uart1_2";
+		};
+	};
+
+	pwm_pins: pwm0-pins-func-1 {
+		mux {
+			function = "pwm";
+			groups = "pwm0";
+		};
+	};
+
+	mmc0_pins_default: mmc0default {
+		mux {
+			function = "flash";
+			groups =  "emmc_45";
+			input-schmitt-enable;
+		};
+
+		conf-cmd-dat {
+			pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO",
+			       "SPI0_CS", "SPI0_HOLD", "SPI0_WP",
+			       "SPI1_CLK", "SPI1_MOSI", "SPI1_MISO";
+			input-enable;
+			drive-strength = <MTK_DRIVE_4mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+
+		conf-clk {
+			pins = "SPI1_CS";
+			drive-strength = <MTK_DRIVE_6mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+		};
+
+		conf-rst {
+			pins = "PWM1";
+			drive-strength = <MTK_DRIVE_4mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+	};
+};
+
+&snand {
+	pinctrl-names = "default";
+	pinctrl-0 = <&snfi_pins>;
+	status = "okay";
+	quad-spi;
+};
+
+&spi0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi_flash_pins>;
+	status = "okay";
+	must_tx;
+	enhance_timing;
+	dma_ext;
+	ipm_design;
+	support_quad;
+	tick_dly = <2>;
+	sample_sel = <0>;
+
+	spi_nor@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <52000000>;
+	};
+
+	spi_nand@1 {
+		compatible = "spi-nand";
+		reg = <1>;
+		spi-max-frequency = <52000000>;
+	};
+};
+
+&pwm {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pwm_pins>;
+	status = "okay";
+};
+
+&watchdog {
+	status = "disabled";
+};
+
+&mmc0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc0_pins_default>;
+	bus-width = <8>;
+	max-frequency = <52000000>;
+	cap-mmc-highspeed;
+	cap-mmc-hw-reset;
+	vmmc-supply = <&reg_3p3v>;
+	non-removable;
+	status = "okay";
+};
diff --git a/arch/arm/dts/mt7986b-sd-rfb.dts
 b/arch/arm/dts/mt7986b-sd-rfb.dts
new file mode 100644
index 0000000000..48f9320e7a
--- /dev/null
+++ b/arch/arm/dts/mt7986b-sd-rfb.dts
@@ -0,0 +1,173 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+/dts-v1/;
+#include "mt7986.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	model = "mt7986-rfb";
+	compatible = "mediatek,mt7986", "mediatek,mt7986-rfb",
+		     "mediatek,mt7986-sd-rfb";
+	chosen {
+		stdout-path = &uart0;
+		tick-timer = &timer0;
+	};
+
+	reg_3p3v: regulator-3p3v {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-3.3V";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins>;
+	status = "disabled";
+};
+
+&eth {
+	status = "okay";
+	mediatek,gmac-id = <0>;
+	phy-mode = "sgmii";
+	mediatek,switch = "mt7531";
+	reset-gpios = <&gpio 5 GPIO_ACTIVE_HIGH>;
+
+	fixed-link {
+		speed = <1000>;
+		full-duplex;
+	};
+};
+
+&pinctrl {
+	spi_flash_pins: spi0-pins-func-1 {
+		mux {
+			function = "flash";
+			groups = "spi0", "spi0_wp_hold";
+		};
+
+		conf-pu {
+			pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP";
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_11>;
+		};
+
+		conf-pd {
+			pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO";
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_11>;
+		};
+	};
+
+	spic_pins: spi1-pins-func-1 {
+		mux {
+			function = "spi";
+			groups = "spi1_2";
+		};
+	};
+
+	uart1_pins: spi1-pins-func-3 {
+		mux {
+			function = "uart";
+			groups = "uart1_2";
+		};
+	};
+
+	pwm_pins: pwm0-pins-func-1 {
+		mux {
+			function = "pwm";
+			groups = "pwm0";
+		};
+	};
+
+	mmc0_pins_default: mmc0default {
+		mux {
+			function = "flash";
+			groups =  "emmc_45";
+			input-schmitt-enable;
+		};
+
+		conf-cmd-dat {
+			pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO",
+			       "SPI0_CS", "SPI0_HOLD", "SPI0_WP",
+			       "SPI1_CLK", "SPI1_MOSI", "SPI1_MISO";
+			input-enable;
+			drive-strength = <MTK_DRIVE_4mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+
+		conf-clk {
+			pins = "SPI1_CS";
+			drive-strength = <MTK_DRIVE_6mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+		};
+
+		conf-rst {
+			pins = "PWM1";
+			drive-strength = <MTK_DRIVE_4mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+	};
+};
+
+&spi0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi_flash_pins>;
+	status = "okay";
+	must_tx;
+	enhance_timing;
+	dma_ext;
+	ipm_design;
+	support_quad;
+	tick_dly = <2>;
+	sample_sel = <0>;
+
+	spi_nor@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <52000000>;
+	};
+
+	spi_nand@1 {
+		compatible = "spi-nand";
+		reg = <1>;
+		spi-max-frequency = <52000000>;
+	};
+};
+
+&pwm {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pwm_pins>;
+	status = "okay";
+};
+
+&watchdog {
+	status = "disabled";
+};
+
+&mmc0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc0_pins_default>;
+	bus-width = <4>;
+	max-frequency = <52000000>;
+	cap-sd-highspeed;
+	r_smpl = <1>;
+	vmmc-supply = <&reg_3p3v>;
+	vqmmc-supply = <&reg_3p3v>;
+	status = "okay";
+};
diff --git a/board/mediatek/mt7986/MAINTAINERS
 b/board/mediatek/mt7986/MAINTAINERS
new file mode 100644
index 0000000000..fddee20001
--- /dev/null
+++ b/board/mediatek/mt7986/MAINTAINERS
@@ -0,0 +1,10 @@
+MT7986
+M:	Sam Shih <sam.shih@mediatek.com>
+S:	Maintained
+F:	board/mediatek/mt7986
+F:	include/configs/mt7986.h
+F:	configs/mt7986_rfb_defconfig
+F:	configs/mt7986a_emmc_rfb_defconfig
+F:	configs/mt7986a_sd_rfb_defconfig
+F:	configs/mt7986b_emmc_rfb_defconfig
+F:	configs/mt7986b_sd_rfb_defconfig
diff --git a/board/mediatek/mt7986/Makefile b/board/mediatek/mt7986/Makefile
new file mode 100644
index 0000000000..7bb84fa2f4
--- /dev/null
+++ b/board/mediatek/mt7986/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier:	GPL-2.0
+
+obj-y	+= mt7986_rfb.o
diff --git a/board/mediatek/mt7986/mt7986_rfb.c
 b/board/mediatek/mt7986/mt7986_rfb.c
new file mode 100644
index 0000000000..846c715ca0
--- /dev/null
+++ b/board/mediatek/mt7986/mt7986_rfb.c
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+int board_init(void)
+{
+	return 0;
+}
diff --git a/configs/mt7986_rfb_defconfig b/configs/mt7986_rfb_defconfig
new file mode 100644
index 0000000000..ff1e63b6bd
--- /dev/null
+++ b/configs/mt7986_rfb_defconfig
@@ -0,0 +1,66 @@
+CONFIG_ARM=y
+CONFIG_POSITION_INDEPENDENT=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_SYS_TEXT_BASE=0x41e00000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_DEFAULT_DEVICE_TREE="mt7986a-rfb"
+CONFIG_TARGET_MT7986=y
+CONFIG_DEBUG_UART_BASE=0x11002000
+CONFIG_DEBUG_UART_CLOCK=40000000
+CONFIG_SYS_LOAD_ADDR=0x46000000
+CONFIG_DEBUG_UART=y
+# CONFIG_AUTOBOOT is not set
+CONFIG_DEFAULT_FDT_FILE="mt7986a-rfb"
+CONFIG_LOGLEVEL=7
+CONFIG_LOG=y
+CONFIG_SYS_PROMPT="MT7986> "
+CONFIG_SYS_CBSIZE=512
+CONFIG_SYS_PBSIZE=1049
+# CONFIG_BOOTM_NETBSD is not set
+# CONFIG_BOOTM_PLAN9 is not set
+# CONFIG_BOOTM_RTEMS is not set
+# CONFIG_BOOTM_VXWORKS is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_UNLZ4 is not set
+# CONFIG_CMD_UNZIP is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_MTD=y
+CONFIG_CMD_SF_TEST=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_SMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+# CONFIG_MMC is not set
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_MTD_SPI_NAND=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_EON=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_ISSI=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_XMC=y
+CONFIG_SPI_FLASH_XTX=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_ETH=y
+CONFIG_MEDIATEK_ETH=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_MT7986=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_MTK_POWER_DOMAIN=y
+CONFIG_DM_SERIAL=y
+CONFIG_MTK_SERIAL=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_MTK_SPIM=y
+CONFIG_HEXDUMP=y
diff --git a/configs/mt7986a_emmc_rfb_defconfig
 b/configs/mt7986a_emmc_rfb_defconfig
new file mode 100644
index 0000000000..3e368b68de
--- /dev/null
+++ b/configs/mt7986a_emmc_rfb_defconfig
@@ -0,0 +1,64 @@
+CONFIG_ARM=y
+CONFIG_POSITION_INDEPENDENT=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_SYS_TEXT_BASE=0x41e00000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x80000
+CONFIG_ENV_OFFSET=0x300000
+CONFIG_DEFAULT_DEVICE_TREE="mt7986a-emmc-rfb"
+CONFIG_TARGET_MT7986=y
+CONFIG_DEBUG_UART_BASE=0x11002000
+CONFIG_DEBUG_UART_CLOCK=40000000
+CONFIG_SYS_LOAD_ADDR=0x46000000
+CONFIG_DEBUG_UART=y
+# CONFIG_AUTOBOOT is not set
+CONFIG_DEFAULT_FDT_FILE="mt7986a-emmc-rfb"
+CONFIG_LOGLEVEL=7
+CONFIG_LOG=y
+CONFIG_SYS_PROMPT="MT7986> "
+CONFIG_SYS_CBSIZE=512
+CONFIG_SYS_PBSIZE=1049
+# CONFIG_BOOTM_NETBSD is not set
+# CONFIG_BOOTM_PLAN9 is not set
+# CONFIG_BOOTM_RTEMS is not set
+# CONFIG_BOOTM_VXWORKS is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_UNLZ4 is not set
+# CONFIG_CMD_UNZIP is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_GPT_RENAME=y
+CONFIG_CMD_LSBLK=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PART=y
+CONFIG_CMD_READ=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_SMC=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_PARTITION_TYPE_GUID=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_MMC_MTK=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_ETH=y
+CONFIG_MEDIATEK_ETH=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_MT7986=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_MTK_POWER_DOMAIN=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_SERIAL=y
+CONFIG_MTK_SERIAL=y
+CONFIG_FAT_WRITE=y
+CONFIG_HEXDUMP=y
+# CONFIG_EFI_LOADER is not set
diff --git a/configs/mt7986a_sd_rfb_defconfig
 b/configs/mt7986a_sd_rfb_defconfig
new file mode 100644
index 0000000000..b9a69a3d3d
--- /dev/null
+++ b/configs/mt7986a_sd_rfb_defconfig
@@ -0,0 +1,64 @@
+CONFIG_ARM=y
+CONFIG_POSITION_INDEPENDENT=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_SYS_TEXT_BASE=0x41e00000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x80000
+CONFIG_ENV_OFFSET=0x300000
+CONFIG_DEFAULT_DEVICE_TREE="mt7986a-sd-rfb"
+CONFIG_TARGET_MT7986=y
+CONFIG_DEBUG_UART_BASE=0x11002000
+CONFIG_DEBUG_UART_CLOCK=40000000
+CONFIG_SYS_LOAD_ADDR=0x46000000
+CONFIG_DEBUG_UART=y
+# CONFIG_AUTOBOOT is not set
+CONFIG_DEFAULT_FDT_FILE="mt7986a-sd-rfb"
+CONFIG_LOGLEVEL=7
+CONFIG_LOG=y
+CONFIG_SYS_PROMPT="MT7986> "
+CONFIG_SYS_CBSIZE=512
+CONFIG_SYS_PBSIZE=1049
+# CONFIG_BOOTM_NETBSD is not set
+# CONFIG_BOOTM_PLAN9 is not set
+# CONFIG_BOOTM_RTEMS is not set
+# CONFIG_BOOTM_VXWORKS is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_UNLZ4 is not set
+# CONFIG_CMD_UNZIP is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_GPT_RENAME=y
+CONFIG_CMD_LSBLK=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PART=y
+CONFIG_CMD_READ=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_SMC=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_PARTITION_TYPE_GUID=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_MMC_MTK=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_ETH=y
+CONFIG_MEDIATEK_ETH=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_MT7986=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_MTK_POWER_DOMAIN=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_SERIAL=y
+CONFIG_MTK_SERIAL=y
+CONFIG_FAT_WRITE=y
+CONFIG_HEXDUMP=y
+# CONFIG_EFI_LOADER is not set
diff --git a/configs/mt7986b_emmc_rfb_defconfig
 b/configs/mt7986b_emmc_rfb_defconfig
new file mode 100644
index 0000000000..c3a72a342a
--- /dev/null
+++ b/configs/mt7986b_emmc_rfb_defconfig
@@ -0,0 +1,64 @@
+CONFIG_ARM=y
+CONFIG_POSITION_INDEPENDENT=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_SYS_TEXT_BASE=0x41e00000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x80000
+CONFIG_ENV_OFFSET=0x300000
+CONFIG_DEFAULT_DEVICE_TREE="mt7986b-emmc-rfb"
+CONFIG_TARGET_MT7986=y
+CONFIG_DEBUG_UART_BASE=0x11002000
+CONFIG_DEBUG_UART_CLOCK=40000000
+CONFIG_SYS_LOAD_ADDR=0x46000000
+CONFIG_DEBUG_UART=y
+# CONFIG_AUTOBOOT is not set
+CONFIG_DEFAULT_FDT_FILE="mt7986b-emmc-rfb"
+CONFIG_LOGLEVEL=7
+CONFIG_LOG=y
+CONFIG_SYS_PROMPT="MT7986> "
+CONFIG_SYS_CBSIZE=512
+CONFIG_SYS_PBSIZE=1049
+# CONFIG_BOOTM_NETBSD is not set
+# CONFIG_BOOTM_PLAN9 is not set
+# CONFIG_BOOTM_RTEMS is not set
+# CONFIG_BOOTM_VXWORKS is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_UNLZ4 is not set
+# CONFIG_CMD_UNZIP is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_GPT_RENAME=y
+CONFIG_CMD_LSBLK=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PART=y
+CONFIG_CMD_READ=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_SMC=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_PARTITION_TYPE_GUID=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_MMC_MTK=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_ETH=y
+CONFIG_MEDIATEK_ETH=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_MT7986=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_MTK_POWER_DOMAIN=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_SERIAL=y
+CONFIG_MTK_SERIAL=y
+CONFIG_FAT_WRITE=y
+CONFIG_HEXDUMP=y
+# CONFIG_EFI_LOADER is not set
diff --git a/configs/mt7986b_sd_rfb_defconfig
 b/configs/mt7986b_sd_rfb_defconfig
new file mode 100644
index 0000000000..0e5ab55ab5
--- /dev/null
+++ b/configs/mt7986b_sd_rfb_defconfig
@@ -0,0 +1,64 @@
+CONFIG_ARM=y
+CONFIG_POSITION_INDEPENDENT=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_SYS_TEXT_BASE=0x41e00000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x80000
+CONFIG_ENV_OFFSET=0x300000
+CONFIG_DEFAULT_DEVICE_TREE="mt7986b-sd-rfb"
+CONFIG_TARGET_MT7986=y
+CONFIG_DEBUG_UART_BASE=0x11002000
+CONFIG_DEBUG_UART_CLOCK=40000000
+CONFIG_SYS_LOAD_ADDR=0x46000000
+CONFIG_DEBUG_UART=y
+# CONFIG_AUTOBOOT is not set
+CONFIG_DEFAULT_FDT_FILE="mt7986b-sd-rfb"
+CONFIG_LOGLEVEL=7
+CONFIG_LOG=y
+CONFIG_SYS_PROMPT="MT7986> "
+CONFIG_SYS_CBSIZE=512
+CONFIG_SYS_PBSIZE=1049
+# CONFIG_BOOTM_NETBSD is not set
+# CONFIG_BOOTM_PLAN9 is not set
+# CONFIG_BOOTM_RTEMS is not set
+# CONFIG_BOOTM_VXWORKS is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_UNLZ4 is not set
+# CONFIG_CMD_UNZIP is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_GPT_RENAME=y
+CONFIG_CMD_LSBLK=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PART=y
+CONFIG_CMD_READ=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_SMC=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_PARTITION_TYPE_GUID=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_MMC_MTK=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_ETH=y
+CONFIG_MEDIATEK_ETH=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_MT7986=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_MTK_POWER_DOMAIN=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_SERIAL=y
+CONFIG_MTK_SERIAL=y
+CONFIG_FAT_WRITE=y
+CONFIG_HEXDUMP=y
+# CONFIG_EFI_LOADER is not set
diff --git a/include/configs/mt7986.h b/include/configs/mt7986.h
new file mode 100644
index 0000000000..b28fc0f613
--- /dev/null
+++ b/include/configs/mt7986.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Configuration for MediaTek MT7986 SoC
+ *
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+#ifndef __MT7986_H
+#define __MT7986_H
+
+#include <linux/sizes.h>
+
+#define CONFIG_SYS_NONCACHED_MEMORY	SZ_1M
+#define CONFIG_SYS_MMC_ENV_DEV		0
+
+/* Uboot definition */
+#define CONFIG_SYS_UBOOT_BASE		CONFIG_SYS_TEXT_BASE
+
+/* SPL -> Uboot */
+#define CONFIG_SYS_UBOOT_START		CONFIG_SYS_TEXT_BASE
+
+/* DRAM */
+#define CONFIG_SYS_SDRAM_BASE		0x40000000
+
+#endif
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 04/31] board: mediatek: add MT7981 reference boards
  2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
                   ` (2 preceding siblings ...)
  2022-08-04  3:35 ` [PATCH 03/31] board: mediatek: add MT7986 reference boards Weijie Gao
@ 2022-08-04  3:35 ` Weijie Gao
  2022-08-04 13:57   ` Simon Glass
  2022-08-04  3:35 ` [PATCH 05/31] mmc: mediatek: add support for MediaTek MT7891/MT7986 SoCs Weijie Gao
                   ` (26 subsequent siblings)
  30 siblings, 1 reply; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:35 UTC (permalink / raw)
  To: u-boot
  Cc: GSS_MTK_Uboot_upstream, Simon Glass, Marcel Ziswiler,
	Andre Przywara, Fabio Estevam, Samuel Holland, Marek Vasut,
	Ying-Chun Liu (PaulLiu),
	Christian Hewitt, Weijie Gao

This patch adds general board files based on MT7981 SoCs.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 arch/arm/dts/Makefile                  |   5 +
 arch/arm/dts/mt7981-emmc-rfb.dts       | 139 +++++++++++++++++++++++++
 arch/arm/dts/mt7981-rfb.dts            | 133 +++++++++++++++++++++++
 arch/arm/dts/mt7981-sd-rfb.dts         | 139 +++++++++++++++++++++++++
 arch/arm/dts/mt7981-spim-nand-rfb.dts  | 138 ++++++++++++++++++++++++
 arch/arm/dts/mt7981-spim-nor-rfb.dts   | 133 +++++++++++++++++++++++
 board/mediatek/mt7981/MAINTAINERS      |  10 ++
 board/mediatek/mt7981/Makefile         |   3 +
 board/mediatek/mt7981/mt7981_rfb.c     |  10 ++
 configs/mt7981_emmc_rfb_defconfig      |  64 ++++++++++++
 configs/mt7981_rfb_defconfig           |  65 ++++++++++++
 configs/mt7981_sd_rfb_defconfig        |  64 ++++++++++++
 configs/mt7981_spim_nand_rfb_defconfig |  59 +++++++++++
 configs/mt7981_spim_nor_rfb_defconfig  |  70 +++++++++++++
 include/configs/mt7981.h               |  26 +++++
 15 files changed, 1058 insertions(+)
 create mode 100644 arch/arm/dts/mt7981-emmc-rfb.dts
 create mode 100644 arch/arm/dts/mt7981-rfb.dts
 create mode 100644 arch/arm/dts/mt7981-sd-rfb.dts
 create mode 100644 arch/arm/dts/mt7981-spim-nand-rfb.dts
 create mode 100644 arch/arm/dts/mt7981-spim-nor-rfb.dts
 create mode 100644 board/mediatek/mt7981/MAINTAINERS
 create mode 100644 board/mediatek/mt7981/Makefile
 create mode 100644 board/mediatek/mt7981/mt7981_rfb.c
 create mode 100644 configs/mt7981_emmc_rfb_defconfig
 create mode 100644 configs/mt7981_rfb_defconfig
 create mode 100644 configs/mt7981_sd_rfb_defconfig
 create mode 100644 configs/mt7981_spim_nand_rfb_defconfig
 create mode 100644 configs/mt7981_spim_nor_rfb_defconfig
 create mode 100644 include/configs/mt7981.h

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index eeb08116c0..3529e3e88a 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -1226,6 +1226,11 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \
 	mt7622-bananapi-bpi-r64.dtb \
 	mt7623n-bananapi-bpi-r2.dtb \
 	mt7629-rfb.dtb \
+	mt7981-rfb.dtb \
+	mt7981-spim-nand-rfb.dtb \
+	mt7981-spim-nor-rfb.dtb \
+	mt7981-emmc-rfb.dtb \
+	mt7981-sd-rfb.dtb \
 	mt7986a-rfb.dtb \
 	mt7986b-rfb.dtb \
 	mt7986a-sd-rfb.dtb \
diff --git a/arch/arm/dts/mt7981-emmc-rfb.dts
 b/arch/arm/dts/mt7981-emmc-rfb.dts
new file mode 100644
index 0000000000..2b7eae99ce
--- /dev/null
+++ b/arch/arm/dts/mt7981-emmc-rfb.dts
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+/dts-v1/;
+#include "mt7981.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	model = "mt7981-rfb";
+	compatible = "mediatek,mt7981", "mediatek,mt7981-rfb";
+	chosen {
+		stdout-path = &uart0;
+		tick-timer = &timer0;
+	};
+
+	reg_3p3v: regulator-3p3v {
+		  compatible = "regulator-fixed";
+		  regulator-name = "fixed-3.3V";
+		  regulator-min-microvolt = <3300000>;
+		  regulator-max-microvolt = <3300000>;
+		  regulator-boot-on;
+		  regulator-always-on;
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins>;
+	status = "disabled";
+};
+
+&eth {
+	status = "okay";
+	mediatek,gmac-id = <0>;
+	phy-mode = "sgmii";
+	mediatek,switch = "mt7531";
+	reset-gpios = <&gpio 39 GPIO_ACTIVE_HIGH>;
+
+	fixed-link {
+		speed = <1000>;
+		full-duplex;
+	};
+};
+
+&pinctrl {
+	spic_pins: spi1-pins-func-1 {
+		mux {
+			function = "spi";
+			groups = "spi1_1";
+		};
+	};
+
+	uart1_pins: spi1-pins-func-3 {
+		mux {
+			function = "uart";
+			groups = "uart1_2";
+		};
+	};
+
+	/* pin15 as pwm0 */
+	one_pwm_pins: one-pwm-pins {
+		mux {
+			function = "pwm";
+			groups = "pwm0_1";
+		};
+	};
+
+	/* pin15 as pwm0 and pin14 as pwm1 */
+	two_pwm_pins: two-pwm-pins {
+		mux {
+			function = "pwm";
+			groups = "pwm0_1", "pwm1_0";
+		};
+	};
+
+	/* pin15 as pwm0, pin14 as pwm1, pin7 as pwm2 */
+	three_pwm_pins: three-pwm-pins {
+		mux {
+			function = "pwm";
+			groups = "pwm0_1", "pwm1_0", "pwm2";
+		};
+	};
+
+	mmc0_pins_default: mmc0default {
+		mux {
+			function = "flash";
+			groups =  "emmc_45";
+		};
+		conf-cmd-dat {
+			pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO",
+				"SPI0_CS",  "SPI0_HOLD", "SPI0_WP",
+				"SPI1_CLK", "SPI1_MOSI", "SPI1_MISO";
+			input-enable;
+			drive-strength = <MTK_DRIVE_4mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+		conf-clk {
+			pins = "SPI1_CS";
+			drive-strength = <MTK_DRIVE_6mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+		};
+		conf-rst {
+			pins = "PWM0";
+			drive-strength = <MTK_DRIVE_4mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+	};
+};
+
+&pwm {
+	pinctrl-names = "default";
+	pinctrl-0 = <&two_pwm_pins>;
+	status = "okay";
+};
+
+&watchdog {
+	status = "disabled";
+};
+
+&mmc0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc0_pins_default>;
+	bus-width = <8>;
+	max-frequency = <52000000>;
+	cap-mmc-highspeed;
+	cap-mmc-hw-reset;
+	vmmc-supply = <&reg_3p3v>;
+	non-removable;
+	status = "okay";
+};
diff --git a/arch/arm/dts/mt7981-rfb.dts b/arch/arm/dts/mt7981-rfb.dts
new file mode 100644
index 0000000000..1b163e2eff
--- /dev/null
+++ b/arch/arm/dts/mt7981-rfb.dts
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+/dts-v1/;
+#include "mt7981.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	model = "mt7981-rfb";
+	compatible = "mediatek,mt7981", "mediatek,mt7981-rfb";
+	chosen {
+		stdout-path = &uart0;
+		tick-timer = &timer0;
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins>;
+	status = "disabled";
+};
+
+&eth {
+	status = "okay";
+	mediatek,gmac-id = <0>;
+	phy-mode = "sgmii";
+	mediatek,switch = "mt7531";
+	reset-gpios = <&gpio 39 GPIO_ACTIVE_HIGH>;
+
+	fixed-link {
+		speed = <1000>;
+		full-duplex;
+	};
+};
+
+&pinctrl {
+	spi_flash_pins: spi0-pins-func-1 {
+		mux {
+			function = "flash";
+			groups = "spi0", "spi0_wp_hold";
+		};
+
+		conf-pu {
+			pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP";
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_11>;
+		};
+
+		conf-pd {
+			pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO";
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_11>;
+		};
+	};
+
+	spic_pins: spi1-pins-func-1 {
+		mux {
+			function = "spi";
+			groups = "spi1_1";
+		};
+	};
+
+	uart1_pins: spi1-pins-func-3 {
+		mux {
+			function = "uart";
+			groups = "uart1_2";
+		};
+	};
+
+	/* pin15 as pwm0 */
+	one_pwm_pins: one-pwm-pins {
+		mux {
+			function = "pwm";
+			groups = "pwm0_1";
+		};
+	};
+
+	/* pin15 as pwm0 and pin14 as pwm1 */
+	two_pwm_pins: two-pwm-pins {
+		mux {
+			function = "pwm";
+			groups = "pwm0_1", "pwm1_0";
+		};
+	};
+
+	/* pin15 as pwm0, pin14 as pwm1, pin7 as pwm2 */
+	three_pwm_pins: three-pwm-pins {
+		mux {
+			function = "pwm";
+			groups = "pwm0_1", "pwm1_0", "pwm2";
+		};
+	};
+};
+
+&spi0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi_flash_pins>;
+	status = "okay";
+	must_tx;
+	enhance_timing;
+	dma_ext;
+	ipm_design;
+	support_quad;
+	tick_dly = <2>;
+	sample_sel = <0>;
+
+	spi_nand@0 {
+		compatible = "spi-nand";
+		reg = <0>;
+		spi-max-frequency = <52000000>;
+	};
+};
+
+&pwm {
+	pinctrl-names = "default";
+	pinctrl-0 = <&two_pwm_pins>;
+	status = "okay";
+};
+
+&watchdog {
+	status = "disabled";
+};
diff --git a/arch/arm/dts/mt7981-sd-rfb.dts b/arch/arm/dts/mt7981-sd-rfb.dts
new file mode 100644
index 0000000000..34ac227ecf
--- /dev/null
+++ b/arch/arm/dts/mt7981-sd-rfb.dts
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+/dts-v1/;
+#include "mt7981.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	model = "mt7981-rfb";
+	compatible = "mediatek,mt7981", "mediatek,mt7981-sd-rfb";
+	chosen {
+		stdout-path = &uart0;
+		tick-timer = &timer0;
+	};
+
+	reg_3p3v: regulator-3p3v {
+		  compatible = "regulator-fixed";
+		  regulator-name = "fixed-3.3V";
+		  regulator-min-microvolt = <3300000>;
+		  regulator-max-microvolt = <3300000>;
+		  regulator-boot-on;
+		  regulator-always-on;
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins>;
+	status = "disabled";
+};
+
+&eth {
+	status = "okay";
+	mediatek,gmac-id = <0>;
+	phy-mode = "sgmii";
+	mediatek,switch = "mt7531";
+	reset-gpios = <&gpio 39 GPIO_ACTIVE_HIGH>;
+
+	fixed-link {
+		speed = <1000>;
+		full-duplex;
+	};
+};
+
+&pinctrl {
+	spic_pins: spi1-pins-func-1 {
+		mux {
+			function = "spi";
+			groups = "spi1_1";
+		};
+	};
+
+	uart1_pins: spi1-pins-func-3 {
+		mux {
+			function = "uart";
+			groups = "uart1_2";
+		};
+	};
+
+	/* pin15 as pwm0 */
+	one_pwm_pins: one-pwm-pins {
+		mux {
+			function = "pwm";
+			groups = "pwm0_1";
+		};
+	};
+
+	/* pin15 as pwm0 and pin14 as pwm1 */
+	two_pwm_pins: two-pwm-pins {
+		mux {
+			function = "pwm";
+			groups = "pwm0_1", "pwm1_0";
+		};
+	};
+
+	/* pin15 as pwm0, pin14 as pwm1, pin7 as pwm2 */
+	three_pwm_pins: three-pwm-pins {
+		mux {
+			function = "pwm";
+			groups = "pwm0_1", "pwm1_0", "pwm2";
+		};
+	};
+
+	mmc0_pins_default: mmc0default {
+		mux {
+			function = "flash";
+			groups =  "emmc_45";
+		};
+		conf-cmd-dat {
+			pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO",
+				"SPI0_CS",  "SPI0_HOLD", "SPI0_WP",
+				"SPI1_CLK", "SPI1_MOSI", "SPI1_MISO";
+			input-enable;
+			drive-strength = <MTK_DRIVE_4mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+		conf-clk {
+			pins = "SPI1_CS";
+			drive-strength = <MTK_DRIVE_6mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+		};
+		conf-rst {
+			pins = "PWM0";
+			drive-strength = <MTK_DRIVE_4mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+	};
+};
+
+&pwm {
+	pinctrl-names = "default";
+	pinctrl-0 = <&two_pwm_pins>;
+	status = "okay";
+};
+
+&watchdog {
+	status = "disabled";
+};
+
+&mmc0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc0_pins_default>;
+	bus-width = <4>;
+	max-frequency = <52000000>;
+	cap-sd-highspeed;
+	r_smpl = <0>;
+	vmmc-supply = <&reg_3p3v>;
+	vqmmc-supply = <&reg_3p3v>;
+	status = "okay";
+};
diff --git a/arch/arm/dts/mt7981-spim-nand-rfb.dts
 b/arch/arm/dts/mt7981-spim-nand-rfb.dts
new file mode 100644
index 0000000000..205f6deb30
--- /dev/null
+++ b/arch/arm/dts/mt7981-spim-nand-rfb.dts
@@ -0,0 +1,138 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+/dts-v1/;
+#include "mt7981.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	model = "mt7981-rfb";
+	compatible = "mediatek,mt7981", "mediatek,mt7981-rfb";
+	chosen {
+		stdout-path = &uart0;
+		tick-timer = &timer0;
+	};
+
+	memory@40000000 {
+		device_type = "memory";
+		reg = <0x40000000 0x10000000>;
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins>;
+	status = "disabled";
+};
+
+&eth {
+	status = "okay";
+	mediatek,gmac-id = <0>;
+	phy-mode = "sgmii";
+	mediatek,switch = "mt7531";
+	reset-gpios = <&gpio 39 GPIO_ACTIVE_HIGH>;
+
+	fixed-link {
+		speed = <1000>;
+		full-duplex;
+	};
+};
+
+&pinctrl {
+	spi_flash_pins: spi0-pins-func-1 {
+		mux {
+			function = "flash";
+			groups = "spi0", "spi0_wp_hold";
+		};
+
+		conf-pu {
+			pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP";
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_11>;
+		};
+
+		conf-pd {
+			pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO";
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_11>;
+		};
+	};
+
+	spic_pins: spi1-pins-func-1 {
+		mux {
+			function = "spi";
+			groups = "spi1_1";
+		};
+	};
+
+	uart1_pins: spi1-pins-func-3 {
+		mux {
+			function = "uart";
+			groups = "uart1_2";
+		};
+	};
+
+	/* pin15 as pwm0 */
+	one_pwm_pins: one-pwm-pins {
+		mux {
+			function = "pwm";
+			groups = "pwm0_1";
+		};
+	};
+
+	/* pin15 as pwm0 and pin14 as pwm1 */
+	two_pwm_pins: two-pwm-pins {
+		mux {
+			function = "pwm";
+			groups = "pwm0_1", "pwm1_0";
+		};
+	};
+
+	/* pin15 as pwm0, pin14 as pwm1, pin7 as pwm2 */
+	three_pwm_pins: three-pwm-pins {
+		mux {
+			function = "pwm";
+			groups = "pwm0_1", "pwm1_0", "pwm2";
+		};
+	};
+};
+
+&spi0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi_flash_pins>;
+	status = "okay";
+	must_tx;
+	enhance_timing;
+	dma_ext;
+	ipm_design;
+	support_quad;
+	tick_dly = <2>;
+	sample_sel = <0>;
+
+	spi_nand@0 {
+		compatible = "spi-nand";
+		reg = <0>;
+		spi-max-frequency = <52000000>;
+	};
+};
+
+&pwm {
+	pinctrl-names = "default";
+	pinctrl-0 = <&two_pwm_pins>;
+	status = "okay";
+};
+
+&watchdog {
+	status = "disabled";
+};
diff --git a/arch/arm/dts/mt7981-spim-nor-rfb.dts
 b/arch/arm/dts/mt7981-spim-nor-rfb.dts
new file mode 100644
index 0000000000..ff521c38b2
--- /dev/null
+++ b/arch/arm/dts/mt7981-spim-nor-rfb.dts
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+/dts-v1/;
+#include "mt7981.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	model = "mt7981-rfb";
+	compatible = "mediatek,mt7981", "mediatek,mt7981-rfb";
+	chosen {
+		stdout-path = &uart0;
+		tick-timer = &timer0;
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins>;
+	status = "disabled";
+};
+
+&eth {
+	status = "okay";
+	mediatek,gmac-id = <0>;
+	phy-mode = "sgmii";
+	mediatek,switch = "mt7531";
+	reset-gpios = <&gpio 39 GPIO_ACTIVE_HIGH>;
+
+	fixed-link {
+		speed = <1000>;
+		full-duplex;
+	};
+};
+
+&pinctrl {
+	spic_pins: spi1-pins-func-1 {
+		mux {
+			function = "spi";
+			groups = "spi1_1";
+		};
+	};
+
+	spi2_flash_pins: spi2-spi2-pins {
+		mux {
+			function = "spi";
+			groups = "spi2", "spi2_wp_hold";
+		};
+
+		conf-pu {
+			pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP";
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_00>;
+		};
+
+		conf-pd {
+			pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO";
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_00>;
+		};
+	};
+
+	uart1_pins: spi1-pins-func-3 {
+		mux {
+			function = "uart";
+			groups = "uart1_2";
+		};
+	};
+
+	/* pin15 as pwm0 */
+	one_pwm_pins: one-pwm-pins {
+		mux {
+			function = "pwm";
+			groups = "pwm0_1";
+		};
+	};
+
+	/* pin15 as pwm0 and pin14 as pwm1 */
+	two_pwm_pins: two-pwm-pins {
+		mux {
+			function = "pwm";
+			groups = "pwm0_1", "pwm1_0";
+		};
+	};
+
+	/* pin15 as pwm0, pin14 as pwm1, pin7 as pwm2 */
+	three_pwm_pins: three-pwm-pins {
+		mux {
+			function = "pwm";
+			groups = "pwm0_1", "pwm1_0", "pwm2";
+		};
+	};
+};
+
+&spi2 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi2_flash_pins>;
+	status = "okay";
+	must_tx;
+	enhance_timing;
+	dma_ext;
+	ipm_design;
+	support_quad;
+	tick_dly = <2>;
+	sample_sel = <0>;
+
+	spi_nor@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <52000000>;
+	};
+};
+
+&pwm {
+	pinctrl-names = "default";
+	pinctrl-0 = <&two_pwm_pins>;
+	status = "okay";
+};
+
+&watchdog {
+	status = "disabled";
+};
diff --git a/board/mediatek/mt7981/MAINTAINERS
 b/board/mediatek/mt7981/MAINTAINERS
new file mode 100644
index 0000000000..e7592a7a54
--- /dev/null
+++ b/board/mediatek/mt7981/MAINTAINERS
@@ -0,0 +1,10 @@
+MT7981
+M:	Sam Shih <sam.shih@mediatek.com>
+S:	Maintained
+F:	board/mediatek/mt7981
+F:	include/configs/mt7981.h
+F:	configs/mt7981_emmc_rfb_defconfig
+F:	configs/mt7981_rfb_defconfig
+F:	configs/mt7981_sd_rfb_defconfig
+F:	configs/mt7981_spim_nand_rfb_defconfig
+F:	configs/mt7981_spim_nor_rfb_defconfig
diff --git a/board/mediatek/mt7981/Makefile b/board/mediatek/mt7981/Makefile
new file mode 100644
index 0000000000..fa5990ffb2
--- /dev/null
+++ b/board/mediatek/mt7981/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier:	GPL-2.0
+
+obj-y	+= mt7981_rfb.o
diff --git a/board/mediatek/mt7981/mt7981_rfb.c
 b/board/mediatek/mt7981/mt7981_rfb.c
new file mode 100644
index 0000000000..846c715ca0
--- /dev/null
+++ b/board/mediatek/mt7981/mt7981_rfb.c
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+int board_init(void)
+{
+	return 0;
+}
diff --git a/configs/mt7981_emmc_rfb_defconfig
 b/configs/mt7981_emmc_rfb_defconfig
new file mode 100644
index 0000000000..5f9f6d8582
--- /dev/null
+++ b/configs/mt7981_emmc_rfb_defconfig
@@ -0,0 +1,64 @@
+CONFIG_ARM=y
+CONFIG_POSITION_INDEPENDENT=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_SYS_TEXT_BASE=0x41e00000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x80000
+CONFIG_ENV_OFFSET=0x300000
+CONFIG_DEFAULT_DEVICE_TREE="mt7981-emmc-rfb"
+CONFIG_TARGET_MT7981=y
+CONFIG_DEBUG_UART_BASE=0x11002000
+CONFIG_DEBUG_UART_CLOCK=40000000
+CONFIG_SYS_LOAD_ADDR=0x46000000
+CONFIG_DEBUG_UART=y
+# CONFIG_AUTOBOOT is not set
+CONFIG_DEFAULT_FDT_FILE="mt7981-emmc-rfb"
+CONFIG_LOGLEVEL=7
+CONFIG_LOG=y
+CONFIG_SYS_PROMPT="MT7981> "
+CONFIG_SYS_CBSIZE=512
+CONFIG_SYS_PBSIZE=1049
+# CONFIG_BOOTM_NETBSD is not set
+# CONFIG_BOOTM_PLAN9 is not set
+# CONFIG_BOOTM_RTEMS is not set
+# CONFIG_BOOTM_VXWORKS is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_UNLZ4 is not set
+# CONFIG_CMD_UNZIP is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_GPT_RENAME=y
+CONFIG_CMD_LSBLK=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PART=y
+CONFIG_CMD_READ=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_SMC=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_PARTITION_TYPE_GUID=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_MMC_MTK=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_ETH=y
+CONFIG_MEDIATEK_ETH=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_MT7981=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_MTK_POWER_DOMAIN=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_SERIAL=y
+CONFIG_MTK_SERIAL=y
+CONFIG_FAT_WRITE=y
+CONFIG_HEXDUMP=y
+# CONFIG_EFI_LOADER is not set
diff --git a/configs/mt7981_rfb_defconfig b/configs/mt7981_rfb_defconfig
new file mode 100644
index 0000000000..90a0839c8e
--- /dev/null
+++ b/configs/mt7981_rfb_defconfig
@@ -0,0 +1,65 @@
+CONFIG_ARM=y
+CONFIG_POSITION_INDEPENDENT=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_SYS_TEXT_BASE=0x41e00000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_DEFAULT_DEVICE_TREE="mt7981-rfb"
+CONFIG_TARGET_MT7981=y
+CONFIG_DEBUG_UART_BASE=0x11002000
+CONFIG_DEBUG_UART_CLOCK=40000000
+CONFIG_SYS_LOAD_ADDR=0x46000000
+CONFIG_DEBUG_UART=y
+# CONFIG_AUTOBOOT is not set
+CONFIG_DEFAULT_FDT_FILE="mt7981-rfb"
+CONFIG_LOGLEVEL=7
+CONFIG_LOG=y
+CONFIG_SYS_PROMPT="MT7981> "
+CONFIG_SYS_CBSIZE=512
+CONFIG_SYS_PBSIZE=1049
+# CONFIG_BOOTM_NETBSD is not set
+# CONFIG_BOOTM_PLAN9 is not set
+# CONFIG_BOOTM_RTEMS is not set
+# CONFIG_BOOTM_VXWORKS is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_UNLZ4 is not set
+# CONFIG_CMD_UNZIP is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_SF_TEST=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_SMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_MMC_MTK=y
+CONFIG_DM_MTD=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_EON=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_ISSI=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_XMC=y
+CONFIG_SPI_FLASH_XTX=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_ETH=y
+CONFIG_MEDIATEK_ETH=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_MT7981=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_MTK_POWER_DOMAIN=y
+CONFIG_DM_SERIAL=y
+CONFIG_MTK_SERIAL=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_MTK_SPIM=y
+CONFIG_HEXDUMP=y
+# CONFIG_EFI_LOADER is not set
diff --git a/configs/mt7981_sd_rfb_defconfig
 b/configs/mt7981_sd_rfb_defconfig
new file mode 100644
index 0000000000..b5c765bd7c
--- /dev/null
+++ b/configs/mt7981_sd_rfb_defconfig
@@ -0,0 +1,64 @@
+CONFIG_ARM=y
+CONFIG_POSITION_INDEPENDENT=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_SYS_TEXT_BASE=0x41e00000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x80000
+CONFIG_ENV_OFFSET=0x300000
+CONFIG_DEFAULT_DEVICE_TREE="mt7981-sd-rfb"
+CONFIG_TARGET_MT7981=y
+CONFIG_DEBUG_UART_BASE=0x11002000
+CONFIG_DEBUG_UART_CLOCK=40000000
+CONFIG_SYS_LOAD_ADDR=0x46000000
+CONFIG_DEBUG_UART=y
+# CONFIG_AUTOBOOT is not set
+CONFIG_DEFAULT_FDT_FILE="mt7981-sd-rfb"
+CONFIG_LOGLEVEL=7
+CONFIG_LOG=y
+CONFIG_SYS_PROMPT="MT7981> "
+CONFIG_SYS_CBSIZE=512
+CONFIG_SYS_PBSIZE=1049
+# CONFIG_BOOTM_NETBSD is not set
+# CONFIG_BOOTM_PLAN9 is not set
+# CONFIG_BOOTM_RTEMS is not set
+# CONFIG_BOOTM_VXWORKS is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_UNLZ4 is not set
+# CONFIG_CMD_UNZIP is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_GPT_RENAME=y
+CONFIG_CMD_LSBLK=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PART=y
+CONFIG_CMD_READ=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_SMC=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_PARTITION_TYPE_GUID=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_MMC_MTK=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_ETH=y
+CONFIG_MEDIATEK_ETH=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_MT7981=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_MTK_POWER_DOMAIN=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_SERIAL=y
+CONFIG_MTK_SERIAL=y
+CONFIG_FAT_WRITE=y
+CONFIG_HEXDUMP=y
+# CONFIG_EFI_LOADER is not set
diff --git a/configs/mt7981_spim_nand_rfb_defconfig
 b/configs/mt7981_spim_nand_rfb_defconfig
new file mode 100644
index 0000000000..9673c3727d
--- /dev/null
+++ b/configs/mt7981_spim_nand_rfb_defconfig
@@ -0,0 +1,59 @@
+CONFIG_ARM=y
+CONFIG_POSITION_INDEPENDENT=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_SYS_TEXT_BASE=0x41e00000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x20000
+CONFIG_DEFAULT_DEVICE_TREE="mt7981-spim-nand-rfb"
+CONFIG_TARGET_MT7981=y
+CONFIG_DEBUG_UART_BASE=0x11002000
+CONFIG_DEBUG_UART_CLOCK=40000000
+CONFIG_SYS_LOAD_ADDR=0x46000000
+CONFIG_DEBUG_UART=y
+# CONFIG_AUTOBOOT is not set
+CONFIG_DEFAULT_FDT_FILE="mt7981-spim-nand-rfb"
+CONFIG_LOGLEVEL=7
+CONFIG_LOG=y
+CONFIG_SYS_PROMPT="MT7981> "
+CONFIG_SYS_CBSIZE=512
+CONFIG_SYS_PBSIZE=1049
+# CONFIG_BOOTM_NETBSD is not set
+# CONFIG_BOOTM_PLAN9 is not set
+# CONFIG_BOOTM_RTEMS is not set
+# CONFIG_BOOTM_VXWORKS is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_UNLZ4 is not set
+# CONFIG_CMD_UNZIP is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_MTD=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_SMC=y
+CONFIG_MTDIDS_DEFAULT="spi-nand0=spi-nand0"
+CONFIG_MTDPARTS_DEFAULT="spi-nand0:1024k(bl2),512k(u-boot-env),2048k(factory),2048k(fip),65536k(ubi)"
+CONFIG_CMD_UBI=y
+CONFIG_CMD_UBI_RENAME=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+# CONFIG_MMC is not set
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_MTD_SPI_NAND=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_ETH=y
+CONFIG_MEDIATEK_ETH=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_MT7981=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_MTK_POWER_DOMAIN=y
+CONFIG_DM_SERIAL=y
+CONFIG_MTK_SERIAL=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_MTK_SPIM=y
+CONFIG_HEXDUMP=y
diff --git a/configs/mt7981_spim_nor_rfb_defconfig
 b/configs/mt7981_spim_nor_rfb_defconfig
new file mode 100644
index 0000000000..e16bc40c39
--- /dev/null
+++ b/configs/mt7981_spim_nor_rfb_defconfig
@@ -0,0 +1,70 @@
+CONFIG_ARM=y
+CONFIG_POSITION_INDEPENDENT=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_SYS_TEXT_BASE=0x41e00000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x10000
+CONFIG_ENV_OFFSET=0x40000
+CONFIG_ENV_SECT_SIZE=0x10000
+CONFIG_DEFAULT_DEVICE_TREE="mt7981-spim-nor-rfb"
+CONFIG_TARGET_MT7981=y
+CONFIG_DEBUG_UART_BASE=0x11002000
+CONFIG_DEBUG_UART_CLOCK=40000000
+CONFIG_SYS_LOAD_ADDR=0x46000000
+CONFIG_DEBUG_UART=y
+# CONFIG_AUTOBOOT is not set
+CONFIG_DEFAULT_FDT_FILE="mt7981-spim-nor-rfb"
+CONFIG_LOGLEVEL=7
+CONFIG_LOG=y
+CONFIG_SYS_PROMPT="MT7981> "
+CONFIG_SYS_CBSIZE=512
+CONFIG_SYS_PBSIZE=1049
+# CONFIG_BOOTM_NETBSD is not set
+# CONFIG_BOOTM_PLAN9 is not set
+# CONFIG_BOOTM_RTEMS is not set
+# CONFIG_BOOTM_VXWORKS is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_UNLZ4 is not set
+# CONFIG_CMD_UNZIP is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_SF_TEST=y
+CONFIG_CMD_PING=y
+CONFIG_MTDIDS_DEFAULT="nor0=nor0"
+CONFIG_MTDPARTS_DEFAULT="nor0:256k(bl2),64k(u-boot-env),704k(factory),512k(fip),-(firmware)"
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_ENV_SECT_SIZE_AUTO=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+# CONFIG_MMC is not set
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_EON=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_ISSI=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_XMC=y
+CONFIG_SPI_FLASH_XTX=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_ETH=y
+CONFIG_MEDIATEK_ETH=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_MT7981=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_MTK_POWER_DOMAIN=y
+CONFIG_DM_SERIAL=y
+CONFIG_MTK_SERIAL=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_MTK_SPIM=y
+CONFIG_HEXDUMP=y
diff --git a/include/configs/mt7981.h b/include/configs/mt7981.h
new file mode 100644
index 0000000000..a213b8de88
--- /dev/null
+++ b/include/configs/mt7981.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Configuration for MediaTek MT7981 SoC
+ *
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+#ifndef __MT7981_H
+#define __MT7981_H
+
+#include <linux/sizes.h>
+
+#define CONFIG_SYS_NONCACHED_MEMORY	SZ_1M
+#define CONFIG_SYS_MMC_ENV_DEV		0
+
+/* Uboot definition */
+#define CONFIG_SYS_UBOOT_BASE		CONFIG_SYS_TEXT_BASE
+
+/* SPL -> Uboot */
+#define CONFIG_SYS_UBOOT_START		CONFIG_SYS_TEXT_BASE
+
+/* DRAM */
+#define CONFIG_SYS_SDRAM_BASE		0x40000000
+
+#endif
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 05/31] mmc: mediatek: add support for MediaTek MT7891/MT7986 SoCs
  2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
                   ` (3 preceding siblings ...)
  2022-08-04  3:35 ` [PATCH 04/31] board: mediatek: add MT7981 " Weijie Gao
@ 2022-08-04  3:35 ` Weijie Gao
  2022-08-04 13:57   ` Simon Glass
  2022-08-11  5:50   ` jh80.chung
  2022-08-04  3:35 ` [PATCH 06/31] net: mediatek: use a struct to cover variations of all SoCs Weijie Gao
                   ` (25 subsequent siblings)
  30 siblings, 2 replies; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:35 UTC (permalink / raw)
  To: u-boot; +Cc: GSS_MTK_Uboot_upstream, Peng Fan, Jaehoon Chung, Weijie Gao

This patch adds eMMC and SDXC support for MediaTek MT7981/MT7986 SoCs

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 drivers/mmc/mtk-sd.c | 68 ++++++++++++++++++++++++++++++++++----------
 1 file changed, 53 insertions(+), 15 deletions(-)

diff --git a/drivers/mmc/mtk-sd.c b/drivers/mmc/mtk-sd.c
index e61e8cf4b9..b206b0a085 100644
--- a/drivers/mmc/mtk-sd.c
+++ b/drivers/mmc/mtk-sd.c
@@ -1496,7 +1496,12 @@ static void msdc_init_hw(struct msdc_host *host)
 	/* Enable data & cmd interrupts */
 	writel(DATA_INTS_MASK | CMD_INTS_MASK, &host->base->msdc_inten);
 
-	writel(0, tune_reg);
+	if (host->top_base) {
+		writel(0, &host->top_base->emmc_top_control);
+		writel(0, &host->top_base->emmc_top_cmd);
+	} else {
+		writel(0, tune_reg);
+	}
 	writel(0, &host->base->msdc_iocon);
 
 	if (host->r_smpl)
@@ -1507,9 +1512,14 @@ static void msdc_init_hw(struct msdc_host *host)
 	writel(0x403c0046, &host->base->patch_bit0);
 	writel(0xffff4089, &host->base->patch_bit1);
 
-	if (host->dev_comp->stop_clk_fix)
+	if (host->dev_comp->stop_clk_fix) {
 		clrsetbits_le32(&host->base->patch_bit1, MSDC_PB1_STOP_DLY_M,
 				3 << MSDC_PB1_STOP_DLY_S);
+		clrbits_le32(&host->base->sdc_fifo_cfg,
+			     SDC_FIFO_CFG_WRVALIDSEL);
+		clrbits_le32(&host->base->sdc_fifo_cfg,
+			     SDC_FIFO_CFG_RDVALIDSEL);
+	}
 
 	if (host->dev_comp->busy_check)
 		clrbits_le32(&host->base->patch_bit1, (1 << 7));
@@ -1544,15 +1554,28 @@ static void msdc_init_hw(struct msdc_host *host)
 	}
 
 	if (host->dev_comp->data_tune) {
-		setbits_le32(tune_reg,
-			     MSDC_PAD_TUNE_RD_SEL | MSDC_PAD_TUNE_CMD_SEL);
-		clrsetbits_le32(&host->base->patch_bit0,
-				MSDC_INT_DAT_LATCH_CK_SEL_M,
-				host->latch_ck <<
-				MSDC_INT_DAT_LATCH_CK_SEL_S);
+		if (host->top_base) {
+			setbits_le32(&host->top_base->emmc_top_control,
+				     PAD_DAT_RD_RXDLY_SEL);
+			clrbits_le32(&host->top_base->emmc_top_control,
+				     DATA_K_VALUE_SEL);
+			setbits_le32(&host->top_base->emmc_top_cmd,
+				     PAD_CMD_RD_RXDLY_SEL);
+		} else {
+			setbits_le32(tune_reg,
+				     MSDC_PAD_TUNE_RD_SEL | MSDC_PAD_TUNE_CMD_SEL);
+			clrsetbits_le32(&host->base->patch_bit0,
+					MSDC_INT_DAT_LATCH_CK_SEL_M,
+					host->latch_ck <<
+					MSDC_INT_DAT_LATCH_CK_SEL_S);
+		}
 	} else {
 		/* choose clock tune */
-		setbits_le32(tune_reg, MSDC_PAD_TUNE_RXDLYSEL);
+		if (host->top_base)
+			setbits_le32(&host->top_base->emmc_top_control,
+				     PAD_RXDLY_SEL);
+		else
+			setbits_le32(tune_reg, MSDC_PAD_TUNE_RXDLYSEL);
 	}
 
 	if (host->dev_comp->builtin_pad_ctrl) {
@@ -1604,12 +1627,6 @@ static void msdc_init_hw(struct msdc_host *host)
 	clrsetbits_le32(&host->base->sdc_cfg, SDC_CFG_DTOC_M,
 			3 << SDC_CFG_DTOC_S);
 
-	if (host->dev_comp->stop_clk_fix) {
-		clrbits_le32(&host->base->sdc_fifo_cfg,
-			     SDC_FIFO_CFG_WRVALIDSEL);
-		clrbits_le32(&host->base->sdc_fifo_cfg,
-			     SDC_FIFO_CFG_RDVALIDSEL);
-	}
 
 	host->def_tune_para.iocon = readl(&host->base->msdc_iocon);
 	host->def_tune_para.pad_tune = readl(&host->base->pad_tune);
@@ -1792,6 +1809,25 @@ static const struct msdc_compatible mt7623_compat = {
 	.enhance_rx = false
 };
 
+static const struct msdc_compatible mt7986_compat = {
+	.clk_div_bits = 12,
+	.pad_tune0 = true,
+	.async_fifo = true,
+	.data_tune = true,
+	.busy_check = true,
+	.stop_clk_fix = true,
+	.enhance_rx = true,
+};
+
+static const struct msdc_compatible mt7981_compat = {
+	.clk_div_bits = 12,
+	.pad_tune0 = true,
+	.async_fifo = true,
+	.data_tune = true,
+	.busy_check = true,
+	.stop_clk_fix = true,
+};
+
 static const struct msdc_compatible mt8512_compat = {
 	.clk_div_bits = 12,
 	.pad_tune0 = true,
@@ -1824,6 +1860,8 @@ static const struct udevice_id msdc_ids[] = {
 	{ .compatible = "mediatek,mt7621-mmc", .data = (ulong)&mt7621_compat },
 	{ .compatible = "mediatek,mt7622-mmc", .data = (ulong)&mt7622_compat },
 	{ .compatible = "mediatek,mt7623-mmc", .data = (ulong)&mt7623_compat },
+	{ .compatible = "mediatek,mt7986-mmc", .data = (ulong)&mt7986_compat },
+	{ .compatible = "mediatek,mt7981-mmc", .data = (ulong)&mt7981_compat },
 	{ .compatible = "mediatek,mt8512-mmc", .data = (ulong)&mt8512_compat },
 	{ .compatible = "mediatek,mt8516-mmc", .data = (ulong)&mt8516_compat },
 	{ .compatible = "mediatek,mt8183-mmc", .data = (ulong)&mt8183_compat },
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 06/31] net: mediatek: use a struct to cover variations of all SoCs
  2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
                   ` (4 preceding siblings ...)
  2022-08-04  3:35 ` [PATCH 05/31] mmc: mediatek: add support for MediaTek MT7891/MT7986 SoCs Weijie Gao
@ 2022-08-04  3:35 ` Weijie Gao
  2022-08-04 13:56   ` Simon Glass
  2022-08-04  3:35 ` [PATCH 07/31] net: mediatek: stop using bitfileds for DMA descriptors Weijie Gao
                   ` (24 subsequent siblings)
  30 siblings, 1 reply; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:35 UTC (permalink / raw)
  To: u-boot; +Cc: GSS_MTK_Uboot_upstream, Joe Hershberger, Ramon Fried, Weijie Gao

Using a single soc id to control different initialization and TX/RX flow
for all SoCs is not extensible if more hardware variations are added in
the future.

This patch introduces a struct to replace the original mtk_soc to allow
the driver be able handle newer hardwares.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 drivers/net/mtk_eth.c | 50 +++++++++++++++++++++++++++++--------------
 drivers/net/mtk_eth.h | 25 +++++++++++++++++++++-
 2 files changed, 58 insertions(+), 17 deletions(-)

diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c
index 4fe7ee0d36..92d2ea4f2a 100644
--- a/drivers/net/mtk_eth.c
+++ b/drivers/net/mtk_eth.c
@@ -142,11 +142,9 @@ enum mtk_switch {
 	SW_MT7531
 };
 
-enum mtk_soc {
-	SOC_MT7623,
-	SOC_MT7629,
-	SOC_MT7622,
-	SOC_MT7621
+struct mtk_soc_data {
+	u32 caps;
+	u32 ana_rgc3;
 };
 
 struct mtk_eth_priv {
@@ -171,7 +169,7 @@ struct mtk_eth_priv {
 	int (*mmd_write)(struct mtk_eth_priv *priv, u8 addr, u8 devad, u16 reg,
 			 u16 val);
 
-	enum mtk_soc soc;
+	const struct mtk_soc_data *soc;
 	int gmac_id;
 	int force_mode;
 	int speed;
@@ -679,7 +677,7 @@ static int mt7530_setup(struct mtk_eth_priv *priv)
 	u32 val, txdrv;
 	int i;
 
-	if (priv->soc != SOC_MT7621) {
+	if (!MTK_HAS_CAPS(priv->soc->caps, MTK_TRGMII_MT7621_CLK)) {
 		/* Select 250MHz clk for RGMII mode */
 		mtk_ethsys_rmw(priv, ETHSYS_CLKCFG0_REG,
 			       ETHSYS_TRGMII_CLK_SEL362_5, 0);
@@ -1108,9 +1106,8 @@ static int mtk_phy_probe(struct udevice *dev)
 static void mtk_sgmii_init(struct mtk_eth_priv *priv)
 {
 	/* Set SGMII GEN2 speed(2.5G) */
-	clrsetbits_le32(priv->sgmii_base + ((priv->soc == SOC_MT7622) ?
-			SGMSYS_GEN2_SPEED : SGMSYS_GEN2_SPEED_V2),
-			SGMSYS_SPEED_2500, SGMSYS_SPEED_2500);
+	setbits_le32(priv->sgmii_base + priv->soc->ana_rgc3,
+		     SGMSYS_SPEED_2500);
 
 	/* Disable SGMII AN */
 	clrsetbits_le32(priv->sgmii_base + SGMSYS_PCS_CONTROL_1,
@@ -1182,7 +1179,8 @@ static void mtk_mac_init(struct mtk_eth_priv *priv)
 		mtk_gmac_write(priv, GMAC_PORT_MCR(priv->gmac_id), mcr);
 	}
 
-	if (priv->soc == SOC_MT7623) {
+	if (MTK_HAS_CAPS(priv->soc->caps, MTK_GMAC1_TRGMII) &&
+	    !MTK_HAS_CAPS(priv->soc->caps, MTK_TRGMII_MT7621_CLK)) {
 		/* Lower Tx Driving for TRGMII path */
 		for (i = 0 ; i < NUM_TRGMII_CTRL; i++)
 			mtk_gmac_write(priv, GMAC_TRGMII_TD_ODT(i),
@@ -1431,7 +1429,11 @@ static int mtk_eth_of_to_plat(struct udevice *dev)
 	ofnode subnode;
 	int ret;
 
-	priv->soc = dev_get_driver_data(dev);
+	priv->soc = (const struct mtk_soc_data *)dev_get_driver_data(dev);
+	if (!priv->soc) {
+		dev_err(dev, "missing soc compatible data\n");
+		return -EINVAL;
+	}
 
 	pdata->iobase = (phys_addr_t)dev_remap_addr(dev);
 
@@ -1544,11 +1546,27 @@ static int mtk_eth_of_to_plat(struct udevice *dev)
 	return 0;
 }
 
+static const struct mtk_soc_data mt7629_data = {
+	.ana_rgc3 = 0x128,
+};
+
+static const struct mtk_soc_data mt7623_data = {
+	.caps = MT7623_CAPS,
+};
+
+static const struct mtk_soc_data mt7622_data = {
+	.ana_rgc3 = 0x2028,
+};
+
+static const struct mtk_soc_data mt7621_data = {
+	.caps = MT7621_CAPS,
+};
+
 static const struct udevice_id mtk_eth_ids[] = {
-	{ .compatible = "mediatek,mt7629-eth", .data = SOC_MT7629 },
-	{ .compatible = "mediatek,mt7623-eth", .data = SOC_MT7623 },
-	{ .compatible = "mediatek,mt7622-eth", .data = SOC_MT7622 },
-	{ .compatible = "mediatek,mt7621-eth", .data = SOC_MT7621 },
+	{ .compatible = "mediatek,mt7629-eth", .data = (ulong)&mt7629_data },
+	{ .compatible = "mediatek,mt7623-eth", .data = (ulong)&mt7623_data },
+	{ .compatible = "mediatek,mt7622-eth", .data = (ulong)&mt7622_data },
+	{ .compatible = "mediatek,mt7621-eth", .data = (ulong)&mt7621_data },
 	{}
 };
 
diff --git a/drivers/net/mtk_eth.h b/drivers/net/mtk_eth.h
index 057ecfaabf..15c2030617 100644
--- a/drivers/net/mtk_eth.h
+++ b/drivers/net/mtk_eth.h
@@ -9,8 +9,31 @@
 #ifndef _MTK_ETH_H_
 #define _MTK_ETH_H_
 
-/* Frame Engine Register Bases */
 #include <linux/bitops.h>
+
+enum mkt_eth_capabilities {
+	MTK_TRGMII_BIT,
+	MTK_TRGMII_MT7621_CLK_BIT,
+
+	/* PATH BITS */
+	MTK_ETH_PATH_GMAC1_TRGMII_BIT,
+};
+
+#define MTK_TRGMII			BIT(MTK_TRGMII_BIT)
+#define MTK_TRGMII_MT7621_CLK		BIT(MTK_TRGMII_MT7621_CLK_BIT)
+
+/* Supported path present on SoCs */
+#define MTK_ETH_PATH_GMAC1_TRGMII	BIT(MTK_ETH_PATH_GMAC1_TRGMII_BIT)
+
+#define MTK_GMAC1_TRGMII	(MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII)
+
+#define MTK_HAS_CAPS(caps, _x)		(((caps) & (_x)) == (_x))
+
+#define MT7621_CAPS  (MTK_GMAC1_TRGMII | MTK_TRGMII_MT7621_CLK)
+
+#define MT7623_CAPS  (MTK_GMAC1_TRGMII)
+
+/* Frame Engine Register Bases */
 #define PDMA_BASE			0x0800
 #define GDMA1_BASE			0x0500
 #define GDMA2_BASE			0x1500
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 07/31] net: mediatek: stop using bitfileds for DMA descriptors
  2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
                   ` (5 preceding siblings ...)
  2022-08-04  3:35 ` [PATCH 06/31] net: mediatek: use a struct to cover variations of all SoCs Weijie Gao
@ 2022-08-04  3:35 ` Weijie Gao
  2022-08-04 13:56   ` Simon Glass
  2022-08-06 17:50   ` Ramon Fried
  2022-08-04  3:35 ` [PATCH 08/31] net: mediatek: add support for PDMA v2 Weijie Gao
                   ` (23 subsequent siblings)
  30 siblings, 2 replies; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:35 UTC (permalink / raw)
  To: u-boot; +Cc: GSS_MTK_Uboot_upstream, Joe Hershberger, Ramon Fried, Weijie Gao

This patch is a preparation for adding a new version of PDMA of which the
DMA descriptor fields has changed. Using bitfields will result in a complex
modification. Convert bitfields to u32 units can solve this problem easily.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 drivers/net/mtk_eth.c | 144 ++++++++++++++----------------------------
 drivers/net/mtk_eth.h |  32 ++++++++++
 2 files changed, 80 insertions(+), 96 deletions(-)

diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c
index 92d2ea4f2a..bfa049cf79 100644
--- a/drivers/net/mtk_eth.c
+++ b/drivers/net/mtk_eth.c
@@ -65,77 +65,6 @@
 	(DP_DISCARD << MC_DP_S) | \
 	(DP_DISCARD << UN_DP_S))
 
-struct pdma_rxd_info1 {
-	u32 PDP0;
-};
-
-struct pdma_rxd_info2 {
-	u32 PLEN1 : 14;
-	u32 LS1 : 1;
-	u32 UN_USED : 1;
-	u32 PLEN0 : 14;
-	u32 LS0 : 1;
-	u32 DDONE : 1;
-};
-
-struct pdma_rxd_info3 {
-	u32 PDP1;
-};
-
-struct pdma_rxd_info4 {
-	u32 FOE_ENTRY : 14;
-	u32 CRSN : 5;
-	u32 SP : 3;
-	u32 L4F : 1;
-	u32 L4VLD : 1;
-	u32 TACK : 1;
-	u32 IP4F : 1;
-	u32 IP4 : 1;
-	u32 IP6 : 1;
-	u32 UN_USED : 4;
-};
-
-struct pdma_rxdesc {
-	struct pdma_rxd_info1 rxd_info1;
-	struct pdma_rxd_info2 rxd_info2;
-	struct pdma_rxd_info3 rxd_info3;
-	struct pdma_rxd_info4 rxd_info4;
-};
-
-struct pdma_txd_info1 {
-	u32 SDP0;
-};
-
-struct pdma_txd_info2 {
-	u32 SDL1 : 14;
-	u32 LS1 : 1;
-	u32 BURST : 1;
-	u32 SDL0 : 14;
-	u32 LS0 : 1;
-	u32 DDONE : 1;
-};
-
-struct pdma_txd_info3 {
-	u32 SDP1;
-};
-
-struct pdma_txd_info4 {
-	u32 VLAN_TAG : 16;
-	u32 INS : 1;
-	u32 RESV : 2;
-	u32 UDF : 6;
-	u32 FPORT : 3;
-	u32 TSO : 1;
-	u32 TUI_CO : 3;
-};
-
-struct pdma_txdesc {
-	struct pdma_txd_info1 txd_info1;
-	struct pdma_txd_info2 txd_info2;
-	struct pdma_txd_info3 txd_info3;
-	struct pdma_txd_info4 txd_info4;
-};
-
 enum mtk_switch {
 	SW_NONE,
 	SW_MT7530,
@@ -145,13 +74,15 @@ enum mtk_switch {
 struct mtk_soc_data {
 	u32 caps;
 	u32 ana_rgc3;
+	u32 txd_size;
+	u32 rxd_size;
 };
 
 struct mtk_eth_priv {
 	char pkt_pool[TOTAL_PKT_BUF_SIZE] __aligned(ARCH_DMA_MINALIGN);
 
-	struct pdma_txdesc *tx_ring_noc;
-	struct pdma_rxdesc *rx_ring_noc;
+	void *tx_ring_noc;
+	void *rx_ring_noc;
 
 	int rx_dma_owner_idx0;
 	int tx_cpu_owner_idx0;
@@ -1196,14 +1127,16 @@ static void mtk_mac_init(struct mtk_eth_priv *priv)
 static void mtk_eth_fifo_init(struct mtk_eth_priv *priv)
 {
 	char *pkt_base = priv->pkt_pool;
+	struct mtk_tx_dma *txd;
+	struct mtk_rx_dma *rxd;
 	int i;
 
 	mtk_pdma_rmw(priv, PDMA_GLO_CFG_REG, 0xffff0000, 0);
 	udelay(500);
 
-	memset(priv->tx_ring_noc, 0, NUM_TX_DESC * sizeof(struct pdma_txdesc));
-	memset(priv->rx_ring_noc, 0, NUM_RX_DESC * sizeof(struct pdma_rxdesc));
-	memset(priv->pkt_pool, 0, TOTAL_PKT_BUF_SIZE);
+	memset(priv->tx_ring_noc, 0, NUM_TX_DESC * priv->soc->txd_size);
+	memset(priv->rx_ring_noc, 0, NUM_RX_DESC * priv->soc->rxd_size);
+	memset(priv->pkt_pool, 0xff, TOTAL_PKT_BUF_SIZE);
 
 	flush_dcache_range((ulong)pkt_base,
 			   (ulong)(pkt_base + TOTAL_PKT_BUF_SIZE));
@@ -1212,17 +1145,21 @@ static void mtk_eth_fifo_init(struct mtk_eth_priv
 *priv)
 	priv->tx_cpu_owner_idx0 = 0;
 
 	for (i = 0; i < NUM_TX_DESC; i++) {
-		priv->tx_ring_noc[i].txd_info2.LS0 = 1;
-		priv->tx_ring_noc[i].txd_info2.DDONE = 1;
-		priv->tx_ring_noc[i].txd_info4.FPORT = priv->gmac_id + 1;
+		txd = priv->tx_ring_noc + i * priv->soc->txd_size;
+
+		txd->txd1 = virt_to_phys(pkt_base);
+		txd->txd2 = PDMA_TXD2_DDONE | PDMA_TXD2_LS0;
+		txd->txd4 = PDMA_TXD4_FPORT_SET(priv->gmac_id + 1);
 
-		priv->tx_ring_noc[i].txd_info1.SDP0 = virt_to_phys(pkt_base);
 		pkt_base += PKTSIZE_ALIGN;
 	}
 
 	for (i = 0; i < NUM_RX_DESC; i++) {
-		priv->rx_ring_noc[i].rxd_info2.PLEN0 = PKTSIZE_ALIGN;
-		priv->rx_ring_noc[i].rxd_info1.PDP0 = virt_to_phys(pkt_base);
+		rxd = priv->rx_ring_noc + i * priv->soc->rxd_size;
+
+		rxd->rxd1 = virt_to_phys(pkt_base);
+		rxd->rxd2 = PDMA_RXD2_PLEN0_SET(PKTSIZE_ALIGN);
+
 		pkt_base += PKTSIZE_ALIGN;
 	}
 
@@ -1309,20 +1246,22 @@ static int mtk_eth_send(struct udevice *dev, void
 *packet, int length)
 {
 	struct mtk_eth_priv *priv = dev_get_priv(dev);
 	u32 idx = priv->tx_cpu_owner_idx0;
+	struct mtk_tx_dma *txd;
 	void *pkt_base;
 
-	if (!priv->tx_ring_noc[idx].txd_info2.DDONE) {
+	txd = priv->tx_ring_noc + idx * priv->soc->txd_size;
+
+	if (!(txd->txd2 & PDMA_TXD2_DDONE)) {
 		debug("mtk-eth: TX DMA descriptor ring is full\n");
 		return -EPERM;
 	}
 
-	pkt_base = (void *)phys_to_virt(priv->tx_ring_noc[idx].txd_info1.SDP0);
+	pkt_base = (void *)phys_to_virt(txd->txd1);
 	memcpy(pkt_base, packet, length);
 	flush_dcache_range((ulong)pkt_base, (ulong)pkt_base +
 			   roundup(length, ARCH_DMA_MINALIGN));
 
-	priv->tx_ring_noc[idx].txd_info2.SDL0 = length;
-	priv->tx_ring_noc[idx].txd_info2.DDONE = 0;
+	txd->txd2 = PDMA_TXD2_LS0 | PDMA_TXD2_SDL0_SET(length);
 
 	priv->tx_cpu_owner_idx0 = (priv->tx_cpu_owner_idx0 + 1) % NUM_TX_DESC;
 	mtk_pdma_write(priv, TX_CTX_IDX_REG(0), priv->tx_cpu_owner_idx0);
@@ -1334,16 +1273,20 @@ static int mtk_eth_recv(struct udevice *dev, int
 flags, uchar **packetp)
 {
 	struct mtk_eth_priv *priv = dev_get_priv(dev);
 	u32 idx = priv->rx_dma_owner_idx0;
+	struct mtk_rx_dma *rxd;
 	uchar *pkt_base;
 	u32 length;
 
-	if (!priv->rx_ring_noc[idx].rxd_info2.DDONE) {
+	rxd = priv->rx_ring_noc + idx * priv->soc->rxd_size;
+
+	if (!(rxd->rxd2 & PDMA_RXD2_DDONE)) {
 		debug("mtk-eth: RX DMA descriptor ring is empty\n");
 		return -EAGAIN;
 	}
 
-	length = priv->rx_ring_noc[idx].rxd_info2.PLEN0;
-	pkt_base = (void *)phys_to_virt(priv->rx_ring_noc[idx].rxd_info1.PDP0);
+	length = PDMA_RXD2_PLEN0_GET(rxd->rxd2);
+
+	pkt_base = (void *)phys_to_virt(rxd->rxd1);
 	invalidate_dcache_range((ulong)pkt_base, (ulong)pkt_base +
 				roundup(length, ARCH_DMA_MINALIGN));
 
@@ -1357,10 +1300,11 @@ static int mtk_eth_free_pkt(struct udevice *dev,
 uchar *packet, int length)
 {
 	struct mtk_eth_priv *priv = dev_get_priv(dev);
 	u32 idx = priv->rx_dma_owner_idx0;
+	struct mtk_rx_dma *rxd;
+
+	rxd = priv->rx_ring_noc + idx * priv->soc->rxd_size;
 
-	priv->rx_ring_noc[idx].rxd_info2.DDONE = 0;
-	priv->rx_ring_noc[idx].rxd_info2.LS0 = 0;
-	priv->rx_ring_noc[idx].rxd_info2.PLEN0 = PKTSIZE_ALIGN;
+	rxd->rxd2 = PDMA_RXD2_PLEN0_SET(PKTSIZE_ALIGN);
 
 	mtk_pdma_write(priv, RX_CRX_IDX_REG(0), idx);
 	priv->rx_dma_owner_idx0 = (priv->rx_dma_owner_idx0 + 1) % NUM_RX_DESC;
@@ -1387,11 +1331,11 @@ static int mtk_eth_probe(struct udevice *dev)
 		return ret;
 
 	/* Prepare for tx/rx rings */
-	priv->tx_ring_noc = (struct pdma_txdesc *)
-		noncached_alloc(sizeof(struct pdma_txdesc) * NUM_TX_DESC,
+	priv->tx_ring_noc = (void *)
+		noncached_alloc(priv->soc->txd_size * NUM_TX_DESC,
 				ARCH_DMA_MINALIGN);
-	priv->rx_ring_noc = (struct pdma_rxdesc *)
-		noncached_alloc(sizeof(struct pdma_rxdesc) * NUM_RX_DESC,
+	priv->rx_ring_noc = (void *)
+		noncached_alloc(priv->soc->rxd_size * NUM_RX_DESC,
 				ARCH_DMA_MINALIGN);
 
 	/* Set MAC mode */
@@ -1548,18 +1492,26 @@ static int mtk_eth_of_to_plat(struct udevice *dev)
 
 static const struct mtk_soc_data mt7629_data = {
 	.ana_rgc3 = 0x128,
+	.txd_size = sizeof(struct mtk_tx_dma),
+	.rxd_size = sizeof(struct mtk_rx_dma),
 };
 
 static const struct mtk_soc_data mt7623_data = {
 	.caps = MT7623_CAPS,
+	.txd_size = sizeof(struct mtk_tx_dma),
+	.rxd_size = sizeof(struct mtk_rx_dma),
 };
 
 static const struct mtk_soc_data mt7622_data = {
 	.ana_rgc3 = 0x2028,
+	.txd_size = sizeof(struct mtk_tx_dma),
+	.rxd_size = sizeof(struct mtk_rx_dma),
 };
 
 static const struct mtk_soc_data mt7621_data = {
 	.caps = MT7621_CAPS,
+	.txd_size = sizeof(struct mtk_tx_dma),
+	.rxd_size = sizeof(struct mtk_rx_dma),
 };
 
 static const struct udevice_id mtk_eth_ids[] = {
diff --git a/drivers/net/mtk_eth.h b/drivers/net/mtk_eth.h
index 15c2030617..65bc9fcc04 100644
--- a/drivers/net/mtk_eth.h
+++ b/drivers/net/mtk_eth.h
@@ -10,6 +10,7 @@
 #define _MTK_ETH_H_
 
 #include <linux/bitops.h>
+#include <linux/bitfield.h>
 
 enum mkt_eth_capabilities {
 	MTK_TRGMII_BIT,
@@ -435,4 +436,35 @@ enum mkt_eth_capabilities {
 #define PHY_POWER_SAVING_M		0x300
 #define PHY_POWER_SAVING_TX		0x0
 
+/* PDMA descriptors */
+struct mtk_rx_dma {
+	unsigned int rxd1;
+	unsigned int rxd2;
+	unsigned int rxd3;
+	unsigned int rxd4;
+} __packed __aligned(4);
+
+struct mtk_tx_dma {
+	unsigned int txd1;
+	unsigned int txd2;
+	unsigned int txd3;
+	unsigned int txd4;
+} __packed __aligned(4);
+
+/* PDMA TXD fields */
+#define PDMA_TXD2_DDONE			BIT(31)
+#define PDMA_TXD2_LS0			BIT(30)
+#define PDMA_TXD2_SDL0_M		GENMASK(29, 16)
+#define PDMA_TXD2_SDL0_SET(_v)	FIELD_PREP(PDMA_TXD2_SDL0_M, (_v))
+
+#define PDMA_TXD4_FPORT_M		GENMASK(27, 25)
+#define PDMA_TXD4_FPORT_SET(_v)	FIELD_PREP(PDMA_TXD4_FPORT_M, (_v))
+
+/* PDMA RXD fields */
+#define PDMA_RXD2_DDONE			BIT(31)
+#define PDMA_RXD2_LS0			BIT(30)
+#define PDMA_RXD2_PLEN0_M		GENMASK(29, 16)
+#define PDMA_RXD2_PLEN0_GET(_v)	FIELD_GET(PDMA_RXD2_PLEN0_M, (_v))
+#define PDMA_RXD2_PLEN0_SET(_v)	FIELD_PREP(PDMA_RXD2_PLEN0_M, (_v))
+
 #endif /* _MTK_ETH_H_ */
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 08/31] net: mediatek: add support for PDMA v2
  2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
                   ` (6 preceding siblings ...)
  2022-08-04  3:35 ` [PATCH 07/31] net: mediatek: stop using bitfileds for DMA descriptors Weijie Gao
@ 2022-08-04  3:35 ` Weijie Gao
  2022-08-04 13:56   ` Simon Glass
  2022-08-04  3:35 ` [PATCH 09/31] net: mediatek: add support for MediaTek MT7981/MT7986 Weijie Gao
                   ` (22 subsequent siblings)
  30 siblings, 1 reply; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:35 UTC (permalink / raw)
  To: u-boot; +Cc: GSS_MTK_Uboot_upstream, Joe Hershberger, Ramon Fried, Weijie Gao

This patch adds support for PDMA v2 hardware. The PDMA v2 has extended the
DMA descriptor to 8-words, and some of its fields have changed comparing
to the v1 hardware.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 drivers/net/mtk_eth.c | 51 ++++++++++++++++++++++++++++++-----------
 drivers/net/mtk_eth.h | 53 ++++++++++++++++++++++++++++++++++++-------
 2 files changed, 83 insertions(+), 21 deletions(-)

diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c
index bfa049cf79..47a4e698c0 100644
--- a/drivers/net/mtk_eth.c
+++ b/drivers/net/mtk_eth.c
@@ -74,6 +74,7 @@ enum mtk_switch {
 struct mtk_soc_data {
 	u32 caps;
 	u32 ana_rgc3;
+	u32 pdma_base;
 	u32 txd_size;
 	u32 rxd_size;
 };
@@ -124,13 +125,13 @@ struct mtk_eth_priv {
 
 static void mtk_pdma_write(struct mtk_eth_priv *priv, u32 reg, u32 val)
 {
-	writel(val, priv->fe_base + PDMA_BASE + reg);
+	writel(val, priv->fe_base + priv->soc->pdma_base + reg);
 }
 
 static void mtk_pdma_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr,
 			 u32 set)
 {
-	clrsetbits_le32(priv->fe_base + PDMA_BASE + reg, clr, set);
+	clrsetbits_le32(priv->fe_base + priv->soc->pdma_base + reg, clr, set);
 }
 
 static void mtk_gdma_write(struct mtk_eth_priv *priv, int no, u32 reg,
@@ -1127,8 +1128,8 @@ static void mtk_mac_init(struct mtk_eth_priv *priv)
 static void mtk_eth_fifo_init(struct mtk_eth_priv *priv)
 {
 	char *pkt_base = priv->pkt_pool;
-	struct mtk_tx_dma *txd;
-	struct mtk_rx_dma *rxd;
+	struct mtk_tx_dma_v2 *txd;
+	struct mtk_rx_dma_v2 *rxd;
 	int i;
 
 	mtk_pdma_rmw(priv, PDMA_GLO_CFG_REG, 0xffff0000, 0);
@@ -1149,7 +1150,11 @@ static void mtk_eth_fifo_init(struct mtk_eth_priv
 *priv)
 
 		txd->txd1 = virt_to_phys(pkt_base);
 		txd->txd2 = PDMA_TXD2_DDONE | PDMA_TXD2_LS0;
-		txd->txd4 = PDMA_TXD4_FPORT_SET(priv->gmac_id + 1);
+
+		if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2))
+			txd->txd5 = PDMA_V2_TXD5_FPORT_SET(priv->gmac_id + 1);
+		else
+			txd->txd4 = PDMA_V1_TXD4_FPORT_SET(priv->gmac_id + 1);
 
 		pkt_base += PKTSIZE_ALIGN;
 	}
@@ -1158,7 +1163,11 @@ static void mtk_eth_fifo_init(struct mtk_eth_priv
 *priv)
 		rxd = priv->rx_ring_noc + i * priv->soc->rxd_size;
 
 		rxd->rxd1 = virt_to_phys(pkt_base);
-		rxd->rxd2 = PDMA_RXD2_PLEN0_SET(PKTSIZE_ALIGN);
+
+		if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2))
+			rxd->rxd2 = PDMA_V2_RXD2_PLEN0_SET(PKTSIZE_ALIGN);
+		else
+			rxd->rxd2 = PDMA_V1_RXD2_PLEN0_SET(PKTSIZE_ALIGN);
 
 		pkt_base += PKTSIZE_ALIGN;
 	}
@@ -1187,6 +1196,9 @@ static int mtk_eth_start(struct udevice *dev)
 	reset_deassert(&priv->rst_fe);
 	mdelay(10);
 
+	if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2))
+		setbits_le32(priv->fe_base + FE_GLO_MISC_REG, PDMA_VER_V2);
+
 	/* Packets forward to PDMA */
 	mtk_gdma_write(priv, priv->gmac_id, GDMA_IG_CTRL_REG, GDMA_FWD_TO_CPU);
 
@@ -1221,7 +1233,7 @@ static void mtk_eth_stop(struct udevice *dev)
 		     TX_WB_DDONE | RX_DMA_EN | TX_DMA_EN, 0);
 	udelay(500);
 
-	wait_for_bit_le32(priv->fe_base + PDMA_BASE + PDMA_GLO_CFG_REG,
+	wait_for_bit_le32(priv->fe_base + priv->soc->pdma_base + PDMA_GLO_CFG_REG,
 			  RX_DMA_BUSY | TX_DMA_BUSY, 0, 5000, 0);
 }
 
@@ -1246,7 +1258,7 @@ static int mtk_eth_send(struct udevice *dev, void
 *packet, int length)
 {
 	struct mtk_eth_priv *priv = dev_get_priv(dev);
 	u32 idx = priv->tx_cpu_owner_idx0;
-	struct mtk_tx_dma *txd;
+	struct mtk_tx_dma_v2 *txd;
 	void *pkt_base;
 
 	txd = priv->tx_ring_noc + idx * priv->soc->txd_size;
@@ -1261,7 +1273,10 @@ static int mtk_eth_send(struct udevice *dev, void
 *packet, int length)
 	flush_dcache_range((ulong)pkt_base, (ulong)pkt_base +
 			   roundup(length, ARCH_DMA_MINALIGN));
 
-	txd->txd2 = PDMA_TXD2_LS0 | PDMA_TXD2_SDL0_SET(length);
+	if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2))
+		txd->txd2 = PDMA_TXD2_LS0 | PDMA_V2_TXD2_SDL0_SET(length);
+	else
+		txd->txd2 = PDMA_TXD2_LS0 | PDMA_V1_TXD2_SDL0_SET(length);
 
 	priv->tx_cpu_owner_idx0 = (priv->tx_cpu_owner_idx0 + 1) % NUM_TX_DESC;
 	mtk_pdma_write(priv, TX_CTX_IDX_REG(0), priv->tx_cpu_owner_idx0);
@@ -1273,7 +1288,7 @@ static int mtk_eth_recv(struct udevice *dev, int
 flags, uchar **packetp)
 {
 	struct mtk_eth_priv *priv = dev_get_priv(dev);
 	u32 idx = priv->rx_dma_owner_idx0;
-	struct mtk_rx_dma *rxd;
+	struct mtk_rx_dma_v2 *rxd;
 	uchar *pkt_base;
 	u32 length;
 
@@ -1284,7 +1299,10 @@ static int mtk_eth_recv(struct udevice *dev, int
 flags, uchar **packetp)
 		return -EAGAIN;
 	}
 
-	length = PDMA_RXD2_PLEN0_GET(rxd->rxd2);
+	if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2))
+		length = PDMA_V2_RXD2_PLEN0_GET(rxd->rxd2);
+	else
+		length = PDMA_V1_RXD2_PLEN0_GET(rxd->rxd2);
 
 	pkt_base = (void *)phys_to_virt(rxd->rxd1);
 	invalidate_dcache_range((ulong)pkt_base, (ulong)pkt_base +
@@ -1300,11 +1318,14 @@ static int mtk_eth_free_pkt(struct udevice *dev,
 uchar *packet, int length)
 {
 	struct mtk_eth_priv *priv = dev_get_priv(dev);
 	u32 idx = priv->rx_dma_owner_idx0;
-	struct mtk_rx_dma *rxd;
+	struct mtk_rx_dma_v2 *rxd;
 
 	rxd = priv->rx_ring_noc + idx * priv->soc->rxd_size;
 
-	rxd->rxd2 = PDMA_RXD2_PLEN0_SET(PKTSIZE_ALIGN);
+	if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2))
+		rxd->rxd2 = PDMA_V2_RXD2_PLEN0_SET(PKTSIZE_ALIGN);
+	else
+		rxd->rxd2 = PDMA_V1_RXD2_PLEN0_SET(PKTSIZE_ALIGN);
 
 	mtk_pdma_write(priv, RX_CRX_IDX_REG(0), idx);
 	priv->rx_dma_owner_idx0 = (priv->rx_dma_owner_idx0 + 1) % NUM_RX_DESC;
@@ -1492,24 +1513,28 @@ static int mtk_eth_of_to_plat(struct udevice *dev)
 
 static const struct mtk_soc_data mt7629_data = {
 	.ana_rgc3 = 0x128,
+	.pdma_base = PDMA_V1_BASE,
 	.txd_size = sizeof(struct mtk_tx_dma),
 	.rxd_size = sizeof(struct mtk_rx_dma),
 };
 
 static const struct mtk_soc_data mt7623_data = {
 	.caps = MT7623_CAPS,
+	.pdma_base = PDMA_V1_BASE,
 	.txd_size = sizeof(struct mtk_tx_dma),
 	.rxd_size = sizeof(struct mtk_rx_dma),
 };
 
 static const struct mtk_soc_data mt7622_data = {
 	.ana_rgc3 = 0x2028,
+	.pdma_base = PDMA_V1_BASE,
 	.txd_size = sizeof(struct mtk_tx_dma),
 	.rxd_size = sizeof(struct mtk_rx_dma),
 };
 
 static const struct mtk_soc_data mt7621_data = {
 	.caps = MT7621_CAPS,
+	.pdma_base = PDMA_V1_BASE,
 	.txd_size = sizeof(struct mtk_tx_dma),
 	.rxd_size = sizeof(struct mtk_rx_dma),
 };
diff --git a/drivers/net/mtk_eth.h b/drivers/net/mtk_eth.h
index 65bc9fcc04..236c498a1b 100644
--- a/drivers/net/mtk_eth.h
+++ b/drivers/net/mtk_eth.h
@@ -15,6 +15,7 @@
 enum mkt_eth_capabilities {
 	MTK_TRGMII_BIT,
 	MTK_TRGMII_MT7621_CLK_BIT,
+	MTK_NETSYS_V2_BIT,
 
 	/* PATH BITS */
 	MTK_ETH_PATH_GMAC1_TRGMII_BIT,
@@ -22,6 +23,7 @@ enum mkt_eth_capabilities {
 
 #define MTK_TRGMII			BIT(MTK_TRGMII_BIT)
 #define MTK_TRGMII_MT7621_CLK		BIT(MTK_TRGMII_MT7621_CLK_BIT)
+#define MTK_NETSYS_V2			BIT(MTK_NETSYS_V2_BIT)
 
 /* Supported path present on SoCs */
 #define MTK_ETH_PATH_GMAC1_TRGMII	BIT(MTK_ETH_PATH_GMAC1_TRGMII_BIT)
@@ -35,7 +37,8 @@ enum mkt_eth_capabilities {
 #define MT7623_CAPS  (MTK_GMAC1_TRGMII)
 
 /* Frame Engine Register Bases */
-#define PDMA_BASE			0x0800
+#define PDMA_V1_BASE			0x0800
+#define PDMA_V2_BASE			0x6000
 #define GDMA1_BASE			0x0500
 #define GDMA2_BASE			0x1500
 #define GMAC_BASE			0x10000
@@ -74,6 +77,8 @@ enum mkt_eth_capabilities {
 #define SGMSYS_SPEED_2500		BIT(2)
 
 /* Frame Engine Registers */
+#define FE_GLO_MISC_REG			0x124
+#define PDMA_VER_V2			BIT(4)
 
 /* PDMA */
 #define TX_BASE_PTR_REG(n)		(0x000 + (n) * 0x10)
@@ -444,6 +449,17 @@ struct mtk_rx_dma {
 	unsigned int rxd4;
 } __packed __aligned(4);
 
+struct mtk_rx_dma_v2 {
+	unsigned int rxd1;
+	unsigned int rxd2;
+	unsigned int rxd3;
+	unsigned int rxd4;
+	unsigned int rxd5;
+	unsigned int rxd6;
+	unsigned int rxd7;
+	unsigned int rxd8;
+} __packed __aligned(4);
+
 struct mtk_tx_dma {
 	unsigned int txd1;
 	unsigned int txd2;
@@ -451,20 +467,41 @@ struct mtk_tx_dma {
 	unsigned int txd4;
 } __packed __aligned(4);
 
+struct mtk_tx_dma_v2 {
+	unsigned int txd1;
+	unsigned int txd2;
+	unsigned int txd3;
+	unsigned int txd4;
+	unsigned int txd5;
+	unsigned int txd6;
+	unsigned int txd7;
+	unsigned int txd8;
+} __packed __aligned(4);
+
 /* PDMA TXD fields */
 #define PDMA_TXD2_DDONE			BIT(31)
 #define PDMA_TXD2_LS0			BIT(30)
-#define PDMA_TXD2_SDL0_M		GENMASK(29, 16)
-#define PDMA_TXD2_SDL0_SET(_v)	FIELD_PREP(PDMA_TXD2_SDL0_M, (_v))
+#define PDMA_V1_TXD2_SDL0_M		GENMASK(29, 16)
+#define PDMA_V1_TXD2_SDL0_SET(_v)	FIELD_PREP(PDMA_V1_TXD2_SDL0_M, (_v))
+#define PDMA_V2_TXD2_SDL0_M		GENMASK(23, 8)
+#define PDMA_V2_TXD2_SDL0_SET(_v)	FIELD_PREP(PDMA_V2_TXD2_SDL0_M, (_v))
+
+#define PDMA_V1_TXD4_FPORT_M		GENMASK(27, 25)
+#define PDMA_V1_TXD4_FPORT_SET(_v)	FIELD_PREP(PDMA_V1_TXD4_FPORT_M, (_v))
+#define PDMA_V2_TXD4_FPORT_M		GENMASK(27, 24)
+#define PDMA_V2_TXD4_FPORT_SET(_v)	FIELD_PREP(PDMA_V2_TXD4_FPORT_M, (_v))
 
-#define PDMA_TXD4_FPORT_M		GENMASK(27, 25)
-#define PDMA_TXD4_FPORT_SET(_v)	FIELD_PREP(PDMA_TXD4_FPORT_M, (_v))
+#define PDMA_V2_TXD5_FPORT_M		GENMASK(19, 16)
+#define PDMA_V2_TXD5_FPORT_SET(_v)	FIELD_PREP(PDMA_V2_TXD5_FPORT_M, (_v))
 
 /* PDMA RXD fields */
 #define PDMA_RXD2_DDONE			BIT(31)
 #define PDMA_RXD2_LS0			BIT(30)
-#define PDMA_RXD2_PLEN0_M		GENMASK(29, 16)
-#define PDMA_RXD2_PLEN0_GET(_v)	FIELD_GET(PDMA_RXD2_PLEN0_M, (_v))
-#define PDMA_RXD2_PLEN0_SET(_v)	FIELD_PREP(PDMA_RXD2_PLEN0_M, (_v))
+#define PDMA_V1_RXD2_PLEN0_M		GENMASK(29, 16)
+#define PDMA_V1_RXD2_PLEN0_GET(_v)	FIELD_GET(PDMA_V1_RXD2_PLEN0_M, (_v))
+#define PDMA_V1_RXD2_PLEN0_SET(_v)	FIELD_PREP(PDMA_V1_RXD2_PLEN0_M, (_v))
+#define PDMA_V2_RXD2_PLEN0_M		GENMASK(23, 8)
+#define PDMA_V2_RXD2_PLEN0_GET(_v)	FIELD_GET(PDMA_V2_RXD2_PLEN0_M, (_v))
+#define PDMA_V2_RXD2_PLEN0_SET(_v)	FIELD_PREP(PDMA_V2_RXD2_PLEN0_M, (_v))
 
 #endif /* _MTK_ETH_H_ */
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 09/31] net: mediatek: add support for MediaTek MT7981/MT7986
  2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
                   ` (7 preceding siblings ...)
  2022-08-04  3:35 ` [PATCH 08/31] net: mediatek: add support for PDMA v2 Weijie Gao
@ 2022-08-04  3:35 ` Weijie Gao
  2022-08-06 17:48   ` Ramon Fried
  2022-08-04  3:35 ` [PATCH 10/31] serial: mtk: add support for using dynamic baud clock souce Weijie Gao
                   ` (21 subsequent siblings)
  30 siblings, 1 reply; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:35 UTC (permalink / raw)
  To: u-boot; +Cc: GSS_MTK_Uboot_upstream, Joe Hershberger, Ramon Fried, Weijie Gao

This patch adds support for MediaTek MT7981 and MT7986. Both chips uses
PDMA v2.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 drivers/net/mtk_eth.c | 27 +++++++++++++++++++++++++++
 drivers/net/mtk_eth.h |  5 +++++
 2 files changed, 32 insertions(+)

diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c
index 47a4e698c0..7bff0b5b04 100644
--- a/drivers/net/mtk_eth.c
+++ b/drivers/net/mtk_eth.c
@@ -106,6 +106,7 @@ struct mtk_eth_priv {
 	int force_mode;
 	int speed;
 	int duplex;
+	bool pn_swap;
 
 	struct phy_device *phydev;
 	int phy_interface;
@@ -1048,6 +1049,12 @@ static void mtk_sgmii_init(struct mtk_eth_priv *priv)
 	/* SGMII force mode setting */
 	writel(SGMII_FORCE_MODE, priv->sgmii_base + SGMSYS_SGMII_MODE);
 
+	/* SGMII PN SWAP setting */
+	if (priv->pn_swap) {
+		setbits_le32(priv->sgmii_base + SGMSYS_QPHY_WRAP_CTRL,
+			     SGMII_PN_SWAP_TX_RX);
+	}
+
 	/* Release PHYA power down state */
 	clrsetbits_le32(priv->sgmii_base + SGMSYS_QPHY_PWR_STATE_CTRL,
 			SGMII_PHYA_PWD, 0);
@@ -1461,6 +1468,8 @@ static int mtk_eth_of_to_plat(struct udevice *dev)
 			dev_err(dev, "Unable to find sgmii\n");
 			return -ENODEV;
 		}
+
+		priv->pn_swap = ofnode_read_bool(args.node, "pn_swap");
 	}
 
 	/* check for switch first, otherwise phy will be used */
@@ -1511,6 +1520,22 @@ static int mtk_eth_of_to_plat(struct udevice *dev)
 	return 0;
 }
 
+static const struct mtk_soc_data mt7986_data = {
+	.caps = MT7986_CAPS,
+	.ana_rgc3 = 0x128,
+	.pdma_base = PDMA_V2_BASE,
+	.txd_size = sizeof(struct mtk_tx_dma_v2),
+	.rxd_size = sizeof(struct mtk_rx_dma_v2),
+};
+
+static const struct mtk_soc_data mt7981_data = {
+	.caps = MT7986_CAPS,
+	.ana_rgc3 = 0x128,
+	.pdma_base = PDMA_V2_BASE,
+	.txd_size = sizeof(struct mtk_tx_dma_v2),
+	.rxd_size = sizeof(struct mtk_rx_dma_v2),
+};
+
 static const struct mtk_soc_data mt7629_data = {
 	.ana_rgc3 = 0x128,
 	.pdma_base = PDMA_V1_BASE,
@@ -1540,6 +1565,8 @@ static const struct mtk_soc_data mt7621_data = {
 };
 
 static const struct udevice_id mtk_eth_ids[] = {
+	{ .compatible = "mediatek,mt7986-eth", .data = (ulong)&mt7986_data },
+	{ .compatible = "mediatek,mt7981-eth", .data = (ulong)&mt7981_data },
 	{ .compatible = "mediatek,mt7629-eth", .data = (ulong)&mt7629_data },
 	{ .compatible = "mediatek,mt7623-eth", .data = (ulong)&mt7623_data },
 	{ .compatible = "mediatek,mt7622-eth", .data = (ulong)&mt7622_data },
diff --git a/drivers/net/mtk_eth.h b/drivers/net/mtk_eth.h
index 236c498a1b..1382ccbeb2 100644
--- a/drivers/net/mtk_eth.h
+++ b/drivers/net/mtk_eth.h
@@ -36,6 +36,8 @@ enum mkt_eth_capabilities {
 
 #define MT7623_CAPS  (MTK_GMAC1_TRGMII)
 
+#define MT7986_CAPS  (MTK_NETSYS_V2)
+
 /* Frame Engine Register Bases */
 #define PDMA_V1_BASE			0x0800
 #define PDMA_V2_BASE			0x6000
@@ -72,6 +74,9 @@ enum mkt_eth_capabilities {
 #define SGMSYS_QPHY_PWR_STATE_CTRL	0xe8
 #define SGMII_PHYA_PWD			BIT(4)
 
+#define SGMSYS_QPHY_WRAP_CTRL		0xec
+#define SGMII_PN_SWAP_TX_RX		0x03
+
 #define SGMSYS_GEN2_SPEED		0x2028
 #define SGMSYS_GEN2_SPEED_V2		0x128
 #define SGMSYS_SPEED_2500		BIT(2)
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 10/31] serial: mtk: add support for using dynamic baud clock souce
  2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
                   ` (8 preceding siblings ...)
  2022-08-04  3:35 ` [PATCH 09/31] net: mediatek: add support for MediaTek MT7981/MT7986 Weijie Gao
@ 2022-08-04  3:35 ` Weijie Gao
  2022-08-04 13:56   ` Simon Glass
  2022-08-04  3:35 ` [PATCH 11/31] arm: dts: mt7622: force high-speed mode for uart Weijie Gao
                   ` (20 subsequent siblings)
  30 siblings, 1 reply; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:35 UTC (permalink / raw)
  To: u-boot; +Cc: GSS_MTK_Uboot_upstream, Pali Rohár, Weijie Gao

The baud clock on some platform may change due to assigned-clock-parent
set in DT. In current flow the baud clock is only retrieved during probe
stage. If the parent of the source clock changes after probe stage, the
setbrg will set wrong baudrate.

To get the right clock rate, this patch records the baud clk struct to the
driver's priv, and changes the driver's flow to get the clock rate before
calling _mtk_serial_setbrg().

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 drivers/serial/serial_mtk.c | 72 ++++++++++++++++++++-----------------
 1 file changed, 39 insertions(+), 33 deletions(-)

diff --git a/drivers/serial/serial_mtk.c b/drivers/serial/serial_mtk.c
index a84f39b3fa..99cf62b8d9 100644
--- a/drivers/serial/serial_mtk.c
+++ b/drivers/serial/serial_mtk.c
@@ -10,6 +10,7 @@
 #include <common.h>
 #include <div64.h>
 #include <dm.h>
+#include <dm/device_compat.h>
 #include <errno.h>
 #include <log.h>
 #include <serial.h>
@@ -72,25 +73,27 @@ struct mtk_serial_regs {
 
 struct mtk_serial_priv {
 	struct mtk_serial_regs __iomem *regs;
-	u32 clock;
+	struct clk clk;
+	u32 fixed_clk_rate;
 	bool force_highspeed;
 };
 
-static void _mtk_serial_setbrg(struct mtk_serial_priv *priv, int baud)
+static void _mtk_serial_setbrg(struct mtk_serial_priv *priv, int baud,
+			       u32 clk_rate)
 {
 	u32 quot, realbaud, samplecount = 1;
 
 	/* Special case for low baud clock */
-	if (baud <= 115200 && priv->clock <= 12000000) {
+	if (baud <= 115200 && clk_rate == 12000000) {
 		writel(3, &priv->regs->highspeed);
 
-		quot = DIV_ROUND_CLOSEST(priv->clock, 256 * baud);
+		quot = DIV_ROUND_CLOSEST(clk_rate, 256 * baud);
 		if (quot == 0)
 			quot = 1;
 
-		samplecount = DIV_ROUND_CLOSEST(priv->clock, quot * baud);
+		samplecount = DIV_ROUND_CLOSEST(clk_rate, quot * baud);
 
-		realbaud = priv->clock / samplecount / quot;
+		realbaud = clk_rate / samplecount / quot;
 		if (realbaud > BAUD_ALLOW_MAX(baud) ||
 		    realbaud < BAUD_ALLOW_MIX(baud)) {
 			pr_info("baud %d can't be handled\n", baud);
@@ -104,7 +107,7 @@ static void _mtk_serial_setbrg(struct mtk_serial_priv
 *priv, int baud)
 
 	if (baud <= 115200) {
 		writel(0, &priv->regs->highspeed);
-		quot = DIV_ROUND_CLOSEST(priv->clock, 16 * baud);
+		quot = DIV_ROUND_CLOSEST(clk_rate, 16 * baud);
 	} else if (baud <= 576000) {
 		writel(2, &priv->regs->highspeed);
 
@@ -112,13 +115,13 @@ static void _mtk_serial_setbrg(struct mtk_serial_priv
 *priv, int baud)
 		if ((baud == 500000) || (baud == 576000))
 			baud = 460800;
 
-		quot = DIV_ROUND_UP(priv->clock, 4 * baud);
+		quot = DIV_ROUND_UP(clk_rate, 4 * baud);
 	} else {
 use_hs3:
 		writel(3, &priv->regs->highspeed);
 
-		quot = DIV_ROUND_UP(priv->clock, 256 * baud);
-		samplecount = DIV_ROUND_CLOSEST(priv->clock, quot * baud);
+		quot = DIV_ROUND_UP(clk_rate, 256 * baud);
+		samplecount = DIV_ROUND_CLOSEST(clk_rate, quot * baud);
 	}
 
 set_baud:
@@ -167,8 +170,13 @@ static int _mtk_serial_pending(struct mtk_serial_priv
 *priv, bool input)
 static int mtk_serial_setbrg(struct udevice *dev, int baudrate)
 {
 	struct mtk_serial_priv *priv = dev_get_priv(dev);
+	u32 clk_rate;
+
+	clk_rate = clk_get_rate(&priv->clk);
+	if (IS_ERR_VALUE(clk_rate) || clk_rate == 0)
+		clk_rate = priv->fixed_clk_rate;
 
-	_mtk_serial_setbrg(priv, baudrate);
+	_mtk_serial_setbrg(priv, baudrate, clk_rate);
 
 	return 0;
 }
@@ -211,7 +219,6 @@ static int mtk_serial_of_to_plat(struct udevice *dev)
 {
 	struct mtk_serial_priv *priv = dev_get_priv(dev);
 	fdt_addr_t addr;
-	struct clk clk;
 	int err;
 
 	addr = dev_read_addr(dev);
@@ -220,22 +227,19 @@ static int mtk_serial_of_to_plat(struct udevice *dev)
 
 	priv->regs = map_physmem(addr, 0, MAP_NOCACHE);
 
-	err = clk_get_by_index(dev, 0, &clk);
-	if (!err) {
-		err = clk_get_rate(&clk);
-		if (!IS_ERR_VALUE(err))
-			priv->clock = err;
-	} else if (err != -ENOENT && err != -ENODEV && err != -ENOSYS) {
-		debug("mtk_serial: failed to get clock\n");
-		return err;
-	}
-
-	if (!priv->clock)
-		priv->clock = dev_read_u32_default(dev, "clock-frequency", 0);
-
-	if (!priv->clock) {
-		debug("mtk_serial: clock not defined\n");
-		return -EINVAL;
+	err = clk_get_by_index(dev, 0, &priv->clk);
+	if (err) {
+		err = dev_read_u32(dev, "clock-frequency", &priv->fixed_clk_rate);
+		if (err) {
+			dev_err(dev, "baud clock not defined\n");
+			return -EINVAL;
+		}
+	} else {
+		err = clk_get_rate(&priv->clk);
+		if (IS_ERR_VALUE(err)) {
+			dev_err(dev, "invalid baud clock\n");
+			return -EINVAL;
+		}
 	}
 
 	priv->force_highspeed = dev_read_bool(dev, "mediatek,force-highspeed");
@@ -273,7 +277,7 @@ 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 \
+	.fixed_clk_rate = CONFIG_SYS_NS16550_CLK \
 };
 
 #define DECLARE_HSUART_FUNCTIONS(port) \
@@ -282,12 +286,14 @@ DECLARE_GLOBAL_DATA_PTR;
 		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); \
+		_mtk_serial_setbrg(&mtk_hsuart##port, gd->baudrate, \
+				   mtk_hsuart##port.fixed_clk_rate); \
 		return 0 ; \
 	} \
 	static void mtk_serial##port##_setbrg(void) \
 	{ \
-		_mtk_serial_setbrg(&mtk_hsuart##port, gd->baudrate); \
+		_mtk_serial_setbrg(&mtk_hsuart##port, gd->baudrate, \
+				   mtk_hsuart##port.fixed_clk_rate); \
 	} \
 	static int mtk_serial##port##_getc(void) \
 	{ \
@@ -427,13 +433,13 @@ static inline void _debug_uart_init(void)
 	struct mtk_serial_priv priv;
 
 	priv.regs = (void *) CONFIG_VAL(DEBUG_UART_BASE);
-	priv.clock = CONFIG_DEBUG_UART_CLOCK;
+	priv.fixed_clk_rate = 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);
+	_mtk_serial_setbrg(&priv, CONFIG_BAUDRATE, priv.fixed_clk_rate);
 }
 
 static inline void _debug_uart_putc(int ch)
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 11/31] arm: dts: mt7622: force high-speed mode for uart
  2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
                   ` (9 preceding siblings ...)
  2022-08-04  3:35 ` [PATCH 10/31] serial: mtk: add support for using dynamic baud clock souce Weijie Gao
@ 2022-08-04  3:35 ` Weijie Gao
  2022-08-04 13:57   ` Simon Glass
  2022-08-04  3:35 ` [PATCH 12/31] pwm: mtk: add support for MediaTek MT7986 SoC Weijie Gao
                   ` (19 subsequent siblings)
  30 siblings, 1 reply; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:35 UTC (permalink / raw)
  To: u-boot; +Cc: GSS_MTK_Uboot_upstream, Weijie Gao

The input clock for uart is too slow (25MHz) which introduces frequent data
error on both receiving and transmitting even if the baudrate is 115200.

Using high-speed can significantly solve this issue.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 arch/arm/dts/mt7622.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/dts/mt7622.dtsi b/arch/arm/dts/mt7622.dtsi
index 0127474c95..fb6c1b7154 100644
--- a/arch/arm/dts/mt7622.dtsi
+++ b/arch/arm/dts/mt7622.dtsi
@@ -175,6 +175,7 @@
 		status = "disabled";
 		assigned-clocks = <&topckgen CLK_TOP_AXI_SEL>;
 		assigned-clock-parents = <&topckgen CLK_TOP_SYSPLL1_D2>;
+		mediatek,force-highspeed;
 	};
 
 	mmc0: mmc@11230000 {
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 12/31] pwm: mtk: add support for MediaTek MT7986 SoC
  2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
                   ` (10 preceding siblings ...)
  2022-08-04  3:35 ` [PATCH 11/31] arm: dts: mt7622: force high-speed mode for uart Weijie Gao
@ 2022-08-04  3:35 ` Weijie Gao
  2022-08-04 13:57   ` Simon Glass
  2022-08-04  3:35 ` [PATCH 13/31] pwm: mtk: add support for MediaTek MT7981 SoC Weijie Gao
                   ` (18 subsequent siblings)
  30 siblings, 1 reply; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:35 UTC (permalink / raw)
  To: u-boot; +Cc: GSS_MTK_Uboot_upstream, Weijie Gao

This patch adds PWM support for MediaTek MT7986 SoC.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 drivers/pwm/pwm-mtk.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/pwm/pwm-mtk.c b/drivers/pwm/pwm-mtk.c
index aee1d825a0..3100b5caaf 100644
--- a/drivers/pwm/pwm-mtk.c
+++ b/drivers/pwm/pwm-mtk.c
@@ -171,10 +171,16 @@ static const struct mtk_pwm_soc mt7629_data = {
 	.pwm45_fixup = false,
 };
 
+static const struct mtk_pwm_soc mt7986_data = {
+	.num_pwms = 2,
+	.pwm45_fixup = false,
+};
+
 static const struct udevice_id mtk_pwm_ids[] = {
 	{ .compatible = "mediatek,mt7622-pwm", .data = (ulong)&mt7622_data },
 	{ .compatible = "mediatek,mt7623-pwm", .data = (ulong)&mt7623_data },
 	{ .compatible = "mediatek,mt7629-pwm", .data = (ulong)&mt7629_data },
+	{ .compatible = "mediatek,mt7986-pwm", .data = (ulong)&mt7986_data },
 	{ }
 };
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 13/31] pwm: mtk: add support for MediaTek MT7981 SoC
  2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
                   ` (11 preceding siblings ...)
  2022-08-04  3:35 ` [PATCH 12/31] pwm: mtk: add support for MediaTek MT7986 SoC Weijie Gao
@ 2022-08-04  3:35 ` Weijie Gao
  2022-08-04 13:57   ` Simon Glass
  2022-08-04  3:35 ` [PATCH 14/31] timer: mtk: add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
                   ` (17 subsequent siblings)
  30 siblings, 1 reply; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:35 UTC (permalink / raw)
  To: u-boot; +Cc: GSS_MTK_Uboot_upstream, Weijie Gao

This patch adds PWM support for MediaTek MT7981 SoC.
MT7981 uses a different register offset so we have to add a version field
to indicate the IP core version.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 drivers/pwm/pwm-mtk.c | 34 ++++++++++++++++++++++++++++++++--
 1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/drivers/pwm/pwm-mtk.c b/drivers/pwm/pwm-mtk.c
index 3100b5caaf..605142eab0 100644
--- a/drivers/pwm/pwm-mtk.c
+++ b/drivers/pwm/pwm-mtk.c
@@ -29,13 +29,23 @@
 
 #define NSEC_PER_SEC 1000000000L
 
-static const unsigned int mtk_pwm_reg_offset[] = {
+enum mtk_pwm_reg_ver {
+	PWM_REG_V1,
+	PWM_REG_V2,
+};
+
+static const unsigned int mtk_pwm_reg_offset_v1[] = {
 	0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220
 };
 
+static const unsigned int mtk_pwm_reg_offset_v2[] = {
+	0x0080, 0x00c0, 0x0100, 0x0140, 0x0180, 0x01c0, 0x0200, 0x0240
+};
+
 struct mtk_pwm_soc {
 	unsigned int num_pwms;
 	bool pwm45_fixup;
+	enum mtk_pwm_reg_ver reg_ver;
 };
 
 struct mtk_pwm_priv {
@@ -49,7 +59,16 @@ struct mtk_pwm_priv {
 static void mtk_pwm_w32(struct udevice *dev, uint channel, uint reg, uint
 val)
 {
 	struct mtk_pwm_priv *priv = dev_get_priv(dev);
-	u32 offset = mtk_pwm_reg_offset[channel];
+	u32 offset;
+
+	switch (priv->soc->reg_ver) {
+	case PWM_REG_V2:
+		offset = mtk_pwm_reg_offset_v2[channel];
+		break;
+
+	default:
+		offset = mtk_pwm_reg_offset_v1[channel];
+	}
 
 	writel(val, priv->base + offset + reg);
 }
@@ -159,27 +178,38 @@ static const struct pwm_ops mtk_pwm_ops = {
 static const struct mtk_pwm_soc mt7622_data = {
 	.num_pwms = 6,
 	.pwm45_fixup = false,
+	.reg_ver = PWM_REG_V1,
 };
 
 static const struct mtk_pwm_soc mt7623_data = {
 	.num_pwms = 5,
 	.pwm45_fixup = true,
+	.reg_ver = PWM_REG_V1,
 };
 
 static const struct mtk_pwm_soc mt7629_data = {
 	.num_pwms = 1,
 	.pwm45_fixup = false,
+	.reg_ver = PWM_REG_V1,
+};
+
+static const struct mtk_pwm_soc mt7981_data = {
+	.num_pwms = 2,
+	.pwm45_fixup = false,
+	.reg_ver = PWM_REG_V2,
 };
 
 static const struct mtk_pwm_soc mt7986_data = {
 	.num_pwms = 2,
 	.pwm45_fixup = false,
+	.reg_ver = PWM_REG_V1,
 };
 
 static const struct udevice_id mtk_pwm_ids[] = {
 	{ .compatible = "mediatek,mt7622-pwm", .data = (ulong)&mt7622_data },
 	{ .compatible = "mediatek,mt7623-pwm", .data = (ulong)&mt7623_data },
 	{ .compatible = "mediatek,mt7629-pwm", .data = (ulong)&mt7629_data },
+	{ .compatible = "mediatek,mt7981-pwm", .data = (ulong)&mt7981_data },
 	{ .compatible = "mediatek,mt7986-pwm", .data = (ulong)&mt7986_data },
 	{ }
 };
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 14/31] timer: mtk: add support for MediaTek MT7981/MT7986 SoCs
  2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
                   ` (12 preceding siblings ...)
  2022-08-04  3:35 ` [PATCH 13/31] pwm: mtk: add support for MediaTek MT7981 SoC Weijie Gao
@ 2022-08-04  3:35 ` Weijie Gao
  2022-08-04 13:57   ` Simon Glass
  2022-08-04  3:35 ` [PATCH 15/31] watchdog: mediatek: add support for MediaTek MT7986 SoC Weijie Gao
                   ` (16 subsequent siblings)
  30 siblings, 1 reply; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:35 UTC (permalink / raw)
  To: u-boot; +Cc: GSS_MTK_Uboot_upstream, Weijie Gao

This patch add general-purpose timer support for MediaTek MT7981/MT7986.
These two SoCs uses a newer version of timer with its register definition
slightly changed.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 drivers/timer/mtk_timer.c | 59 ++++++++++++++++++++++++---------------
 1 file changed, 37 insertions(+), 22 deletions(-)

diff --git a/drivers/timer/mtk_timer.c b/drivers/timer/mtk_timer.c
index f6b97f868c..223e63f6c1 100644
--- a/drivers/timer/mtk_timer.c
+++ b/drivers/timer/mtk_timer.c
@@ -13,24 +13,32 @@
 #include <asm/io.h>
 #include <linux/bitops.h>
 
-#define MTK_GPT4_CTRL	0x40
-#define MTK_GPT4_CLK	0x44
-#define MTK_GPT4_CNT	0x48
+#define MTK_GPT4_OFFSET_V1	0x40
+#define MTK_GPT4_OFFSET_V2	0x80
 
-#define GPT4_ENABLE	BIT(0)
-#define GPT4_CLEAR	BIT(1)
-#define GPT4_FREERUN	GENMASK(5, 4)
-#define GPT4_CLK_SYS	0x0
-#define GPT4_CLK_DIV1	0x0
+#define MTK_GPT_CON		0x0
+#define MTK_GPT_V1_CLK		0x4
+#define MTK_GPT_CNT		0x8
+
+#define GPT_ENABLE		BIT(0)
+#define GPT_CLEAR		BIT(1)
+#define GPT_V1_FREERUN		GENMASK(5, 4)
+#define GPT_V2_FREERUN		GENMASK(6, 5)
+
+enum mtk_gpt_ver {
+	MTK_GPT_V1,
+	MTK_GPT_V2
+};
 
 struct mtk_timer_priv {
 	void __iomem *base;
+	unsigned int gpt4_offset;
 };
 
 static u64 mtk_timer_get_count(struct udevice *dev)
 {
 	struct mtk_timer_priv *priv = dev_get_priv(dev);
-	u32 val = readl(priv->base + MTK_GPT4_CNT);
+	u32 val = readl(priv->base + priv->gpt4_offset + MTK_GPT_CNT);
 
 	return timer_conv_64(val);
 }
@@ -40,12 +48,27 @@ static int mtk_timer_probe(struct udevice *dev)
 	struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 	struct mtk_timer_priv *priv = dev_get_priv(dev);
 	struct clk clk, parent;
-	int ret;
+	int ret, gpt_ver;
 
 	priv->base = dev_read_addr_ptr(dev);
+	gpt_ver = dev_get_driver_data(dev);
+
 	if (!priv->base)
 		return -ENOENT;
 
+	if (gpt_ver == MTK_GPT_V2) {
+		priv->gpt4_offset = MTK_GPT4_OFFSET_V2;
+
+		writel(GPT_V2_FREERUN | GPT_CLEAR | GPT_ENABLE,
+		       priv->base + priv->gpt4_offset + MTK_GPT_CON);
+	} else {
+		priv->gpt4_offset = MTK_GPT4_OFFSET_V1;
+
+		writel(GPT_V1_FREERUN | GPT_CLEAR | GPT_ENABLE,
+		       priv->base + priv->gpt4_offset + MTK_GPT_CON);
+		writel(0, priv->base + priv->gpt4_offset + MTK_GPT_V1_CLK);
+	}
+
 	ret = clk_get_by_index(dev, 0, &clk);
 	if (ret)
 		return ret;
@@ -61,16 +84,6 @@ static int mtk_timer_probe(struct udevice *dev)
 	if (!uc_priv->clock_rate)
 		return -EINVAL;
 
-	/*
-	 * Initialize the timer:
-	 * 1. set clock source to system clock with clock divider setting to 1
-	 * 2. set timer mode to free running
-	 * 3. reset timer counter to 0 then enable the timer
-	 */
-	writel(GPT4_CLK_SYS | GPT4_CLK_DIV1, priv->base + MTK_GPT4_CLK);
-	writel(GPT4_FREERUN | GPT4_CLEAR | GPT4_ENABLE,
-	       priv->base + MTK_GPT4_CTRL);
-
 	return 0;
 }
 
@@ -79,8 +92,10 @@ static const struct timer_ops mtk_timer_ops = {
 };
 
 static const struct udevice_id mtk_timer_ids[] = {
-	{ .compatible = "mediatek,timer" },
-	{ .compatible = "mediatek,mt6577-timer" },
+	{ .compatible = "mediatek,timer", .data = MTK_GPT_V1 },
+	{ .compatible = "mediatek,mt6577-timer", .data = MTK_GPT_V1 },
+	{ .compatible = "mediatek,mt7981-timer", .data = MTK_GPT_V2 },
+	{ .compatible = "mediatek,mt7986-timer", .data = MTK_GPT_V2 },
 	{ }
 };
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 15/31] watchdog: mediatek: add support for MediaTek MT7986 SoC
  2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
                   ` (13 preceding siblings ...)
  2022-08-04  3:35 ` [PATCH 14/31] timer: mtk: add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
@ 2022-08-04  3:35 ` Weijie Gao
  2022-08-04 13:57   ` Simon Glass
  2022-08-04  3:36 ` [PATCH 16/31] spi: add support for MediaTek spi-mem controller Weijie Gao
                   ` (15 subsequent siblings)
  30 siblings, 1 reply; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:35 UTC (permalink / raw)
  To: u-boot; +Cc: GSS_MTK_Uboot_upstream, Stefan Roese, Weijie Gao

This patch adds watchdog support for MediaTek MT7986 SoC

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 drivers/watchdog/mtk_wdt.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c
index b098b2e3cf..368b36849c 100644
--- a/drivers/watchdog/mtk_wdt.c
+++ b/drivers/watchdog/mtk_wdt.c
@@ -145,6 +145,7 @@ static const struct wdt_ops mtk_wdt_ops = {
 static const struct udevice_id mtk_wdt_ids[] = {
 	{ .compatible = "mediatek,wdt"},
 	{ .compatible = "mediatek,mt6589-wdt"},
+	{ .compatible = "mediatek,mt7986-wdt" },
 	{}
 };
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 16/31] spi: add support for MediaTek spi-mem controller
  2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
                   ` (14 preceding siblings ...)
  2022-08-04  3:35 ` [PATCH 15/31] watchdog: mediatek: add support for MediaTek MT7986 SoC Weijie Gao
@ 2022-08-04  3:36 ` Weijie Gao
  2022-08-04 13:57   ` Simon Glass
  2022-08-04  3:36 ` [PATCH 17/31] i2c: add support for MediaTek I2C interface Weijie Gao
                   ` (14 subsequent siblings)
  30 siblings, 1 reply; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:36 UTC (permalink / raw)
  To: u-boot; +Cc: GSS_MTK_Uboot_upstream, Jagan Teki, Weijie Gao, SkyLake . Huang

This patch adds support for spi-mem controller found on newer MediaTek SoCs
This controller supports Single/Dual/Quad SPI mode.

Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
---
 drivers/spi/Kconfig    |   8 +
 drivers/spi/Makefile   |   1 +
 drivers/spi/mtk_spim.c | 705 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 714 insertions(+)
 create mode 100644 drivers/spi/mtk_spim.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 75b794548b..7e72ab9c24 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -276,6 +276,14 @@ config MTK_SNFI_SPI
 	  used to access SPI memory devices like SPI-NOR or SPI-NAND on
 	  platforms embedding this IP core, like MT7622/M7629.
 
+config MTK_SPIM
+	bool "Mediatek SPI-MEM master controller driver"
+	depends on SPI_MEM
+	help
+	  Enable MediaTek SPI-MEM master controller driver. This driver mainly
+	  supports SPI flashes. You can use single, dual or quad mode
+	  transmission on this controller.
+
 config MVEBU_A3700_SPI
 	bool "Marvell Armada 3700 SPI driver"
 	select CLK_ARMADA_3720
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 4de77c260a..309f6b5328 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_MPC8XX_SPI) += mpc8xx_spi.o
 obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
 obj-$(CONFIG_MTK_SNFI_SPI) += mtk_snfi_spi.o
 obj-$(CONFIG_MTK_SNOR) += mtk_snor.o
+obj-$(CONFIG_MTK_SPIM) += mtk_spim.o
 obj-$(CONFIG_MT7620_SPI) += mt7620_spi.o
 obj-$(CONFIG_MT7621_SPI) += mt7621_spi.o
 obj-$(CONFIG_MSCC_BB_SPI) += mscc_bb_spi.o
diff --git a/drivers/spi/mtk_spim.c b/drivers/spi/mtk_spim.c
new file mode 100644
index 0000000000..b0f63c3c3f
--- /dev/null
+++ b/drivers/spi/mtk_spim.c
@@ -0,0 +1,705 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 MediaTek Inc. All Rights Reserved.
+ *
+ * Author: SkyLake.Huang <skylake.huang@mediatek.com>
+ */
+
+#include <clk.h>
+#include <cpu_func.h>
+#include <div64.h>
+#include <dm.h>
+#include <dm/device.h>
+#include <dm/device_compat.h>
+#include <dm/devres.h>
+#include <dm/pinctrl.h>
+#include <linux/bitops.h>
+#include <linux/completion.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <spi.h>
+#include <spi-mem.h>
+#include <stdbool.h>
+#include <watchdog.h>
+
+#define SPI_CFG0_REG				0x0000
+#define SPI_CFG1_REG				0x0004
+#define SPI_TX_SRC_REG				0x0008
+#define SPI_RX_DST_REG				0x000c
+#define SPI_TX_DATA_REG				0x0010
+#define SPI_RX_DATA_REG				0x0014
+#define SPI_CMD_REG				0x0018
+#define SPI_IRQ_REG				0x001c
+#define SPI_STATUS_REG				0x0020
+#define SPI_PAD_SEL_REG				0x0024
+#define SPI_CFG2_REG				0x0028
+#define SPI_TX_SRC_REG_64			0x002c
+#define SPI_RX_DST_REG_64			0x0030
+#define SPI_CFG3_IPM_REG			0x0040
+
+#define SPI_CFG0_SCK_HIGH_OFFSET		0
+#define SPI_CFG0_SCK_LOW_OFFSET			8
+#define SPI_CFG0_CS_HOLD_OFFSET			16
+#define SPI_CFG0_CS_SETUP_OFFSET		24
+#define SPI_ADJUST_CFG0_CS_HOLD_OFFSET		0
+#define SPI_ADJUST_CFG0_CS_SETUP_OFFSET		16
+
+#define SPI_CFG1_CS_IDLE_OFFSET			0
+#define SPI_CFG1_PACKET_LOOP_OFFSET		8
+#define SPI_CFG1_PACKET_LENGTH_OFFSET		16
+#define SPI_CFG1_GET_TICKDLY_OFFSET		29
+
+#define SPI_CFG1_GET_TICKDLY_MASK		GENMASK(31, 29)
+#define SPI_CFG1_CS_IDLE_MASK			0xff
+#define SPI_CFG1_PACKET_LOOP_MASK		0xff00
+#define SPI_CFG1_PACKET_LENGTH_MASK		0x3ff0000
+#define SPI_CFG1_IPM_PACKET_LENGTH_MASK		GENMASK(31, 16)
+#define SPI_CFG2_SCK_HIGH_OFFSET		0
+#define SPI_CFG2_SCK_LOW_OFFSET			16
+#define SPI_CFG2_SCK_HIGH_MASK			GENMASK(15, 0)
+#define SPI_CFG2_SCK_LOW_MASK			GENMASK(31, 16)
+
+#define SPI_CMD_ACT				BIT(0)
+#define SPI_CMD_RESUME				BIT(1)
+#define SPI_CMD_RST				BIT(2)
+#define SPI_CMD_PAUSE_EN			BIT(4)
+#define SPI_CMD_DEASSERT			BIT(5)
+#define SPI_CMD_SAMPLE_SEL			BIT(6)
+#define SPI_CMD_CS_POL				BIT(7)
+#define SPI_CMD_CPHA				BIT(8)
+#define SPI_CMD_CPOL				BIT(9)
+#define SPI_CMD_RX_DMA				BIT(10)
+#define SPI_CMD_TX_DMA				BIT(11)
+#define SPI_CMD_TXMSBF				BIT(12)
+#define SPI_CMD_RXMSBF				BIT(13)
+#define SPI_CMD_RX_ENDIAN			BIT(14)
+#define SPI_CMD_TX_ENDIAN			BIT(15)
+#define SPI_CMD_FINISH_IE			BIT(16)
+#define SPI_CMD_PAUSE_IE			BIT(17)
+#define SPI_CMD_IPM_NONIDLE_MODE		BIT(19)
+#define SPI_CMD_IPM_SPIM_LOOP			BIT(21)
+#define SPI_CMD_IPM_GET_TICKDLY_OFFSET		22
+
+#define SPI_CMD_IPM_GET_TICKDLY_MASK		GENMASK(24, 22)
+
+#define PIN_MODE_CFG(x)				((x) / 2)
+
+#define SPI_CFG3_IPM_PIN_MODE_OFFSET		0
+#define SPI_CFG3_IPM_HALF_DUPLEX_DIR		BIT(2)
+#define SPI_CFG3_IPM_HALF_DUPLEX_EN		BIT(3)
+#define SPI_CFG3_IPM_XMODE_EN			BIT(4)
+#define SPI_CFG3_IPM_NODATA_FLAG		BIT(5)
+#define SPI_CFG3_IPM_CMD_BYTELEN_OFFSET		8
+#define SPI_CFG3_IPM_ADDR_BYTELEN_OFFSET	12
+#define SPI_CFG3_IPM_DUMMY_BYTELEN_OFFSET	16
+
+#define SPI_CFG3_IPM_CMD_PIN_MODE_MASK		GENMASK(1, 0)
+#define SPI_CFG3_IPM_CMD_BYTELEN_MASK		GENMASK(11, 8)
+#define SPI_CFG3_IPM_ADDR_BYTELEN_MASK		GENMASK(15, 12)
+#define SPI_CFG3_IPM_DUMMY_BYTELEN_MASK		GENMASK(19, 16)
+
+#define MT8173_SPI_MAX_PAD_SEL			3
+
+#define MTK_SPI_PAUSE_INT_STATUS		0x2
+
+#define MTK_SPI_IDLE				0
+#define MTK_SPI_PAUSED				1
+
+#define MTK_SPI_MAX_FIFO_SIZE			32U
+#define MTK_SPI_PACKET_SIZE			1024
+#define MTK_SPI_IPM_PACKET_SIZE			SZ_64K
+#define MTK_SPI_IPM_PACKET_LOOP			SZ_256
+
+#define MTK_SPI_32BITS_MASK			0xffffffff
+
+#define DMA_ADDR_EXT_BITS			36
+#define DMA_ADDR_DEF_BITS			32
+
+#define CLK_TO_US(freq, clkcnt) DIV_ROUND_UP((clkcnt), (freq) / 1000000)
+
+struct mtk_spim_capability {
+	bool need_pad_sel;
+	/* Must explicitly send dummy Tx bytes to do Rx only transfer */
+	bool must_tx;
+	/* some IC design adjust cfg register to enhance time accuracy */
+	bool enhance_timing;
+	/* some IC support DMA addr extension */
+	bool dma_ext;
+	/* the IPM IP design improve some feature, and support dual/quad mode */
+	bool ipm_design;
+	bool support_quad;
+};
+
+struct mtk_spim_priv {
+	void __iomem *base;
+	u32 state;
+	int pad_num;
+	u32 *pad_sel;
+	struct clk sel_clk, spi_clk;
+	struct spi_transfer *cur_transfer;
+	u32 xfer_len;
+	u32 num_xfered;
+	struct scatterlist *tx_sgl, *rx_sgl;
+	u32 tx_sgl_len, rx_sgl_len;
+	struct mtk_spim_capability hw_cap;
+	u32 tick_dly;
+	u32 sample_sel;
+
+	struct completion spimem_done;
+	bool use_spimem;
+	struct device *dev;
+	dma_addr_t tx_dma;
+	dma_addr_t rx_dma;
+};
+
+static void mtk_spim_reset(struct mtk_spim_priv *priv)
+{
+	u32 reg_val;
+
+	/* set the software reset bit in SPI_CMD_REG. */
+	reg_val = readl(priv->base + SPI_CMD_REG);
+	reg_val |= SPI_CMD_RST;
+	writel(reg_val, priv->base + SPI_CMD_REG);
+
+	reg_val = readl(priv->base + SPI_CMD_REG);
+	reg_val &= ~SPI_CMD_RST;
+	writel(reg_val, priv->base + SPI_CMD_REG);
+}
+
+static int mtk_spim_hw_init(struct spi_slave *slave)
+{
+	struct udevice *bus = dev_get_parent(slave->dev);
+	struct mtk_spim_priv *priv = dev_get_priv(bus);
+	u16 cpha, cpol;
+	u32 reg_val;
+
+	cpha = slave->mode & SPI_CPHA ? 1 : 0;
+	cpol = slave->mode & SPI_CPOL ? 1 : 0;
+
+	if (priv->hw_cap.enhance_timing) {
+		if (priv->hw_cap.ipm_design) {
+			/* CFG3 reg only used for spi-mem,
+			 * here write to default value
+			 */
+			writel(0x0, priv->base + SPI_CFG3_IPM_REG);
+
+			reg_val = readl(priv->base + SPI_CMD_REG);
+			reg_val &= ~SPI_CMD_IPM_GET_TICKDLY_MASK;
+			reg_val |= priv->tick_dly
+				   << SPI_CMD_IPM_GET_TICKDLY_OFFSET;
+			writel(reg_val, priv->base + SPI_CMD_REG);
+		} else {
+			reg_val = readl(priv->base + SPI_CFG1_REG);
+			reg_val &= ~SPI_CFG1_GET_TICKDLY_MASK;
+			reg_val |= priv->tick_dly
+				   << SPI_CFG1_GET_TICKDLY_OFFSET;
+			writel(reg_val, priv->base + SPI_CFG1_REG);
+		}
+	}
+
+	reg_val = readl(priv->base + SPI_CMD_REG);
+	if (priv->hw_cap.ipm_design) {
+		/* SPI transfer without idle time until packet length done */
+		reg_val |= SPI_CMD_IPM_NONIDLE_MODE;
+		if (slave->mode & SPI_LOOP)
+			reg_val |= SPI_CMD_IPM_SPIM_LOOP;
+		else
+			reg_val &= ~SPI_CMD_IPM_SPIM_LOOP;
+	}
+
+	if (cpha)
+		reg_val |= SPI_CMD_CPHA;
+	else
+		reg_val &= ~SPI_CMD_CPHA;
+	if (cpol)
+		reg_val |= SPI_CMD_CPOL;
+	else
+		reg_val &= ~SPI_CMD_CPOL;
+
+	/* set the mlsbx and mlsbtx */
+	if (slave->mode & SPI_LSB_FIRST) {
+		reg_val &= ~SPI_CMD_TXMSBF;
+		reg_val &= ~SPI_CMD_RXMSBF;
+	} else {
+		reg_val |= SPI_CMD_TXMSBF;
+		reg_val |= SPI_CMD_RXMSBF;
+	}
+
+	/* set the tx/rx endian */
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+	reg_val &= ~SPI_CMD_TX_ENDIAN;
+	reg_val &= ~SPI_CMD_RX_ENDIAN;
+#else
+	reg_val |= SPI_CMD_TX_ENDIAN;
+	reg_val |= SPI_CMD_RX_ENDIAN;
+#endif
+
+	if (priv->hw_cap.enhance_timing) {
+		/* set CS polarity */
+		if (slave->mode & SPI_CS_HIGH)
+			reg_val |= SPI_CMD_CS_POL;
+		else
+			reg_val &= ~SPI_CMD_CS_POL;
+
+		if (priv->sample_sel)
+			reg_val |= SPI_CMD_SAMPLE_SEL;
+		else
+			reg_val &= ~SPI_CMD_SAMPLE_SEL;
+	}
+
+	/* disable dma mode */
+	reg_val &= ~(SPI_CMD_TX_DMA | SPI_CMD_RX_DMA);
+
+	/* disable deassert mode */
+	reg_val &= ~SPI_CMD_DEASSERT;
+
+	writel(reg_val, priv->base + SPI_CMD_REG);
+
+#if !CONFIG_IS_ENABLED(DM_SPI)
+	/* pad select, we don't need this in IPM design. */
+	if (priv->hw_cap.need_pad_sel)
+		writel(priv->pad_sel[slave->cs],
+		       priv->base + SPI_PAD_SEL_REG);
+#endif
+
+	return 0;
+}
+
+static void mtk_spim_prepare_transfer(struct mtk_spim_priv *priv,
+				      u32 speed_hz)
+{
+	u32 spi_clk_hz, div, sck_time, cs_time, reg_val;
+
+	spi_clk_hz = clk_get_rate(&priv->spi_clk);
+	if (speed_hz <= spi_clk_hz / 4)
+		div = DIV_ROUND_UP(spi_clk_hz, speed_hz);
+	else
+		div = 4;
+
+	sck_time = (div + 1) / 2;
+	cs_time = sck_time * 2;
+
+	if (priv->hw_cap.enhance_timing) {
+		reg_val = (((sck_time - 1) & 0xffff)
+			   << SPI_CFG2_SCK_HIGH_OFFSET);
+		reg_val |= (((sck_time - 1) & 0xffff)
+			   << SPI_CFG2_SCK_LOW_OFFSET);
+		writel(reg_val, priv->base + SPI_CFG2_REG);
+		reg_val = (((cs_time - 1) & 0xffff)
+			   << SPI_ADJUST_CFG0_CS_HOLD_OFFSET);
+		reg_val |= (((cs_time - 1) & 0xffff)
+			   << SPI_ADJUST_CFG0_CS_SETUP_OFFSET);
+		writel(reg_val, priv->base + SPI_CFG0_REG);
+	} else {
+		reg_val = (((sck_time - 1) & 0xff)
+			   << SPI_CFG0_SCK_HIGH_OFFSET);
+		reg_val |= (((sck_time - 1) & 0xff) << SPI_CFG0_SCK_LOW_OFFSET);
+		reg_val |= (((cs_time - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET);
+		reg_val |= (((cs_time - 1) & 0xff) << SPI_CFG0_CS_SETUP_OFFSET);
+		writel(reg_val, priv->base + SPI_CFG0_REG);
+	}
+
+	reg_val = readl(priv->base + SPI_CFG1_REG);
+	reg_val &= ~SPI_CFG1_CS_IDLE_MASK;
+	reg_val |= (((cs_time - 1) & 0xff) << SPI_CFG1_CS_IDLE_OFFSET);
+	writel(reg_val, priv->base + SPI_CFG1_REG);
+}
+
+static void mtk_spim_setup_packet(struct mtk_spim_priv *priv)
+{
+	u32 packet_size, packet_loop, reg_val;
+
+	if (priv->hw_cap.ipm_design)
+		packet_size = min_t(u32,
+				    priv->xfer_len,
+				    MTK_SPI_IPM_PACKET_SIZE);
+	else
+		packet_size = min_t(u32,
+				    priv->xfer_len,
+				    MTK_SPI_PACKET_SIZE);
+
+	packet_loop = priv->xfer_len / packet_size;
+
+	reg_val = readl(priv->base + SPI_CFG1_REG);
+	if (priv->hw_cap.ipm_design)
+		reg_val &= ~SPI_CFG1_IPM_PACKET_LENGTH_MASK;
+	else
+		reg_val &= ~SPI_CFG1_PACKET_LENGTH_MASK;
+
+	reg_val |= (packet_size - 1) << SPI_CFG1_PACKET_LENGTH_OFFSET;
+
+	reg_val &= ~SPI_CFG1_PACKET_LOOP_MASK;
+
+	reg_val |= (packet_loop - 1) << SPI_CFG1_PACKET_LOOP_OFFSET;
+
+	writel(reg_val, priv->base + SPI_CFG1_REG);
+}
+
+static void mtk_spim_enable_transfer(struct mtk_spim_priv *priv)
+{
+	u32 cmd;
+
+	cmd = readl(priv->base + SPI_CMD_REG);
+	if (priv->state == MTK_SPI_IDLE)
+		cmd |= SPI_CMD_ACT;
+	else
+		cmd |= SPI_CMD_RESUME;
+	writel(cmd, priv->base + SPI_CMD_REG);
+}
+
+static bool mtk_spim_supports_op(struct spi_slave *slave,
+				 const struct spi_mem_op *op)
+{
+	if (op->cmd.buswidth == 0 || op->cmd.buswidth > 4 ||
+	    op->addr.buswidth > 4 || op->dummy.buswidth > 4 ||
+	    op->data.buswidth > 4)
+		return false;
+
+	if (op->addr.nbytes && op->dummy.nbytes &&
+	    op->addr.buswidth != op->dummy.buswidth)
+		return false;
+
+	if (op->addr.nbytes + op->dummy.nbytes > 16)
+		return false;
+
+	if (op->data.nbytes > MTK_SPI_IPM_PACKET_SIZE) {
+		if (op->data.nbytes / MTK_SPI_IPM_PACKET_SIZE >
+		    MTK_SPI_IPM_PACKET_LOOP ||
+		    op->data.nbytes % MTK_SPI_IPM_PACKET_SIZE != 0)
+			return false;
+	}
+
+	return true;
+}
+
+static void mtk_spim_setup_dma_xfer(struct mtk_spim_priv *priv,
+				    const struct spi_mem_op *op)
+{
+	writel((u32)(priv->tx_dma & MTK_SPI_32BITS_MASK),
+	       priv->base + SPI_TX_SRC_REG);
+
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+	if (priv->dev_comp->dma_ext)
+		writel((u32)(priv->tx_dma >> 32),
+		       priv->base + SPI_TX_SRC_REG_64);
+#endif
+
+	if (op->data.dir == SPI_MEM_DATA_IN) {
+		writel((u32)(priv->rx_dma & MTK_SPI_32BITS_MASK),
+		       priv->base + SPI_RX_DST_REG);
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+		if (priv->dev_comp->dma_ext)
+			writel((u32)(priv->rx_dma >> 32),
+			       priv->base + SPI_RX_DST_REG_64);
+#endif
+	}
+}
+
+static int mtk_spim_transfer_wait(struct spi_slave *slave,
+				  const struct spi_mem_op *op)
+{
+	struct udevice *bus = dev_get_parent(slave->dev);
+	struct mtk_spim_priv *priv = dev_get_priv(bus);
+	u32 sck_l, sck_h, spi_bus_clk, clk_count, reg;
+	ulong us = 1;
+	int ret = 0;
+
+	if (op->data.dir == SPI_MEM_NO_DATA)
+		clk_count = 32;
+	else
+		clk_count = op->data.nbytes;
+
+	spi_bus_clk = clk_get_rate(&priv->spi_clk);
+	sck_l = readl(priv->base + SPI_CFG2_REG) >> SPI_CFG2_SCK_LOW_OFFSET;
+	sck_h = readl(priv->base + SPI_CFG2_REG) & SPI_CFG2_SCK_HIGH_MASK;
+	do_div(spi_bus_clk, sck_l + sck_h + 2);
+
+	us = CLK_TO_US(spi_bus_clk, clk_count * 8);
+	us += 1000 * 1000; /* 1s tolerance */
+
+	if (us > UINT_MAX)
+		us = UINT_MAX;
+
+	ret = readl_poll_timeout(priv->base + SPI_STATUS_REG, reg,
+				 reg & 0x1, us);
+	if (ret < 0) {
+		dev_err(priv->dev, "transfer timeout, val: 0x%lx\n", us);
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
+static int mtk_spim_exec_op(struct spi_slave *slave,
+			    const struct spi_mem_op *op)
+{
+	struct udevice *bus = dev_get_parent(slave->dev);
+	struct mtk_spim_priv *priv = dev_get_priv(bus);
+	u32 reg_val, nio = 1, tx_size;
+	char *tx_tmp_buf;
+	char *rx_tmp_buf;
+	int i, ret = 0;
+
+	priv->use_spimem = true;
+
+	mtk_spim_reset(priv);
+	mtk_spim_hw_init(slave);
+	mtk_spim_prepare_transfer(priv, slave->max_hz);
+
+	reg_val = readl(priv->base + SPI_CFG3_IPM_REG);
+	/* opcode byte len */
+	reg_val &= ~SPI_CFG3_IPM_CMD_BYTELEN_MASK;
+	reg_val |= 1 << SPI_CFG3_IPM_CMD_BYTELEN_OFFSET;
+
+	/* addr & dummy byte len */
+	if (op->addr.nbytes || op->dummy.nbytes)
+		reg_val |= (op->addr.nbytes + op->dummy.nbytes) <<
+			    SPI_CFG3_IPM_ADDR_BYTELEN_OFFSET;
+
+	/* data byte len */
+	if (!op->data.nbytes) {
+		reg_val |= SPI_CFG3_IPM_NODATA_FLAG;
+		writel(0, priv->base + SPI_CFG1_REG);
+	} else {
+		reg_val &= ~SPI_CFG3_IPM_NODATA_FLAG;
+		priv->xfer_len = op->data.nbytes;
+		mtk_spim_setup_packet(priv);
+	}
+
+	if (op->addr.nbytes || op->dummy.nbytes) {
+		if (op->addr.buswidth == 1 || op->dummy.buswidth == 1)
+			reg_val |= SPI_CFG3_IPM_XMODE_EN;
+		else
+			reg_val &= ~SPI_CFG3_IPM_XMODE_EN;
+	}
+
+	if (op->addr.buswidth == 2 ||
+	    op->dummy.buswidth == 2 ||
+	    op->data.buswidth == 2)
+		nio = 2;
+	else if (op->addr.buswidth == 4 ||
+		 op->dummy.buswidth == 4 ||
+		 op->data.buswidth == 4)
+		nio = 4;
+
+	reg_val &= ~SPI_CFG3_IPM_CMD_PIN_MODE_MASK;
+	reg_val |= PIN_MODE_CFG(nio) << SPI_CFG3_IPM_PIN_MODE_OFFSET;
+
+	reg_val |= SPI_CFG3_IPM_HALF_DUPLEX_EN;
+	if (op->data.dir == SPI_MEM_DATA_IN)
+		reg_val |= SPI_CFG3_IPM_HALF_DUPLEX_DIR;
+	else
+		reg_val &= ~SPI_CFG3_IPM_HALF_DUPLEX_DIR;
+	writel(reg_val, priv->base + SPI_CFG3_IPM_REG);
+
+	tx_size = 1 + op->addr.nbytes + op->dummy.nbytes;
+	if (op->data.dir == SPI_MEM_DATA_OUT)
+		tx_size += op->data.nbytes;
+
+	tx_size = max(tx_size, (u32)32);
+
+	/* Fill up tx data*/
+	tx_tmp_buf = kzalloc(tx_size, GFP_KERNEL);
+	if (!tx_tmp_buf) {
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	tx_tmp_buf[0] = op->cmd.opcode;
+
+	if (op->addr.nbytes) {
+		for (i = 0; i < op->addr.nbytes; i++)
+			tx_tmp_buf[i + 1] = op->addr.val >>
+					(8 * (op->addr.nbytes - i - 1));
+	}
+
+	if (op->dummy.nbytes)
+		memset(tx_tmp_buf + op->addr.nbytes + 1, 0xff,
+		       op->dummy.nbytes);
+
+	if (op->data.nbytes && op->data.dir == SPI_MEM_DATA_OUT)
+		memcpy(tx_tmp_buf + op->dummy.nbytes + op->addr.nbytes + 1,
+		       op->data.buf.out, op->data.nbytes);
+	/* Finish filling up tx data*/
+
+	priv->tx_dma = dma_map_single(tx_tmp_buf, tx_size, DMA_TO_DEVICE);
+	if (dma_mapping_error(priv->dev, priv->tx_dma)) {
+		ret = -ENOMEM;
+		goto tx_free;
+	}
+
+	if (op->data.dir == SPI_MEM_DATA_IN) {
+		if (!IS_ALIGNED((size_t)op->data.buf.in, 4)) {
+			rx_tmp_buf = kzalloc(op->data.nbytes, GFP_KERNEL);
+			if (!rx_tmp_buf) {
+				ret = -ENOMEM;
+				goto tx_unmap;
+			}
+		} else {
+			rx_tmp_buf = op->data.buf.in;
+		}
+
+		priv->rx_dma = dma_map_single(rx_tmp_buf, op->data.nbytes,
+					      DMA_FROM_DEVICE);
+		if (dma_mapping_error(priv->dev, priv->rx_dma)) {
+			ret = -ENOMEM;
+			goto rx_free;
+		}
+	}
+
+	reg_val = readl(priv->base + SPI_CMD_REG);
+	reg_val |= SPI_CMD_TX_DMA;
+	if (op->data.dir == SPI_MEM_DATA_IN)
+		reg_val |= SPI_CMD_RX_DMA;
+
+	writel(reg_val, priv->base + SPI_CMD_REG);
+
+	mtk_spim_setup_dma_xfer(priv, op);
+
+	mtk_spim_enable_transfer(priv);
+
+	/* Wait for the interrupt. */
+	ret = mtk_spim_transfer_wait(slave, op);
+	if (ret)
+		goto rx_unmap;
+
+	if (op->data.dir == SPI_MEM_DATA_IN &&
+	    !IS_ALIGNED((size_t)op->data.buf.in, 4))
+		memcpy(op->data.buf.in, rx_tmp_buf, op->data.nbytes);
+
+rx_unmap:
+	/* spi disable dma */
+	reg_val = readl(priv->base + SPI_CMD_REG);
+	reg_val &= ~SPI_CMD_TX_DMA;
+	if (op->data.dir == SPI_MEM_DATA_IN)
+		reg_val &= ~SPI_CMD_RX_DMA;
+	writel(reg_val, priv->base + SPI_CMD_REG);
+
+	writel(0, priv->base + SPI_TX_SRC_REG);
+	writel(0, priv->base + SPI_RX_DST_REG);
+
+	if (op->data.dir == SPI_MEM_DATA_IN)
+		dma_unmap_single(priv->rx_dma,
+				 op->data.nbytes, DMA_FROM_DEVICE);
+rx_free:
+	if (op->data.dir == SPI_MEM_DATA_IN &&
+	    !IS_ALIGNED((size_t)op->data.buf.in, 4))
+		kfree(rx_tmp_buf);
+tx_unmap:
+	dma_unmap_single(priv->tx_dma,
+			 tx_size, DMA_TO_DEVICE);
+tx_free:
+	kfree(tx_tmp_buf);
+exit:
+	priv->use_spimem = false;
+
+	return ret;
+}
+
+static int mtk_spim_adjust_op_size(struct spi_slave *slave,
+				   struct spi_mem_op *op)
+{
+	int opcode_len;
+
+	if (!op->data.nbytes)
+		return 0;
+
+	if (op->data.dir != SPI_MEM_NO_DATA) {
+		opcode_len = 1 + op->addr.nbytes + op->dummy.nbytes;
+		if (opcode_len + op->data.nbytes > MTK_SPI_IPM_PACKET_SIZE) {
+			op->data.nbytes = MTK_SPI_IPM_PACKET_SIZE - opcode_len;
+			/* force data buffer dma-aligned. */
+			op->data.nbytes -= op->data.nbytes % 4;
+		}
+	}
+
+	return 0;
+}
+
+static int mtk_spim_get_attr(struct mtk_spim_priv *priv, struct udevice
 *dev)
+{
+	int ret;
+
+	priv->hw_cap.need_pad_sel = dev_read_bool(dev, "need_pad_sel");
+	priv->hw_cap.must_tx = dev_read_bool(dev, "must_tx");
+	priv->hw_cap.enhance_timing = dev_read_bool(dev, "enhance_timing");
+	priv->hw_cap.dma_ext = dev_read_bool(dev, "dma_ext");
+	priv->hw_cap.ipm_design = dev_read_bool(dev, "ipm_design");
+	priv->hw_cap.support_quad = dev_read_bool(dev, "support_quad");
+
+	ret = dev_read_u32(dev, "tick_dly", &priv->tick_dly);
+	if (ret < 0)
+		dev_err(priv->dev, "tick dly not set.\n");
+
+	ret = dev_read_u32(dev, "sample_sel", &priv->sample_sel);
+	if (ret < 0)
+		dev_err(priv->dev, "sample sel not set.\n");
+
+	return ret;
+}
+
+static int mtk_spim_probe(struct udevice *dev)
+{
+	struct mtk_spim_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	priv->base = (void __iomem *)devfdt_get_addr(dev);
+	if (!priv->base)
+		return -EINVAL;
+
+	mtk_spim_get_attr(priv, dev);
+
+	ret = clk_get_by_name(dev, "sel-clk", &priv->sel_clk);
+	if (ret < 0) {
+		dev_err(dev, "failed to get sel-clk\n");
+		return ret;
+	}
+
+	ret = clk_get_by_name(dev, "spi-clk", &priv->spi_clk);
+	if (ret < 0) {
+		dev_err(dev, "failed to get spi-clk\n");
+		return ret;
+	}
+
+	clk_enable(&priv->sel_clk);
+	clk_enable(&priv->spi_clk);
+
+	return 0;
+}
+
+static int mtk_spim_set_speed(struct udevice *dev, uint speed)
+{
+	return 0;
+}
+
+static int mtk_spim_set_mode(struct udevice *dev, uint mode)
+{
+	return 0;
+}
+
+static const struct spi_controller_mem_ops mtk_spim_mem_ops = {
+	.adjust_op_size = mtk_spim_adjust_op_size,
+	.supports_op = mtk_spim_supports_op,
+	.exec_op = mtk_spim_exec_op
+};
+
+static const struct dm_spi_ops mtk_spim_ops = {
+	.mem_ops = &mtk_spim_mem_ops,
+	.set_speed = mtk_spim_set_speed,
+	.set_mode = mtk_spim_set_mode,
+};
+
+static const struct udevice_id mtk_spim_ids[] = {
+	{ .compatible = "mediatek,ipm-spi" },
+	{}
+};
+
+U_BOOT_DRIVER(mtk_spim) = {
+	.name = "mtk_spim",
+	.id = UCLASS_SPI,
+	.of_match = mtk_spim_ids,
+	.ops = &mtk_spim_ops,
+	.priv_auto = sizeof(struct mtk_spim_priv),
+	.probe = mtk_spim_probe,
+};
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 17/31] i2c: add support for MediaTek I2C interface
  2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
                   ` (15 preceding siblings ...)
  2022-08-04  3:36 ` [PATCH 16/31] spi: add support for MediaTek spi-mem controller Weijie Gao
@ 2022-08-04  3:36 ` Weijie Gao
  2022-08-04 13:57   ` Simon Glass
                     ` (2 more replies)
  2022-08-04  3:36 ` [PATCH 18/31] arm: dts: mt7622: add i2c support Weijie Gao
                   ` (13 subsequent siblings)
  30 siblings, 3 replies; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:36 UTC (permalink / raw)
  To: u-boot; +Cc: GSS_MTK_Uboot_upstream, Heiko Schocher, Weijie Gao

This patch adds support for MediaTek I2C interface

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 drivers/i2c/Kconfig   |   9 +
 drivers/i2c/Makefile  |   1 +
 drivers/i2c/mtk_i2c.c | 822 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 832 insertions(+)
 create mode 100644 drivers/i2c/mtk_i2c.c

diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index be4724bf8e..08b6c7bdcc 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -261,6 +261,15 @@ config SYS_I2C_MESON
 	  internal buffer holding up to 8 bytes for transfers and supports
 	  both 7-bit and 10-bit addresses.
 
+config SYS_I2C_MTK
+	bool "MediaTek I2C driver"
+	help
+	  This selects the MediaTek Integrated Inter Circuit bus driver.
+	  The I2C bus adapter is the base for some other I2C client,
+	  eg: touch, sensors.
+	  If you want to use MediaTek I2C interface, say Y here.
+	  If unsure, say N.
+
 config SYS_I2C_MICROCHIP
 	bool "Microchip I2C driver"
 	help
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 7e046f809a..920aafb91c 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_SYS_I2C_MICROCHIP) += i2c-microchip.o
 obj-$(CONFIG_SYS_I2C_MV) += mv_i2c.o
 obj-$(CONFIG_SYS_I2C_MVTWSI) += mvtwsi.o
 obj-$(CONFIG_SYS_I2C_MXC) += mxc_i2c.o
+obj-$(CONFIG_SYS_I2C_MTK) += mtk_i2c.o
 obj-$(CONFIG_SYS_I2C_NEXELL) += nx_i2c.o
 obj-$(CONFIG_SYS_I2C_NPCM) += npcm_i2c.o
 obj-$(CONFIG_SYS_I2C_OCORES) += ocores_i2c.o
diff --git a/drivers/i2c/mtk_i2c.c b/drivers/i2c/mtk_i2c.c
new file mode 100644
index 0000000000..1d4a93f8c9
--- /dev/null
+++ b/drivers/i2c/mtk_i2c.c
@@ -0,0 +1,822 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2022 MediaTek Inc. All Rights Reserved.
+ *
+ * Author: Mingming Lee <Mingming.Lee@mediatek.com>
+ *
+ * MediaTek I2C Interface driver
+ */
+
+#include <clk.h>
+#include <cpu_func.h>
+#include <dm.h>
+#include <i2c.h>
+#include <log.h>
+#include <asm/cache.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+
+#define I2C_RS_TRANSFER			BIT(4)
+#define I2C_HS_NACKERR			BIT(2)
+#define I2C_ACKERR			BIT(1)
+#define I2C_TRANSAC_COMP		BIT(0)
+#define I2C_TRANSAC_START		BIT(0)
+#define I2C_RS_MUL_CNFG			BIT(15)
+#define I2C_RS_MUL_TRIG			BIT(14)
+#define I2C_DCM_DISABLE			0x0000
+#define I2C_IO_CONFIG_OPEN_DRAIN	0x0003
+#define I2C_IO_CONFIG_PUSH_PULL		0x0000
+#define I2C_SOFT_RST			0x0001
+#define I2C_FIFO_ADDR_CLR		0x0001
+#define I2C_DELAY_LEN			0x0002
+#define I2C_ST_START_CON		0x8001
+#define I2C_FS_START_CON		0x1800
+#define I2C_TIME_CLR_VALUE		0x0000
+#define I2C_TIME_DEFAULT_VALUE		0x0003
+#define I2C_WRRD_TRANAC_VALUE		0x0002
+#define I2C_RD_TRANAC_VALUE		0x0001
+
+#define I2C_DMA_CON_TX			0x0000
+#define I2C_DMA_CON_RX			0x0001
+#define I2C_DMA_START_EN		0x0001
+#define I2C_DMA_INT_FLAG_NONE		0x0000
+#define I2C_DMA_CLR_FLAG		0x0000
+#define I2C_DMA_TX_RX			0x0000
+#define I2C_DMA_HARD_RST		0x0002
+
+#define MAX_ST_MODE_SPEED		100000
+#define MAX_FS_MODE_SPEED		400000
+#define MAX_HS_MODE_SPEED		3400000
+#define MAX_SAMPLE_CNT_DIV		8
+#define MAX_STEP_CNT_DIV		64
+#define MAX_HS_STEP_CNT_DIV		8
+#define I2C_DEFAULT_CLK_DIV		4
+
+#define MAX_I2C_ADDR			0x7f
+#define MAX_I2C_LEN			0xff
+#define TRANS_ADDR_ONLY			BIT(8)
+#define TRANSFER_TIMEOUT		50000  /* us */
+#define I2C_FIFO_STAT1_MASK		0x001f
+#define TIMING_SAMPLE_OFFSET		8
+#define HS_SAMPLE_OFFSET		12
+#define HS_STEP_OFFSET			8
+
+#define I2C_CONTROL_WRAPPER		BIT(0)
+#define I2C_CONTROL_RS			BIT(1)
+#define I2C_CONTROL_DMA_EN		BIT(2)
+#define I2C_CONTROL_CLK_EXT_EN		BIT(3)
+#define I2C_CONTROL_DIR_CHANGE		BIT(4)
+#define I2C_CONTROL_ACKERR_DET_EN	BIT(5)
+#define I2C_CONTROL_TRANSFER_LEN_CHANGE BIT(6)
+#define I2C_CONTROL_DMAACK		BIT(8)
+#define I2C_CONTROL_ASYNC		BIT(9)
+
+enum I2C_REGS_OFFSET {
+	REG_PORT,
+	REG_SLAVE_ADDR,
+	REG_INTR_MASK,
+	REG_INTR_STAT,
+	REG_CONTROL,
+	REG_TRANSFER_LEN,
+	REG_TRANSAC_LEN,
+	REG_DELAY_LEN,
+	REG_TIMING,
+	REG_START,
+	REG_EXT_CONF,
+	REG_FIFO_STAT1,
+	REG_LTIMING,
+	REG_FIFO_STAT,
+	REG_FIFO_THRESH,
+	REG_FIFO_ADDR_CLR,
+	REG_IO_CONFIG,
+	REG_RSV_DEBUG,
+	REG_HS,
+	REG_SOFTRESET,
+	REG_DCM_EN,
+	REG_PATH_DIR,
+	REG_DEBUGSTAT,
+	REG_DEBUGCTRL,
+	REG_TRANSFER_LEN_AUX,
+	REG_CLOCK_DIV,
+	REG_SCL_HL_RATIO,
+	REG_SCL_HS_HL_RATIO,
+	REG_SCL_MIS_COMP_POINT,
+	REG_STA_STOP_AC_TIME,
+	REG_HS_STA_STOP_AC_TIME,
+	REG_DATA_TIME,
+};
+
+enum DMA_REGS_OFFSET {
+	REG_INT_FLAG = 0x0,
+	REG_INT_EN = 0x04,
+	REG_EN = 0x08,
+	REG_RST = 0x0c,
+	REG_CON = 0x18,
+	REG_TX_MEM_ADDR = 0x1c,
+	REG_RX_MEM_ADDR = 0x20,
+	REG_TX_LEN = 0x24,
+	REG_RX_LEN = 0x28,
+};
+
+static const uint mt_i2c_regs_v1[] = {
+	[REG_PORT] = 0x0,
+	[REG_SLAVE_ADDR] = 0x4,
+	[REG_INTR_MASK] = 0x8,
+	[REG_INTR_STAT] = 0xc,
+	[REG_CONTROL] = 0x10,
+	[REG_TRANSFER_LEN] = 0x14,
+	[REG_TRANSAC_LEN] = 0x18,
+	[REG_DELAY_LEN] = 0x1c,
+	[REG_TIMING] = 0x20,
+	[REG_START] = 0x24,
+	[REG_EXT_CONF] = 0x28,
+	[REG_FIFO_STAT1] = 0x2c,
+	[REG_FIFO_STAT] = 0x30,
+	[REG_FIFO_THRESH] = 0x34,
+	[REG_FIFO_ADDR_CLR] = 0x38,
+	[REG_IO_CONFIG] = 0x40,
+	[REG_RSV_DEBUG] = 0x44,
+	[REG_HS] = 0x48,
+	[REG_SOFTRESET] = 0x50,
+	[REG_SOFTRESET] = 0x50,
+	[REG_DCM_EN] = 0x54,
+	[REG_DEBUGSTAT] = 0x64,
+	[REG_DEBUGCTRL] = 0x68,
+	[REG_TRANSFER_LEN_AUX] = 0x6c,
+	[REG_CLOCK_DIV] = 0x70,
+	[REG_SCL_HL_RATIO] = 0x74,
+	[REG_SCL_HS_HL_RATIO] = 0x78,
+	[REG_SCL_MIS_COMP_POINT] = 0x7c,
+	[REG_STA_STOP_AC_TIME] = 0x80,
+	[REG_HS_STA_STOP_AC_TIME] = 0x84,
+	[REG_DATA_TIME] = 0x88,
+};
+
+static const uint mt_i2c_regs_v2[] = {
+	[REG_PORT] = 0x0,
+	[REG_SLAVE_ADDR] = 0x4,
+	[REG_INTR_MASK] = 0x8,
+	[REG_INTR_STAT] = 0xc,
+	[REG_CONTROL] = 0x10,
+	[REG_TRANSFER_LEN] = 0x14,
+	[REG_TRANSAC_LEN] = 0x18,
+	[REG_DELAY_LEN] = 0x1c,
+	[REG_TIMING] = 0x20,
+	[REG_START] = 0x24,
+	[REG_EXT_CONF] = 0x28,
+	[REG_LTIMING] = 0x2c,
+	[REG_HS] = 0x30,
+	[REG_IO_CONFIG] = 0x34,
+	[REG_FIFO_ADDR_CLR] = 0x38,
+	[REG_TRANSFER_LEN_AUX] = 0x44,
+	[REG_CLOCK_DIV] = 0x48,
+	[REG_SOFTRESET] = 0x50,
+	[REG_DEBUGSTAT] = 0xe0,
+	[REG_DEBUGCTRL] = 0xe8,
+	[REG_FIFO_STAT] = 0xf4,
+	[REG_FIFO_THRESH] = 0xf8,
+	[REG_DCM_EN] = 0xf88,
+};
+
+enum mtk_trans_op {
+	I2C_MASTER_WR = 1,
+	I2C_MASTER_RD,
+	I2C_MASTER_WRRD,
+};
+
+struct mtk_i2c_soc_data {
+	const uint *regs;
+	uint dma_sync: 1;
+};
+
+struct mtk_i2c_priv {
+	/* set in i2c probe */
+	void __iomem *base;		/* i2c base addr */
+	void __iomem *pdmabase;		/* dma base address*/
+	struct clk clk_main;		/* main clock for i2c bus */
+	struct clk clk_dma;		/* DMA clock for i2c via DMA */
+	const struct mtk_i2c_soc_data *soc_data; /* Compatible data for different
 IC */
+	enum mtk_trans_op op;		/* operation mode */
+	bool zero_len;			/* Only transfer slave address, no data */
+	bool pushpull;			/* push pull mode or open drain mode */
+	bool filter_msg;		/* filter msg error log */
+	bool auto_restart;		/* restart mode */
+	bool ignore_restart_irq;	/* ignore restart IRQ */
+	uint speed;			/* i2c speed, unit: hz */
+};
+
+static inline void i2c_writel(struct mtk_i2c_priv *priv, uint reg, uint
 value)
+{
+	u32 offset = priv->soc_data->regs[reg];
+
+	writel(value, priv->base + offset);
+}
+
+static inline uint i2c_readl(struct mtk_i2c_priv *priv, uint offset)
+{
+	return readl(priv->base + priv->soc_data->regs[offset]);
+}
+
+static int mtk_i2c_clk_enable(struct mtk_i2c_priv *priv)
+{
+	int ret;
+
+	ret = clk_enable(&priv->clk_main);
+	if (ret)
+		return log_msg_ret("enable clk_main", ret);
+
+	ret = clk_enable(&priv->clk_dma);
+	if (ret)
+		return log_msg_ret("enable clk_dma", ret);
+
+	return 0;
+}
+
+static int mtk_i2c_clk_disable(struct mtk_i2c_priv *priv)
+{
+	int ret;
+
+	ret = clk_disable(&priv->clk_dma);
+	if (ret)
+		return log_msg_ret("disable clk_dma", ret);
+
+	ret = clk_disable(&priv->clk_main);
+	if (ret)
+		return log_msg_ret("disable clk_main", ret);
+
+	return 0;
+}
+
+static void mtk_i2c_init_hw(struct mtk_i2c_priv *priv)
+{
+	uint control_reg;
+
+	writel(I2C_DMA_HARD_RST, priv->pdmabase + REG_RST);
+	writel(I2C_DMA_CLR_FLAG, priv->pdmabase + REG_RST);
+	i2c_writel(priv, REG_SOFTRESET, I2C_SOFT_RST);
+	/* set ioconfig */
+	if (priv->pushpull)
+		i2c_writel(priv, REG_IO_CONFIG, I2C_IO_CONFIG_PUSH_PULL);
+	else
+		i2c_writel(priv, REG_IO_CONFIG, I2C_IO_CONFIG_OPEN_DRAIN);
+
+	i2c_writel(priv, REG_DCM_EN, I2C_DCM_DISABLE);
+	control_reg = I2C_CONTROL_ACKERR_DET_EN | I2C_CONTROL_CLK_EXT_EN;
+	if (priv->soc_data->dma_sync)
+		control_reg |= I2C_CONTROL_DMAACK | I2C_CONTROL_ASYNC;
+	i2c_writel(priv, REG_CONTROL, control_reg);
+	i2c_writel(priv, REG_DELAY_LEN, I2C_DELAY_LEN);
+}
+
+/*
+ * Calculate i2c port speed
+ *
+ * Hardware design:
+ * i2c_bus_freq = parent_clk / (clock_div * 2 * sample_cnt * step_cnt)
+ * clock_div: fixed in hardware, but may be various in different SoCs
+ *
+ * The calculation want to pick the highest bus frequency that is still
+ * less than or equal to target_speed. The calculation try to get
+ * sample_cnt and step_cn
+ * @param[in]
+ *     clk_src: i2c clock source
+ * @param[out]
+ *     timing_step_cnt: step cnt calculate result
+ * @param[out]
+ *     timing_sample_cnt: sample cnt calculate result
+ * @return
+ *     0, set speed successfully.
+ *     -EINVAL, Unsupported speed.
+ */
+static int mtk_i2c_calculate_speed(uint clk_src,
+				   uint target_speed,
+				   uint *timing_step_cnt,
+				   uint *timing_sample_cnt)
+{
+	uint base_sample_cnt = MAX_SAMPLE_CNT_DIV;
+	uint base_step_cnt;
+	uint max_step_cnt;
+	uint sample_cnt;
+	uint step_cnt;
+	uint opt_div;
+	uint best_mul;
+	uint cnt_mul;
+
+	if (target_speed > MAX_HS_MODE_SPEED)
+		target_speed = MAX_HS_MODE_SPEED;
+
+	if (target_speed > MAX_FS_MODE_SPEED)
+		max_step_cnt = MAX_HS_STEP_CNT_DIV;
+	else
+		max_step_cnt = MAX_STEP_CNT_DIV;
+
+	base_step_cnt = max_step_cnt;
+	/* Find the best combination */
+	opt_div = DIV_ROUND_UP(clk_src >> 1, target_speed);
+	best_mul = MAX_SAMPLE_CNT_DIV * max_step_cnt;
+
+	/*
+	 * Search for the best pair (sample_cnt, step_cnt) with
+	 * 0 < sample_cnt < MAX_SAMPLE_CNT_DIV
+	 * 0 < step_cnt < max_step_cnt
+	 * sample_cnt * step_cnt >= opt_div
+	 * optimizing for sample_cnt * step_cnt being minimal
+	 */
+	for (sample_cnt = 1; sample_cnt <= MAX_SAMPLE_CNT_DIV; sample_cnt++) {
+		step_cnt = DIV_ROUND_UP(opt_div, sample_cnt);
+		cnt_mul = step_cnt * sample_cnt;
+		if (step_cnt > max_step_cnt)
+			continue;
+
+		if (cnt_mul < best_mul) {
+			best_mul = cnt_mul;
+			base_sample_cnt = sample_cnt;
+			base_step_cnt = step_cnt;
+			if (best_mul == opt_div)
+				break;
+		}
+	}
+
+	sample_cnt = base_sample_cnt;
+	step_cnt = base_step_cnt;
+
+	if ((clk_src / (2 * sample_cnt * step_cnt)) > target_speed) {
+		/*
+		 * In this case, hardware can't support such
+		 * low i2c_bus_freq
+		 */
+		debug("Unsupported speed(%uhz)\n", target_speed);
+		return log_msg_ret("calculate speed", -EINVAL);
+	}
+
+	*timing_step_cnt = step_cnt - 1;
+	*timing_sample_cnt = sample_cnt - 1;
+
+	return 0;
+}
+
+/*
+ * mtk_i2c_set_speed
+ *
+ * @par Description
+ *     Calculate i2c speed and write sample_cnt, step_cnt to TIMING
 register.
+ * @param[in]
+ *     dev: udevice pointer, struct udevice contains i2c source clock,
+ *     clock divide and speed.
+ * @return
+ *     0, set speed successfully.\n
+ *     error code from mtk_i2c_calculate_speed().
+ */
+static int mtk_i2c_set_speed(struct udevice *dev, uint speed)
+{
+	struct mtk_i2c_priv *priv = dev_get_priv(dev);
+	uint high_speed_reg;
+	uint sample_cnt;
+	uint timing_reg;
+	uint step_cnt;
+	uint clk_src;
+	int ret = 0;
+
+	priv->speed = speed;
+	if (mtk_i2c_clk_enable(priv))
+		return log_msg_ret("set_speed enable clk", -1);
+
+	clk_src = clk_get_rate(&priv->clk_main) / I2C_DEFAULT_CLK_DIV;
+	i2c_writel(priv, REG_CLOCK_DIV, (I2C_DEFAULT_CLK_DIV - 1));
+	if (priv->speed > MAX_FS_MODE_SPEED) {
+		/* Set master code speed register */
+		ret = mtk_i2c_calculate_speed(clk_src, MAX_FS_MODE_SPEED,
+					      &step_cnt, &sample_cnt);
+		if (ret < 0)
+			goto exit;
+
+		timing_reg = (sample_cnt << TIMING_SAMPLE_OFFSET) | step_cnt;
+		i2c_writel(priv, REG_TIMING, timing_reg);
+		/* Set the high speed mode register */
+		ret = mtk_i2c_calculate_speed(clk_src, priv->speed,
+					      &step_cnt, &sample_cnt);
+		if (ret < 0)
+			goto exit;
+
+		high_speed_reg = I2C_TIME_DEFAULT_VALUE |
+				(sample_cnt << HS_SAMPLE_OFFSET) |
+				(step_cnt << HS_STEP_OFFSET);
+		i2c_writel(priv, REG_HS, high_speed_reg);
+	} else {
+		ret = mtk_i2c_calculate_speed(clk_src, priv->speed,
+					      &step_cnt, &sample_cnt);
+		if (ret < 0)
+			goto exit;
+
+		timing_reg = (sample_cnt << TIMING_SAMPLE_OFFSET) | step_cnt;
+		/* Disable the high speed transaction */
+		high_speed_reg = I2C_TIME_CLR_VALUE;
+		i2c_writel(priv, REG_TIMING, timing_reg);
+		i2c_writel(priv, REG_HS, high_speed_reg);
+	}
+exit:
+	if (mtk_i2c_clk_disable(priv))
+		return log_msg_ret("set_speed disable clk", -1);
+
+	return ret;
+}
+
+/*
+ * mtk_i2c_do_transfer
+ *
+ * @par Description
+ *     Configure i2c register and trigger transfer.
+ * @param[in]
+ *     priv: mtk_i2cmtk_i2c_priv pointer, struct mtk_i2c_priv contains
 register base\n
+ *     address, operation mode, interrupt status and i2c driver data.
+ * @param[in]
+ *     msgs: i2c_msg pointer, struct i2c_msg contains slave\n
+ *     address, operation mode, msg length and data buffer.
+ * @param[in]
+ *     num: i2c_msg number.
+ * @param[in]
+ *     left_num: left i2c_msg number.
+ * @return
+ *     0, i2c transfer successfully.\n
+ *     -ETIMEDOUT, i2c transfer timeout.\n
+ *     -EREMOTEIO, i2c transfer ack error.
+ */
+static int mtk_i2c_do_transfer(struct mtk_i2c_priv *priv,
+			       struct i2c_msg *msgs,
+			       int num, int left_num)
+{
+	uint restart_flag = 0;
+	uint trans_error = 0;
+	uint irq_stat = 0;
+	uint tmo_poll = 0;
+	uint control_reg;
+	bool tmo = false;
+	uint start_reg;
+	uint addr_reg;
+	int ret = 0;
+
+	if (priv->auto_restart)
+		restart_flag = I2C_RS_TRANSFER;
+
+	control_reg = i2c_readl(priv, REG_CONTROL) &
+		~(I2C_CONTROL_DIR_CHANGE | I2C_CONTROL_RS);
+
+	if (priv->speed > MAX_FS_MODE_SPEED || num > 1)
+		control_reg |= I2C_CONTROL_RS;
+
+	if (priv->op == I2C_MASTER_WRRD)
+		control_reg |= I2C_CONTROL_DIR_CHANGE | I2C_CONTROL_RS;
+
+	control_reg |= I2C_CONTROL_DMA_EN;
+	i2c_writel(priv, REG_CONTROL, control_reg);
+
+	/* set start condition */
+	if (priv->speed <= MAX_ST_MODE_SPEED)
+		i2c_writel(priv, REG_EXT_CONF, I2C_ST_START_CON);
+	else
+		i2c_writel(priv, REG_EXT_CONF, I2C_FS_START_CON);
+
+	addr_reg = msgs->addr << 1;
+	if (priv->op == I2C_MASTER_RD)
+		addr_reg |= I2C_M_RD;
+	if (priv->zero_len)
+		i2c_writel(priv, REG_SLAVE_ADDR, addr_reg | TRANS_ADDR_ONLY);
+	else
+		i2c_writel(priv, REG_SLAVE_ADDR, addr_reg);
+
+	/* clear interrupt status */
+	i2c_writel(priv, REG_INTR_STAT, restart_flag | I2C_HS_NACKERR |
+		   I2C_ACKERR | I2C_TRANSAC_COMP);
+	i2c_writel(priv, REG_FIFO_ADDR_CLR, I2C_FIFO_ADDR_CLR);
+
+	/* enable interrupt */
+	i2c_writel(priv, REG_INTR_MASK, restart_flag | I2C_HS_NACKERR |
+		   I2C_ACKERR | I2C_TRANSAC_COMP);
+
+	/* set transfer and transaction len */
+	if (priv->op == I2C_MASTER_WRRD) {
+		i2c_writel(priv, REG_TRANSFER_LEN, msgs->len);
+		i2c_writel(priv, REG_TRANSFER_LEN_AUX, (msgs + 1)->len);
+		i2c_writel(priv, REG_TRANSAC_LEN, I2C_WRRD_TRANAC_VALUE);
+	} else {
+		i2c_writel(priv, REG_TRANSFER_LEN, msgs->len);
+		i2c_writel(priv, REG_TRANSAC_LEN, num);
+	}
+
+	/*
+	 * prepare buffer data to start transfer
+	 * three cases here: read, write, write then read
+	 */
+	if (priv->op == I2C_MASTER_RD) {
+		/* Clear DMA interrupt flag*/
+		writel(I2C_DMA_INT_FLAG_NONE, priv->pdmabase + REG_INT_FLAG);
+		/* Set DMA direction RX*/
+		writel(I2C_DMA_CON_RX, priv->pdmabase + REG_CON);
+		flush_cache((ulong)msgs->buf, msgs->len);
+		/* Write the rx buffer address to dma register*/
+		writel((ulong)msgs->buf, priv->pdmabase + REG_RX_MEM_ADDR);
+		/* Write the rx length to dma register*/
+		writel(msgs->len, priv->pdmabase + REG_RX_LEN);
+	} else if (priv->op == I2C_MASTER_WR) {
+		/* Clear DMA interrupt flag*/
+		writel(I2C_DMA_INT_FLAG_NONE, priv->pdmabase + REG_INT_FLAG);
+		/* Set DMA direction TX*/
+		writel(I2C_DMA_CON_TX, priv->pdmabase + REG_CON);
+		flush_cache((ulong)msgs->buf, msgs->len);
+		/* Write the tx buffer address to dma register*/
+		writel((ulong)msgs->buf, priv->pdmabase + REG_TX_MEM_ADDR);
+		/* Write the tx length to dma register*/
+		writel(msgs->len, priv->pdmabase + REG_TX_LEN);
+	} else {
+		/* Clear DMA interrupt flag*/
+		writel(I2C_DMA_INT_FLAG_NONE, priv->pdmabase + REG_INT_FLAG);
+		/* Set DMA direction TX and RX*/
+		writel(I2C_DMA_TX_RX, priv->pdmabase + REG_CON);
+		flush_cache((ulong)msgs->buf, msgs->len);
+		flush_cache((ulong)(msgs + 1)->buf, (msgs + 1)->len);
+		/* Write the tx buffer address to dma register*/
+		writel((ulong)msgs->buf, priv->pdmabase + REG_TX_MEM_ADDR);
+		/* Write the tx buffer address to dma register*/
+		writel((ulong)(msgs + 1)->buf, priv->pdmabase + REG_RX_MEM_ADDR);
+		/* Write the tx length to dma register*/
+		writel(msgs->len, priv->pdmabase + REG_TX_LEN);
+		/* Write the rx length to dma register*/
+		writel((msgs + 1)->len, priv->pdmabase + REG_RX_LEN);
+	}
+
+	writel(I2C_DMA_START_EN, priv->pdmabase + REG_EN);
+
+	if (!priv->auto_restart) {
+		start_reg = I2C_TRANSAC_START;
+	} else {
+		start_reg = I2C_TRANSAC_START | I2C_RS_MUL_TRIG;
+		if (left_num >= 1)
+			start_reg |= I2C_RS_MUL_CNFG;
+	}
+	i2c_writel(priv, REG_START, start_reg);
+
+	for (;;) {
+		irq_stat = i2c_readl(priv, REG_INTR_STAT);
+
+		/* ignore the first restart irq after the master code */
+		if (priv->ignore_restart_irq && (irq_stat | restart_flag)) {
+			priv->ignore_restart_irq = false;
+			irq_stat = 0;
+			writel(I2C_RS_MUL_CNFG | I2C_RS_MUL_TRIG |
+			       I2C_TRANSAC_START, priv->base + REG_START);
+		}
+
+		if (irq_stat & (I2C_TRANSAC_COMP | restart_flag)) {
+			tmo = false;
+			if (irq_stat & (I2C_HS_NACKERR | I2C_ACKERR))
+				trans_error = 1;
+
+			break;
+		}
+		udelay(1);
+		if (tmo_poll++ >= TRANSFER_TIMEOUT) {
+			tmo = true;
+			break;
+		}
+	}
+
+	/* clear interrupt mask */
+	i2c_writel(priv, REG_INTR_MASK, ~(restart_flag | I2C_HS_NACKERR |
+		  I2C_ACKERR | I2C_TRANSAC_COMP));
+
+	if (!tmo && trans_error != 0) {
+		if (tmo) {
+			ret = -ETIMEDOUT;
+			if (!priv->filter_msg)
+				debug("I2C timeout! addr: 0x%x,\n", msgs->addr);
+		} else {
+			ret = -EREMOTEIO;
+			if (!priv->filter_msg)
+				debug("I2C ACKERR! addr: 0x%x,IRQ:0x%x\n",
+				      msgs->addr, irq_stat);
+		}
+		mtk_i2c_init_hw(priv);
+	}
+
+	return ret;
+}
+
+/*
+ * mtk_i2c_transfer
+ *
+ * @par Description
+ *     Common i2c transfer API. Set i2c transfer mode according to
 i2c_msg\n
+ *     information, then call mtk_i2c_do_transfer() to configure i2c
 register\n
+ *     and trigger transfer.
+ * @param[in]
+ *     dev: udevice pointer, struct udevice contains struct mtk_i2c_priv,
 \n
+ *	   struct mtk_i2c_priv contains register base\n
+ *     address, operation mode, interrupt status and i2c driver data.
+ * @param[in]
+ *     msgs: i2c_msg pointer, struct i2c_msg contains slave\n
+ *     address, operation mode, msg length and data buffer.
+ * @param[in]
+ *     num: i2c_msg number.
+ * @return
+ *     i2c_msg number, i2c transfer successfully.\n
+ *     -EINVAL, msg length is more than 16\n
+ *     use DMA MODE or slave address more than 0x7f.\n
+ *     error code from mtk_i2c_init_base().\n
+ *     error code from mtk_i2c_set_speed().\n
+ *     error code from mtk_i2c_do_transfer().
+ */
+static int mtk_i2c_transfer(struct udevice *dev, struct i2c_msg *msg,
+			    int nmsgs)
+{
+	struct mtk_i2c_priv *priv = dev_get_priv(dev);
+	int left_num;
+	uint num_cnt;
+	int ret;
+
+	priv->auto_restart = true;
+	left_num = nmsgs;
+	if (mtk_i2c_clk_enable(priv))
+		return log_msg_ret("transfer enable clk", -1);
+
+	for (num_cnt = 0; num_cnt < nmsgs; num_cnt++) {
+		if (((msg + num_cnt)->addr) > MAX_I2C_ADDR) {
+			ret = -EINVAL;
+			goto err_exit;
+		}
+		if ((msg + num_cnt)->len > MAX_I2C_LEN) {
+			ret = -EINVAL;
+			goto err_exit;
+		}
+	}
+
+	/* check if we can skip restart and optimize using WRRD mode */
+	if (priv->auto_restart && nmsgs == 2) {
+		if (!(msg[0].flags & I2C_M_RD) && (msg[1].flags & I2C_M_RD) &&
+		    msg[0].addr == msg[1].addr) {
+			priv->auto_restart = false;
+		}
+	}
+
+	if (priv->auto_restart && nmsgs >= 2 && priv->speed > MAX_FS_MODE_SPEED)
+		/* ignore the first restart irq after the master code,
+		 * otherwise the first transfer will be discarded.
+		 */
+		priv->ignore_restart_irq = true;
+	else
+		priv->ignore_restart_irq = false;
+
+	while (left_num--) {
+		/* transfer slave address only to support devices detect */
+		if (!msg->buf)
+			priv->zero_len = true;
+		else
+			priv->zero_len = false;
+
+		if (msg->flags & I2C_M_RD)
+			priv->op = I2C_MASTER_RD;
+		else
+			priv->op = I2C_MASTER_WR;
+
+		if (!priv->auto_restart) {
+			if (nmsgs > 1) {
+				/* combined two messages into one transaction */
+				priv->op = I2C_MASTER_WRRD;
+				left_num--;
+			}
+		}
+		ret = mtk_i2c_do_transfer(priv, msg, nmsgs, left_num);
+		if (ret < 0)
+			goto err_exit;
+		msg++;
+	}
+	ret = 0;
+
+err_exit:
+	if (mtk_i2c_clk_disable(priv))
+		return log_msg_ret("transfer disable clk", -1);
+
+	return ret;
+}
+
+static int mtk_i2c_ofdata_to_platdata(struct udevice *dev)
+{
+	struct mtk_i2c_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	priv->base = dev_remap_addr_index(dev, 0);
+	priv->pdmabase = dev_remap_addr_index(dev, 1);
+	ret = clk_get_by_index(dev, 0, &priv->clk_main);
+	if (ret)
+		return log_msg_ret("clk_get_by_index 0", ret);
+
+	ret = clk_get_by_index(dev, 1, &priv->clk_dma);
+
+	return ret;
+}
+
+static int mtk_i2c_probe(struct udevice *dev)
+{
+	struct mtk_i2c_priv *priv = dev_get_priv(dev);
+
+	priv->soc_data = (struct mtk_i2c_soc_data *)dev_get_driver_data(dev);
+
+	if (mtk_i2c_clk_enable(priv))
+		return log_msg_ret("probe enable clk", -1);
+
+	mtk_i2c_init_hw(priv);
+
+	if (mtk_i2c_clk_disable(priv))
+		return log_msg_ret("probe disable clk", -1);
+
+	return 0;
+}
+
+static int mtk_i2c_deblock(struct udevice *dev)
+{
+	struct mtk_i2c_priv *priv = dev_get_priv(dev);
+
+	if (mtk_i2c_clk_enable(priv))
+		return log_msg_ret("deblock enable clk", -1);
+
+	mtk_i2c_init_hw(priv);
+
+	if (mtk_i2c_clk_disable(priv))
+		return log_msg_ret("deblock disable clk", -1);
+
+	return 0;
+}
+
+static const struct mtk_i2c_soc_data mt76xx_soc_data = {
+	.regs = mt_i2c_regs_v1,
+	.dma_sync = 0,
+};
+
+static const struct mtk_i2c_soc_data mt7981_soc_data = {
+	.regs = mt_i2c_regs_v1,
+	.dma_sync = 1,
+};
+
+static const struct mtk_i2c_soc_data mt7986_soc_data = {
+	.regs = mt_i2c_regs_v1,
+	.dma_sync = 1,
+};
+
+static const struct mtk_i2c_soc_data mt8183_soc_data = {
+	.regs = mt_i2c_regs_v2,
+	.dma_sync = 1,
+};
+
+static const struct mtk_i2c_soc_data mt8518_soc_data = {
+	.regs = mt_i2c_regs_v1,
+	.dma_sync = 0,
+};
+
+static const struct mtk_i2c_soc_data mt8512_soc_data = {
+	.regs = mt_i2c_regs_v1,
+	.dma_sync = 1,
+};
+
+static const struct dm_i2c_ops mtk_i2c_ops = {
+	.xfer		= mtk_i2c_transfer,
+	.set_bus_speed	= mtk_i2c_set_speed,
+	.deblock	= mtk_i2c_deblock,
+};
+
+static const struct udevice_id mtk_i2c_ids[] = {
+	{
+		.compatible = "mediatek,mt7622-i2c",
+		.data = (ulong)&mt76xx_soc_data,
+	}, {
+		.compatible = "mediatek,mt7623-i2c",
+		.data = (ulong)&mt76xx_soc_data,
+	}, {
+		.compatible = "mediatek,mt7629-i2c",
+		.data = (ulong)&mt76xx_soc_data,
+	}, {
+		.compatible = "mediatek,mt7981-i2c",
+		.data = (ulong)&mt7981_soc_data,
+	}, {
+		.compatible = "mediatek,mt7986-i2c",
+		.data = (ulong)&mt7986_soc_data,
+	}, {
+		.compatible = "mediatek,mt8183-i2c",
+		.data = (ulong)&mt8183_soc_data,
+	}, {
+		.compatible = "mediatek,mt8512-i2c",
+		.data = (ulong)&mt8512_soc_data,
+	}, {
+		.compatible = "mediatek,mt8518-i2c",
+		.data = (ulong)&mt8518_soc_data,
+	}
+};
+
+U_BOOT_DRIVER(mtk_i2c) = {
+	.name		= "mtk_i2c",
+	.id		= UCLASS_I2C,
+	.of_match	= mtk_i2c_ids,
+	.of_to_plat	= mtk_i2c_ofdata_to_platdata,
+	.probe		= mtk_i2c_probe,
+	.priv_auto	= sizeof(struct mtk_i2c_priv),
+	.ops		= &mtk_i2c_ops,
+};
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 18/31] arm: dts: mt7622: add i2c support
  2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
                   ` (16 preceding siblings ...)
  2022-08-04  3:36 ` [PATCH 17/31] i2c: add support for MediaTek I2C interface Weijie Gao
@ 2022-08-04  3:36 ` Weijie Gao
  2022-08-04 13:57   ` Simon Glass
  2022-08-04  3:36 ` [PATCH 19/31] dt-bindings: pinctrl: mediatek: add a header for common pinconf parameters Weijie Gao
                   ` (12 subsequent siblings)
  30 siblings, 1 reply; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:36 UTC (permalink / raw)
  To: u-boot; +Cc: GSS_MTK_Uboot_upstream, Weijie Gao

Add both hardware and software i2c support for mt7622.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 arch/arm/dts/mt7622-rfb.dts | 18 ++++++++++++++++++
 arch/arm/dts/mt7622.dtsi    | 24 ++++++++++++++++++++++++
 2 files changed, 42 insertions(+)

diff --git a/arch/arm/dts/mt7622-rfb.dts b/arch/arm/dts/mt7622-rfb.dts
index 30a9137407..b44f19f05a 100644
--- a/arch/arm/dts/mt7622-rfb.dts
+++ b/arch/arm/dts/mt7622-rfb.dts
@@ -159,6 +159,14 @@
 		};
 
 	};
+
+	i2c1_pins_default: i2c1-default {
+		mux {
+			function = "i2c";
+			groups = "i2c1_0";
+		};
+	};
+
 };
 
 &snfi {
@@ -242,3 +250,13 @@
 &u3phy {
        status = "okay";
 };
+
+&soft_i2c {
+	status = "disabled";
+};
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pins_default>;
+	status = "okay";
+};
diff --git a/arch/arm/dts/mt7622.dtsi b/arch/arm/dts/mt7622.dtsi
index fb6c1b7154..2d89fa08b4 100644
--- a/arch/arm/dts/mt7622.dtsi
+++ b/arch/arm/dts/mt7622.dtsi
@@ -424,4 +424,28 @@
 		status = "disabled";
 	};
 
+	soft_i2c: soft_i2c@0 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "i2c-gpio";
+		gpios = <&gpio 56 GPIO_ACTIVE_HIGH>, /* SDA */
+			<&gpio 55 GPIO_ACTIVE_HIGH>; /* CLK */
+		i2c-gpio,delay-us = <5>;
+		status = "disabled";
+	};
+
+	i2c1: i2c@11008000 {
+		compatible = "mediatek,mt7622-i2c";
+		reg = <0x11008000 0x90>,
+		      <0x11000180 0x80>;
+		interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_LOW>;
+		clock-div = <16>;
+		clocks = <&pericfg CLK_PERI_I2C1_PD>,
+			 <&pericfg CLK_PERI_AP_DMA_PD>;
+		clock-names = "main", "dma";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
 };
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 19/31] dt-bindings: pinctrl: mediatek: add a header for common pinconf parameters
  2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
                   ` (17 preceding siblings ...)
  2022-08-04  3:36 ` [PATCH 18/31] arm: dts: mt7622: add i2c support Weijie Gao
@ 2022-08-04  3:36 ` Weijie Gao
  2022-08-04 13:57   ` Simon Glass
  2022-08-04  3:36 ` [PATCH 20/31] pinctrl: mediatek: add pinctrl driver for MT7981 SoC Weijie Gao
                   ` (11 subsequent siblings)
  30 siblings, 1 reply; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:36 UTC (permalink / raw)
  To: u-boot; +Cc: GSS_MTK_Uboot_upstream, Weijie Gao

This patch adds a pinctrl header for common pinconf parameters such as
pull-up/pull-down resistors and drive strengths.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 include/dt-bindings/pinctrl/mt65xx.h | 41 ++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)
 create mode 100644 include/dt-bindings/pinctrl/mt65xx.h

diff --git a/include/dt-bindings/pinctrl/mt65xx.h
 b/include/dt-bindings/pinctrl/mt65xx.h
new file mode 100644
index 0000000000..fbea8d35bc
--- /dev/null
+++ b/include/dt-bindings/pinctrl/mt65xx.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Hongzhou.Yang <hongzhou.yang@mediatek.com>
+ */
+
+#ifndef _DT_BINDINGS_PINCTRL_MT65XX_H
+#define _DT_BINDINGS_PINCTRL_MT65XX_H
+
+#define MTK_PIN_NO(x)		((x) << 8)
+#define MTK_GET_PIN_NO(x)	((x) >> 8)
+#define MTK_GET_PIN_FUNC(x)	((x) & 0xf)
+
+#define MTK_PUPD_SET_R1R0_00	100
+#define MTK_PUPD_SET_R1R0_01	101
+#define MTK_PUPD_SET_R1R0_10	102
+#define MTK_PUPD_SET_R1R0_11	103
+
+#define MTK_PULL_SET_RSEL_000	200
+#define MTK_PULL_SET_RSEL_001	201
+#define MTK_PULL_SET_RSEL_010	202
+#define MTK_PULL_SET_RSEL_011	203
+#define MTK_PULL_SET_RSEL_100	204
+#define MTK_PULL_SET_RSEL_101	205
+#define MTK_PULL_SET_RSEL_110	206
+#define MTK_PULL_SET_RSEL_111	207
+
+#define MTK_DRIVE_2mA		2
+#define MTK_DRIVE_4mA		4
+#define MTK_DRIVE_6mA		6
+#define MTK_DRIVE_8mA		8
+#define MTK_DRIVE_10mA		10
+#define MTK_DRIVE_12mA		12
+#define MTK_DRIVE_14mA		14
+#define MTK_DRIVE_16mA		16
+#define MTK_DRIVE_20mA		20
+#define MTK_DRIVE_24mA		24
+#define MTK_DRIVE_28mA		28
+#define MTK_DRIVE_32mA		32
+
+#endif /* _DT_BINDINGS_PINCTRL_MT65XX_H */
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 20/31] pinctrl: mediatek: add pinctrl driver for MT7981 SoC
  2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
                   ` (18 preceding siblings ...)
  2022-08-04  3:36 ` [PATCH 19/31] dt-bindings: pinctrl: mediatek: add a header for common pinconf parameters Weijie Gao
@ 2022-08-04  3:36 ` Weijie Gao
  2022-08-04 13:57   ` Simon Glass
  2022-08-04  3:36 ` [PATCH 21/31] pinctrl: mediatek: add pinctrl driver for MT7986 SoC Weijie Gao
                   ` (10 subsequent siblings)
  30 siblings, 1 reply; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:36 UTC (permalink / raw)
  To: u-boot; +Cc: GSS_MTK_Uboot_upstream, Weijie Gao

This patch adds pinctrl and gpio support for MT7981 SoC

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 drivers/pinctrl/mediatek/Kconfig          |    4 +
 drivers/pinctrl/mediatek/Makefile         |    1 +
 drivers/pinctrl/mediatek/pinctrl-mt7981.c | 1049 +++++++++++++++++++++
 3 files changed, 1054 insertions(+)
 create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt7981.c

diff --git a/drivers/pinctrl/mediatek/Kconfig
 b/drivers/pinctrl/mediatek/Kconfig
index 58df508d7e..aceec9277d 100644
--- a/drivers/pinctrl/mediatek/Kconfig
+++ b/drivers/pinctrl/mediatek/Kconfig
@@ -16,6 +16,10 @@ config PINCTRL_MT7629
 	bool "MT7629 SoC pinctrl driver"
 	select PINCTRL_MTK
 
+config PINCTRL_MT7981
+	bool "MT7981 SoC pinctrl driver"
+	select PINCTRL_MTK
+
 config PINCTRL_MT8512
 	bool "MT8512 SoC pinctrl driver"
 	select PINCTRL_MTK
diff --git a/drivers/pinctrl/mediatek/Makefile
 b/drivers/pinctrl/mediatek/Makefile
index d7e8cf1727..1879d7ae2a 100644
--- a/drivers/pinctrl/mediatek/Makefile
+++ b/drivers/pinctrl/mediatek/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_PINCTRL_MTK) += pinctrl-mtk-common.o
 obj-$(CONFIG_PINCTRL_MT7622) += pinctrl-mt7622.o
 obj-$(CONFIG_PINCTRL_MT7623) += pinctrl-mt7623.o
 obj-$(CONFIG_PINCTRL_MT7629) += pinctrl-mt7629.o
+obj-$(CONFIG_PINCTRL_MT7981) += pinctrl-mt7981.o
 obj-$(CONFIG_PINCTRL_MT8512) += pinctrl-mt8512.o
 obj-$(CONFIG_PINCTRL_MT8516) += pinctrl-mt8516.o
 obj-$(CONFIG_PINCTRL_MT8518) += pinctrl-mt8518.o
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7981.c
 b/drivers/pinctrl/mediatek/pinctrl-mt7981.c
new file mode 100644
index 0000000000..d8875241cb
--- /dev/null
+++ b/drivers/pinctrl/mediatek/pinctrl-mt7981.c
@@ -0,0 +1,1049 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The MT7981 driver based on Linux generic pinctrl binding.
+ *
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+#include <dm.h>
+#include "pinctrl-mtk-common.h"
+
+#define MT7981_TYPE0_PIN(_number, _name)	\
+	MTK_TYPED_PIN(_number, _name, DRV_GRP4, IO_TYPE_GRP0)
+
+#define MT7981_TYPE1_PIN(_number, _name)	\
+	MTK_TYPED_PIN(_number, _name, DRV_GRP4, IO_TYPE_GRP1)
+
+#define PIN_FIELD_GPIO(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits)
	\
+	PIN_FIELD_BASE_CALC(_s_pin, _e_pin, GPIO_BASE, _s_addr, _x_addrs,	\
+			    _s_bit, _x_bits, 32, 0)
+
+#define PIN_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,
	\
+		       _x_bits)							\
+	PIN_FIELD_BASE_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,	\
+	_x_bits, 32, 0)
+
+/**
+ * enum - Locking variants of the iocfg bases
+ *
+ * MT7981 have multiple bases to program pin configuration listed as the
 below:
+ * iocfg_rt:0x11c00000, iocfg_rm:0x11c10000, iocfg_rb:0x11d20000,
+ * iocfg_lb:0x11e00000, iocfg_bl:0x11e20000, iocfg_tm:0x11f00000,
+ * iocfg_tl:0x11f10000,
+ * _i_based could be used to indicate what base the pin should be mapped
 into.
+ *
+ * Each iocfg register base control different group of pads on the SoC
+ *
+ *
+ *  chip carrier
+ *
+ *      A  B  C  D  E  F  G  H
+ *    +------------------------+
+ *  8 | o  o  o  o  o  o  o  o |
+ *  7 | o  o  o  o  o  o  o  o |
+ *  6 | o  o  o  o  o  o  o  o |
+ *  5 | o  o  o  o  o  o  o  o |
+ *  4 | o  o  o  o  o  o  o  o |
+ *  3 | o  o  o  o  o  o  o  o |
+ *  2 | o  o  o  o  o  o  o  o |
+ *  1 | o  o  o  o  o  o  o  o |
+ *    +------------------------+
+ *
+ *  inside Chip carrier
+ *
+ *      A  B  C  D  E  F  G  H
+ *    +------------------------+
+ *  8 |                        |
+ *  7 |       TL TM            |
+ *  6 |      +---------+       |
+ *  5 |      |         | RT    |
+ *  4 |      |         | RM    |
+ *  3 |   LB |         | RB    |
+ *  2 |      +---------+       |
+ *  1 |        BL              |
+ *    +------------------------+
+ *
+ */
+
+enum {
+	GPIO_BASE,
+	IOCFG_RT_BASE,
+	IOCFG_RM_BASE,
+	IOCFG_RB_BASE,
+	IOCFG_LB_BASE,
+	IOCFG_BL_BASE,
+	IOCFG_TM_BASE,
+	IOCFG_TL_BASE,
+};
+
+static const struct mtk_pin_field_calc mt7981_pin_mode_range[] = {
+	PIN_FIELD_GPIO(0, 56, 0x300, 0x10, 0, 4),
+};
+
+static const struct mtk_pin_field_calc mt7981_pin_dir_range[] = {
+	PIN_FIELD_GPIO(0, 56, 0x0, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7981_pin_di_range[] = {
+	PIN_FIELD_GPIO(0, 56, 0x200, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7981_pin_do_range[] = {
+	PIN_FIELD_GPIO(0, 56, 0x100, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7981_pin_ies_range[] = {
+	PIN_FIELD_BASE(0, 0, 1, 0x10, 0x10, 1, 1),
+	PIN_FIELD_BASE(1, 1, 1, 0x10, 0x10, 0, 1),
+	PIN_FIELD_BASE(2, 2, 5, 0x20, 0x10, 6, 1),
+	PIN_FIELD_BASE(3, 3, 4, 0x20, 0x10, 6, 1),
+	PIN_FIELD_BASE(4, 4, 4, 0x20, 0x10, 2, 1),
+	PIN_FIELD_BASE(5, 5, 4, 0x20, 0x10, 1, 1),
+	PIN_FIELD_BASE(6, 6, 4, 0x20, 0x10, 3, 1),
+	PIN_FIELD_BASE(7, 7, 4, 0x20, 0x10, 0, 1),
+	PIN_FIELD_BASE(8, 8, 4, 0x20, 0x10, 4, 1),
+	PIN_FIELD_BASE(9, 9, 4, 0x20, 0x10, 9, 1),
+
+	PIN_FIELD_BASE(10, 10, 5, 0x20, 0x10, 8, 1),
+	PIN_FIELD_BASE(11, 11, 5, 0x40, 0x10, 10, 1),
+	PIN_FIELD_BASE(12, 12, 5, 0x20, 0x10, 7, 1),
+	PIN_FIELD_BASE(13, 13, 5, 0x20, 0x10, 11, 1),
+
+	PIN_FIELD_BASE(14, 14, 4, 0x20, 0x10, 8, 1),
+
+	PIN_FIELD_BASE(15, 15, 2, 0x20, 0x10, 0, 1),
+	PIN_FIELD_BASE(16, 16, 2, 0x20, 0x10, 1, 1),
+	PIN_FIELD_BASE(17, 17, 2, 0x20, 0x10, 5, 1),
+	PIN_FIELD_BASE(18, 18, 2, 0x20, 0x10, 4, 1),
+	PIN_FIELD_BASE(19, 19, 2, 0x20, 0x10, 2, 1),
+	PIN_FIELD_BASE(20, 20, 2, 0x20, 0x10, 3, 1),
+	PIN_FIELD_BASE(21, 21, 2, 0x20, 0x10, 6, 1),
+	PIN_FIELD_BASE(22, 22, 2, 0x20, 0x10, 7, 1),
+	PIN_FIELD_BASE(23, 23, 2, 0x20, 0x10, 10, 1),
+	PIN_FIELD_BASE(24, 24, 2, 0x20, 0x10, 9, 1),
+	PIN_FIELD_BASE(25, 25, 2, 0x20, 0x10, 8, 1),
+
+	PIN_FIELD_BASE(26, 26, 5, 0x20, 0x10, 0, 1),
+	PIN_FIELD_BASE(27, 27, 5, 0x20, 0x10, 4, 1),
+	PIN_FIELD_BASE(28, 28, 5, 0x20, 0x10, 3, 1),
+	PIN_FIELD_BASE(29, 29, 5, 0x20, 0x10, 1, 1),
+	PIN_FIELD_BASE(30, 30, 5, 0x20, 0x10, 2, 1),
+	PIN_FIELD_BASE(31, 31, 5, 0x20, 0x10, 5, 1),
+
+	PIN_FIELD_BASE(32, 32, 1, 0x10, 0x10, 2, 1),
+	PIN_FIELD_BASE(33, 33, 1, 0x10, 0x10, 3, 1),
+
+	PIN_FIELD_BASE(34, 34, 4, 0x20, 0x10, 5, 1),
+	PIN_FIELD_BASE(35, 35, 4, 0x20, 0x10, 7, 1),
+
+	PIN_FIELD_BASE(36, 36, 3, 0x10, 0x10, 2, 1),
+	PIN_FIELD_BASE(37, 37, 3, 0x10, 0x10, 3, 1),
+	PIN_FIELD_BASE(38, 38, 3, 0x10, 0x10, 0, 1),
+	PIN_FIELD_BASE(39, 39, 3, 0x10, 0x10, 1, 1),
+
+	PIN_FIELD_BASE(40, 40, 7, 0x30, 0x10, 1, 1),
+	PIN_FIELD_BASE(41, 41, 7, 0x30, 0x10, 0, 1),
+	PIN_FIELD_BASE(42, 42, 7, 0x30, 0x10, 9, 1),
+	PIN_FIELD_BASE(43, 43, 7, 0x30, 0x10, 7, 1),
+	PIN_FIELD_BASE(44, 44, 7, 0x30, 0x10, 8, 1),
+	PIN_FIELD_BASE(45, 45, 7, 0x30, 0x10, 3, 1),
+	PIN_FIELD_BASE(46, 46, 7, 0x30, 0x10, 4, 1),
+	PIN_FIELD_BASE(47, 47, 7, 0x30, 0x10, 5, 1),
+	PIN_FIELD_BASE(48, 48, 7, 0x30, 0x10, 6, 1),
+	PIN_FIELD_BASE(49, 49, 7, 0x30, 0x10, 2, 1),
+
+	PIN_FIELD_BASE(50, 50, 6, 0x10, 0x10, 0, 1),
+	PIN_FIELD_BASE(51, 51, 6, 0x10, 0x10, 2, 1),
+	PIN_FIELD_BASE(52, 52, 6, 0x10, 0x10, 3, 1),
+	PIN_FIELD_BASE(53, 53, 6, 0x10, 0x10, 4, 1),
+	PIN_FIELD_BASE(54, 54, 6, 0x10, 0x10, 5, 1),
+	PIN_FIELD_BASE(55, 55, 6, 0x10, 0x10, 6, 1),
+	PIN_FIELD_BASE(56, 56, 6, 0x10, 0x10, 1, 1),
+};
+
+static const struct mtk_pin_field_calc mt7981_pin_smt_range[] = {
+	PIN_FIELD_BASE(0, 0, 1, 0x60, 0x10, 1, 1),
+	PIN_FIELD_BASE(1, 1, 1, 0x60, 0x10, 0, 1),
+	PIN_FIELD_BASE(2, 2, 5, 0x90, 0x10, 6, 1),
+	PIN_FIELD_BASE(3, 3, 4, 0x80, 0x10, 6, 1),
+	PIN_FIELD_BASE(4, 4, 4, 0x80, 0x10, 2, 1),
+	PIN_FIELD_BASE(5, 5, 4, 0x80, 0x10, 1, 1),
+	PIN_FIELD_BASE(6, 6, 4, 0x80, 0x10, 3, 1),
+	PIN_FIELD_BASE(7, 7, 4, 0x80, 0x10, 0, 1),
+	PIN_FIELD_BASE(8, 8, 4, 0x80, 0x10, 4, 1),
+	PIN_FIELD_BASE(9, 9, 4, 0x80, 0x10, 9, 1),
+
+	PIN_FIELD_BASE(10, 10, 5, 0x90, 0x10, 8, 1),
+	PIN_FIELD_BASE(11, 11, 5, 0x90, 0x10, 10, 1),
+	PIN_FIELD_BASE(12, 12, 5, 0x90, 0x10, 7, 1),
+	PIN_FIELD_BASE(13, 13, 5, 0x90, 0x10, 11, 1),
+
+	PIN_FIELD_BASE(14, 14, 4, 0x80, 0x10, 8, 1),
+
+	PIN_FIELD_BASE(15, 15, 2, 0x90, 0x10, 0, 1),
+	PIN_FIELD_BASE(16, 16, 2, 0x90, 0x10, 1, 1),
+	PIN_FIELD_BASE(17, 17, 2, 0x90, 0x10, 5, 1),
+	PIN_FIELD_BASE(18, 18, 2, 0x90, 0x10, 4, 1),
+	PIN_FIELD_BASE(19, 19, 2, 0x90, 0x10, 2, 1),
+	PIN_FIELD_BASE(20, 20, 2, 0x90, 0x10, 3, 1),
+	PIN_FIELD_BASE(21, 21, 2, 0x90, 0x10, 6, 1),
+	PIN_FIELD_BASE(22, 22, 2, 0x90, 0x10, 7, 1),
+	PIN_FIELD_BASE(23, 23, 2, 0x90, 0x10, 10, 1),
+	PIN_FIELD_BASE(24, 24, 2, 0x90, 0x10, 9, 1),
+	PIN_FIELD_BASE(25, 25, 2, 0x90, 0x10, 8, 1),
+
+	PIN_FIELD_BASE(26, 26, 5, 0x90, 0x10, 0, 1),
+	PIN_FIELD_BASE(27, 27, 5, 0x90, 0x10, 4, 1),
+	PIN_FIELD_BASE(28, 28, 5, 0x90, 0x10, 3, 1),
+	PIN_FIELD_BASE(29, 29, 5, 0x90, 0x10, 1, 1),
+	PIN_FIELD_BASE(30, 30, 5, 0x90, 0x10, 2, 1),
+	PIN_FIELD_BASE(31, 31, 5, 0x90, 0x10, 5, 1),
+
+	PIN_FIELD_BASE(32, 32, 1, 0x60, 0x10, 2, 1),
+	PIN_FIELD_BASE(33, 33, 1, 0x60, 0x10, 3, 1),
+
+	PIN_FIELD_BASE(34, 34, 4, 0x80, 0x10, 5, 1),
+	PIN_FIELD_BASE(35, 35, 4, 0x80, 0x10, 7, 1),
+
+	PIN_FIELD_BASE(36, 36, 3, 0x60, 0x10, 2, 1),
+	PIN_FIELD_BASE(37, 37, 3, 0x60, 0x10, 3, 1),
+	PIN_FIELD_BASE(38, 38, 3, 0x60, 0x10, 0, 1),
+	PIN_FIELD_BASE(39, 39, 3, 0x60, 0x10, 1, 1),
+
+	PIN_FIELD_BASE(40, 40, 7, 0x70, 0x10, 1, 1),
+	PIN_FIELD_BASE(41, 41, 7, 0x70, 0x10, 0, 1),
+	PIN_FIELD_BASE(42, 42, 7, 0x70, 0x10, 9, 1),
+	PIN_FIELD_BASE(43, 43, 7, 0x70, 0x10, 7, 1),
+	PIN_FIELD_BASE(44, 44, 7, 0x30, 0x10, 8, 1),
+	PIN_FIELD_BASE(45, 45, 7, 0x70, 0x10, 3, 1),
+	PIN_FIELD_BASE(46, 46, 7, 0x70, 0x10, 4, 1),
+	PIN_FIELD_BASE(47, 47, 7, 0x70, 0x10, 5, 1),
+	PIN_FIELD_BASE(48, 48, 7, 0x70, 0x10, 6, 1),
+	PIN_FIELD_BASE(49, 49, 7, 0x70, 0x10, 2, 1),
+
+	PIN_FIELD_BASE(50, 50, 6, 0x50, 0x10, 0, 1),
+	PIN_FIELD_BASE(51, 51, 6, 0x50, 0x10, 2, 1),
+	PIN_FIELD_BASE(52, 52, 6, 0x50, 0x10, 3, 1),
+	PIN_FIELD_BASE(53, 53, 6, 0x50, 0x10, 4, 1),
+	PIN_FIELD_BASE(54, 54, 6, 0x50, 0x10, 5, 1),
+	PIN_FIELD_BASE(55, 55, 6, 0x50, 0x10, 6, 1),
+	PIN_FIELD_BASE(56, 56, 6, 0x50, 0x10, 1, 1),
+};
+
+static const struct mtk_pin_field_calc mt7981_pin_pu_range[] = {
+	PIN_FIELD_BASE(40, 40, 7, 0x50, 0x10, 1, 1),
+	PIN_FIELD_BASE(41, 41, 7, 0x50, 0x10, 0, 1),
+	PIN_FIELD_BASE(42, 42, 7, 0x50, 0x10, 9, 1),
+	PIN_FIELD_BASE(43, 43, 7, 0x50, 0x10, 7, 1),
+	PIN_FIELD_BASE(44, 44, 7, 0x50, 0x10, 8, 1),
+	PIN_FIELD_BASE(45, 45, 7, 0x50, 0x10, 3, 1),
+	PIN_FIELD_BASE(46, 46, 7, 0x50, 0x10, 4, 1),
+	PIN_FIELD_BASE(47, 47, 7, 0x50, 0x10, 5, 1),
+	PIN_FIELD_BASE(48, 48, 7, 0x50, 0x10, 6, 1),
+	PIN_FIELD_BASE(49, 49, 7, 0x50, 0x10, 2, 1),
+
+	PIN_FIELD_BASE(50, 50, 6, 0x30, 0x10, 0, 1),
+	PIN_FIELD_BASE(51, 51, 6, 0x30, 0x10, 2, 1),
+	PIN_FIELD_BASE(52, 52, 6, 0x30, 0x10, 3, 1),
+	PIN_FIELD_BASE(53, 53, 6, 0x30, 0x10, 4, 1),
+	PIN_FIELD_BASE(54, 54, 6, 0x30, 0x10, 5, 1),
+	PIN_FIELD_BASE(55, 55, 6, 0x30, 0x10, 6, 1),
+	PIN_FIELD_BASE(56, 56, 6, 0x30, 0x10, 1, 1),
+};
+
+static const struct mtk_pin_field_calc mt7981_pin_pd_range[] = {
+	PIN_FIELD_BASE(40, 40, 7, 0x40, 0x10, 1, 1),
+	PIN_FIELD_BASE(41, 41, 7, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(42, 42, 7, 0x40, 0x10, 9, 1),
+	PIN_FIELD_BASE(43, 43, 7, 0x40, 0x10, 7, 1),
+	PIN_FIELD_BASE(44, 44, 7, 0x40, 0x10, 8, 1),
+	PIN_FIELD_BASE(45, 45, 7, 0x40, 0x10, 3, 1),
+	PIN_FIELD_BASE(46, 46, 7, 0x40, 0x10, 4, 1),
+	PIN_FIELD_BASE(47, 47, 7, 0x40, 0x10, 5, 1),
+	PIN_FIELD_BASE(48, 48, 7, 0x40, 0x10, 6, 1),
+	PIN_FIELD_BASE(49, 49, 7, 0x40, 0x10, 2, 1),
+
+	PIN_FIELD_BASE(50, 50, 6, 0x20, 0x10, 0, 1),
+	PIN_FIELD_BASE(51, 51, 6, 0x20, 0x10, 2, 1),
+	PIN_FIELD_BASE(52, 52, 6, 0x20, 0x10, 3, 1),
+	PIN_FIELD_BASE(53, 53, 6, 0x20, 0x10, 4, 1),
+	PIN_FIELD_BASE(54, 54, 6, 0x20, 0x10, 5, 1),
+	PIN_FIELD_BASE(55, 55, 6, 0x20, 0x10, 6, 1),
+	PIN_FIELD_BASE(56, 56, 6, 0x20, 0x10, 1, 1),
+};
+
+static const struct mtk_pin_field_calc mt7981_pin_drv_range[] = {
+	PIN_FIELD_BASE(0, 0, 1, 0x00, 0x10, 3, 3),
+	PIN_FIELD_BASE(1, 1, 1, 0x00, 0x10, 0, 3),
+
+	PIN_FIELD_BASE(2, 2, 5, 0x00, 0x10, 18, 3),
+
+	PIN_FIELD_BASE(3, 3, 4, 0x00, 0x10, 18, 1),
+	PIN_FIELD_BASE(4, 4, 4, 0x00, 0x10, 6, 1),
+	PIN_FIELD_BASE(5, 5, 4, 0x00, 0x10, 3, 3),
+	PIN_FIELD_BASE(6, 6, 4, 0x00, 0x10, 9, 3),
+	PIN_FIELD_BASE(7, 7, 4, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(8, 8, 4, 0x00, 0x10, 12, 3),
+	PIN_FIELD_BASE(9, 9, 4, 0x00, 0x10, 27, 3),
+
+	PIN_FIELD_BASE(10, 10, 5, 0x00, 0x10, 24, 3),
+	PIN_FIELD_BASE(11, 11, 5, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(12, 12, 5, 0x00, 0x10, 21, 3),
+	PIN_FIELD_BASE(13, 13, 5, 0x00, 0x10, 3, 3),
+
+	PIN_FIELD_BASE(14, 14, 4, 0x00, 0x10, 27, 3),
+
+	PIN_FIELD_BASE(15, 15, 2, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(16, 16, 2, 0x00, 0x10, 3, 3),
+	PIN_FIELD_BASE(17, 17, 2, 0x00, 0x10, 15, 3),
+	PIN_FIELD_BASE(18, 18, 2, 0x00, 0x10, 12, 3),
+	PIN_FIELD_BASE(19, 19, 2, 0x00, 0x10, 6, 3),
+	PIN_FIELD_BASE(20, 20, 2, 0x00, 0x10, 9, 3),
+	PIN_FIELD_BASE(21, 21, 2, 0x00, 0x10, 18, 3),
+	PIN_FIELD_BASE(22, 22, 2, 0x00, 0x10, 21, 3),
+	PIN_FIELD_BASE(23, 23, 2, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(24, 24, 2, 0x00, 0x10, 27, 3),
+	PIN_FIELD_BASE(25, 25, 2, 0x00, 0x10, 24, 3),
+
+	PIN_FIELD_BASE(26, 26, 5, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(27, 27, 5, 0x00, 0x10, 12, 3),
+	PIN_FIELD_BASE(28, 28, 5, 0x00, 0x10, 9, 3),
+	PIN_FIELD_BASE(29, 29, 5, 0x00, 0x10, 3, 3),
+	PIN_FIELD_BASE(30, 30, 5, 0x00, 0x10, 6, 3),
+	PIN_FIELD_BASE(31, 31, 5, 0x00, 0x10, 15, 3),
+
+	PIN_FIELD_BASE(32, 32, 1, 0x00, 0x10, 9, 3),
+	PIN_FIELD_BASE(33, 33, 1, 0x00, 0x10, 12, 3),
+
+	PIN_FIELD_BASE(34, 34, 4, 0x00, 0x10, 15, 3),
+	PIN_FIELD_BASE(35, 35, 4, 0x00, 0x10, 21, 3),
+
+	PIN_FIELD_BASE(36, 36, 3, 0x00, 0x10, 6, 3),
+	PIN_FIELD_BASE(37, 37, 3, 0x00, 0x10, 9, 3),
+	PIN_FIELD_BASE(38, 38, 3, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(39, 39, 3, 0x00, 0x10, 3, 3),
+
+	PIN_FIELD_BASE(40, 40, 7, 0x00, 0x10, 3, 3),
+	PIN_FIELD_BASE(41, 41, 7, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(42, 42, 7, 0x00, 0x10, 27, 3),
+	PIN_FIELD_BASE(43, 43, 7, 0x00, 0x10, 21, 3),
+	PIN_FIELD_BASE(44, 44, 7, 0x00, 0x10, 24, 3),
+	PIN_FIELD_BASE(45, 45, 7, 0x00, 0x10, 9, 3),
+	PIN_FIELD_BASE(46, 46, 7, 0x00, 0x10, 12, 3),
+	PIN_FIELD_BASE(47, 47, 7, 0x00, 0x10, 15, 3),
+	PIN_FIELD_BASE(48, 48, 7, 0x00, 0x10, 18, 3),
+	PIN_FIELD_BASE(49, 49, 7, 0x00, 0x10, 6, 3),
+
+	PIN_FIELD_BASE(50, 50, 6, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(51, 51, 6, 0x00, 0x10, 6, 3),
+	PIN_FIELD_BASE(52, 52, 6, 0x00, 0x10, 9, 3),
+	PIN_FIELD_BASE(53, 53, 6, 0x00, 0x10, 12, 3),
+	PIN_FIELD_BASE(54, 54, 6, 0x00, 0x10, 15, 3),
+	PIN_FIELD_BASE(55, 55, 6, 0x00, 0x10, 18, 3),
+	PIN_FIELD_BASE(56, 56, 6, 0x00, 0x10, 3, 3),
+};
+
+static const struct mtk_pin_field_calc mt7981_pin_pupd_range[] = {
+	PIN_FIELD_BASE(0, 0, 1, 0x20, 0x10, 1, 1),
+	PIN_FIELD_BASE(1, 1, 1, 0x20, 0x10, 0, 1),
+	PIN_FIELD_BASE(2, 2, 5, 0x30, 0x10, 6, 1),
+	PIN_FIELD_BASE(3, 3, 4, 0x30, 0x10, 6, 1),
+	PIN_FIELD_BASE(4, 4, 4, 0x30, 0x10, 2, 1),
+	PIN_FIELD_BASE(5, 5, 4, 0x30, 0x10, 1, 1),
+	PIN_FIELD_BASE(6, 6, 4, 0x30, 0x10, 3, 1),
+	PIN_FIELD_BASE(7, 7, 4, 0x30, 0x10, 0, 1),
+	PIN_FIELD_BASE(8, 8, 4, 0x30, 0x10, 4, 1),
+	PIN_FIELD_BASE(9, 9, 4, 0x30, 0x10, 9, 1),
+
+	PIN_FIELD_BASE(10, 10, 5, 0x30, 0x10, 8, 1),
+	PIN_FIELD_BASE(11, 11, 5, 0x30, 0x10, 10, 1),
+	PIN_FIELD_BASE(12, 12, 5, 0x30, 0x10, 7, 1),
+	PIN_FIELD_BASE(13, 13, 5, 0x30, 0x10, 11, 1),
+
+	PIN_FIELD_BASE(14, 14, 4, 0x30, 0x10, 8, 1),
+
+	PIN_FIELD_BASE(15, 15, 2, 0x30, 0x10, 0, 1),
+	PIN_FIELD_BASE(16, 16, 2, 0x30, 0x10, 1, 1),
+	PIN_FIELD_BASE(17, 17, 2, 0x30, 0x10, 5, 1),
+	PIN_FIELD_BASE(18, 18, 2, 0x30, 0x10, 4, 1),
+	PIN_FIELD_BASE(19, 19, 2, 0x30, 0x10, 2, 1),
+	PIN_FIELD_BASE(20, 20, 2, 0x90, 0x10, 3, 1),
+	PIN_FIELD_BASE(21, 21, 2, 0x30, 0x10, 6, 1),
+	PIN_FIELD_BASE(22, 22, 2, 0x30, 0x10, 7, 1),
+	PIN_FIELD_BASE(23, 23, 2, 0x30, 0x10, 10, 1),
+	PIN_FIELD_BASE(24, 24, 2, 0x30, 0x10, 9, 1),
+	PIN_FIELD_BASE(25, 25, 2, 0x30, 0x10, 8, 1),
+
+	PIN_FIELD_BASE(26, 26, 5, 0x30, 0x10, 0, 1),
+	PIN_FIELD_BASE(27, 27, 5, 0x30, 0x10, 4, 1),
+	PIN_FIELD_BASE(28, 28, 5, 0x30, 0x10, 3, 1),
+	PIN_FIELD_BASE(29, 29, 5, 0x30, 0x10, 1, 1),
+	PIN_FIELD_BASE(30, 30, 5, 0x30, 0x10, 2, 1),
+	PIN_FIELD_BASE(31, 31, 5, 0x30, 0x10, 5, 1),
+
+	PIN_FIELD_BASE(32, 32, 1, 0x20, 0x10, 2, 1),
+	PIN_FIELD_BASE(33, 33, 1, 0x20, 0x10, 3, 1),
+
+	PIN_FIELD_BASE(34, 34, 4, 0x30, 0x10, 5, 1),
+	PIN_FIELD_BASE(35, 35, 4, 0x30, 0x10, 7, 1),
+
+	PIN_FIELD_BASE(36, 36, 3, 0x20, 0x10, 2, 1),
+	PIN_FIELD_BASE(37, 37, 3, 0x20, 0x10, 3, 1),
+	PIN_FIELD_BASE(38, 38, 3, 0x20, 0x10, 0, 1),
+	PIN_FIELD_BASE(39, 39, 3, 0x20, 0x10, 1, 1),
+};
+
+static const struct mtk_pin_field_calc mt7981_pin_r0_range[] = {
+	PIN_FIELD_BASE(0, 0, 1, 0x30, 0x10, 1, 1),
+	PIN_FIELD_BASE(1, 1, 1, 0x30, 0x10, 0, 1),
+	PIN_FIELD_BASE(2, 2, 5, 0x40, 0x10, 6, 1),
+	PIN_FIELD_BASE(3, 3, 4, 0x40, 0x10, 6, 1),
+	PIN_FIELD_BASE(4, 4, 4, 0x40, 0x10, 2, 1),
+	PIN_FIELD_BASE(5, 5, 4, 0x40, 0x10, 1, 1),
+	PIN_FIELD_BASE(6, 6, 4, 0x40, 0x10, 3, 1),
+	PIN_FIELD_BASE(7, 7, 4, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(8, 8, 4, 0x40, 0x10, 4, 1),
+	PIN_FIELD_BASE(9, 9, 4, 0x40, 0x10, 9, 1),
+
+	PIN_FIELD_BASE(10, 10, 5, 0x40, 0x10, 8, 1),
+	PIN_FIELD_BASE(11, 11, 5, 0x40, 0x10, 10, 1),
+	PIN_FIELD_BASE(12, 12, 5, 0x40, 0x10, 7, 1),
+	PIN_FIELD_BASE(13, 13, 5, 0x40, 0x10, 11, 1),
+
+	PIN_FIELD_BASE(14, 14, 4, 0x40, 0x10, 8, 1),
+
+	PIN_FIELD_BASE(15, 15, 2, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(16, 16, 2, 0x40, 0x10, 1, 1),
+	PIN_FIELD_BASE(17, 17, 2, 0x40, 0x10, 5, 1),
+	PIN_FIELD_BASE(18, 18, 2, 0x40, 0x10, 4, 1),
+	PIN_FIELD_BASE(19, 19, 2, 0x40, 0x10, 2, 1),
+	PIN_FIELD_BASE(20, 20, 2, 0x40, 0x10, 3, 1),
+	PIN_FIELD_BASE(21, 21, 2, 0x40, 0x10, 6, 1),
+	PIN_FIELD_BASE(22, 22, 2, 0x40, 0x10, 7, 1),
+	PIN_FIELD_BASE(23, 23, 2, 0x40, 0x10, 10, 1),
+	PIN_FIELD_BASE(24, 24, 2, 0x40, 0x10, 9, 1),
+	PIN_FIELD_BASE(25, 25, 2, 0x40, 0x10, 8, 1),
+
+	PIN_FIELD_BASE(26, 26, 5, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(27, 27, 5, 0x40, 0x10, 4, 1),
+	PIN_FIELD_BASE(28, 28, 5, 0x40, 0x10, 3, 1),
+	PIN_FIELD_BASE(29, 29, 5, 0x40, 0x10, 1, 1),
+	PIN_FIELD_BASE(30, 30, 5, 0x40, 0x10, 2, 1),
+	PIN_FIELD_BASE(31, 31, 5, 0x40, 0x10, 5, 1),
+
+	PIN_FIELD_BASE(32, 32, 1, 0x30, 0x10, 2, 1),
+	PIN_FIELD_BASE(33, 33, 1, 0x30, 0x10, 3, 1),
+
+	PIN_FIELD_BASE(34, 34, 4, 0x40, 0x10, 5, 1),
+	PIN_FIELD_BASE(35, 35, 4, 0x40, 0x10, 7, 1),
+
+	PIN_FIELD_BASE(36, 36, 3, 0x30, 0x10, 2, 1),
+	PIN_FIELD_BASE(37, 37, 3, 0x30, 0x10, 3, 1),
+	PIN_FIELD_BASE(38, 38, 3, 0x30, 0x10, 0, 1),
+	PIN_FIELD_BASE(39, 39, 3, 0x30, 0x10, 1, 1),
+};
+
+static const struct mtk_pin_field_calc mt7981_pin_r1_range[] = {
+	PIN_FIELD_BASE(0, 0, 1, 0x40, 0x10, 1, 1),
+	PIN_FIELD_BASE(1, 1, 1, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(2, 2, 5, 0x50, 0x10, 6, 1),
+	PIN_FIELD_BASE(3, 3, 4, 0x50, 0x10, 6, 1),
+	PIN_FIELD_BASE(4, 4, 4, 0x50, 0x10, 2, 1),
+	PIN_FIELD_BASE(5, 5, 4, 0x50, 0x10, 1, 1),
+	PIN_FIELD_BASE(6, 6, 4, 0x50, 0x10, 3, 1),
+	PIN_FIELD_BASE(7, 7, 4, 0x50, 0x10, 0, 1),
+	PIN_FIELD_BASE(8, 8, 4, 0x50, 0x10, 4, 1),
+	PIN_FIELD_BASE(9, 9, 4, 0x50, 0x10, 9, 1),
+
+	PIN_FIELD_BASE(10, 10, 5, 0x50, 0x10, 8, 1),
+	PIN_FIELD_BASE(11, 11, 5, 0x50, 0x10, 10, 1),
+	PIN_FIELD_BASE(12, 12, 5, 0x50, 0x10, 7, 1),
+	PIN_FIELD_BASE(13, 13, 5, 0x50, 0x10, 11, 1),
+
+	PIN_FIELD_BASE(14, 14, 4, 0x50, 0x10, 8, 1),
+
+	PIN_FIELD_BASE(15, 15, 2, 0x50, 0x10, 0, 1),
+	PIN_FIELD_BASE(16, 16, 2, 0x50, 0x10, 1, 1),
+	PIN_FIELD_BASE(17, 17, 2, 0x50, 0x10, 5, 1),
+	PIN_FIELD_BASE(18, 18, 2, 0x50, 0x10, 4, 1),
+	PIN_FIELD_BASE(19, 19, 2, 0x50, 0x10, 2, 1),
+	PIN_FIELD_BASE(20, 20, 2, 0x50, 0x10, 3, 1),
+	PIN_FIELD_BASE(21, 21, 2, 0x50, 0x10, 6, 1),
+	PIN_FIELD_BASE(22, 22, 2, 0x50, 0x10, 7, 1),
+	PIN_FIELD_BASE(23, 23, 2, 0x50, 0x10, 10, 1),
+	PIN_FIELD_BASE(24, 24, 2, 0x50, 0x10, 9, 1),
+	PIN_FIELD_BASE(25, 25, 2, 0x50, 0x10, 8, 1),
+
+	PIN_FIELD_BASE(26, 26, 5, 0x50, 0x10, 0, 1),
+	PIN_FIELD_BASE(27, 27, 5, 0x50, 0x10, 4, 1),
+	PIN_FIELD_BASE(28, 28, 5, 0x50, 0x10, 3, 1),
+	PIN_FIELD_BASE(29, 29, 5, 0x50, 0x10, 1, 1),
+	PIN_FIELD_BASE(30, 30, 5, 0x50, 0x10, 2, 1),
+	PIN_FIELD_BASE(31, 31, 5, 0x50, 0x10, 5, 1),
+
+	PIN_FIELD_BASE(32, 32, 1, 0x40, 0x10, 2, 1),
+	PIN_FIELD_BASE(33, 33, 1, 0x40, 0x10, 3, 1),
+
+	PIN_FIELD_BASE(34, 34, 4, 0x50, 0x10, 5, 1),
+	PIN_FIELD_BASE(35, 35, 4, 0x50, 0x10, 7, 1),
+
+	PIN_FIELD_BASE(36, 36, 3, 0x40, 0x10, 2, 1),
+	PIN_FIELD_BASE(37, 37, 3, 0x40, 0x10, 3, 1),
+	PIN_FIELD_BASE(38, 38, 3, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(39, 39, 3, 0x40, 0x10, 1, 1),
+};
+
+static const struct mtk_pin_reg_calc mt7981_reg_cals[] = {
+	[PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7981_pin_mode_range),
+	[PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7981_pin_dir_range),
+	[PINCTRL_PIN_REG_DI] = MTK_RANGE(mt7981_pin_di_range),
+	[PINCTRL_PIN_REG_DO] = MTK_RANGE(mt7981_pin_do_range),
+	[PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt7981_pin_smt_range),
+	[PINCTRL_PIN_REG_IES] = MTK_RANGE(mt7981_pin_ies_range),
+	[PINCTRL_PIN_REG_PU] = MTK_RANGE(mt7981_pin_pu_range),
+	[PINCTRL_PIN_REG_PD] = MTK_RANGE(mt7981_pin_pd_range),
+	[PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt7981_pin_drv_range),
+	[PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt7981_pin_pupd_range),
+	[PINCTRL_PIN_REG_R0] = MTK_RANGE(mt7981_pin_r0_range),
+	[PINCTRL_PIN_REG_R1] = MTK_RANGE(mt7981_pin_r1_range),
+};
+
+static const struct mtk_pin_desc mt7981_pins[] = {
+	MT7981_TYPE0_PIN(0, "GPIO_WPS"),
+	MT7981_TYPE0_PIN(1, "GPIO_RESET"),
+	MT7981_TYPE0_PIN(2, "SYS_WATCHDOG"),
+	MT7981_TYPE0_PIN(3, "PCIE_PERESET_N"),
+	MT7981_TYPE0_PIN(4, "JTAG_JTDO"),
+	MT7981_TYPE0_PIN(5, "JTAG_JTDI"),
+	MT7981_TYPE0_PIN(6, "JTAG_JTMS"),
+	MT7981_TYPE0_PIN(7, "JTAG_JTCLK"),
+	MT7981_TYPE0_PIN(8, "JTAG_JTRST_N"),
+	MT7981_TYPE0_PIN(9, "WO_JTAG_JTDO"),
+	MT7981_TYPE0_PIN(10, "WO_JTAG_JTDI"),
+	MT7981_TYPE0_PIN(11, "WO_JTAG_JTMS"),
+	MT7981_TYPE0_PIN(12, "WO_JTAG_JTCLK"),
+	MT7981_TYPE0_PIN(13, "WO_JTAG_JTRST_N"),
+	MT7981_TYPE0_PIN(14, "USB_VBUS"),
+	MT7981_TYPE0_PIN(15, "PWM0"),
+	MT7981_TYPE0_PIN(16, "SPI0_CLK"),
+	MT7981_TYPE0_PIN(17, "SPI0_MOSI"),
+	MT7981_TYPE0_PIN(18, "SPI0_MISO"),
+	MT7981_TYPE0_PIN(19, "SPI0_CS"),
+	MT7981_TYPE0_PIN(20, "SPI0_HOLD"),
+	MT7981_TYPE0_PIN(21, "SPI0_WP"),
+	MT7981_TYPE0_PIN(22, "SPI1_CLK"),
+	MT7981_TYPE0_PIN(23, "SPI1_MOSI"),
+	MT7981_TYPE0_PIN(24, "SPI1_MISO"),
+	MT7981_TYPE0_PIN(25, "SPI1_CS"),
+	MT7981_TYPE0_PIN(26, "SPI2_CLK"),
+	MT7981_TYPE0_PIN(27, "SPI2_MOSI"),
+	MT7981_TYPE0_PIN(28, "SPI2_MISO"),
+	MT7981_TYPE0_PIN(29, "SPI2_CS"),
+	MT7981_TYPE0_PIN(30, "SPI2_HOLD"),
+	MT7981_TYPE0_PIN(31, "SPI2_WP"),
+	MT7981_TYPE0_PIN(32, "UART0_RXD"),
+	MT7981_TYPE0_PIN(33, "UART0_TXD"),
+	MT7981_TYPE0_PIN(34, "PCIE_CLK_REQ"),
+	MT7981_TYPE0_PIN(35, "PCIE_WAKE_N"),
+	MT7981_TYPE0_PIN(36, "SMI_MDC"),
+	MT7981_TYPE0_PIN(37, "SMI_MDIO"),
+	MT7981_TYPE0_PIN(38, "GBE_INT"),
+	MT7981_TYPE0_PIN(39, "GBE_RESET"),
+	MT7981_TYPE1_PIN(40, "WF_DIG_RESETB"),
+	MT7981_TYPE1_PIN(41, "WF_CBA_RESETB"),
+	MT7981_TYPE1_PIN(42, "WF_XO_REQ"),
+	MT7981_TYPE1_PIN(43, "WF_TOP_CLK"),
+	MT7981_TYPE1_PIN(44, "WF_TOP_DATA"),
+	MT7981_TYPE1_PIN(45, "WF_HB1"),
+	MT7981_TYPE1_PIN(46, "WF_HB2"),
+	MT7981_TYPE1_PIN(47, "WF_HB3"),
+	MT7981_TYPE1_PIN(48, "WF_HB4"),
+	MT7981_TYPE1_PIN(49, "WF_HB0"),
+	MT7981_TYPE1_PIN(50, "WF_HB0_B"),
+	MT7981_TYPE1_PIN(51, "WF_HB5"),
+	MT7981_TYPE1_PIN(52, "WF_HB6"),
+	MT7981_TYPE1_PIN(53, "WF_HB7"),
+	MT7981_TYPE1_PIN(54, "WF_HB8"),
+	MT7981_TYPE1_PIN(55, "WF_HB9"),
+	MT7981_TYPE1_PIN(56, "WF_HB10"),
+};
+
+/* WA_AICE */
+static int mt7981_wa_aice1_pins[] = { 0, 1, };
+static int mt7981_wa_aice1_funcs[] = { 2, 2, };
+
+static int mt7981_wa_aice2_pins[] = { 0, 1, };
+static int mt7981_wa_aice2_funcs[] = { 3, 3, };
+
+static int mt7981_wa_aice3_pins[] = { 28, 29, };
+static int mt7981_wa_aice3_funcs[] = { 3, 3, };
+
+static int mt7981_wm_aice1_pins[] = { 9, 10, };
+static int mt7981_wm_aice1_funcs[] = { 2, 2, };
+
+static int mt7981_wm_aice2_pins[] = { 30, 31, };
+static int mt7981_wm_aice2_funcs[] = { 5, 5, };
+
+/* WM_UART */
+static int mt7981_wm_uart_0_pins[] = { 0, 1, };
+static int mt7981_wm_uart_0_funcs[] = { 5, 5, };
+
+static int mt7981_wm_uart_1_pins[] = { 20, 21, };
+static int mt7981_wm_uart_1_funcs[] = { 4, 4, };
+
+static int mt7981_wm_uart_2_pins[] = { 30, 31, };
+static int mt7981_wm_uart_2_funcs[] = { 3, 3, };
+
+/* DFD */
+static int mt7981_dfd_pins[] = { 0, 1, 4, 5, };
+static int mt7981_dfd_funcs[] = { 5, 5, 6, 6, };
+
+/* SYS_WATCHDOG */
+static int mt7981_watchdog_pins[] = { 2, };
+static int mt7981_watchdog_funcs[] = { 1, };
+
+static int mt7981_watchdog1_pins[] = { 13, };
+static int mt7981_watchdog1_funcs[] = { 5, };
+
+/* PCIE_PERESET_N */
+static int mt7981_pcie_pereset_pins[] = { 3, };
+static int mt7981_pcie_pereset_funcs[] = { 1, };
+
+/* JTAG */
+static int mt7981_jtag_pins[] = { 4, 5, 6, 7, 8, };
+static int mt7981_jtag_funcs[] = { 1, 1, 1, 1, 1, };
+
+/* WM_JTAG */
+static int mt7981_wm_jtag_0_pins[] = { 4, 5, 6, 7, 8, };
+static int mt7981_wm_jtag_0_funcs[] = { 2, 2, 2, 2, 2, };
+
+static int mt7981_wm_jtag_1_pins[] = { 20, 21, 22, 23, 24, };
+static int mt7981_wm_jtag_1_funcs[] = { 5, 5, 5, 5, 5, };
+
+/* WO0_JTAG */
+static int mt7981_wo0_jtag_0_pins[] = { 9, 10, 11, 12, 13, };
+static int mt7981_wo0_jtag_0_funcs[] = { 1, 1, 1, 1, 1, };
+
+static int mt7981_wo0_jtag_1_pins[] = { 25, 26, 27, 28, 29, };
+static int mt7981_wo0_jtag_1_funcs[] = { 5, 5, 5, 5, 5, };
+
+/* UART2 */
+static int mt7981_uart2_0_pins[] = { 4, 5, 6, 7, };
+static int mt7981_uart2_0_funcs[] = { 3, 3, 3, 3, };
+
+/* GBE_LED0 */
+static int mt7981_gbe_led0_pins[] = { 8, };
+static int mt7981_gbe_led0_funcs[] = { 3, };
+
+/* PTA_EXT */
+static int mt7981_pta_ext_0_pins[] = { 4, 5, 6, };
+static int mt7981_pta_ext_0_funcs[] = { 4, 4, 4, };
+
+static int mt7981_pta_ext_1_pins[] = { 22, 23, 24, };
+static int mt7981_pta_ext_1_funcs[] = { 4, 4, 4, };
+
+/* PWM2 */
+static int mt7981_pwm2_pins[] = { 7, };
+static int mt7981_pwm2_funcs[] = { 4, };
+
+/* NET_WO0_UART_TXD */
+static int mt7981_net_wo0_uart_txd_0_pins[] = { 8, };
+static int mt7981_net_wo0_uart_txd_0_funcs[] = { 4, };
+
+static int mt7981_net_wo0_uart_txd_1_pins[] = { 14, };
+static int mt7981_net_wo0_uart_txd_1_funcs[] = { 3, };
+
+static int mt7981_net_wo0_uart_txd_2_pins[] = { 15, };
+static int mt7981_net_wo0_uart_txd_2_funcs[] = { 4, };
+
+/* SPI1 */
+static int mt7981_spi1_0_pins[] = { 4, 5, 6, 7, };
+static int mt7981_spi1_0_funcs[] = { 5, 5, 5, 5, };
+
+/* I2C */
+static int mt7981_i2c0_0_pins[] = { 6, 7, };
+static int mt7981_i2c0_0_funcs[] = { 6, 6, };
+
+static int mt7981_i2c0_1_pins[] = { 30, 31, };
+static int mt7981_i2c0_1_funcs[] = { 4, 4, };
+
+static int mt7981_i2c0_2_pins[] = { 36, 37, };
+static int mt7981_i2c0_2_funcs[] = { 2, 2, };
+
+static int mt7981_u2_phy_i2c_pins[] = { 30, 31, };
+static int mt7981_u2_phy_i2c_funcs[] = { 6, 6, };
+
+static int mt7981_u3_phy_i2c_pins[] = { 32, 33, };
+static int mt7981_u3_phy_i2c_funcs[] = { 3, 3, };
+
+static int mt7981_sgmii1_phy_i2c_pins[] = { 32, 33, };
+static int mt7981_sgmii1_phy_i2c_funcs[] = { 2, 2, };
+
+static int mt7981_sgmii0_phy_i2c_pins[] = { 32, 33, };
+static int mt7981_sgmii0_phy_i2c_funcs[] = { 5, 5, };
+
+/* DFD_NTRST */
+static int mt7981_dfd_ntrst_pins[] = { 8, };
+static int mt7981_dfd_ntrst_funcs[] = { 6, };
+
+/* PWM0 */
+static int mt7981_pwm0_0_pins[] = { 13, };
+static int mt7981_pwm0_0_funcs[] = { 2, };
+
+static int mt7981_pwm0_1_pins[] = { 15, };
+static int mt7981_pwm0_1_funcs[] = { 1, };
+
+/* PWM1 */
+static int mt7981_pwm1_0_pins[] = { 14, };
+static int mt7981_pwm1_0_funcs[] = { 2, };
+
+static int mt7981_pwm1_1_pins[] = { 15, };
+static int mt7981_pwm1_1_funcs[] = { 3, };
+
+/* GBE_LED1 */
+static int mt7981_gbe_led1_pins[] = { 13, };
+static int mt7981_gbe_led1_funcs[] = { 3, };
+
+/* PCM */
+static int mt7981_pcm_pins[] = { 9, 10, 11, 12, 13, 25 };
+static int mt7981_pcm_funcs[] = { 4, 4, 4, 4, 4, 4, };
+
+/* UDI */
+static int mt7981_udi_pins[] = { 9, 10, 11, 12, 13, };
+static int mt7981_udi_funcs[] = { 6, 6, 6, 6, 6, };
+
+/* DRV_VBUS */
+static int mt7981_drv_vbus_pins[] = { 14, };
+static int mt7981_drv_vbus_funcs[] = { 1, };
+
+/* EMMC */
+static int mt7981_emmc_45_pins[] = { 15, 16, 17, 18, 19, 20, 21, 22, 23,
 24, 25, };
+static int mt7981_emmc_45_funcs[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, };
+
+/* SNFI */
+static int mt7981_snfi_pins[] = { 16, 17, 18, 19, 20, 21, };
+static int mt7981_snfi_funcs[] = { 3, 3, 3, 3, 3, 3, };
+
+/* SPI0 */
+static int mt7981_spi0_pins[] = { 16, 17, 18, 19, };
+static int mt7981_spi0_funcs[] = { 1, 1, 1, 1, };
+
+/* SPI0 */
+static int mt7981_spi0_wp_hold_pins[] = { 20, 21, };
+static int mt7981_spi0_wp_hold_funcs[] = { 1, 1, };
+
+/* SPI1 */
+static int mt7981_spi1_1_pins[] = { 22, 23, 24, 25, };
+static int mt7981_spi1_1_funcs[] = { 1, 1, 1, 1, };
+
+/* SPI2 */
+static int mt7981_spi2_pins[] = { 26, 27, 28, 29, };
+static int mt7981_spi2_funcs[] = { 1, 1, 1, 1, };
+
+/* SPI2 */
+static int mt7981_spi2_wp_hold_pins[] = { 30, 31, };
+static int mt7981_spi2_wp_hold_funcs[] = { 1, 1, };
+
+/* UART1 */
+static int mt7981_uart1_0_pins[] = { 16, 17, 18, 19, };
+static int mt7981_uart1_0_funcs[] = { 4, 4, 4, 4, };
+
+static int mt7981_uart1_1_pins[] = { 26, 27, 28, 29, };
+static int mt7981_uart1_1_funcs[] = { 2, 2, 2, 2, };
+
+/* UART2 */
+static int mt7981_uart2_1_pins[] = { 22, 23, 24, 25, };
+static int mt7981_uart2_1_funcs[] = { 3, 3, 3, 3, };
+
+/* UART0 */
+static int mt7981_uart0_pins[] = { 32, 33, };
+static int mt7981_uart0_funcs[] = { 1, 1, };
+
+/* PCIE_CLK_REQ */
+static int mt7981_pcie_clk_pins[] = { 34, };
+static int mt7981_pcie_clk_funcs[] = { 2, };
+
+/* PCIE_WAKE_N */
+static int mt7981_pcie_wake_pins[] = { 35, };
+static int mt7981_pcie_wake_funcs[] = { 2, };
+
+/* MDC_MDIO */
+static int mt7981_smi_mdc_mdio_pins[] = { 36, 37, };
+static int mt7981_smi_mdc_mdio_funcs[] = { 1, 1, };
+
+static int mt7981_gbe_ext_mdc_mdio_pins[] = { 36, 37, };
+static int mt7981_gbe_ext_mdc_mdio_funcs[] = { 3, 3, };
+
+/* WF0_MODE1 */
+static int mt7981_wf0_mode1_pins[] = { 40, 41, 42, 43, 44, 45, 46, 47, 48,
 49,
+				       50, 51, 52, 53, 54, 55, 56 };
+static int mt7981_wf0_mode1_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 1,
+					1, 1, 1, 1 };
+
+/* WF0_MODE3 */
+static int mt7981_wf0_mode3_pins[] = { 45, 46, 47, 48, 49, 51 };
+static int mt7981_wf0_mode3_funcs[] = { 2, 2, 2, 2, 2, 2 };
+
+/* WF2G_LED */
+static int mt7981_wf2g_led0_pins[] = { 30, };
+static int mt7981_wf2g_led0_funcs[] = { 2, };
+
+static int mt7981_wf2g_led1_pins[] = { 34, };
+static int mt7981_wf2g_led1_funcs[] = { 1, };
+
+/* WF5G_LED */
+static int mt7981_wf5g_led0_pins[] = { 31, };
+static int mt7981_wf5g_led0_funcs[] = { 2, };
+
+static int mt7981_wf5g_led1_pins[] = { 35, };
+static int mt7981_wf5g_led1_funcs[] = { 1, };
+
+/* MT7531_INT */
+static int mt7981_mt7531_int_pins[] = { 38, };
+static int mt7981_mt7531_int_funcs[] = { 1, };
+
+/* ANT_SEL */
+static int mt7981_ant_sel_pins[] = { 14, 15, 16, 17, 18, 19, 20, 21, 22,
 23, 24, 25, 34, 35 };
+static int mt7981_ant_sel_funcs[] = { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 };
+
+static const struct mtk_group_desc mt7981_groups[] = {
+	/* @GPIO(0,1): WA_AICE(2) */
+	PINCTRL_PIN_GROUP("wa_aice1", mt7981_wa_aice1),
+	/* @GPIO(0,1): WA_AICE(3) */
+	PINCTRL_PIN_GROUP("wa_aice2", mt7981_wa_aice2),
+	/* @GPIO(0,1): WM_UART(5) */
+	PINCTRL_PIN_GROUP("wm_uart_0", mt7981_wm_uart_0),
+	/* @GPIO(0,1,4,5): DFD(6) */
+	PINCTRL_PIN_GROUP("dfd", mt7981_dfd),
+	/* @GPIO(2): SYS_WATCHDOG(1) */
+	PINCTRL_PIN_GROUP("watchdog", mt7981_watchdog),
+	/* @GPIO(3): PCIE_PERESET_N(1) */
+	PINCTRL_PIN_GROUP("pcie_pereset", mt7981_pcie_pereset),
+	/* @GPIO(4,8) JTAG(1) */
+	PINCTRL_PIN_GROUP("jtag", mt7981_jtag),
+	/* @GPIO(4,8) WM_JTAG(2) */
+	PINCTRL_PIN_GROUP("wm_jtag_0", mt7981_wm_jtag_0),
+	/* @GPIO(9,13) WO0_JTAG(1) */
+	PINCTRL_PIN_GROUP("wo0_jtag_0", mt7981_wo0_jtag_0),
+	/* @GPIO(4,7) WM_JTAG(3) */
+	PINCTRL_PIN_GROUP("uart2_0", mt7981_uart2_0),
+	/* @GPIO(8) GBE_LED0(3) */
+	PINCTRL_PIN_GROUP("gbe_led0", mt7981_gbe_led0),
+	/* @GPIO(4,6) PTA_EXT(4) */
+	PINCTRL_PIN_GROUP("pta_ext_0", mt7981_pta_ext_0),
+	/* @GPIO(7) PWM2(4) */
+	PINCTRL_PIN_GROUP("pwm2", mt7981_pwm2),
+	/* @GPIO(8) NET_WO0_UART_TXD(4) */
+	PINCTRL_PIN_GROUP("net_wo0_uart_txd_0", mt7981_net_wo0_uart_txd_0),
+	/* @GPIO(4,7) SPI1(5) */
+	PINCTRL_PIN_GROUP("spi1_0", mt7981_spi1_0),
+	/* @GPIO(6,7) I2C(5) */
+	PINCTRL_PIN_GROUP("i2c0_0", mt7981_i2c0_0),
+	/* @GPIO(8): DFD_NTRST(6) */
+	PINCTRL_PIN_GROUP("dfd_ntrst", mt7981_dfd_ntrst),
+	/* @GPIO(9,10): WM_AICE(2) */
+	PINCTRL_PIN_GROUP("wm_aice1", mt7981_wm_aice1),
+	/* @GPIO(13): PWM0(2) */
+	PINCTRL_PIN_GROUP("pwm0_0", mt7981_pwm0_0),
+	/* @GPIO(15): PWM0(1) */
+	PINCTRL_PIN_GROUP("pwm0_1", mt7981_pwm0_1),
+	/* @GPIO(14): PWM1(2) */
+	PINCTRL_PIN_GROUP("pwm1_0", mt7981_pwm1_0),
+	/* @GPIO(15): PWM1(3) */
+	PINCTRL_PIN_GROUP("pwm1_1", mt7981_pwm1_1),
+	/* @GPIO(14) NET_WO0_UART_TXD(3) */
+	PINCTRL_PIN_GROUP("net_wo0_uart_txd_1", mt7981_net_wo0_uart_txd_1),
+	/* @GPIO(15) NET_WO0_UART_TXD(4) */
+	PINCTRL_PIN_GROUP("net_wo0_uart_txd_2", mt7981_net_wo0_uart_txd_2),
+	/* @GPIO(13) GBE_LED0(3) */
+	PINCTRL_PIN_GROUP("gbe_led1", mt7981_gbe_led1),
+	/* @GPIO(9,13) PCM(4) */
+	PINCTRL_PIN_GROUP("pcm", mt7981_pcm),
+	/* @GPIO(13): SYS_WATCHDOG1(5) */
+	PINCTRL_PIN_GROUP("watchdog1", mt7981_watchdog1),
+	/* @GPIO(9,13) UDI(4) */
+	PINCTRL_PIN_GROUP("udi", mt7981_udi),
+	/* @GPIO(14) DRV_VBUS(1) */
+	PINCTRL_PIN_GROUP("drv_vbus", mt7981_drv_vbus),
+	/* @GPIO(15,25): EMMC(2) */
+	PINCTRL_PIN_GROUP("emmc_45", mt7981_emmc_45),
+	/* @GPIO(16,21): SNFI(3) */
+	PINCTRL_PIN_GROUP("snfi", mt7981_snfi),
+	/* @GPIO(16,19): SPI0(1) */
+	PINCTRL_PIN_GROUP("spi0", mt7981_spi0),
+	/* @GPIO(20,21): SPI0(1) */
+	PINCTRL_PIN_GROUP("spi0_wp_hold", mt7981_spi0_wp_hold),
+	/* @GPIO(22,25) SPI1(1) */
+	PINCTRL_PIN_GROUP("spi1_1", mt7981_spi1_1),
+	/* @GPIO(26,29): SPI2(1) */
+	PINCTRL_PIN_GROUP("spi2", mt7981_spi2),
+	/* @GPIO(30,31): SPI2(1) */
+	PINCTRL_PIN_GROUP("spi2_wp_hold", mt7981_spi2_wp_hold),
+	/* @GPIO(16,19): UART1(4) */
+	PINCTRL_PIN_GROUP("uart1_0", mt7981_uart1_0),
+	/* @GPIO(26,29): UART1(2) */
+	PINCTRL_PIN_GROUP("uart1_1", mt7981_uart1_1),
+	/* @GPIO(22,25): UART2(3) */
+	PINCTRL_PIN_GROUP("uart2_0", mt7981_uart2_1),
+	/* @GPIO(22,24) PTA_EXT(4) */
+	PINCTRL_PIN_GROUP("pta_ext_1", mt7981_pta_ext_1),
+	/* @GPIO(20,21): WM_UART(4) */
+	PINCTRL_PIN_GROUP("wm_aurt_1", mt7981_wm_uart_1),
+	/* @GPIO(30,31): WM_UART(3) */
+	PINCTRL_PIN_GROUP("wm_aurt_2", mt7981_wm_uart_2),
+	/* @GPIO(20,24) WM_JTAG(5) */
+	PINCTRL_PIN_GROUP("wm_jtag_1", mt7981_wm_jtag_1),
+	/* @GPIO(25,29) WO0_JTAG(5) */
+	PINCTRL_PIN_GROUP("wo0_jtag_1", mt7981_wo0_jtag_1),
+	/* @GPIO(28,29): WA_AICE(3) */
+	PINCTRL_PIN_GROUP("wa_aice3", mt7981_wa_aice3),
+	/* @GPIO(30,31): WM_AICE(5) */
+	PINCTRL_PIN_GROUP("wm_aice2", mt7981_wm_aice2),
+	/* @GPIO(30,31): I2C(4) */
+	PINCTRL_PIN_GROUP("i2c0_1", mt7981_i2c0_1),
+	/* @GPIO(30,31): I2C(6) */
+	PINCTRL_PIN_GROUP("u2_phy_i2c", mt7981_u2_phy_i2c),
+	/* @GPIO(32,33): I2C(1) */
+	PINCTRL_PIN_GROUP("uart0", mt7981_uart0),
+	/* @GPIO(32,33): I2C(2) */
+	PINCTRL_PIN_GROUP("sgmii1_phy_i2c", mt7981_sgmii1_phy_i2c),
+	/* @GPIO(32,33): I2C(3) */
+	PINCTRL_PIN_GROUP("u3_phy_i2c", mt7981_u3_phy_i2c),
+	/* @GPIO(32,33): I2C(5) */
+	PINCTRL_PIN_GROUP("sgmii0_phy_i2c", mt7981_sgmii0_phy_i2c),
+	/* @GPIO(34): PCIE_CLK_REQ(2) */
+	PINCTRL_PIN_GROUP("pcie_clk", mt7981_pcie_clk),
+	/* @GPIO(35): PCIE_WAKE_N(2) */
+	PINCTRL_PIN_GROUP("pcie_wake", mt7981_pcie_wake),
+	/* @GPIO(36,37): I2C(2) */
+	PINCTRL_PIN_GROUP("i2c0_2", mt7981_i2c0_2),
+	/* @GPIO(36,37): MDC_MDIO(1) */
+	PINCTRL_PIN_GROUP("smi_mdc_mdio", mt7981_smi_mdc_mdio),
+	/* @GPIO(36,37): MDC_MDIO(3) */
+	PINCTRL_PIN_GROUP("gbe_ext_mdc_mdio", mt7981_gbe_ext_mdc_mdio),
+	/* @GPIO(40,56): WF0_MODE1(1) */
+	PINCTRL_PIN_GROUP("wf0_mode1", mt7981_wf0_mode1),
+	/* @GPIO(45,46,47,48,49,51): WF0_MODE3(3) */
+	PINCTRL_PIN_GROUP("wf0_mode3", mt7981_wf0_mode3),
+	/* @GPIO(30): WF2G_LED(2) */
+	PINCTRL_PIN_GROUP("wf2g_led0", mt7981_wf2g_led0),
+	/* @GPIO(34): WF2G_LED(1) */
+	PINCTRL_PIN_GROUP("wf2g_led1", mt7981_wf2g_led1),
+	/* @GPIO(31): WF5G_LED(2) */
+	PINCTRL_PIN_GROUP("wf5g_led0", mt7981_wf5g_led0),
+	/* @GPIO(35): WF5G_LED(1) */
+	PINCTRL_PIN_GROUP("wf5g_led1", mt7981_wf5g_led1),
+	/* @GPIO(38): MT7531_INT(1) */
+	PINCTRL_PIN_GROUP("mt7531_int", mt7981_mt7531_int),
+	/* @GPIO(14,15,26,17,18,19,20,21,22,23,24,25,34,35): ANT_SEL(1) */
+	PINCTRL_PIN_GROUP("ant_sel", mt7981_ant_sel),
+};
+
+static const struct mtk_io_type_desc mt7981_io_type_desc[] = {
+	[IO_TYPE_GRP0] = {
+		.name = "18OD33",
+		.bias_set = mtk_pinconf_bias_set_pupd_r1_r0,
+		.drive_set = mtk_pinconf_drive_set_v1,
+		.input_enable = mtk_pinconf_input_enable_v1,
+	},
+	[IO_TYPE_GRP1] = {
+		.name = "18A01",
+		.bias_set = mtk_pinconf_bias_set_pu_pd,
+		.drive_set = mtk_pinconf_drive_set_v1,
+		.input_enable = mtk_pinconf_input_enable_v1,
+	},
+};
+
+/* Joint those groups owning the same capability in user point of view
 which
+ * allows that people tend to use through the device tree.
+ */
+static const char *const mt7981_wa_aice_groups[] = { "wa_aice1",
 "wa_aice2",
+	"wm_aice1_1", "wa_aice3", "wm_aice1_2", };
+static const char *const mt7981_uart_groups[] = { "wm_uart_0", "uart2_0",
+	"net_wo0_uart_txd_0", "net_wo0_uart_txd_1", "net_wo0_uart_txd_2",
+	"uart1_0", "uart1_1", "uart2_0", "wm_aurt_1", "wm_aurt_2", "uart0", };
+static const char *const mt7981_dfd_groups[] = { "dfd", "dfd_ntrst", };
+static const char *const mt7981_wdt_groups[] = { "watchdog", "watchdog1",
 };
+static const char *const mt7981_pcie_groups[] = { "pcie_pereset",
 "pcie_clk",
+	"pcie_wake", };
+static const char *const mt7981_jtag_groups[] = { "jtag", "wm_jtag_0",
+	"wo0_jtag_0", "wo0_jtag_1", "wm_jtag_1", };
+static const char *const mt7981_led_groups[] = { "gbe_led0", "gbe_led1",
+	"wf2g_led0", "wf2g_led1", "wf5g_led0", "wf5g_led1", };
+static const char *const mt7981_pta_groups[] = { "pta_ext_0", "pta_ext_1",
 };
+static const char *const mt7981_pwm_groups[] = { "pwm2", "pwm0_0",
 "pwm0_1",
+	"pwm1_0", "pwm1_1", };
+static const char *const mt7981_spi_groups[] = { "spi1_0", "spi0",
+	"spi0_wp_hold", "spi1_1", "spi2", "spi2_wp_hold", };
+static const char *const mt7981_i2c_groups[] = { "i2c0_0", "i2c0_1",
+	"u2_phy_i2c", "sgmii1_phy_i2c", "u3_phy_i2c", "sgmii0_phy_i2c",
+	"i2c0_2", };
+static const char *const mt7981_pcm_groups[] = { "pcm", };
+static const char *const mt7981_udi_groups[] = { "udi", };
+static const char *const mt7981_usb_groups[] = { "drv_vbus", };
+static const char *const mt7981_flash_groups[] = { "emmc_45", "snfi", };
+static const char *const mt7981_ethernet_groups[] = { "smi_mdc_mdio",
+	"gbe_ext_mdc_mdio", "wf0_mode1", "wf0_mode3", "mt7531_int", };
+static const char *const mt7981_ant_groups[] = { "ant_sel", };
+
+static const struct mtk_function_desc mt7981_functions[] = {
+	{"wa_aice", mt7981_wa_aice_groups, ARRAY_SIZE(mt7981_wa_aice_groups)},
+	{"dfd", mt7981_dfd_groups, ARRAY_SIZE(mt7981_dfd_groups)},
+	{"jtag", mt7981_jtag_groups, ARRAY_SIZE(mt7981_jtag_groups)},
+	{"pta", mt7981_pta_groups, ARRAY_SIZE(mt7981_pta_groups)},
+	{"pcm", mt7981_pcm_groups, ARRAY_SIZE(mt7981_pcm_groups)},
+	{"udi", mt7981_udi_groups, ARRAY_SIZE(mt7981_udi_groups)},
+	{"usb", mt7981_usb_groups, ARRAY_SIZE(mt7981_usb_groups)},
+	{"ant", mt7981_ant_groups, ARRAY_SIZE(mt7981_ant_groups)},
+	{"eth", mt7981_ethernet_groups, ARRAY_SIZE(mt7981_ethernet_groups)},
+	{"i2c", mt7981_i2c_groups, ARRAY_SIZE(mt7981_i2c_groups)},
+	{"led", mt7981_led_groups, ARRAY_SIZE(mt7981_led_groups)},
+	{"pwm", mt7981_pwm_groups, ARRAY_SIZE(mt7981_pwm_groups)},
+	{"spi", mt7981_spi_groups, ARRAY_SIZE(mt7981_spi_groups)},
+	{"uart", mt7981_uart_groups, ARRAY_SIZE(mt7981_uart_groups)},
+	{"watchdog", mt7981_wdt_groups, ARRAY_SIZE(mt7981_wdt_groups)},
+	{"flash", mt7981_flash_groups, ARRAY_SIZE(mt7981_flash_groups)},
+	{"pcie", mt7981_pcie_groups, ARRAY_SIZE(mt7981_pcie_groups)},
+};
+
+static const char *const mt7981_pinctrl_register_base_names[] = {
+	"gpio_base", "iocfg_rt_base", "iocfg_rm_base", "iocfg_rb_base",
+	"iocfg_lb_base", "iocfg_bl_base", "iocfg_tm_base", "iocfg_tl_base",
+};
+
+static struct mtk_pinctrl_soc mt7981_data = {
+	.name = "mt7981_pinctrl",
+	.reg_cal = mt7981_reg_cals,
+	.pins = mt7981_pins,
+	.npins = ARRAY_SIZE(mt7981_pins),
+	.grps = mt7981_groups,
+	.ngrps = ARRAY_SIZE(mt7981_groups),
+	.funcs = mt7981_functions,
+	.nfuncs = ARRAY_SIZE(mt7981_functions),
+	.io_type = mt7981_io_type_desc,
+	.ntype = ARRAY_SIZE(mt7981_io_type_desc),
+	.gpio_mode = 0,
+	.base_names = mt7981_pinctrl_register_base_names,
+	.nbase_names = ARRAY_SIZE(mt7981_pinctrl_register_base_names),
+	.base_calc = 1,
+};
+
+static int mtk_pinctrl_mt7981_probe(struct udevice *dev)
+{
+	return mtk_pinctrl_common_probe(dev, &mt7981_data);
+}
+
+static const struct udevice_id mt7981_pctrl_match[] = {
+	{.compatible = "mediatek,mt7981-pinctrl"},
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(mt7981_pinctrl) = {
+	.name = "mt7981_pinctrl",
+	.id = UCLASS_PINCTRL,
+	.of_match = mt7981_pctrl_match,
+	.ops = &mtk_pinctrl_ops,
+	.probe = mtk_pinctrl_mt7981_probe,
+	.priv_auto = sizeof(struct mtk_pinctrl_priv),
+};
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 21/31] pinctrl: mediatek: add pinctrl driver for MT7986 SoC
  2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
                   ` (19 preceding siblings ...)
  2022-08-04  3:36 ` [PATCH 20/31] pinctrl: mediatek: add pinctrl driver for MT7981 SoC Weijie Gao
@ 2022-08-04  3:36 ` Weijie Gao
  2022-08-04 13:57   ` Simon Glass
  2022-08-04  3:36 ` [PATCH 22/31] clk: mediatek: add CLK_BYPASS_XTAL flag to allow bypassing searching clock parent of xtal clock Weijie Gao
                   ` (9 subsequent siblings)
  30 siblings, 1 reply; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:36 UTC (permalink / raw)
  To: u-boot; +Cc: GSS_MTK_Uboot_upstream, Weijie Gao

This patch adds pinctrl and gpio support for MT7986 SoC

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 drivers/pinctrl/mediatek/Kconfig          |   4 +
 drivers/pinctrl/mediatek/Makefile         |   1 +
 drivers/pinctrl/mediatek/pinctrl-mt7986.c | 775 ++++++++++++++++++++++
 3 files changed, 780 insertions(+)
 create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt7986.c

diff --git a/drivers/pinctrl/mediatek/Kconfig
 b/drivers/pinctrl/mediatek/Kconfig
index aceec9277d..27e8998e59 100644
--- a/drivers/pinctrl/mediatek/Kconfig
+++ b/drivers/pinctrl/mediatek/Kconfig
@@ -20,6 +20,10 @@ config PINCTRL_MT7981
 	bool "MT7981 SoC pinctrl driver"
 	select PINCTRL_MTK
 
+config PINCTRL_MT7986
+	bool "MT7986 SoC pinctrl driver"
+	select PINCTRL_MTK
+
 config PINCTRL_MT8512
 	bool "MT8512 SoC pinctrl driver"
 	select PINCTRL_MTK
diff --git a/drivers/pinctrl/mediatek/Makefile
 b/drivers/pinctrl/mediatek/Makefile
index 1879d7ae2a..6e733759f5 100644
--- a/drivers/pinctrl/mediatek/Makefile
+++ b/drivers/pinctrl/mediatek/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_PINCTRL_MT7622) += pinctrl-mt7622.o
 obj-$(CONFIG_PINCTRL_MT7623) += pinctrl-mt7623.o
 obj-$(CONFIG_PINCTRL_MT7629) += pinctrl-mt7629.o
 obj-$(CONFIG_PINCTRL_MT7981) += pinctrl-mt7981.o
+obj-$(CONFIG_PINCTRL_MT7986) += pinctrl-mt7986.o
 obj-$(CONFIG_PINCTRL_MT8512) += pinctrl-mt8512.o
 obj-$(CONFIG_PINCTRL_MT8516) += pinctrl-mt8516.o
 obj-$(CONFIG_PINCTRL_MT8518) += pinctrl-mt8518.o
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7986.c
 b/drivers/pinctrl/mediatek/pinctrl-mt7986.c
new file mode 100644
index 0000000000..449e5adcd9
--- /dev/null
+++ b/drivers/pinctrl/mediatek/pinctrl-mt7986.c
@@ -0,0 +1,775 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The MT7986 driver based on Linux generic pinctrl binding.
+ *
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+#include <dm.h>
+#include "pinctrl-mtk-common.h"
+
+#define MT7986_TYPE0_PIN(_number, _name)	\
+	MTK_TYPED_PIN(_number, _name, DRV_GRP4, IO_TYPE_GRP0)
+
+#define MT7986_TYPE1_PIN(_number, _name)	\
+	MTK_TYPED_PIN(_number, _name, DRV_GRP4, IO_TYPE_GRP1)
+
+#define PIN_FIELD_GPIO(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits)
	\
+	PIN_FIELD_BASE_CALC(_s_pin, _e_pin, GPIO_BASE, _s_addr, _x_addrs,	\
+			    _s_bit, _x_bits, 32, 0)
+
+#define PIN_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,
	\
+		       _x_bits)							\
+	PIN_FIELD_BASE_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,	\
+	_x_bits, 32, 0)
+
+/**
+ * enum - Locking variants of the iocfg bases
+ *
+ * MT7986 have multiple bases to program pin configuration listed as the
 below:
+ * iocfg_rt:0x11c30000, iocfg_rb:0x11c40000, iocfg_lt:0x11e20000,
+ * iocfg_lb:0x11e30000, iocfg_tr:0x11f00000, iocfg_tl:0x11f10000,
+ * _i_based could be used to indicate what base the pin should be mapped
 into.
+ *
+ * Each iocfg register base control different group of pads on the SoC
+ *
+ *
+ *  chip carrier
+ *
+ *      A  B  C  D  E  F  G  H
+ *    +------------------------+
+ *  8 | o  o  o  o  o  o  o  o |
+ *  7 | o  o  o  o  o  o  o  o |
+ *  6 | o  o  o  o  o  o  o  o |
+ *  5 | o  o  o  o  o  o  o  o |
+ *  4 | o  o  o  o  o  o  o  o |
+ *  3 | o  o  o  o  o  o  o  o |
+ *  2 | o  o  o  o  o  o  o  o |
+ *  1 | o  o  o  o  o  o  o  o |
+ *    +------------------------+
+ *
+ *  inside Chip carrier
+ *
+ *      A  B  C  D  E  F  G  H
+ *    +------------------------+
+ *  8 |                        |
+ *  7 |        TL  TR          |
+ *  6 |      +---------+       |
+ *  5 |   LT |         | RT    |
+ *  4 |      |         |       |
+ *  3 |   LB |         | RB    |
+ *  2 |      +---------+       |
+ *  1 |                        |
+ *    +------------------------+
+ *
+ */
+
+enum {
+	GPIO_BASE,
+	IOCFG_RT_BASE,
+	IOCFG_RB_BASE,
+	IOCFG_LT_BASE,
+	IOCFG_LB_BASE,
+	IOCFG_TR_BASE,
+	IOCFG_TL_BASE,
+};
+
+static const char *const mt7986_pinctrl_register_base_names[] = {
+	"gpio", "iocfg_rt", "iocfg_rb", "iocfg_lt", "iocfg_lb", "iocfg_tr",
+	"iocfg_tl",
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_mode_range[] = {
+	PIN_FIELD_GPIO(0, 100, 0x300, 0x10, 0, 4),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_dir_range[] = {
+	PIN_FIELD_GPIO(0, 100, 0x0, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_di_range[] = {
+	PIN_FIELD_GPIO(0, 100, 0x200, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_do_range[] = {
+	PIN_FIELD_GPIO(0, 100, 0x100, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_ies_range[] = {
+	PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x40, 0x10, 17, 1),
+	PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x20, 0x10, 10, 1),
+	PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x20, 0x10, 0, 1),
+	PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x20, 0x10, 0, 1),
+	PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0x40, 0x10, 8, 1),
+	PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x40, 0x10, 2, 1),
+	PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x30, 0x10, 12, 1),
+	PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x30, 0x10, 18, 1),
+	PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x30, 0x10, 17, 1),
+	PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x30, 0x10, 15, 1),
+	PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0x30, 0x10, 19, 1),
+	PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x30, 0x10, 23, 1),
+	PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x30, 0x10, 22, 1),
+	PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x30, 0x10, 21, 1),
+	PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x20, 0x10, 4, 1),
+	PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x20, 0x10, 8, 1),
+	PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x20, 0x10, 7, 1),
+	PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x20, 0x10, 5, 1),
+	PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x20, 0x10, 9, 1),
+	PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x40, 0x10, 18, 1),
+	PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x40, 0x10, 12, 1),
+	PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x40, 0x10, 22, 1),
+	PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x40, 0x10, 20, 1),
+	PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x40, 0x10, 26, 1),
+	PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x40, 0x10, 24, 1),
+	PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x30, 0x10, 2, 1),
+	PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x30, 0x10, 1, 1),
+	PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x30, 0x10, 0, 1),
+	PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x30, 0x10, 10, 1),
+	PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x40, 0x10, 15, 1),
+	PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x40, 0x10, 14, 1),
+	PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x40, 0x10, 13, 1),
+	PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x40, 0x10, 16, 1),
+	PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x20, 0x10, 2, 1),
+	PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x30, 0x10, 1, 1),
+	PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x30, 0x10, 0, 1),
+	PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x30, 0x10, 16, 1),
+	PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x30, 0x10, 14, 1),
+	PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x30, 0x10, 4, 1),
+	PIN_FIELD_BASE(75, 77, IOCFG_TR_BASE, 0x30, 0x10, 6, 1),
+	PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x30, 0x10, 2, 1),
+	PIN_FIELD_BASE(80, 84, IOCFG_TR_BASE, 0x30, 0x10, 9, 1),
+	PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x30, 0x10, 5, 1),
+	PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x30, 0x10, 1, 1),
+	PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x30, 0x10, 0, 1),
+	PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x30, 0x10, 14, 1),
+	PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x30, 0x10, 12, 1),
+	PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x30, 0x10, 4, 1),
+	PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x30, 0x10, 2, 1),
+	PIN_FIELD_BASE(97, 100, IOCFG_TL_BASE, 0x30, 0x10, 8, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_smt_range[] = {
+	PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0xf0, 0x10, 17, 1),
+	PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x90, 0x10, 10, 1),
+	PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x90, 0x10, 0, 1),
+	PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0xf0, 0x10, 0, 1),
+	PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x90, 0x10, 0, 1),
+	PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0xf0, 0x10, 8, 1),
+	PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0xf0, 0x10, 2, 1),
+	PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0xc0, 0x10, 12, 1),
+	PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0xc0, 0x10, 18, 1),
+	PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0xc0, 0x10, 17, 1),
+	PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0xc0, 0x10, 15, 1),
+	PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0xc0, 0x10, 19, 1),
+	PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0xc0, 0x10, 23, 1),
+	PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0xc0, 0x10, 22, 1),
+	PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0xc0, 0x10, 21, 1),
+	PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x90, 0x10, 4, 1),
+	PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x90, 0x10, 8, 1),
+	PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x90, 0x10, 7, 1),
+	PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x90, 0x10, 5, 1),
+	PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x90, 0x10, 9, 1),
+	PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0xf0, 0x10, 18, 1),
+	PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0xf0, 0x10, 12, 1),
+	PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0xf0, 0x10, 22, 1),
+	PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0xf0, 0x10, 20, 1),
+	PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0xf0, 0x10, 26, 1),
+	PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0xf0, 0x10, 24, 1),
+	PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0xc0, 0x10, 2, 1),
+	PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0xc0, 0x10, 1, 1),
+	PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0xc0, 0x10, 0, 1),
+	PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0xc0, 0x10, 10, 1),
+	PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0xf0, 0x10, 15, 1),
+	PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0xf0, 0x10, 14, 1),
+	PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0xf0, 0x10, 13, 1),
+	PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0xf0, 0x10, 16, 1),
+	PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x90, 0x10, 2, 1),
+	PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x80, 0x10, 1, 1),
+	PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x80, 0x10, 0, 1),
+	PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x80, 0x10, 16, 1),
+	PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x80, 0x10, 14, 1),
+	PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x80, 0x10, 4, 1),
+	PIN_FIELD_BASE(75, 77, IOCFG_TR_BASE, 0x80, 0x10, 6, 1),
+	PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x80, 0x10, 2, 1),
+	PIN_FIELD_BASE(80, 84, IOCFG_TR_BASE, 0x80, 0x10, 9, 1),
+	PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x80, 0x10, 5, 1),
+	PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x70, 0x10, 1, 1),
+	PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x70, 0x10, 0, 1),
+	PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x70, 0x10, 14, 1),
+	PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x70, 0x10, 12, 1),
+	PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x70, 0x10, 4, 1),
+	PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x70, 0x10, 2, 1),
+	PIN_FIELD_BASE(97, 100, IOCFG_TL_BASE, 0x70, 0x10, 8, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_pu_range[] = {
+	PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x50, 0x10, 1, 1),
+	PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x50, 0x10, 0, 1),
+	PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x50, 0x10, 16, 1),
+	PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x50, 0x10, 14, 1),
+	PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x50, 0x10, 4, 1),
+	PIN_FIELD_BASE(75, 77, IOCFG_TR_BASE, 0x50, 0x10, 6, 1),
+	PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x50, 0x10, 2, 1),
+	PIN_FIELD_BASE(80, 84, IOCFG_TR_BASE, 0x50, 0x10, 9, 1),
+	PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x50, 0x10, 5, 1),
+	PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x50, 0x10, 1, 1),
+	PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x50, 0x10, 0, 1),
+	PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x50, 0x10, 14, 1),
+	PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x50, 0x10, 12, 1),
+	PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x50, 0x10, 4, 1),
+	PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x50, 0x10, 2, 1),
+	PIN_FIELD_BASE(97, 100, IOCFG_TL_BASE, 0x50, 0x10, 8, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_pd_range[] = {
+	PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x40, 0x10, 1, 1),
+	PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x40, 0x10, 16, 1),
+	PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x40, 0x10, 14, 1),
+	PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x40, 0x10, 4, 1),
+	PIN_FIELD_BASE(75, 77, IOCFG_TR_BASE, 0x40, 0x10, 6, 1),
+	PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x40, 0x10, 2, 1),
+	PIN_FIELD_BASE(80, 84, IOCFG_TR_BASE, 0x40, 0x10, 9, 1),
+	PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x40, 0x10, 5, 1),
+	PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x40, 0x10, 1, 1),
+	PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x40, 0x10, 14, 1),
+	PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x40, 0x10, 12, 1),
+	PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x40, 0x10, 4, 1),
+	PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x40, 0x10, 2, 1),
+	PIN_FIELD_BASE(97, 100, IOCFG_TL_BASE, 0x40, 0x10, 8, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_drv_range[] = {
+	PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x10, 0x10, 21, 3),
+	PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x10, 0x10, 0, 3),
+	PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x00, 0x10, 0, 1),
+	PIN_FIELD_BASE(5, 5, IOCFG_RB_BASE, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(6, 6, IOCFG_RB_BASE, 0x00, 0x10, 21, 3),
+	PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(11, 12, IOCFG_RB_BASE, 0x00, 0x10, 24, 3),
+	PIN_FIELD_BASE(13, 14, IOCFG_RB_BASE, 0x10, 0x10, 0, 3),
+	PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x00, 0x10, 3, 3),
+	PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x10, 0x10, 6, 3),
+	PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x10, 0x10, 24, 3),
+	PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x10, 0x10, 21, 3),
+	PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x10, 0x10, 15, 3),
+	PIN_FIELD_BASE(28, 28, IOCFG_RT_BASE, 0x10, 0x10, 27, 3),
+	PIN_FIELD_BASE(29, 29, IOCFG_RT_BASE, 0x20, 0x10, 0, 3),
+	PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x20, 0x10, 9, 3),
+	PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x20, 0x10, 6, 3),
+	PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x20, 0x10, 3, 3),
+	PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x00, 0x10, 12, 3),
+	PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x00, 0x10, 24, 3),
+	PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x00, 0x10, 21, 3),
+	PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x00, 0x10, 15, 3),
+	PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x00, 0x10, 27, 3),
+	PIN_FIELD_BASE(39, 39, IOCFG_RB_BASE, 0x10, 0x10, 27, 3),
+	PIN_FIELD_BASE(40, 40, IOCFG_RB_BASE, 0x20, 0x10, 0, 3),
+	PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x10, 0x10, 6, 3),
+	PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x20, 0x10, 9, 3),
+	PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x20, 0x10, 3, 3),
+	PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x20, 0x10, 21, 3),
+	PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x20, 0x10, 15, 3),
+	PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x00, 0x10, 6, 3),
+	PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x00, 0x10, 3, 3),
+	PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x10, 0x10, 0, 3),
+	PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x10, 0x10, 15, 3),
+	PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x10, 0x10, 12, 3),
+	PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x10, 0x10, 9, 3),
+	PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x10, 0x10, 18, 3),
+	PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x00, 0x10, 2, 3),
+	PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x00, 0x10, 3, 3),
+	PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x10, 0x10, 18, 3),
+	PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x10, 0x10, 12, 3),
+	PIN_FIELD_BASE(74, 77, IOCFG_TR_BASE, 0x00, 0x10, 15, 3),
+	PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x00, 0x10, 6, 3),
+	PIN_FIELD_BASE(80, 80, IOCFG_TR_BASE, 0x00, 0x10, 27, 3),
+	PIN_FIELD_BASE(81, 84, IOCFG_TR_BASE, 0x10, 0x10, 0, 3),
+	PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x00, 0x10, 12, 3),
+	PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x00, 0x10, 3, 3),
+	PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x10, 0x10, 12, 3),
+	PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x10, 0x10, 6, 3),
+	PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x00, 0x10, 12, 3),
+	PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x00, 0x10, 6, 3),
+	PIN_FIELD_BASE(97, 98, IOCFG_TL_BASE, 0x00, 0x10, 24, 3),
+	PIN_FIELD_BASE(99, 100, IOCFG_TL_BASE, 0x10, 0x10, 2, 3),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_pupd_range[] = {
+	PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x60, 0x10, 17, 1),
+	PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x30, 0x10, 10, 1),
+	PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0x60, 0x10, 0, 1),
+	PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x30, 0x10, 0, 1),
+	PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0x60, 0x10, 8, 1),
+	PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x60, 0x10, 2, 1),
+	PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x40, 0x10, 12, 1),
+	PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x40, 0x10, 18, 1),
+	PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x40, 0x10, 17, 1),
+	PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x40, 0x10, 15, 1),
+	PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0x40, 0x10, 19, 1),
+	PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x40, 0x10, 23, 1),
+	PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x40, 0x10, 22, 1),
+	PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x40, 0x10, 21, 1),
+	PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x30, 0x10, 4, 1),
+	PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x30, 0x10, 8, 1),
+	PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x30, 0x10, 7, 1),
+	PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x30, 0x10, 5, 1),
+	PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x30, 0x10, 9, 1),
+	PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x60, 0x10, 18, 1),
+	PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x60, 0x10, 12, 1),
+	PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x60, 0x10, 23, 1),
+	PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x60, 0x10, 21, 1),
+	PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x60, 0x10, 27, 1),
+	PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x60, 0x10, 25, 1),
+	PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x40, 0x10, 2, 1),
+	PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x40, 0x10, 1, 1),
+	PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x40, 0x10, 10, 1),
+	PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x60, 0x10, 15, 1),
+	PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x60, 0x10, 14, 1),
+	PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x60, 0x10, 13, 1),
+	PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x60, 0x10, 16, 1),
+	PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x40, 0x10, 2, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_r0_range[] = {
+	PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x70, 0x10, 17, 1),
+	PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x40, 0x10, 10, 1),
+	PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x50, 0x10, 0, 1),
+	PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0x70, 0x10, 0, 1),
+	PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0x70, 0x10, 8, 1),
+	PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x70, 0x10, 2, 1),
+	PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x50, 0x10, 12, 1),
+	PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x50, 0x10, 18, 1),
+	PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x50, 0x10, 17, 1),
+	PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x50, 0x10, 15, 1),
+	PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0x50, 0x10, 19, 1),
+	PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x50, 0x10, 23, 1),
+	PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x50, 0x10, 22, 1),
+	PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x50, 0x10, 21, 1),
+	PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x40, 0x10, 4, 1),
+	PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x40, 0x10, 8, 1),
+	PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x40, 0x10, 7, 1),
+	PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x40, 0x10, 5, 1),
+	PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x40, 0x10, 9, 1),
+	PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x70, 0x10, 18, 1),
+	PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x70, 0x10, 12, 1),
+	PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x70, 0x10, 23, 1),
+	PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x70, 0x10, 21, 1),
+	PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x70, 0x10, 27, 1),
+	PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x70, 0x10, 25, 1),
+	PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x50, 0x10, 2, 1),
+	PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x50, 0x10, 1, 1),
+	PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x50, 0x10, 0, 1),
+	PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x50, 0x10, 10, 1),
+	PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x70, 0x10, 15, 1),
+	PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x70, 0x10, 14, 1),
+	PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x70, 0x10, 13, 1),
+	PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x70, 0x10, 16, 1),
+	PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x50, 0x10, 2, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_r1_range[] = {
+	PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x80, 0x10, 17, 1),
+	PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x50, 0x10, 10, 1),
+	PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x60, 0x10, 0, 1),
+	PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0x80, 0x10, 0, 1),
+	PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x50, 0x10, 0, 1),
+	PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0x80, 0x10, 8, 1),
+	PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x80, 0x10, 2, 1),
+	PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x60, 0x10, 12, 1),
+	PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x60, 0x10, 18, 1),
+	PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x60, 0x10, 17, 1),
+	PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x60, 0x10, 15, 1),
+	PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0x60, 0x10, 19, 1),
+	PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x60, 0x10, 23, 1),
+	PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x60, 0x10, 22, 1),
+	PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x60, 0x10, 21, 1),
+	PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x50, 0x10, 4, 1),
+	PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x50, 0x10, 8, 1),
+	PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x50, 0x10, 7, 1),
+	PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x50, 0x10, 5, 1),
+	PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x50, 0x10, 9, 1),
+	PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x80, 0x10, 18, 1),
+	PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x80, 0x10, 12, 1),
+	PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x80, 0x10, 23, 1),
+	PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x80, 0x10, 21, 1),
+	PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x80, 0x10, 27, 1),
+	PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x80, 0x10, 25, 1),
+	PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x60, 0x10, 2, 1),
+	PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x60, 0x10, 1, 1),
+	PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x60, 0x10, 0, 1),
+	PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x60, 0x10, 10, 1),
+	PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x80, 0x10, 15, 1),
+	PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x80, 0x10, 14, 1),
+	PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x80, 0x10, 13, 1),
+	PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x80, 0x10, 16, 1),
+	PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x60, 0x10, 2, 1),
+};
+
+static const struct mtk_pin_reg_calc mt7986_reg_cals[] = {
+	[PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7986_pin_mode_range),
+	[PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7986_pin_dir_range),
+	[PINCTRL_PIN_REG_DI] = MTK_RANGE(mt7986_pin_di_range),
+	[PINCTRL_PIN_REG_DO] = MTK_RANGE(mt7986_pin_do_range),
+	[PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt7986_pin_smt_range),
+	[PINCTRL_PIN_REG_IES] = MTK_RANGE(mt7986_pin_ies_range),
+	[PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt7986_pin_drv_range),
+	[PINCTRL_PIN_REG_PU] = MTK_RANGE(mt7986_pin_pu_range),
+	[PINCTRL_PIN_REG_PD] = MTK_RANGE(mt7986_pin_pd_range),
+	[PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt7986_pin_pupd_range),
+	[PINCTRL_PIN_REG_R0] = MTK_RANGE(mt7986_pin_r0_range),
+	[PINCTRL_PIN_REG_R1] = MTK_RANGE(mt7986_pin_r1_range),
+};
+
+static const struct mtk_pin_desc mt7986_pins[] = {
+	MT7986_TYPE0_PIN(0, "SYS_WATCHDOG"),
+	MT7986_TYPE0_PIN(1, "WF2G_LED"),
+	MT7986_TYPE0_PIN(2, "WF5G_LED"),
+	MT7986_TYPE0_PIN(3, "I2C_SCL"),
+	MT7986_TYPE0_PIN(4, "I2C_SDA"),
+	MT7986_TYPE0_PIN(5, "GPIO_0"),
+	MT7986_TYPE0_PIN(6, "GPIO_1"),
+	MT7986_TYPE0_PIN(7, "GPIO_2"),
+	MT7986_TYPE0_PIN(8, "GPIO_3"),
+	MT7986_TYPE0_PIN(9, "GPIO_4"),
+	MT7986_TYPE0_PIN(10, "GPIO_5"),
+	MT7986_TYPE0_PIN(11, "GPIO_6"),
+	MT7986_TYPE0_PIN(12, "GPIO_7"),
+	MT7986_TYPE0_PIN(13, "GPIO_8"),
+	MT7986_TYPE0_PIN(14, "GPIO_9"),
+	MT7986_TYPE0_PIN(15, "GPIO_10"),
+	MT7986_TYPE0_PIN(16, "GPIO_11"),
+	MT7986_TYPE0_PIN(17, "GPIO_12"),
+	MT7986_TYPE0_PIN(18, "GPIO_13"),
+	MT7986_TYPE0_PIN(19, "GPIO_14"),
+	MT7986_TYPE0_PIN(20, "GPIO_15"),
+	MT7986_TYPE0_PIN(21, "PWM0"),
+	MT7986_TYPE0_PIN(22, "PWM1"),
+	MT7986_TYPE0_PIN(23, "SPI0_CLK"),
+	MT7986_TYPE0_PIN(24, "SPI0_MOSI"),
+	MT7986_TYPE0_PIN(25, "SPI0_MISO"),
+	MT7986_TYPE0_PIN(26, "SPI0_CS"),
+	MT7986_TYPE0_PIN(27, "SPI0_HOLD"),
+	MT7986_TYPE0_PIN(28, "SPI0_WP"),
+	MT7986_TYPE0_PIN(29, "SPI1_CLK"),
+	MT7986_TYPE0_PIN(30, "SPI1_MOSI"),
+	MT7986_TYPE0_PIN(31, "SPI1_MISO"),
+	MT7986_TYPE0_PIN(32, "SPI1_CS"),
+	MT7986_TYPE0_PIN(33, "SPI2_CLK"),
+	MT7986_TYPE0_PIN(34, "SPI2_MOSI"),
+	MT7986_TYPE0_PIN(35, "SPI2_MISO"),
+	MT7986_TYPE0_PIN(36, "SPI2_CS"),
+	MT7986_TYPE0_PIN(37, "SPI2_HOLD"),
+	MT7986_TYPE0_PIN(38, "SPI2_WP"),
+	MT7986_TYPE0_PIN(39, "UART0_RXD"),
+	MT7986_TYPE0_PIN(40, "UART0_TXD"),
+	MT7986_TYPE0_PIN(41, "PCIE_PERESET_N"),
+	MT7986_TYPE0_PIN(42, "UART1_RXD"),
+	MT7986_TYPE0_PIN(43, "UART1_TXD"),
+	MT7986_TYPE0_PIN(44, "UART1_CTS"),
+	MT7986_TYPE0_PIN(45, "UART1_RTS"),
+	MT7986_TYPE0_PIN(46, "UART2_RXD"),
+	MT7986_TYPE0_PIN(47, "UART2_TXD"),
+	MT7986_TYPE0_PIN(48, "UART2_CTS"),
+	MT7986_TYPE0_PIN(49, "UART2_RTS"),
+	MT7986_TYPE0_PIN(50, "EMMC_DATA_0"),
+	MT7986_TYPE0_PIN(51, "EMMC_DATA_1"),
+	MT7986_TYPE0_PIN(52, "EMMC_DATA_2"),
+	MT7986_TYPE0_PIN(53, "EMMC_DATA_3"),
+	MT7986_TYPE0_PIN(54, "EMMC_DATA_4"),
+	MT7986_TYPE0_PIN(55, "EMMC_DATA_5"),
+	MT7986_TYPE0_PIN(56, "EMMC_DATA_6"),
+	MT7986_TYPE0_PIN(57, "EMMC_DATA_7"),
+	MT7986_TYPE0_PIN(58, "EMMC_CMD"),
+	MT7986_TYPE0_PIN(59, "EMMC_CK"),
+	MT7986_TYPE0_PIN(60, "EMMC_DSL"),
+	MT7986_TYPE0_PIN(61, "EMMC_RSTB"),
+	MT7986_TYPE0_PIN(62, "PCM_DTX"),
+	MT7986_TYPE0_PIN(63, "PCM_DRX"),
+	MT7986_TYPE0_PIN(64, "PCM_CLK"),
+	MT7986_TYPE0_PIN(65, "PCM_FS"),
+	MT7986_TYPE0_PIN(66, "MT7531_INT"),
+	MT7986_TYPE0_PIN(67, "SMI_MDC"),
+	MT7986_TYPE0_PIN(68, "SMI_MDIO"),
+	MT7986_TYPE1_PIN(69, "WF0_DIG_RESETB"),
+	MT7986_TYPE1_PIN(70, "WF0_CBA_RESETB"),
+	MT7986_TYPE1_PIN(71, "WF0_XO_REQ"),
+	MT7986_TYPE1_PIN(72, "WF0_TOP_CLK"),
+	MT7986_TYPE1_PIN(73, "WF0_TOP_DATA"),
+	MT7986_TYPE1_PIN(74, "WF0_HB1"),
+	MT7986_TYPE1_PIN(75, "WF0_HB2"),
+	MT7986_TYPE1_PIN(76, "WF0_HB3"),
+	MT7986_TYPE1_PIN(77, "WF0_HB4"),
+	MT7986_TYPE1_PIN(78, "WF0_HB0"),
+	MT7986_TYPE1_PIN(79, "WF0_HB0_B"),
+	MT7986_TYPE1_PIN(80, "WF0_HB5"),
+	MT7986_TYPE1_PIN(81, "WF0_HB6"),
+	MT7986_TYPE1_PIN(82, "WF0_HB7"),
+	MT7986_TYPE1_PIN(83, "WF0_HB8"),
+	MT7986_TYPE1_PIN(84, "WF0_HB9"),
+	MT7986_TYPE1_PIN(85, "WF0_HB10"),
+	MT7986_TYPE1_PIN(86, "WF1_DIG_RESETB"),
+	MT7986_TYPE1_PIN(87, "WF1_CBA_RESETB"),
+	MT7986_TYPE1_PIN(88, "WF1_XO_REQ"),
+	MT7986_TYPE1_PIN(89, "WF1_TOP_CLK"),
+	MT7986_TYPE1_PIN(90, "WF1_TOP_DATA"),
+	MT7986_TYPE1_PIN(91, "WF1_HB1"),
+	MT7986_TYPE1_PIN(92, "WF1_HB2"),
+	MT7986_TYPE1_PIN(93, "WF1_HB3"),
+	MT7986_TYPE1_PIN(94, "WF1_HB4"),
+	MT7986_TYPE1_PIN(95, "WF1_HB0"),
+	MT7986_TYPE1_PIN(96, "WF1_HB0_B"),
+	MT7986_TYPE1_PIN(97, "WF1_HB5"),
+	MT7986_TYPE1_PIN(98, "WF1_HB6"),
+	MT7986_TYPE1_PIN(99, "WF1_HB7"),
+	MT7986_TYPE1_PIN(100, "WF1_HB8"),
+};
+
+static const struct mtk_io_type_desc mt7986_io_type_desc[] = {
+	[IO_TYPE_GRP0] = {
+		.name = "18OD33",
+		.bias_set = mtk_pinconf_bias_set_pupd_r1_r0,
+		.drive_set = mtk_pinconf_drive_set_v1,
+		.input_enable = mtk_pinconf_input_enable_v1,
+	},
+	[IO_TYPE_GRP1] = {
+		.name = "18A01",
+		.bias_set = mtk_pinconf_bias_set_pu_pd,
+		.drive_set = mtk_pinconf_drive_set_v1,
+		.input_enable = mtk_pinconf_input_enable_v1,
+	},
+};
+
+/* List all groups consisting of these pins dedicated to the enablement of
+ * certain hardware block and the corresponding mode for all of the pins.
+ * The hardware probably has multiple combinations of these pinouts.
+ */
+
+static int mt7986_watchdog_pins[] = { 0, };
+static int mt7986_watchdog_funcs[] = { 1, };
+
+static int mt7986_wifi_led_pins[] = { 1, 2, };
+static int mt7986_wifi_led_funcs[] = { 1, 1, };
+
+static int mt7986_i2c_pins[] = { 3, 4, };
+static int mt7986_i2c_funcs[] = { 1, 1, };
+
+static int mt7986_uart1_0_pins[] = { 7, 8, 9, 10, };
+static int mt7986_uart1_0_funcs[] = { 3, 3, 3, 3, };
+
+static int mt7986_spi1_0_pins[] = { 11, 12, 13, 14, };
+static int mt7986_spi1_0_funcs[] = { 3, 3, 3, 3, };
+
+static int mt7986_pwm1_1_pins[] = { 20, };
+static int mt7986_pwm1_1_funcs[] = { 2, };
+
+static int mt7986_pwm0_pins[] = { 21, };
+static int mt7986_pwm0_funcs[] = { 1, };
+
+static int mt7986_pwm1_0_pins[] = { 22, };
+static int mt7986_pwm1_0_funcs[] = { 1, };
+
+static int mt7986_emmc_45_pins[] = {
+	22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, };
+static int mt7986_emmc_45_funcs[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, };
+
+static int mt7986_snfi_pins[] = { 23, 24, 25, 26, 27, 28, };
+static int mt7986_snfi_funcs[] = { 1, 1, 1, 1, 1, 1, };
+
+static int mt7986_spi1_1_pins[] = { 23, 24, 25, 26, };
+static int mt7986_spi1_1_funcs[] = { 3, 3, 3, 3, };
+
+static int mt7986_uart1_1_pins[] = { 23, 24, 25, 26, };
+static int mt7986_uart1_1_funcs[] = { 4, 4, 4, 4, };
+
+static int mt7986_spi1_2_pins[] = { 29, 30, 31, 32, };
+static int mt7986_spi1_2_funcs[] = { 1, 1, 1, 1, };
+
+static int mt7986_uart1_2_pins[] = { 29, 30, 31, 32, };
+static int mt7986_uart1_2_funcs[] = { 3, 3, 3, 3, };
+
+static int mt7986_uart2_0_pins[] = { 29, 30, 31, 32, };
+static int mt7986_uart2_0_funcs[] = { 4, 4, 4, 4, };
+
+static int mt7986_spi0_pins[] = { 33, 34, 35, 36, };
+static int mt7986_spi0_funcs[] = { 1, 1, 1, 1, };
+
+static int mt7986_spi0_wp_hold_pins[] = { 37, 38, };
+static int mt7986_spi0_wp_hold_funcs[] = { 1, 1, };
+
+static int mt7986_uart2_1_pins[] = { 33, 34, 35, 36, };
+static int mt7986_uart2_1_funcs[] = { 3, 3, 3, 3, };
+
+static int mt7986_uart1_3_rx_tx_pins[] = { 35, 36, };
+static int mt7986_uart1_3_rx_tx_funcs[] = { 2, 2, };
+
+static int mt7986_uart1_3_cts_rts_pins[] = { 37, 38, };
+static int mt7986_uart1_3_cts_rts_funcs[] = { 2, 2, };
+
+static int mt7986_spi1_3_pins[] = { 33, 34, 35, 36, };
+static int mt7986_spi1_3_funcs[] = { 4, 4, 4, 4, };
+
+static int mt7986_uart0_pins[] = { 39, 40, };
+static int mt7986_uart0_funcs[] = { 1, 1, };
+
+static int mt7986_pcie_reset_pins[] = { 41, };
+static int mt7986_pcie_reset_funcs[] = { 1, };
+
+static int mt7986_uart1_pins[] = { 42, 43, 44, 45, };
+static int mt7986_uart1_funcs[] = { 1, 1, 1, 1, };
+
+static int mt7986_uart2_pins[] = { 46, 47, 48, 49, };
+static int mt7986_uart2_funcs[] = { 1, 1, 1, 1, };
+
+static int mt7986_emmc_51_pins[] = {
+	50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, };
+static int mt7986_emmc_51_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 };
+
+static int mt7986_pcm_pins[] = { 62, 63, 64, 65, };
+static int mt7986_pcm_funcs[] = { 1, 1, 1, 1, };
+
+static int mt7986_i2s_pins[] = { 62, 63, 64, 65, };
+static int mt7986_i2s_funcs[] = { 1, 1, 1, 1, };
+
+static int mt7986_switch_int_pins[] = { 66, };
+static int mt7986_switch_int_funcs[] = { 1, };
+
+static int mt7986_mdc_mdio_pins[] = { 67, 68, };
+static int mt7986_mdc_mdio_funcs[] = { 1, 1, };
+
+static int mt7986_wf_2g_pins[] = {74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
 };
+static int mt7986_wf_2g_funcs[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, };
+
+static int mt7986_wf_5g_pins[] = {91, 92, 93, 94, 95, 96, 97, 98, 99, 100,
 };
+static int mt7986_wf_5g_funcs[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, };
+
+static int mt7986_wf_dbdc_pins[] = {
+	74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, };
+static int mt7986_wf_dbdc_funcs[] = {
+	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, };
+
+static int mt7986_pcie_clk_pins[] = { 9, };
+static int mt7986_pcie_clk_funcs[] = { 1, };
+
+static int mt7986_pcie_wake_pins[] = { 10, };
+static int mt7986_pcie_wake_funcs[] = { 1, };
+
+static const struct mtk_group_desc mt7986_groups[] = {
+	PINCTRL_PIN_GROUP("watchdog", mt7986_watchdog),
+	PINCTRL_PIN_GROUP("wifi_led", mt7986_wifi_led),
+	PINCTRL_PIN_GROUP("i2c", mt7986_i2c),
+	PINCTRL_PIN_GROUP("uart1_0", mt7986_uart1_0),
+	PINCTRL_PIN_GROUP("pcie_clk", mt7986_pcie_clk),
+	PINCTRL_PIN_GROUP("pcie_wake", mt7986_pcie_wake),
+	PINCTRL_PIN_GROUP("spi1_0", mt7986_spi1_0),
+	PINCTRL_PIN_GROUP("pwm1_1", mt7986_pwm1_1),
+	PINCTRL_PIN_GROUP("pwm0", mt7986_pwm0),
+	PINCTRL_PIN_GROUP("pwm1_0", mt7986_pwm1_0),
+	PINCTRL_PIN_GROUP("emmc_45", mt7986_emmc_45),
+	PINCTRL_PIN_GROUP("snfi", mt7986_snfi),
+	PINCTRL_PIN_GROUP("spi1_1", mt7986_spi1_1),
+	PINCTRL_PIN_GROUP("uart1_1", mt7986_uart1_1),
+	PINCTRL_PIN_GROUP("spi1_2", mt7986_spi1_2),
+	PINCTRL_PIN_GROUP("uart1_2", mt7986_uart1_2),
+	PINCTRL_PIN_GROUP("uart2_0", mt7986_uart2_0),
+	PINCTRL_PIN_GROUP("spi0", mt7986_spi0),
+	PINCTRL_PIN_GROUP("spi0_wp_hold", mt7986_spi0_wp_hold),
+	PINCTRL_PIN_GROUP("uart2_1", mt7986_uart2_1),
+	PINCTRL_PIN_GROUP("uart1_3_rx_tx", mt7986_uart1_3_rx_tx),
+	PINCTRL_PIN_GROUP("uart1_3_cts_rts", mt7986_uart1_3_cts_rts),
+	PINCTRL_PIN_GROUP("spi1_3", mt7986_spi1_3),
+	PINCTRL_PIN_GROUP("uart0", mt7986_uart0),
+	PINCTRL_PIN_GROUP("switch_int", mt7986_switch_int),
+	PINCTRL_PIN_GROUP("mdc_mdio", mt7986_mdc_mdio),
+	PINCTRL_PIN_GROUP("pcie_pereset", mt7986_pcie_reset),
+	PINCTRL_PIN_GROUP("uart1", mt7986_uart1),
+	PINCTRL_PIN_GROUP("uart2", mt7986_uart2),
+	PINCTRL_PIN_GROUP("emmc_51", mt7986_emmc_51),
+	PINCTRL_PIN_GROUP("pcm", mt7986_pcm),
+	PINCTRL_PIN_GROUP("i2s", mt7986_i2s),
+	PINCTRL_PIN_GROUP("wf_2g", mt7986_wf_2g),
+	PINCTRL_PIN_GROUP("wf_5g", mt7986_wf_5g),
+	PINCTRL_PIN_GROUP("wf_dbdc", mt7986_wf_dbdc),
+};
+
+/* Joint those groups owning the same capability in user point of view
 which
+ * allows that people tend to use through the device tree.
+ */
+
+static const char *const mt7986_audio_groups[] = { "pcm", "i2s" };
+static const char *const mt7986_emmc_groups[] = { "emmc_45", "emmc_51", };
+static const char *const mt7986_ethernet_groups[] = { "switch_int",
+	"mdc_mdio", };
+static const char *const mt7986_i2c_groups[] = { "i2c", };
+static const char *const mt7986_led_groups[] = { "wifi_led", };
+static const char *const mt7986_flash_groups[] = { "snfi", };
+static const char *const mt7986_pcie_groups[] = { "pcie_clk", "pcie_wake",
+	"pcie_pereset" };
+static const char *const mt7986_pwm_groups[] = { "pwm0", "pwm1_0",
 "pwm1_1", };
+static const char *const mt7986_spi_groups[] = { "spi0", "spi0_wp_hold",
+	"spi1_0", "spi1_1", "spi1_2", "spi1_3", };
+static const char *const mt7986_uart_groups[] = { "uart1_0", "uart1_1",
+	"uart1_2", "uart1_3_rx_tx", "uart1_3_cts_rts", "uart2_0", "uart2_1",
+	"uart0", "uart1", "uart2", };
+static const char *const mt7986_wdt_groups[] = { "watchdog", };
+static const char *const mt7986_wf_groups[] = { "wf_2g", "wf_5g",
 "wf_dbdc", };
+
+static const struct mtk_function_desc mt7986_functions[] = {
+	{"audio", mt7986_audio_groups, ARRAY_SIZE(mt7986_audio_groups)},
+	{"emmc", mt7986_emmc_groups, ARRAY_SIZE(mt7986_emmc_groups)},
+	{"eth", mt7986_ethernet_groups, ARRAY_SIZE(mt7986_ethernet_groups)},
+	{"i2c", mt7986_i2c_groups, ARRAY_SIZE(mt7986_i2c_groups)},
+	{"led", mt7986_led_groups, ARRAY_SIZE(mt7986_led_groups)},
+	{"flash", mt7986_flash_groups, ARRAY_SIZE(mt7986_flash_groups)},
+	{"pcie", mt7986_pcie_groups, ARRAY_SIZE(mt7986_pcie_groups)},
+	{"pwm", mt7986_pwm_groups, ARRAY_SIZE(mt7986_pwm_groups)},
+	{"spi", mt7986_spi_groups, ARRAY_SIZE(mt7986_spi_groups)},
+	{"uart", mt7986_uart_groups, ARRAY_SIZE(mt7986_uart_groups)},
+	{"watchdog", mt7986_wdt_groups, ARRAY_SIZE(mt7986_wdt_groups)},
+	{"wifi", mt7986_wf_groups, ARRAY_SIZE(mt7986_wf_groups)},
+};
+
+static struct mtk_pinctrl_soc mt7986_data = {
+	.name = "mt7986_pinctrl",
+	.reg_cal = mt7986_reg_cals,
+	.pins = mt7986_pins,
+	.npins = ARRAY_SIZE(mt7986_pins),
+	.grps = mt7986_groups,
+	.ngrps = ARRAY_SIZE(mt7986_groups),
+	.funcs = mt7986_functions,
+	.nfuncs = ARRAY_SIZE(mt7986_functions),
+	.io_type = mt7986_io_type_desc,
+	.ntype = ARRAY_SIZE(mt7986_io_type_desc),
+	.gpio_mode = 0,
+	.base_names = mt7986_pinctrl_register_base_names,
+	.nbase_names = ARRAY_SIZE(mt7986_pinctrl_register_base_names),
+	.base_calc = 1,
+};
+
+static int mtk_pinctrl_mt7986_probe(struct udevice *dev)
+{
+	return mtk_pinctrl_common_probe(dev, &mt7986_data);
+}
+
+static const struct udevice_id mt7986_pctrl_match[] = {
+	{.compatible = "mediatek,mt7986-pinctrl"},
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(mt7986_pinctrl) = {
+	.name = "mt7986_pinctrl",
+	.id = UCLASS_PINCTRL,
+	.of_match = mt7986_pctrl_match,
+	.ops = &mtk_pinctrl_ops,
+	.probe = mtk_pinctrl_mt7986_probe,
+	.priv_auto = sizeof(struct mtk_pinctrl_priv),
+};
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 22/31] clk: mediatek: add CLK_BYPASS_XTAL flag to allow bypassing searching clock parent of xtal clock
  2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
                   ` (20 preceding siblings ...)
  2022-08-04  3:36 ` [PATCH 21/31] pinctrl: mediatek: add pinctrl driver for MT7986 SoC Weijie Gao
@ 2022-08-04  3:36 ` Weijie Gao
  2022-08-04 13:57   ` Simon Glass
  2022-08-04  3:36 ` [PATCH 23/31] clk: mediatek: add support to configure clock driver parent Weijie Gao
                   ` (8 subsequent siblings)
  30 siblings, 1 reply; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:36 UTC (permalink / raw)
  To: u-boot; +Cc: GSS_MTK_Uboot_upstream, Lukasz Majewski, Sean Anderson, Weijie Gao

The mtk clock framework in u-boot uses array index for searching clock
parent (kernel uses strings for search), so we need to specify a special
clock with ID=0 for CLK_XTAL in u-boot.

In the mt7622/mt7629 clock tree, the clocks with ID=0 never call
mtk_topckgen_get_mux_rate, adn return xtal clock directly. This what we
expected.

However for newer chips, they may have some clocks with ID=0 not
representing the xtal clock and still needs mtk_topckgen_get_mux_rate be
called. Current logic will make entire clock driver not working.

This patch adds a flag to indicate that whether a clock driver needs clocks
with ID=0 to call mtk_topckgen_get_mux_rate.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 drivers/clk/mediatek/clk-mtk.c | 5 ++++-
 drivers/clk/mediatek/clk-mtk.h | 3 +++
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index d43b8a0648..d99ea55df0 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -314,12 +314,15 @@ static ulong mtk_topckgen_get_mux_rate(struct clk
 *clk, u32 off)
 	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
 	const struct mtk_composite *mux = &priv->tree->muxes[off];
 	u32 index;
+	u32 flag = 0;
 
 	index = readl(priv->base + mux->mux_reg);
 	index &= mux->mux_mask << mux->mux_shift;
 	index = index >> mux->mux_shift;
 
-	if (mux->parent[index])
+	if (mux->parent[index] == CLK_XTAL && priv->tree->flags & CLK_BYPASS_XTAL)
+		flag = 1;
+	if (mux->parent[index] > 0 || flag == 1)
 		return mtk_clk_find_parent_rate(clk, mux->parent[index],
 						NULL);
 
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index 95a23d14a8..0ab6912bf0 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -11,6 +11,8 @@
 #define CLK_XTAL			0
 #define MHZ				(1000 * 1000)
 
+#define CLK_BYPASS_XTAL			BIT(0)
+
 #define HAVE_RST_BAR			BIT(0)
 #define CLK_DOMAIN_SCPSYS		BIT(0)
 #define CLK_MUX_SETCLR_UPD		BIT(1)
@@ -197,6 +199,7 @@ struct mtk_clk_tree {
 	const struct mtk_fixed_clk *fclks;
 	const struct mtk_fixed_factor *fdivs;
 	const struct mtk_composite *muxes;
+	u32 flags;
 };
 
 struct mtk_clk_priv {
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 23/31] clk: mediatek: add support to configure clock driver parent
  2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
                   ` (21 preceding siblings ...)
  2022-08-04  3:36 ` [PATCH 22/31] clk: mediatek: add CLK_BYPASS_XTAL flag to allow bypassing searching clock parent of xtal clock Weijie Gao
@ 2022-08-04  3:36 ` Weijie Gao
  2022-08-04 13:57   ` Simon Glass
  2022-08-13  4:18   ` Sean Anderson
  2022-08-04  3:36 ` [PATCH 24/31] clk: mediatek: add infrasys clock mux support Weijie Gao
                   ` (7 subsequent siblings)
  30 siblings, 2 replies; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:36 UTC (permalink / raw)
  To: u-boot; +Cc: GSS_MTK_Uboot_upstream, Lukasz Majewski, Sean Anderson, Weijie Gao

This patch adds support for a clock node to configure its parent clock
where possible.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 drivers/clk/mediatek/clk-mtk.c | 79 ++++++++++++++++++++--------------
 drivers/clk/mediatek/clk-mtk.h |  2 +
 2 files changed, 48 insertions(+), 33 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index d99ea55df0..908ed2b4ba 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -42,20 +42,14 @@
  * the accurate frequency.
  */
 static ulong mtk_clk_find_parent_rate(struct clk *clk, int id,
-				      const struct driver *drv)
+				      struct udevice *pdev)
 {
 	struct clk parent = { .id = id, };
 
-	if (drv) {
-		struct udevice *dev;
-
-		if (uclass_get_device_by_driver(UCLASS_CLK, drv, &dev))
-			return -ENODEV;
-
-		parent.dev = dev;
-	} else {
+	if (pdev)
+		parent.dev = pdev;
+	else
 		parent.dev = clk->dev;
-	}
 
 	return clk_get_rate(&parent);
 }
@@ -296,7 +290,7 @@ static ulong mtk_topckgen_get_factor_rate(struct clk
 *clk, u32 off)
 	switch (fdiv->flags & CLK_PARENT_MASK) {
 	case CLK_PARENT_APMIXED:
 		rate = mtk_clk_find_parent_rate(clk, fdiv->parent,
-				DM_DRIVER_GET(mtk_clk_apmixedsys));
+						priv->parent);
 		break;
 	case CLK_PARENT_TOPCKGEN:
 		rate = mtk_clk_find_parent_rate(clk, fdiv->parent, NULL);
@@ -322,9 +316,18 @@ static ulong mtk_topckgen_get_mux_rate(struct clk *clk,
 u32 off)
 
 	if (mux->parent[index] == CLK_XTAL && priv->tree->flags & CLK_BYPASS_XTAL)
 		flag = 1;
-	if (mux->parent[index] > 0 || flag == 1)
-		return mtk_clk_find_parent_rate(clk, mux->parent[index],
-						NULL);
+	if (mux->parent[index] > 0 || flag == 1) {
+		switch (mux->flags & CLK_PARENT_MASK) {
+		case CLK_PARENT_APMIXED:
+			return mtk_clk_find_parent_rate(clk, mux->parent[index],
+							priv->parent);
+			break;
+		default:
+			return mtk_clk_find_parent_rate(clk, mux->parent[index],
+							NULL);
+			break;
+		}
+	}
 
 	return priv->tree->xtal_rate;
 }
@@ -343,7 +346,7 @@ static ulong mtk_topckgen_get_rate(struct clk *clk)
 						 priv->tree->muxes_offs);
 }
 
-static int mtk_topckgen_enable(struct clk *clk)
+static int mtk_clk_mux_enable(struct clk *clk)
 {
 	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
 	const struct mtk_composite *mux;
@@ -376,7 +379,7 @@ static int mtk_topckgen_enable(struct clk *clk)
 	return 0;
 }
 
-static int mtk_topckgen_disable(struct clk *clk)
+static int mtk_clk_mux_disable(struct clk *clk)
 {
 	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
 	const struct mtk_composite *mux;
@@ -402,7 +405,7 @@ static int mtk_topckgen_disable(struct clk *clk)
 	return 0;
 }
 
-static int mtk_topckgen_set_parent(struct clk *clk, struct clk *parent)
+static int mtk_common_clk_set_parent(struct clk *clk, struct clk *parent)
 {
 	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
 
@@ -474,19 +477,7 @@ static ulong mtk_clk_gate_get_rate(struct clk *clk)
 	struct mtk_cg_priv *priv = dev_get_priv(clk->dev);
 	const struct mtk_gate *gate = &priv->gates[clk->id];
 
-	switch (gate->flags & CLK_PARENT_MASK) {
-	case CLK_PARENT_APMIXED:
-		return mtk_clk_find_parent_rate(clk, gate->parent,
-				DM_DRIVER_GET(mtk_clk_apmixedsys));
-		break;
-	case CLK_PARENT_TOPCKGEN:
-		return mtk_clk_find_parent_rate(clk, gate->parent,
-				DM_DRIVER_GET(mtk_clk_topckgen));
-		break;
-
-	default:
-		return priv->tree->xtal_rate;
-	}
+	return mtk_clk_find_parent_rate(clk, gate->parent, priv->parent);
 }
 
 const struct clk_ops mtk_clk_apmixedsys_ops = {
@@ -497,10 +488,10 @@ const struct clk_ops mtk_clk_apmixedsys_ops = {
 };
 
 const struct clk_ops mtk_clk_topckgen_ops = {
-	.enable = mtk_topckgen_enable,
-	.disable = mtk_topckgen_disable,
+	.enable = mtk_clk_mux_enable,
+	.disable = mtk_clk_mux_disable,
 	.get_rate = mtk_topckgen_get_rate,
-	.set_parent = mtk_topckgen_set_parent,
+	.set_parent = mtk_common_clk_set_parent,
 };
 
 const struct clk_ops mtk_clk_gate_ops = {
@@ -513,11 +504,22 @@ int mtk_common_clk_init(struct udevice *dev,
 			const struct mtk_clk_tree *tree)
 {
 	struct mtk_clk_priv *priv = dev_get_priv(dev);
+	struct udevice *parent;
+	int ret;
 
 	priv->base = dev_read_addr_ptr(dev);
 	if (!priv->base)
 		return -ENOENT;
 
+	ret = uclass_get_device_by_phandle(UCLASS_CLK, dev, "clock-parent",
 &parent);
+	if (ret || !parent) {
+		ret = uclass_get_device_by_driver(UCLASS_CLK,
+				DM_DRIVER_GET(mtk_clk_apmixedsys), &parent);
+		if (ret || !parent)
+			return -ENOENT;
+	}
+
+	priv->parent = parent;
 	priv->tree = tree;
 
 	return 0;
@@ -528,11 +530,22 @@ int mtk_common_clk_gate_init(struct udevice *dev,
 			     const struct mtk_gate *gates)
 {
 	struct mtk_cg_priv *priv = dev_get_priv(dev);
+	struct udevice *parent;
+	int ret;
 
 	priv->base = dev_read_addr_ptr(dev);
 	if (!priv->base)
 		return -ENOENT;
 
+	ret = uclass_get_device_by_phandle(UCLASS_CLK, dev, "clock-parent",
 &parent);
+	if (ret || !parent) {
+		ret = uclass_get_device_by_driver(UCLASS_CLK,
+				DM_DRIVER_GET(mtk_clk_topckgen), &parent);
+		if (ret || !parent)
+			return -ENOENT;
+	}
+
+	priv->parent = parent;
 	priv->tree = tree;
 	priv->gates = gates;
 
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index 0ab6912bf0..7955d469db 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -203,11 +203,13 @@ struct mtk_clk_tree {
 };
 
 struct mtk_clk_priv {
+	struct udevice *parent;
 	void __iomem *base;
 	const struct mtk_clk_tree *tree;
 };
 
 struct mtk_cg_priv {
+	struct udevice *parent;
 	void __iomem *base;
 	const struct mtk_clk_tree *tree;
 	const struct mtk_gate *gates;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 24/31] clk: mediatek: add infrasys clock mux support
  2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
                   ` (22 preceding siblings ...)
  2022-08-04  3:36 ` [PATCH 23/31] clk: mediatek: add support to configure clock driver parent Weijie Gao
@ 2022-08-04  3:36 ` Weijie Gao
  2022-08-04 13:57   ` Simon Glass
  2022-08-13  4:21   ` Sean Anderson
  2022-08-04  3:36 ` [PATCH 25/31] clk: mediatek: add CLK_XTAL support for clock driver Weijie Gao
                   ` (6 subsequent siblings)
  30 siblings, 2 replies; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:36 UTC (permalink / raw)
  To: u-boot; +Cc: GSS_MTK_Uboot_upstream, Lukasz Majewski, Sean Anderson, Weijie Gao

This patch adds infrasys clock mux support for mediatek clock drivers.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 drivers/clk/mediatek/clk-mtk.c | 72 ++++++++++++++++++++++++++++++++++
 drivers/clk/mediatek/clk-mtk.h |  4 +-
 2 files changed, 75 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index 908ed2b4ba..be3846c85b 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -303,6 +303,24 @@ static ulong mtk_topckgen_get_factor_rate(struct clk
 *clk, u32 off)
 	return mtk_factor_recalc_rate(fdiv, rate);
 }
 
+static ulong mtk_infrasys_get_factor_rate(struct clk *clk, u32 off)
+{
+	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+	const struct mtk_fixed_factor *fdiv = &priv->tree->fdivs[off];
+	ulong rate;
+
+	switch (fdiv->flags & CLK_PARENT_MASK) {
+	case CLK_PARENT_TOPCKGEN:
+		rate = mtk_clk_find_parent_rate(clk, fdiv->parent,
+						priv->parent);
+		break;
+	default:
+		rate = mtk_clk_find_parent_rate(clk, fdiv->parent, NULL);
+	}
+
+	return mtk_factor_recalc_rate(fdiv, rate);
+}
+
 static ulong mtk_topckgen_get_mux_rate(struct clk *clk, u32 off)
 {
 	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
@@ -332,6 +350,34 @@ static ulong mtk_topckgen_get_mux_rate(struct clk *clk,
 u32 off)
 	return priv->tree->xtal_rate;
 }
 
+static ulong mtk_infrasys_get_mux_rate(struct clk *clk, u32 off)
+{
+	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+	const struct mtk_composite *mux = &priv->tree->muxes[off];
+	u32 index;
+	u32 flag;
+
+	index = readl(priv->base + mux->mux_reg);
+	index &= mux->mux_mask << mux->mux_shift;
+	index = index >> mux->mux_shift;
+
+	if (mux->parent[index] == CLK_XTAL && priv->tree->flags & CLK_BYPASS_XTAL)
+		flag = 1;
+	if (mux->parent[index] > 0 || flag == 1) {
+		switch (mux->flags & CLK_PARENT_MASK) {
+		case CLK_PARENT_TOPCKGEN:
+			return mtk_clk_find_parent_rate(clk, mux->parent[index],
+							priv->parent);
+			break;
+		default:
+			return mtk_clk_find_parent_rate(clk, mux->parent[index],
+							NULL);
+			break;
+		}
+	}
+	return 0;
+}
+
 static ulong mtk_topckgen_get_rate(struct clk *clk)
 {
 	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
@@ -346,6 +392,25 @@ static ulong mtk_topckgen_get_rate(struct clk *clk)
 						 priv->tree->muxes_offs);
 }
 
+static ulong mtk_infrasys_get_rate(struct clk *clk)
+{
+	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+
+	ulong rate;
+
+	if (clk->id < priv->tree->fdivs_offs) {
+		rate = priv->tree->fclks[clk->id].rate;
+	} else if (clk->id < priv->tree->muxes_offs) {
+		rate = mtk_infrasys_get_factor_rate(clk, clk->id -
+						    priv->tree->fdivs_offs);
+	} else {
+		rate = mtk_infrasys_get_mux_rate(clk, clk->id -
+						 priv->tree->muxes_offs);
+	}
+
+	return rate;
+}
+
 static int mtk_clk_mux_enable(struct clk *clk)
 {
 	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
@@ -494,6 +559,13 @@ const struct clk_ops mtk_clk_topckgen_ops = {
 	.set_parent = mtk_common_clk_set_parent,
 };
 
+const struct clk_ops mtk_clk_infrasys_ops = {
+	.enable = mtk_clk_mux_enable,
+	.disable = mtk_clk_mux_disable,
+	.get_rate = mtk_infrasys_get_rate,
+	.set_parent = mtk_common_clk_set_parent,
+};
+
 const struct clk_ops mtk_clk_gate_ops = {
 	.enable = mtk_clk_gate_enable,
 	.disable = mtk_clk_gate_disable,
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index 7955d469db..8536275671 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -25,7 +25,8 @@
 
 #define CLK_PARENT_APMIXED		BIT(4)
 #define CLK_PARENT_TOPCKGEN		BIT(5)
-#define CLK_PARENT_MASK			GENMASK(5, 4)
+#define CLK_PARENT_INFRASYS		BIT(6)
+#define CLK_PARENT_MASK			GENMASK(6, 4)
 
 #define ETHSYS_HIFSYS_RST_CTRL_OFS	0x34
 
@@ -217,6 +218,7 @@ struct mtk_cg_priv {
 
 extern const struct clk_ops mtk_clk_apmixedsys_ops;
 extern const struct clk_ops mtk_clk_topckgen_ops;
+extern const struct clk_ops mtk_clk_infrasys_ops;
 extern const struct clk_ops mtk_clk_gate_ops;
 
 int mtk_common_clk_init(struct udevice *dev,
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 25/31] clk: mediatek: add CLK_XTAL support for clock driver
  2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
                   ` (23 preceding siblings ...)
  2022-08-04  3:36 ` [PATCH 24/31] clk: mediatek: add infrasys clock mux support Weijie Gao
@ 2022-08-04  3:36 ` Weijie Gao
  2022-08-04 13:57   ` Simon Glass
  2022-08-13  4:25   ` Sean Anderson
  2022-08-04  3:36 ` [PATCH 26/31] clk: mediatek: add clock driver support for MediaTek MT7986 SoC Weijie Gao
                   ` (5 subsequent siblings)
  30 siblings, 2 replies; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:36 UTC (permalink / raw)
  To: u-boot; +Cc: GSS_MTK_Uboot_upstream, Lukasz Majewski, Sean Anderson, Weijie Gao

This add CLK_XTAL macro and flag to mediatek clock driver common part,
to make thi SoC that has clock directlly connect to XTAL working.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 drivers/clk/mediatek/clk-mtk.c | 3 +++
 drivers/clk/mediatek/clk-mtk.h | 3 ++-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index be3846c85b..5a4650d137 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -296,6 +296,7 @@ static ulong mtk_topckgen_get_factor_rate(struct clk
 *clk, u32 off)
 		rate = mtk_clk_find_parent_rate(clk, fdiv->parent, NULL);
 		break;
 
+	case CLK_PARENT_XTAL:
 	default:
 		rate = priv->tree->xtal_rate;
 	}
@@ -314,6 +315,8 @@ static ulong mtk_infrasys_get_factor_rate(struct clk
 *clk, u32 off)
 		rate = mtk_clk_find_parent_rate(clk, fdiv->parent,
 						priv->parent);
 		break;
+	case CLK_PARENT_XTAL:
+		rate = priv->tree->xtal_rate;
 	default:
 		rate = mtk_clk_find_parent_rate(clk, fdiv->parent, NULL);
 	}
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index 8536275671..211356697b 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -26,7 +26,8 @@
 #define CLK_PARENT_APMIXED		BIT(4)
 #define CLK_PARENT_TOPCKGEN		BIT(5)
 #define CLK_PARENT_INFRASYS		BIT(6)
-#define CLK_PARENT_MASK			GENMASK(6, 4)
+#define CLK_PARENT_XTAL			BIT(7)
+#define CLK_PARENT_MASK			GENMASK(7, 4)
 
 #define ETHSYS_HIFSYS_RST_CTRL_OFS	0x34
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 26/31] clk: mediatek: add clock driver support for MediaTek MT7986 SoC
  2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
                   ` (24 preceding siblings ...)
  2022-08-04  3:36 ` [PATCH 25/31] clk: mediatek: add CLK_XTAL support for clock driver Weijie Gao
@ 2022-08-04  3:36 ` Weijie Gao
  2022-08-04 13:57   ` Simon Glass
  2022-08-04  3:36 ` [PATCH 27/31] clk: mediatek: add clock driver support for MediaTek MT7981 SoC Weijie Gao
                   ` (4 subsequent siblings)
  30 siblings, 1 reply; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:36 UTC (permalink / raw)
  To: u-boot; +Cc: GSS_MTK_Uboot_upstream, Lukasz Majewski, Sean Anderson, Weijie Gao

This patch adds clock driver support for MediaTek MT7986 SoC

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 drivers/clk/mediatek/Makefile          |   1 +
 drivers/clk/mediatek/clk-mt7986.c      | 671 +++++++++++++++++++++++++
 include/dt-bindings/clock/mt7986-clk.h | 249 +++++++++
 3 files changed, 921 insertions(+)
 create mode 100644 drivers/clk/mediatek/clk-mt7986.c
 create mode 100644 include/dt-bindings/clock/mt7986-clk.h

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 522e724221..1aa38215bf 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_MT8512) += clk-mt8512.o
 obj-$(CONFIG_TARGET_MT7623) += clk-mt7623.o
 obj-$(CONFIG_TARGET_MT7622) += clk-mt7622.o
 obj-$(CONFIG_TARGET_MT7629) += clk-mt7629.o
+obj-$(CONFIG_TARGET_MT7986) += clk-mt7986.o
 obj-$(CONFIG_TARGET_MT8183) += clk-mt8183.o
 obj-$(CONFIG_TARGET_MT8516) += clk-mt8516.o
 obj-$(CONFIG_TARGET_MT8518) += clk-mt8518.o
diff --git a/drivers/clk/mediatek/clk-mt7986.c
 b/drivers/clk/mediatek/clk-mt7986.c
new file mode 100644
index 0000000000..11c489cd50
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt7986.c
@@ -0,0 +1,671 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek clock driver for MT7986 SoC
+ *
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+#include <dm.h>
+#include <log.h>
+#include <asm/arch-mediatek/reset.h>
+#include <asm/io.h>
+#include <dt-bindings/clock/mt7986-clk.h>
+#include <linux/bitops.h>
+
+#include "clk-mtk.h"
+
+#define MT7986_CLK_PDN 0x250
+#define MT7986_CLK_PDN_EN_WRITE BIT(31)
+
+#define PLL_FACTOR(_id, _name, _parent, _mult, _div)                       
    \
+	FACTOR(_id, _parent, _mult, _div, CLK_PARENT_APMIXED)
+
+#define TOP_FACTOR(_id, _name, _parent, _mult, _div)                       
    \
+	FACTOR(_id, _parent, _mult, _div, CLK_PARENT_TOPCKGEN)
+
+#define INFRA_FACTOR(_id, _name, _parent, _mult, _div)                     
    \
+	FACTOR(_id, _parent, _mult, _div, CLK_PARENT_INFRASYS)
+
+/* FIXED PLLS */
+static const struct mtk_fixed_clk fixed_pll_clks[] = {
+	FIXED_CLK(CK_APMIXED_ARMPLL, CLK_XTAL, 2000000000),
+	FIXED_CLK(CK_APMIXED_NET2PLL, CLK_XTAL, 800000000),
+	FIXED_CLK(CK_APMIXED_MMPLL, CLK_XTAL, 1440000000),
+	FIXED_CLK(CK_APMIXED_SGMPLL, CLK_XTAL, 325000000),
+	FIXED_CLK(CK_APMIXED_WEDMCUPLL, CLK_XTAL, 760000000),
+	FIXED_CLK(CK_APMIXED_NET1PLL, CLK_XTAL, 2500000000),
+	FIXED_CLK(CK_APMIXED_MPLL, CLK_XTAL, 416000000),
+	FIXED_CLK(CK_APMIXED_APLL2, CLK_XTAL, 196608000),
+};
+
+/* TOPCKGEN FIXED CLK */
+static const struct mtk_fixed_clk top_fixed_clks[] = {
+	FIXED_CLK(CK_TOP_CB_CKSQ_40M, CLK_XTAL, 40000000),
+};
+
+/* TOPCKGEN FIXED DIV */
+static const struct mtk_fixed_factor top_fixed_divs[] = {
+	PLL_FACTOR(CK_TOP_CB_M_416M, "cb_m_416m", CK_APMIXED_MPLL, 1, 1),
+	PLL_FACTOR(CK_TOP_CB_M_D2, "cb_m_d2", CK_APMIXED_MPLL, 1, 2),
+	PLL_FACTOR(CK_TOP_CB_M_D4, "cb_m_d4", CK_APMIXED_MPLL, 1, 4),
+	PLL_FACTOR(CK_TOP_CB_M_D8, "cb_m_d8", CK_APMIXED_MPLL, 1, 8),
+	PLL_FACTOR(CK_TOP_M_D8_D2, "m_d8_d2", CK_APMIXED_MPLL, 1, 16),
+	PLL_FACTOR(CK_TOP_M_D3_D2, "m_d3_d2", CK_APMIXED_MPLL, 1, 2),
+	PLL_FACTOR(CK_TOP_CB_MM_D2, "cb_mm_d2", CK_APMIXED_MMPLL, 1, 2),
+	PLL_FACTOR(CK_TOP_CB_MM_D4, "cb_mm_d4", CK_APMIXED_MMPLL, 1, 4),
+	PLL_FACTOR(CK_TOP_CB_MM_D8, "cb_mm_d8", CK_APMIXED_MMPLL, 1, 8),
+	PLL_FACTOR(CK_TOP_MM_D8_D2, "mm_d8_d2", CK_APMIXED_MMPLL, 1, 16),
+	PLL_FACTOR(CK_TOP_MM_D3_D8, "mm_d3_d8", CK_APMIXED_MMPLL, 1, 8),
+	PLL_FACTOR(CK_TOP_CB_U2_PHYD_CK, "cb_u2_phyd", CK_APMIXED_MMPLL, 1, 30),
+	PLL_FACTOR(CK_TOP_CB_APLL2_196M, "cb_apll2_196m", CK_APMIXED_APLL2, 1,
+		   1),
+	PLL_FACTOR(CK_TOP_APLL2_D4, "apll2_d4", CK_APMIXED_APLL2, 1, 4),
+	PLL_FACTOR(CK_TOP_CB_NET1_D4, "cb_net1_d4", CK_APMIXED_NET1PLL, 1, 4),
+	PLL_FACTOR(CK_TOP_CB_NET1_D5, "cb_net1_d5", CK_APMIXED_NET1PLL, 1, 5),
+	PLL_FACTOR(CK_TOP_NET1_D5_D2, "net1_d5_d2", CK_APMIXED_NET1PLL, 1, 10),
+	PLL_FACTOR(CK_TOP_NET1_D5_D4, "net1_d5_d4", CK_APMIXED_NET1PLL, 1, 20),
+	PLL_FACTOR(CK_TOP_NET1_D8_D2, "net1_d8_d2", CK_APMIXED_NET1PLL, 1, 16),
+	PLL_FACTOR(CK_TOP_NET1_D8_D4, "net1_d8_d4", CK_APMIXED_NET1PLL, 1, 32),
+	PLL_FACTOR(CK_TOP_CB_NET2_800M, "cb_net2_800m", CK_APMIXED_NET2PLL, 1,
+		   1),
+	PLL_FACTOR(CK_TOP_CB_NET2_D4, "cb_net2_d4", CK_APMIXED_NET2PLL, 1, 4),
+	PLL_FACTOR(CK_TOP_NET2_D4_D2, "net2_d4_d2", CK_APMIXED_NET2PLL, 1, 8),
+	PLL_FACTOR(CK_TOP_NET2_D3_D2, "net2_d3_d2", CK_APMIXED_NET2PLL, 1, 2),
+	PLL_FACTOR(CK_TOP_CB_WEDMCU_760M, "cb_wedmcu_760m",
+		   CK_APMIXED_WEDMCUPLL, 1, 1),
+	PLL_FACTOR(CK_TOP_WEDMCU_D5_D2, "wedmcu_d5_d2", CK_APMIXED_WEDMCUPLL, 1,
+		   10),
+	PLL_FACTOR(CK_TOP_CB_SGM_325M, "cb_sgm_325m", CK_APMIXED_SGMPLL, 1, 1),
+	TOP_FACTOR(CK_TOP_CB_CKSQ_40M_D2, "cb_cksq_40m_d2", CK_TOP_CB_CKSQ_40M,
+		   1, 2),
+	TOP_FACTOR(CK_TOP_CB_RTC_32K, "cb_rtc_32k", CK_TOP_CB_CKSQ_40M, 1,
+		   1250),
+	TOP_FACTOR(CK_TOP_CB_RTC_32P7K, "cb_rtc_32p7k", CK_TOP_CB_CKSQ_40M, 1,
+		   1220),
+	TOP_FACTOR(CK_TOP_NFI1X, "nfi1x", CK_TOP_NFI1X_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_USB_EQ_RX250M, "usb_eq_rx250m", CK_TOP_CB_CKSQ_40M, 1,
+		   1),
+	TOP_FACTOR(CK_TOP_USB_TX250M, "usb_tx250m", CK_TOP_CB_CKSQ_40M, 1, 1),
+	TOP_FACTOR(CK_TOP_USB_LN0_CK, "usb_ln0", CK_TOP_CB_CKSQ_40M, 1, 1),
+	TOP_FACTOR(CK_TOP_USB_CDR_CK, "usb_cdr", CK_TOP_CB_CKSQ_40M, 1, 1),
+	TOP_FACTOR(CK_TOP_SPINFI_BCK, "spinfi_bck", CK_TOP_SPINFI_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_I2C_BCK, "i2c_bck", CK_TOP_I2C_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_PEXTP_TL, "pextp_tl", CK_TOP_PEXTP_TL_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_EMMC_250M, "emmc_250m", CK_TOP_EMMC_250M_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_EMMC_416M, "emmc_416m", CK_TOP_EMMC_416M_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_F_26M_ADC_CK, "f_26m_adc", CK_TOP_F_26M_ADC_SEL, 1,
+		   1),
+	TOP_FACTOR(CK_TOP_SYSAXI, "sysaxi", CK_TOP_SYSAXI_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_NETSYS_WED_MCU, "netsys_wed_mcu",
+		   CK_TOP_NETSYS_MCU_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_NETSYS_2X, "netsys_2x", CK_TOP_NETSYS_2X_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_SGM_325M, "sgm_325m", CK_TOP_SGM_325M_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_A1SYS, "a1sys", CK_TOP_A1SYS_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_EIP_B, "eip_b", CK_TOP_EIP_B_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_F26M, "csw_f26m", CK_TOP_F26M_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_AUD_L, "aud_l", CK_TOP_AUD_L_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_A_TUNER, "a_tuner", CK_TOP_A_TUNER_SEL, 2, 1),
+	TOP_FACTOR(CK_TOP_U2U3_REF, "u2u3_ref", CK_TOP_U2U3_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_U2U3_SYS, "u2u3_sys", CK_TOP_U2U3_SYS_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_U2U3_XHCI, "u2u3_xhci", CK_TOP_U2U3_XHCI_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_AP2CNN_HOST, "ap2cnn_host", CK_TOP_AP2CNN_HOST_SEL, 1,
+		   1),
+};
+
+/* TOPCKGEN MUX PARENTS */
+static const int nfi1x_parents[] = { CK_TOP_CB_CKSQ_40M,  CK_TOP_CB_MM_D8,
+				     CK_TOP_NET1_D8_D2,   CK_TOP_NET2_D3_D2,
+				     CK_TOP_CB_M_D4,      CK_TOP_MM_D8_D2,
+				     CK_TOP_WEDMCU_D5_D2, CK_TOP_CB_M_D8 };
+
+static const int spinfi_parents[] = {
+	CK_TOP_CB_CKSQ_40M_D2, CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D5_D4,
+	CK_TOP_CB_M_D4,	CK_TOP_MM_D8_D2,    CK_TOP_WEDMCU_D5_D2,
+	CK_TOP_MM_D3_D8,       CK_TOP_CB_M_D8
+};
+
+static const int spi_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D2,
+				   CK_TOP_CB_MM_D8,    CK_TOP_NET1_D8_D2,
+				   CK_TOP_NET2_D3_D2,  CK_TOP_NET1_D5_D4,
+				   CK_TOP_CB_M_D4,     CK_TOP_WEDMCU_D5_D2 };
+
+static const int uart_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D8,
+				    CK_TOP_M_D8_D2 };
+
+static const int pwm_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D8_D2,
+				   CK_TOP_NET1_D5_D4, CK_TOP_CB_M_D4 };
+
+static const int i2c_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D5_D4,
+				   CK_TOP_CB_M_D4, CK_TOP_NET1_D8_D4 };
+
+static const int pextp_tl_ck_parents[] = { CK_TOP_CB_CKSQ_40M,
+					   CK_TOP_NET1_D5_D4, CK_TOP_NET2_D4_D2,
+					   CK_TOP_CB_RTC_32K };
+
+static const int emmc_250m_parents[] = { CK_TOP_CB_CKSQ_40M,
+					 CK_TOP_NET1_D5_D2 };
+
+static const int emmc_416m_parents[] = { CK_TOP_CB_CKSQ_40M,
 CK_TOP_CB_M_416M };
+
+static const int f_26m_adc_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_M_D8_D2
 };
+
+static const int dramc_md32_parents[] = { CK_TOP_CB_CKSQ_40M,
 CK_TOP_CB_M_D2 };
+
+static const int sysaxi_parents[] = { CK_TOP_CB_CKSQ_40M,
 CK_TOP_NET1_D8_D2,
+				      CK_TOP_CB_NET2_D4 };
+
+static const int sysapb_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_M_D3_D2,
+				      CK_TOP_NET2_D4_D2 };
+
+static const int arm_db_main_parents[] = { CK_TOP_CB_CKSQ_40M,
+					   CK_TOP_NET2_D3_D2 };
+
+static const int arm_db_jtsel_parents[] = { -1, CK_TOP_CB_CKSQ_40M };
+
+static const int netsys_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_MM_D4
 };
+
+static const int netsys_500m_parents[] = { CK_TOP_CB_CKSQ_40M,
+					   CK_TOP_CB_NET1_D5 };
+
+static const int netsys_mcu_parents[] = { CK_TOP_CB_CKSQ_40M,
+					  CK_TOP_CB_WEDMCU_760M,
+					  CK_TOP_CB_MM_D2, CK_TOP_CB_NET1_D4,
+					  CK_TOP_CB_NET1_D5 };
+
+static const int netsys_2x_parents[] = { CK_TOP_CB_CKSQ_40M,
+					 CK_TOP_CB_NET2_800M,
+					 CK_TOP_CB_WEDMCU_760M,
+					 CK_TOP_CB_MM_D2 };
+
+static const int sgm_325m_parents[] = { CK_TOP_CB_CKSQ_40M,
+					CK_TOP_CB_SGM_325M };
+
+static const int sgm_reg_parents[] = { CK_TOP_CB_CKSQ_40M,
 CK_TOP_NET1_D8_D4 };
+
+static const int a1sys_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_APLL2_D4 };
+
+static const int conn_mcusys_parents[] = { CK_TOP_CB_CKSQ_40M,
+					   CK_TOP_CB_MM_D2 };
+
+static const int eip_b_parents[] = { CK_TOP_CB_CKSQ_40M,
 CK_TOP_CB_NET2_800M };
+
+static const int aud_l_parents[] = { CK_TOP_CB_CKSQ_40M,
 CK_TOP_CB_APLL2_196M,
+				     CK_TOP_M_D8_D2 };
+
+static const int a_tuner_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_APLL2_D4,
+				       CK_TOP_M_D8_D2 };
+
+static const int u2u3_sys_parents[] = { CK_TOP_CB_CKSQ_40M,
 CK_TOP_NET1_D5_D4 };
+
+static const int da_u2_refsel_parents[] = { CK_TOP_CB_CKSQ_40M,
+					    CK_TOP_CB_U2_PHYD_CK };
+
+#define TOP_MUX(_id, _name, _parents, _mux_ofs, _mux_set_ofs, _mux_clr_ofs,
    \
+		_shift, _width, _gate, _upd_ofs, _upd)                         \
+	{                                                                      \
+		.id = _id, .mux_reg = _mux_ofs, .mux_set_reg = _mux_set_ofs,   \
+		.mux_clr_reg = _mux_clr_ofs, .upd_reg = _upd_ofs,              \
+		.upd_shift = _upd, .mux_shift = _shift,                        \
+		.mux_mask = BIT(_width) - 1, .gate_reg = _mux_ofs,             \
+		.gate_shift = _gate, .parent = _parents,                       \
+		.num_parents = ARRAY_SIZE(_parents),                           \
+		.flags = CLK_MUX_SETCLR_UPD,                                   \
+	}
+
+/* TOPCKGEN MUX_GATE */
+static const struct mtk_composite top_muxes[] = {
+	/* CLK_CFG_0 */
+	TOP_MUX(CK_TOP_NFI1X_SEL, "nfi1x_sel", nfi1x_parents, 0x000, 0x004,
+		0x008, 0, 3, 7, 0x1C0, 0),
+	TOP_MUX(CK_TOP_SPINFI_SEL, "spinfi_sel", spinfi_parents, 0x000, 0x004,
+		0x008, 8, 3, 15, 0x1C0, 1),
+	TOP_MUX(CK_TOP_SPI_SEL, "spi_sel", spi_parents, 0x000, 0x004, 0x008, 16,
+		3, 23, 0x1C0, 2),
+	TOP_MUX(CK_TOP_SPIM_MST_SEL, "spim_mst_sel", spi_parents, 0x000, 0x004,
+		0x008, 24, 3, 31, 0x1C0, 3),
+	/* CLK_CFG_1 */
+	TOP_MUX(CK_TOP_UART_SEL, "uart_sel", uart_parents, 0x010, 0x014, 0x018,
+		0, 2, 7, 0x1C0, 4),
+	TOP_MUX(CK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x010, 0x014, 0x018, 8,
+		2, 15, 0x1C0, 5),
+	TOP_MUX(CK_TOP_I2C_SEL, "i2c_sel", i2c_parents, 0x010, 0x014, 0x018, 16,
+		2, 23, 0x1C0, 6),
+	TOP_MUX(CK_TOP_PEXTP_TL_SEL, "pextp_tl_ck_sel", pextp_tl_ck_parents,
+		0x010, 0x014, 0x018, 24, 2, 31, 0x1C0, 7),
+	/* CLK_CFG_2 */
+	TOP_MUX(CK_TOP_EMMC_250M_SEL, "emmc_250m_sel", emmc_250m_parents, 0x020,
+		0x024, 0x028, 0, 1, 7, 0x1C0, 8),
+	TOP_MUX(CK_TOP_EMMC_416M_SEL, "emmc_416m_sel", emmc_416m_parents, 0x020,
+		0x024, 0x028, 8, 1, 15, 0x1C0, 9),
+	TOP_MUX(CK_TOP_F_26M_ADC_SEL, "f_26m_adc_sel", f_26m_adc_parents, 0x020,
+		0x024, 0x028, 16, 1, 23, 0x1C0, 10),
+	TOP_MUX(CK_TOP_DRAMC_SEL, "dramc_sel", f_26m_adc_parents, 0x020, 0x024,
+		0x028, 24, 1, 31, 0x1C0, 11),
+	/* CLK_CFG_3 */
+	TOP_MUX(CK_TOP_DRAMC_MD32_SEL, "dramc_md32_sel", dramc_md32_parents,
+		0x030, 0x034, 0x038, 0, 1, 7, 0x1C0, 12),
+	TOP_MUX(CK_TOP_SYSAXI_SEL, "sysaxi_sel", sysaxi_parents, 0x030, 0x034,
+		0x038, 8, 2, 15, 0x1C0, 13),
+	TOP_MUX(CK_TOP_SYSAPB_SEL, "sysapb_sel", sysapb_parents, 0x030, 0x034,
+		0x038, 16, 2, 23, 0x1C0, 14),
+	TOP_MUX(CK_TOP_ARM_DB_MAIN_SEL, "arm_db_main_sel", arm_db_main_parents,
+		0x030, 0x034, 0x038, 24, 1, 31, 0x1C0, 15),
+	/* CLK_CFG_4 */
+	TOP_MUX(CK_TOP_ARM_DB_JTSEL, "arm_db_jtsel", arm_db_jtsel_parents,
+		0x040, 0x044, 0x048, 0, 1, 7, 0x1C0, 16),
+	TOP_MUX(CK_TOP_NETSYS_SEL, "netsys_sel", netsys_parents, 0x040, 0x044,
+		0x048, 8, 1, 15, 0x1C0, 17),
+	TOP_MUX(CK_TOP_NETSYS_500M_SEL, "netsys_500m_sel", netsys_500m_parents,
+		0x040, 0x044, 0x048, 16, 1, 23, 0x1C0, 18),
+	TOP_MUX(CK_TOP_NETSYS_MCU_SEL, "netsys_mcu_sel", netsys_mcu_parents,
+		0x040, 0x044, 0x048, 24, 3, 31, 0x1C0, 19),
+	/* CLK_CFG_5 */
+	TOP_MUX(CK_TOP_NETSYS_2X_SEL, "netsys_2x_sel", netsys_2x_parents, 0x050,
+		0x054, 0x058, 0, 2, 7, 0x1C0, 20),
+	TOP_MUX(CK_TOP_SGM_325M_SEL, "sgm_325m_sel", sgm_325m_parents, 0x050,
+		0x054, 0x058, 8, 1, 15, 0x1C0, 21),
+	TOP_MUX(CK_TOP_SGM_REG_SEL, "sgm_reg_sel", sgm_reg_parents, 0x050,
+		0x054, 0x058, 16, 1, 23, 0x1C0, 22),
+	TOP_MUX(CK_TOP_A1SYS_SEL, "a1sys_sel", a1sys_parents, 0x050, 0x054,
+		0x058, 24, 1, 31, 0x1C0, 23),
+	/* CLK_CFG_6 */
+	TOP_MUX(CK_TOP_CONN_MCUSYS_SEL, "conn_mcusys_sel", conn_mcusys_parents,
+		0x060, 0x064, 0x068, 0, 1, 7, 0x1C0, 24),
+	TOP_MUX(CK_TOP_EIP_B_SEL, "eip_b_sel", eip_b_parents, 0x060, 0x064,
+		0x068, 8, 1, 15, 0x1C0, 25),
+	TOP_MUX(CK_TOP_PCIE_PHY_SEL, "pcie_phy_sel", f_26m_adc_parents, 0x060,
+		0x064, 0x068, 16, 1, 23, 0x1C0, 26),
+	TOP_MUX(CK_TOP_USB3_PHY_SEL, "usb3_phy_sel", f_26m_adc_parents, 0x060,
+		0x064, 0x068, 24, 1, 31, 0x1C0, 27),
+	/* CLK_CFG_7 */
+	TOP_MUX(CK_TOP_F26M_SEL, "csw_f26m_sel", f_26m_adc_parents, 0x070,
+		0x074, 0x078, 0, 1, 7, 0x1C0, 28),
+	TOP_MUX(CK_TOP_AUD_L_SEL, "aud_l_sel", aud_l_parents, 0x070, 0x074,
+		0x078, 8, 2, 15, 0x1C0, 29),
+	TOP_MUX(CK_TOP_A_TUNER_SEL, "a_tuner_sel", a_tuner_parents, 0x070,
+		0x074, 0x078, 16, 2, 23, 0x1C0, 30),
+	TOP_MUX(CK_TOP_U2U3_SEL, "u2u3_sel", f_26m_adc_parents, 0x070, 0x074,
+		0x078, 24, 1, 31, 0x1C4, 0),
+	/* CLK_CFG_8 */
+	TOP_MUX(CK_TOP_U2U3_SYS_SEL, "u2u3_sys_sel", u2u3_sys_parents, 0x080,
+		0x084, 0x088, 0, 1, 7, 0x1C4, 1),
+	TOP_MUX(CK_TOP_U2U3_XHCI_SEL, "u2u3_xhci_sel", u2u3_sys_parents, 0x080,
+		0x084, 0x088, 8, 1, 15, 0x1C4, 2),
+	TOP_MUX(CK_TOP_DA_U2_REFSEL, "da_u2_refsel", da_u2_refsel_parents,
+		0x080, 0x084, 0x088, 16, 1, 23, 0x1C4, 3),
+	TOP_MUX(CK_TOP_DA_U2_CK_1P_SEL, "da_u2_ck_1p_sel", da_u2_refsel_parents,
+		0x080, 0x084, 0x088, 24, 1, 31, 0x1C4, 4),
+	/* CLK_CFG_9 */
+	TOP_MUX(CK_TOP_AP2CNN_HOST_SEL, "ap2cnn_host_sel", sgm_reg_parents,
+		0x090, 0x094, 0x098, 0, 1, 7, 0x1C4, 5),
+};
+
+/* INFRA FIXED DIV */
+static const struct mtk_fixed_factor infra_fixed_divs[] = {
+	TOP_FACTOR(CK_INFRA_CK_F26M, "infra_ck_f26m", CK_TOP_F26M_SEL, 1, 1),
+	TOP_FACTOR(CK_INFRA_UART, "infra_uart", CK_TOP_UART_SEL, 1, 1),
+	TOP_FACTOR(CK_INFRA_ISPI0, "infra_ispi0", CK_TOP_SPI_SEL, 1, 1),
+	TOP_FACTOR(CK_INFRA_I2C, "infra_i2c", CK_TOP_I2C_SEL, 1, 1),
+	TOP_FACTOR(CK_INFRA_ISPI1, "infra_ispi1", CK_TOP_SPINFI_SEL, 1, 1),
+	TOP_FACTOR(CK_INFRA_PWM, "infra_pwm", CK_TOP_PWM_SEL, 1, 1),
+	TOP_FACTOR(CK_INFRA_66M_MCK, "infra_66m_mck", CK_TOP_SYSAXI_SEL, 1, 2),
+	TOP_FACTOR(CK_INFRA_CK_F32K, "infra_ck_f32k", CK_TOP_CB_RTC_32P7K, 1,
+		   1),
+	TOP_FACTOR(CK_INFRA_PCIE_CK, "infra_pcie", CK_TOP_PEXTP_TL_SEL, 1, 1),
+	INFRA_FACTOR(CK_INFRA_PWM_BCK, "infra_pwm_bck", CK_INFRA_PWM_BSEL, 1,
+		     1),
+	INFRA_FACTOR(CK_INFRA_PWM_CK1, "infra_pwm_ck1", CK_INFRA_PWM1_SEL, 1,
+		     1),
+	INFRA_FACTOR(CK_INFRA_PWM_CK2, "infra_pwm_ck2", CK_INFRA_PWM2_SEL, 1,
+		     1),
+	TOP_FACTOR(CK_INFRA_133M_HCK, "infra_133m_hck", CK_TOP_SYSAXI, 1, 1),
+	TOP_FACTOR(CK_INFRA_EIP_CK, "infra_eip", CK_TOP_EIP_B, 1, 1),
+	INFRA_FACTOR(CK_INFRA_66M_PHCK, "infra_66m_phck", CK_INFRA_133M_HCK, 1,
+		     1),
+	TOP_FACTOR(CK_INFRA_FAUD_L_CK, "infra_faud_l", CK_TOP_AUD_L, 1, 1),
+	TOP_FACTOR(CK_INFRA_FAUD_AUD_CK, "infra_faud_aud", CK_TOP_A1SYS, 1, 1),
+	TOP_FACTOR(CK_INFRA_FAUD_EG2_CK, "infra_faud_eg2", CK_TOP_A_TUNER, 1,
+		   1),
+	TOP_FACTOR(CK_INFRA_I2CS_CK, "infra_i2cs", CK_TOP_I2C_BCK, 1, 1),
+	INFRA_FACTOR(CK_INFRA_MUX_UART0, "infra_mux_uart0", CK_INFRA_UART0_SEL,
+		     1, 1),
+	INFRA_FACTOR(CK_INFRA_MUX_UART1, "infra_mux_uart1", CK_INFRA_UART1_SEL,
+		     1, 1),
+	INFRA_FACTOR(CK_INFRA_MUX_UART2, "infra_mux_uart2", CK_INFRA_UART2_SEL,
+		     1, 1),
+	TOP_FACTOR(CK_INFRA_NFI_CK, "infra_nfi", CK_TOP_NFI1X, 1, 1),
+	TOP_FACTOR(CK_INFRA_SPINFI_CK, "infra_spinfi", CK_TOP_SPINFI_BCK, 1, 1),
+	INFRA_FACTOR(CK_INFRA_MUX_SPI0, "infra_mux_spi0", CK_INFRA_SPI0_SEL, 1,
+		     1),
+	INFRA_FACTOR(CK_INFRA_MUX_SPI1, "infra_mux_spi1", CK_INFRA_SPI1_SEL, 1,
+		     1),
+	TOP_FACTOR(CK_INFRA_RTC_32K, "infra_rtc_32k", CK_TOP_CB_RTC_32K, 1, 1),
+	TOP_FACTOR(CK_INFRA_FMSDC_CK, "infra_fmsdc", CK_TOP_EMMC_416M, 1, 1),
+	TOP_FACTOR(CK_INFRA_FMSDC_HCK_CK, "infra_fmsdc_hck", CK_TOP_EMMC_250M,
+		   1, 1),
+	TOP_FACTOR(CK_INFRA_PERI_133M, "infra_peri_133m", CK_TOP_SYSAXI, 1, 1),
+	TOP_FACTOR(CK_INFRA_133M_PHCK, "infra_133m_phck", CK_TOP_SYSAXI, 1, 1),
+	TOP_FACTOR(CK_INFRA_USB_SYS_CK, "infra_usb_sys", CK_TOP_U2U3_SYS, 1, 1),
+	TOP_FACTOR(CK_INFRA_USB_CK, "infra_usb", CK_TOP_U2U3_REF, 1, 1),
+	TOP_FACTOR(CK_INFRA_USB_XHCI_CK, "infra_usb_xhci", CK_TOP_U2U3_XHCI, 1,
+		   1),
+	TOP_FACTOR(CK_INFRA_PCIE_GFMUX_TL_O_PRE, "infra_pcie_mux",
+		   CK_TOP_PEXTP_TL, 1, 1),
+	TOP_FACTOR(CK_INFRA_F26M_CK0, "infra_f26m_ck0", CK_TOP_F26M, 1, 1),
+	TOP_FACTOR(CK_INFRA_HD_133M, "infra_hd_133m", CK_TOP_SYSAXI, 1, 1),
+};
+
+/* INFRASYS MUX PARENTS */
+static const int infra_uart0_parents[] = { CK_INFRA_CK_F26M, CK_INFRA_UART
 };
+
+static const int infra_spi0_parents[] = { CK_INFRA_I2C, CK_INFRA_ISPI0 };
+
+static const int infra_spi1_parents[] = { CK_INFRA_I2C, CK_INFRA_ISPI1 };
+
+static const int infra_pwm_bsel_parents[] = { CK_INFRA_CK_F32K,
+					      CK_INFRA_CK_F26M,
+					      CK_INFRA_66M_MCK, CK_INFRA_PWM };
+
+static const int infra_pcie_parents[] = { CK_INFRA_CK_F32K,
 CK_INFRA_CK_F26M,
+					  -1, CK_INFRA_PCIE_CK };
+
+#define INFRA_MUX(_id, _name, _parents, _reg, _shift, _width)              
    \
+	{                                                                      \
+		.id = _id, .mux_reg = (_reg) + 0x8,                            \
+		.mux_set_reg = (_reg) + 0x0, .mux_clr_reg = (_reg) + 0x4,      \
+		.mux_shift = _shift, .mux_mask = BIT(_width) - 1,              \
+		.parent = _parents, .num_parents = ARRAY_SIZE(_parents),       \
+		.flags = CLK_MUX_SETCLR_UPD | CLK_PARENT_INFRASYS,             \
+	}
+
+/* INFRA MUX */
+
+static const struct mtk_composite infra_muxes[] = {
+	/* MODULE_CLK_SEL_0 */
+	INFRA_MUX(CK_INFRA_UART0_SEL, "infra_uart0_sel", infra_uart0_parents,
+		  0x10, 0, 1),
+	INFRA_MUX(CK_INFRA_UART1_SEL, "infra_uart1_sel", infra_uart0_parents,
+		  0x10, 1, 1),
+	INFRA_MUX(CK_INFRA_UART2_SEL, "infra_uart2_sel", infra_uart0_parents,
+		  0x10, 2, 1),
+	INFRA_MUX(CK_INFRA_SPI0_SEL, "infra_spi0_sel", infra_spi0_parents, 0x10,
+		  4, 1),
+	INFRA_MUX(CK_INFRA_SPI1_SEL, "infra_spi1_sel", infra_spi1_parents, 0x10,
+		  5, 1),
+	INFRA_MUX(CK_INFRA_PWM1_SEL, "infra_pwm1_sel", infra_pwm_bsel_parents,
+		  0x10, 9, 2),
+	INFRA_MUX(CK_INFRA_PWM2_SEL, "infra_pwm2_sel", infra_pwm_bsel_parents,
+		  0x10, 11, 2),
+	INFRA_MUX(CK_INFRA_PWM_BSEL, "infra_pwm_bsel", infra_pwm_bsel_parents,
+		  0x10, 13, 2),
+	/* MODULE_CLK_SEL_1 */
+	INFRA_MUX(CK_INFRA_PCIE_SEL, "infra_pcie_sel", infra_pcie_parents, 0x20,
+		  0, 2),
+};
+
+static const struct mtk_gate_regs infra_0_cg_regs = {
+	.set_ofs = 0x40,
+	.clr_ofs = 0x44,
+	.sta_ofs = 0x48,
+};
+
+static const struct mtk_gate_regs infra_1_cg_regs = {
+	.set_ofs = 0x50,
+	.clr_ofs = 0x54,
+	.sta_ofs = 0x58,
+};
+
+static const struct mtk_gate_regs infra_2_cg_regs = {
+	.set_ofs = 0x60,
+	.clr_ofs = 0x64,
+	.sta_ofs = 0x68,
+};
+
+#define GATE_INFRA0(_id, _name, _parent, _shift)                           
    \
+	{                                                                      \
+		.id = _id, .parent = _parent, .regs = &infra_0_cg_regs,        \
+		.shift = _shift,                                               \
+		.flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS,                \
+	}
+
+#define GATE_INFRA1(_id, _name, _parent, _shift)                           
    \
+	{                                                                      \
+		.id = _id, .parent = _parent, .regs = &infra_1_cg_regs,        \
+		.shift = _shift,                                               \
+		.flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS,                \
+	}
+
+#define GATE_INFRA2(_id, _name, _parent, _shift)                           
    \
+	{                                                                      \
+		.id = _id, .parent = _parent, .regs = &infra_2_cg_regs,        \
+		.shift = _shift,                                               \
+		.flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS,                \
+	}
+
+/* INFRA GATE */
+
+static const struct mtk_gate infracfg_ao_gates[] = {
+	/* INFRA0 */
+	GATE_INFRA0(CK_INFRA_GPT_STA, "infra_gpt_sta", CK_INFRA_66M_MCK, 0),
+	GATE_INFRA0(CK_INFRA_PWM_HCK, "infra_pwm_hck", CK_INFRA_66M_MCK, 1),
+	GATE_INFRA0(CK_INFRA_PWM_STA, "infra_pwm_sta", CK_INFRA_PWM_BCK, 2),
+	GATE_INFRA0(CK_INFRA_PWM1_CK, "infra_pwm1", CK_INFRA_PWM_CK1, 3),
+	GATE_INFRA0(CK_INFRA_PWM2_CK, "infra_pwm2", CK_INFRA_PWM_CK2, 4),
+	GATE_INFRA0(CK_INFRA_CQ_DMA_CK, "infra_cq_dma", CK_INFRA_133M_HCK, 6),
+	GATE_INFRA0(CK_INFRA_EIP97_CK, "infra_eip97", CK_INFRA_EIP_CK, 7),
+	GATE_INFRA0(CK_INFRA_AUD_BUS_CK, "infra_aud_bus", CK_INFRA_66M_PHCK, 8),
+	GATE_INFRA0(CK_INFRA_AUD_26M_CK, "infra_aud_26m", CK_INFRA_CK_F26M, 9),
+	GATE_INFRA0(CK_INFRA_AUD_L_CK, "infra_aud_l", CK_INFRA_FAUD_L_CK, 10),
+	GATE_INFRA0(CK_INFRA_AUD_AUD_CK, "infra_aud_aud", CK_INFRA_FAUD_AUD_CK,
+		    11),
+	GATE_INFRA0(CK_INFRA_AUD_EG2_CK, "infra_aud_eg2", CK_INFRA_FAUD_EG2_CK,
+		    13),
+	GATE_INFRA0(CK_INFRA_DRAMC_26M_CK, "infra_dramc_26m", CK_INFRA_CK_F26M,
+		    14),
+	GATE_INFRA0(CK_INFRA_DBG_CK, "infra_dbg", CK_INFRA_66M_MCK, 15),
+	GATE_INFRA0(CK_INFRA_AP_DMA_CK, "infra_ap_dma", CK_INFRA_66M_MCK, 16),
+	GATE_INFRA0(CK_INFRA_SEJ_CK, "infra_sej", CK_INFRA_66M_MCK, 24),
+	GATE_INFRA0(CK_INFRA_SEJ_13M_CK, "infra_sej_13m", CK_INFRA_CK_F26M, 25),
+	GATE_INFRA0(CK_INFRA_TRNG_CK, "infra_trng", CK_INFRA_HD_133M, 26),
+	/* INFRA1 */
+	GATE_INFRA1(CK_INFRA_THERM_CK, "infra_therm", CK_INFRA_CK_F26M, 0),
+	GATE_INFRA1(CK_INFRA_I2CO_CK, "infra_i2co", CK_INFRA_I2CS_CK, 1),
+	GATE_INFRA1(CK_INFRA_UART0_CK, "infra_uart0", CK_INFRA_MUX_UART0, 2),
+	GATE_INFRA1(CK_INFRA_UART1_CK, "infra_uart1", CK_INFRA_MUX_UART1, 3),
+	GATE_INFRA1(CK_INFRA_UART2_CK, "infra_uart2", CK_INFRA_MUX_UART2, 4),
+	GATE_INFRA1(CK_INFRA_NFI1_CK, "infra_nfi1", CK_INFRA_NFI_CK, 8),
+	GATE_INFRA1(CK_INFRA_SPINFI1_CK, "infra_spinfi1", CK_INFRA_SPINFI_CK,
+		    9),
+	GATE_INFRA1(CK_INFRA_NFI_HCK_CK, "infra_nfi_hck", CK_INFRA_66M_MCK, 10),
+	GATE_INFRA1(CK_INFRA_SPI0_CK, "infra_spi0", CK_INFRA_MUX_SPI0, 11),
+	GATE_INFRA1(CK_INFRA_SPI1_CK, "infra_spi1", CK_INFRA_MUX_SPI1, 12),
+	GATE_INFRA1(CK_INFRA_SPI0_HCK_CK, "infra_spi0_hck", CK_INFRA_66M_MCK,
+		    13),
+	GATE_INFRA1(CK_INFRA_SPI1_HCK_CK, "infra_spi1_hck", CK_INFRA_66M_MCK,
+		    14),
+	GATE_INFRA1(CK_INFRA_FRTC_CK, "infra_frtc", CK_INFRA_RTC_32K, 15),
+	GATE_INFRA1(CK_INFRA_MSDC_CK, "infra_msdc", CK_INFRA_FMSDC_CK, 16),
+	GATE_INFRA1(CK_INFRA_MSDC_HCK_CK, "infra_msdc_hck",
+		    CK_INFRA_FMSDC_HCK_CK, 17),
+	GATE_INFRA1(CK_INFRA_MSDC_133M_CK, "infra_msdc_133m",
+		    CK_INFRA_PERI_133M, 18),
+	GATE_INFRA1(CK_INFRA_MSDC_66M_CK, "infra_msdc_66m", CK_INFRA_66M_PHCK,
+		    19),
+	GATE_INFRA1(CK_INFRA_ADC_26M_CK, "infra_adc_26m", CK_INFRA_CK_F26M, 20),
+	GATE_INFRA1(CK_INFRA_ADC_FRC_CK, "infra_adc_frc", CK_INFRA_CK_F26M, 21),
+	GATE_INFRA1(CK_INFRA_FBIST2FPC_CK, "infra_fbist2fpc", CK_INFRA_NFI_CK,
+		    23),
+	/* INFRA2 */
+	GATE_INFRA2(CK_INFRA_IUSB_133_CK, "infra_iusb_133", CK_INFRA_133M_PHCK,
+		    0),
+	GATE_INFRA2(CK_INFRA_IUSB_66M_CK, "infra_iusb_66m", CK_INFRA_66M_PHCK,
+		    1),
+	GATE_INFRA2(CK_INFRA_IUSB_SYS_CK, "infra_iusb_sys", CK_INFRA_USB_SYS_CK,
+		    2),
+	GATE_INFRA2(CK_INFRA_IUSB_CK, "infra_iusb", CK_INFRA_USB_CK, 3),
+	GATE_INFRA2(CK_INFRA_IPCIE_CK, "infra_ipcie", CK_INFRA_PCIE_CK, 13),
+	GATE_INFRA2(CK_INFRA_IPCIER_CK, "infra_ipcier", CK_INFRA_F26M_CK0, 15),
+	GATE_INFRA2(CK_INFRA_IPCIEB_CK, "infra_ipcieb", CK_INFRA_133M_PHCK, 15),
+};
+
+static const struct mtk_clk_tree mt7986_fixed_pll_clk_tree = {
+	.fdivs_offs = CLK_APMIXED_NR_CLK,
+	.xtal_rate = 40 * MHZ,
+	.fclks = fixed_pll_clks,
+};
+
+static const struct mtk_clk_tree mt7986_topckgen_clk_tree = {
+	.fdivs_offs = CK_TOP_CB_M_416M,
+	.muxes_offs = CK_TOP_NFI1X_SEL,
+	.fclks = top_fixed_clks,
+	.fdivs = top_fixed_divs,
+	.muxes = top_muxes,
+	.flags = CLK_BYPASS_XTAL,
+};
+
+static const struct mtk_clk_tree mt7986_infracfg_clk_tree = {
+	.fdivs_offs = CK_INFRA_CK_F26M,
+	.muxes_offs = CK_INFRA_UART0_SEL,
+	.fdivs = infra_fixed_divs,
+	.muxes = infra_muxes,
+};
+
+static const struct udevice_id mt7986_fixed_pll_compat[] = {
+	{ .compatible = "mediatek,mt7986-fixed-plls" },
+	{}
+};
+
+static const struct udevice_id mt7986_topckgen_compat[] = {
+	{ .compatible = "mediatek,mt7986-topckgen" },
+	{}
+};
+
+static int mt7986_fixed_pll_probe(struct udevice *dev)
+{
+	return mtk_common_clk_init(dev, &mt7986_fixed_pll_clk_tree);
+}
+
+static int mt7986_topckgen_probe(struct udevice *dev)
+{
+	struct mtk_clk_priv *priv = dev_get_priv(dev);
+
+	priv->base = dev_read_addr_ptr(dev);
+	writel(MT7986_CLK_PDN_EN_WRITE, priv->base + MT7986_CLK_PDN);
+	return mtk_common_clk_init(dev, &mt7986_topckgen_clk_tree);
+}
+
+U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
+	.name = "mt7986-clock-fixed-pll",
+	.id = UCLASS_CLK,
+	.of_match = mt7986_fixed_pll_compat,
+	.probe = mt7986_fixed_pll_probe,
+	.priv_auto = sizeof(struct mtk_clk_priv),
+	.ops = &mtk_clk_topckgen_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(mtk_clk_topckgen) = {
+	.name = "mt7986-clock-topckgen",
+	.id = UCLASS_CLK,
+	.of_match = mt7986_topckgen_compat,
+	.probe = mt7986_topckgen_probe,
+	.priv_auto = sizeof(struct mtk_clk_priv),
+	.ops = &mtk_clk_topckgen_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
+
+static const struct udevice_id mt7986_infracfg_compat[] = {
+	{ .compatible = "mediatek,mt7986-infracfg" },
+	{}
+};
+
+static const struct udevice_id mt7986_infracfg_ao_compat[] = {
+	{ .compatible = "mediatek,mt7986-infracfg_ao" },
+	{}
+};
+
+static int mt7986_infracfg_probe(struct udevice *dev)
+{
+	return mtk_common_clk_init(dev, &mt7986_infracfg_clk_tree);
+}
+
+static int mt7986_infracfg_ao_probe(struct udevice *dev)
+{
+	return mtk_common_clk_gate_init(dev, &mt7986_infracfg_clk_tree,
+					infracfg_ao_gates);
+}
+
+U_BOOT_DRIVER(mtk_clk_infracfg) = {
+	.name = "mt7986-clock-infracfg",
+	.id = UCLASS_CLK,
+	.of_match = mt7986_infracfg_compat,
+	.probe = mt7986_infracfg_probe,
+	.priv_auto = sizeof(struct mtk_clk_priv),
+	.ops = &mtk_clk_infrasys_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(mtk_clk_infracfg_ao) = {
+	.name = "mt7986-clock-infracfg-ao",
+	.id = UCLASS_CLK,
+	.of_match = mt7986_infracfg_ao_compat,
+	.probe = mt7986_infracfg_ao_probe,
+	.priv_auto = sizeof(struct mtk_cg_priv),
+	.ops = &mtk_clk_gate_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
+
+/* ethsys */
+static const struct mtk_gate_regs eth_cg_regs = {
+	.sta_ofs = 0x30,
+};
+
+#define GATE_ETH(_id, _name, _parent, _shift)                              
    \
+	{                                                                      \
+		.id = _id, .parent = _parent, .regs = &eth_cg_regs,            \
+		.shift = _shift,                                               \
+		.flags = CLK_GATE_NO_SETCLR_INV | CLK_PARENT_TOPCKGEN,         \
+	}
+
+static const struct mtk_gate eth_cgs[] = {
+	GATE_ETH(CK_ETH_FE_EN, "eth_fe_en", CK_TOP_NETSYS_2X, 7),
+	GATE_ETH(CK_ETH_GP2_EN, "eth_gp2_en", CK_TOP_SGM_325M, 8),
+	GATE_ETH(CK_ETH_GP1_EN, "eth_gp1_en", CK_TOP_SGM_325M, 8),
+	GATE_ETH(CK_ETH_WOCPU1_EN, "eth_wocpu1_en", CK_TOP_NETSYS_WED_MCU, 14),
+	GATE_ETH(CK_ETH_WOCPU0_EN, "eth_wocpu0_en", CK_TOP_NETSYS_WED_MCU, 15),
+};
+
+static int mt7986_ethsys_probe(struct udevice *dev)
+{
+	return mtk_common_clk_gate_init(dev, &mt7986_topckgen_clk_tree,
+					eth_cgs);
+}
+
+static int mt7986_ethsys_bind(struct udevice *dev)
+{
+	int ret = 0;
+
+#if CONFIG_IS_ENABLED(RESET_MEDIATEK)
+	ret = mediatek_reset_bind(dev, ETHSYS_HIFSYS_RST_CTRL_OFS, 1);
+	if (ret)
+		debug("Warning: failed to bind reset controller\n");
+#endif
+
+	return ret;
+}
+
+static const struct udevice_id mt7986_ethsys_compat[] = {
+	{ .compatible = "mediatek,mt7986-ethsys" },
+	{ }
+};
+
+U_BOOT_DRIVER(mtk_clk_ethsys) = {
+	.name = "mt7986-clock-ethsys",
+	.id = UCLASS_CLK,
+	.of_match = mt7986_ethsys_compat,
+	.probe = mt7986_ethsys_probe,
+	.bind = mt7986_ethsys_bind,
+	.priv_auto = sizeof(struct mtk_cg_priv),
+	.ops = &mtk_clk_gate_ops,
+};
diff --git a/include/dt-bindings/clock/mt7986-clk.h
 b/include/dt-bindings/clock/mt7986-clk.h
new file mode 100644
index 0000000000..820f863183
--- /dev/null
+++ b/include/dt-bindings/clock/mt7986-clk.h
@@ -0,0 +1,249 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2022 MediaTek Inc. All rights reserved.
+ *
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_MT7986_H
+#define _DT_BINDINGS_CLK_MT7986_H
+
+/* INFRACFG */
+
+#define CK_INFRA_CK_F26M		0
+#define CK_INFRA_UART			1
+#define CK_INFRA_ISPI0			2
+#define CK_INFRA_I2C			3
+#define CK_INFRA_ISPI1			4
+#define CK_INFRA_PWM			5
+#define CK_INFRA_66M_MCK		6
+#define CK_INFRA_CK_F32K		7
+#define CK_INFRA_PCIE_CK		8
+#define CK_INFRA_PWM_BCK		9
+#define CK_INFRA_PWM_CK1		10
+#define CK_INFRA_PWM_CK2		11
+#define CK_INFRA_133M_HCK		12
+#define CK_INFRA_EIP_CK			13
+#define CK_INFRA_66M_PHCK		14
+#define CK_INFRA_FAUD_L_CK		15
+#define CK_INFRA_FAUD_AUD_CK		17
+#define CK_INFRA_FAUD_EG2_CK		17
+#define CK_INFRA_I2CS_CK		18
+#define CK_INFRA_MUX_UART0		19
+#define CK_INFRA_MUX_UART1		20
+#define CK_INFRA_MUX_UART2		21
+#define CK_INFRA_NFI_CK			22
+#define CK_INFRA_SPINFI_CK		23
+#define CK_INFRA_MUX_SPI0		24
+#define CK_INFRA_MUX_SPI1		25
+#define CK_INFRA_RTC_32K		26
+#define CK_INFRA_FMSDC_CK		27
+#define CK_INFRA_FMSDC_HCK_CK		28
+#define CK_INFRA_PERI_133M		29
+#define CK_INFRA_133M_PHCK		30
+#define CK_INFRA_USB_SYS_CK		31
+#define CK_INFRA_USB_CK			32
+#define CK_INFRA_USB_XHCI_CK		33
+#define CK_INFRA_PCIE_GFMUX_TL_O_PRE	34
+#define CK_INFRA_F26M_CK0		35
+#define CK_INFRA_HD_133M		36
+#define CLK_INFRA_NR_CLK		37
+
+/* TOPCKGEN */
+
+#define CK_TOP_CB_CKSQ_40M		0
+#define CK_TOP_CB_M_416M		1
+#define CK_TOP_CB_M_D2			2
+#define CK_TOP_CB_M_D4			3
+#define CK_TOP_CB_M_D8			4
+#define CK_TOP_M_D8_D2			5
+#define CK_TOP_M_D3_D2			6
+#define CK_TOP_CB_MM_D2			7
+#define CK_TOP_CB_MM_D4			8
+#define CK_TOP_CB_MM_D8			9
+#define CK_TOP_MM_D8_D2			10
+#define CK_TOP_MM_D3_D8			11
+#define CK_TOP_CB_U2_PHYD_CK		12
+#define CK_TOP_CB_APLL2_196M		13
+#define CK_TOP_APLL2_D4			14
+#define CK_TOP_CB_NET1_D4		15
+#define CK_TOP_CB_NET1_D5		16
+#define CK_TOP_NET1_D5_D2		17
+#define CK_TOP_NET1_D5_D4		18
+#define CK_TOP_NET1_D8_D2		19
+#define CK_TOP_NET1_D8_D4		20
+#define CK_TOP_CB_NET2_800M		21
+#define CK_TOP_CB_NET2_D4		22
+#define CK_TOP_NET2_D4_D2		23
+#define CK_TOP_NET2_D3_D2		24
+#define CK_TOP_CB_WEDMCU_760M		25
+#define CK_TOP_WEDMCU_D5_D2		26
+#define CK_TOP_CB_SGM_325M		27
+#define CK_TOP_CB_CKSQ_40M_D2		28
+#define CK_TOP_CB_RTC_32K		29
+#define CK_TOP_CB_RTC_32P7K		30
+#define CK_TOP_NFI1X			31
+#define CK_TOP_USB_EQ_RX250M		32
+#define CK_TOP_USB_TX250M		33
+#define CK_TOP_USB_LN0_CK		34
+#define CK_TOP_USB_CDR_CK		35
+#define CK_TOP_SPINFI_BCK		36
+#define CK_TOP_I2C_BCK			37
+#define CK_TOP_PEXTP_TL			38
+#define CK_TOP_EMMC_250M		39
+#define CK_TOP_EMMC_416M		40
+#define CK_TOP_F_26M_ADC_CK		41
+#define CK_TOP_SYSAXI			42
+#define CK_TOP_NETSYS_WED_MCU		43
+#define CK_TOP_NETSYS_2X		44
+#define CK_TOP_SGM_325M			45
+#define CK_TOP_A1SYS			46
+#define CK_TOP_EIP_B			47
+#define CK_TOP_F26M			48
+#define CK_TOP_AUD_L			49
+#define CK_TOP_A_TUNER			50
+#define CK_TOP_U2U3_REF			51
+#define CK_TOP_U2U3_SYS			52
+#define CK_TOP_U2U3_XHCI		53
+#define CK_TOP_AP2CNN_HOST		54
+#define CK_TOP_NFI1X_SEL		55
+#define CK_TOP_SPINFI_SEL		56
+#define CK_TOP_SPI_SEL			57
+#define CK_TOP_SPIM_MST_SEL		58
+#define CK_TOP_UART_SEL			59
+#define CK_TOP_PWM_SEL			60
+#define CK_TOP_I2C_SEL			61
+#define CK_TOP_PEXTP_TL_SEL		62
+#define CK_TOP_EMMC_250M_SEL		63
+#define CK_TOP_EMMC_416M_SEL		64
+#define CK_TOP_F_26M_ADC_SEL		65
+#define CK_TOP_DRAMC_SEL		66
+#define CK_TOP_DRAMC_MD32_SEL		67
+#define CK_TOP_SYSAXI_SEL		68
+#define CK_TOP_SYSAPB_SEL		69
+#define CK_TOP_ARM_DB_MAIN_SEL		70
+#define CK_TOP_ARM_DB_JTSEL		71
+#define CK_TOP_NETSYS_SEL		72
+#define CK_TOP_NETSYS_500M_SEL		73
+#define CK_TOP_NETSYS_MCU_SEL		74
+#define CK_TOP_NETSYS_2X_SEL		75
+#define CK_TOP_SGM_325M_SEL		76
+#define CK_TOP_SGM_REG_SEL		77
+#define CK_TOP_A1SYS_SEL		78
+#define CK_TOP_CONN_MCUSYS_SEL		79
+#define CK_TOP_EIP_B_SEL		80
+#define CK_TOP_PCIE_PHY_SEL		81
+#define CK_TOP_USB3_PHY_SEL		82
+#define CK_TOP_F26M_SEL			83
+#define CK_TOP_AUD_L_SEL		84
+#define CK_TOP_A_TUNER_SEL		85
+#define CK_TOP_U2U3_SEL			86
+#define CK_TOP_U2U3_SYS_SEL		87
+#define CK_TOP_U2U3_XHCI_SEL		88
+#define CK_TOP_DA_U2_REFSEL		89
+#define CK_TOP_DA_U2_CK_1P_SEL		90
+#define CK_TOP_AP2CNN_HOST_SEL		91
+#define CLK_TOP_NR_CLK			92
+
+/*
+ * INFRACFG_AO
+ * clock muxes need to be append to infracfg domain, and clock gates
+ * need to be keep in infracgh_ao domain
+ */
+
+#define CK_INFRA_UART0_SEL		(0 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_UART1_SEL		(1 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_UART2_SEL		(2 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_SPI0_SEL		(3 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_SPI1_SEL		(4 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_PWM1_SEL		(5 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_PWM2_SEL		(6 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_PWM_BSEL		(7 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_PCIE_SEL		(8 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_GPT_STA		0
+#define CK_INFRA_PWM_HCK		1
+#define CK_INFRA_PWM_STA		2
+#define CK_INFRA_PWM1_CK		3
+#define CK_INFRA_PWM2_CK		4
+#define CK_INFRA_CQ_DMA_CK		5
+#define CK_INFRA_EIP97_CK		6
+#define CK_INFRA_AUD_BUS_CK		7
+#define CK_INFRA_AUD_26M_CK		8
+#define CK_INFRA_AUD_L_CK		9
+#define CK_INFRA_AUD_AUD_CK		10
+#define CK_INFRA_AUD_EG2_CK		11
+#define CK_INFRA_DRAMC_26M_CK		12
+#define CK_INFRA_DBG_CK			13
+#define CK_INFRA_AP_DMA_CK		14
+#define CK_INFRA_SEJ_CK			15
+#define CK_INFRA_SEJ_13M_CK		16
+#define CK_INFRA_THERM_CK		17
+#define CK_INFRA_I2CO_CK		18
+#define CK_INFRA_TRNG_CK		19
+#define CK_INFRA_UART0_CK		20
+#define CK_INFRA_UART1_CK		21
+#define CK_INFRA_UART2_CK		22
+#define CK_INFRA_NFI1_CK		23
+#define CK_INFRA_SPINFI1_CK		24
+#define CK_INFRA_NFI_HCK_CK		25
+#define CK_INFRA_SPI0_CK		26
+#define CK_INFRA_SPI1_CK		27
+#define CK_INFRA_SPI0_HCK_CK		28
+#define CK_INFRA_SPI1_HCK_CK		29
+#define CK_INFRA_FRTC_CK		30
+#define CK_INFRA_MSDC_CK		31
+#define CK_INFRA_MSDC_HCK_CK		32
+#define CK_INFRA_MSDC_133M_CK		33
+#define CK_INFRA_MSDC_66M_CK		34
+#define CK_INFRA_ADC_26M_CK		35
+#define CK_INFRA_ADC_FRC_CK		36
+#define CK_INFRA_FBIST2FPC_CK		37
+#define CK_INFRA_IUSB_133_CK		38
+#define CK_INFRA_IUSB_66M_CK		39
+#define CK_INFRA_IUSB_SYS_CK		40
+#define CK_INFRA_IUSB_CK		41
+#define CK_INFRA_IPCIE_CK		42
+#define CK_INFRA_IPCIER_CK		43
+#define CK_INFRA_IPCIEB_CK		44
+#define CLK_INFRA_AO_NR_CLK		45
+
+/* APMIXEDSYS */
+
+#define CK_APMIXED_ARMPLL		0
+#define CK_APMIXED_NET2PLL		1
+#define CK_APMIXED_MMPLL		2
+#define CK_APMIXED_SGMPLL		3
+#define CK_APMIXED_WEDMCUPLL		4
+#define CK_APMIXED_NET1PLL		5
+#define CK_APMIXED_MPLL			6
+#define CK_APMIXED_APLL2		7
+#define CLK_APMIXED_NR_CLK		8
+
+/* SGMIISYS_0 */
+
+#define CK_SGM0_TX_EN			0
+#define CK_SGM0_RX_EN			1
+#define CK_SGM0_CK0_EN			2
+#define CK_SGM0_CDR_CK0_EN		3
+#define CLK_SGMII0_NR_CLK		4
+
+/* SGMIISYS_1 */
+
+#define CK_SGM1_TX_EN			0
+#define CK_SGM1_RX_EN			1
+#define CK_SGM1_CK1_EN			2
+#define CK_SGM1_CDR_CK1_EN		3
+#define CLK_SGMII1_NR_CLK		4
+
+/* ETHSYS */
+
+#define CK_ETH_FE_EN			0
+#define CK_ETH_GP2_EN			1
+#define CK_ETH_GP1_EN			2
+#define CK_ETH_WOCPU1_EN		3
+#define CK_ETH_WOCPU0_EN		4
+#define CLK_ETH_NR_CLK			5
+
+#endif
+
+/* _DT_BINDINGS_CLK_MT7986_H */
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 27/31] clk: mediatek: add clock driver support for MediaTek MT7981 SoC
  2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
                   ` (25 preceding siblings ...)
  2022-08-04  3:36 ` [PATCH 26/31] clk: mediatek: add clock driver support for MediaTek MT7986 SoC Weijie Gao
@ 2022-08-04  3:36 ` Weijie Gao
  2022-08-04 13:57   ` Simon Glass
  2022-08-13  4:31   ` Sean Anderson
  2022-08-04  3:36 ` [PATCH 28/31] tools: mtk_image: split gfh header verification into a new function Weijie Gao
                   ` (3 subsequent siblings)
  30 siblings, 2 replies; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:36 UTC (permalink / raw)
  To: u-boot; +Cc: GSS_MTK_Uboot_upstream, Lukasz Majewski, Sean Anderson, Weijie Gao

This patch adds clock driver support for MediaTek MT7981 SoC

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 drivers/clk/mediatek/Makefile          |   1 +
 drivers/clk/mediatek/clk-mt7981.c      | 682 +++++++++++++++++++++++++
 include/dt-bindings/clock/mt7981-clk.h | 267 ++++++++++
 3 files changed, 950 insertions(+)
 create mode 100644 drivers/clk/mediatek/clk-mt7981.c
 create mode 100644 include/dt-bindings/clock/mt7981-clk.h

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 1aa38215bf..1decf31a77 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_TARGET_MT7623) += clk-mt7623.o
 obj-$(CONFIG_TARGET_MT7622) += clk-mt7622.o
 obj-$(CONFIG_TARGET_MT7629) += clk-mt7629.o
 obj-$(CONFIG_TARGET_MT7986) += clk-mt7986.o
+obj-$(CONFIG_TARGET_MT7981) += clk-mt7981.o
 obj-$(CONFIG_TARGET_MT8183) += clk-mt8183.o
 obj-$(CONFIG_TARGET_MT8516) += clk-mt8516.o
 obj-$(CONFIG_TARGET_MT8518) += clk-mt8518.o
diff --git a/drivers/clk/mediatek/clk-mt7981.c
 b/drivers/clk/mediatek/clk-mt7981.c
new file mode 100644
index 0000000000..53d09250e6
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt7981.c
@@ -0,0 +1,682 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek clock driver for MT7981 SoC
+ *
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+#include <dm.h>
+#include <log.h>
+#include <asm/arch-mediatek/reset.h>
+#include <asm/io.h>
+#include <dt-bindings/clock/mt7981-clk.h>
+#include <linux/bitops.h>
+
+#include "clk-mtk.h"
+
+#define MT7981_CLK_PDN 0x250
+#define MT7981_CLK_PDN_EN_WRITE BIT(31)
+
+#define PLL_FACTOR(_id, _name, _parent, _mult, _div)                       
    \
+	FACTOR(_id, _parent, _mult, _div, CLK_PARENT_APMIXED)
+
+#define TOP_FACTOR(_id, _name, _parent, _mult, _div)                       
    \
+	FACTOR(_id, _parent, _mult, _div, CLK_PARENT_TOPCKGEN)
+
+#define INFRA_FACTOR(_id, _name, _parent, _mult, _div)                     
    \
+	FACTOR(_id, _parent, _mult, _div, CLK_PARENT_INFRASYS)
+
+/* FIXED PLLS */
+static const struct mtk_fixed_clk fixed_pll_clks[] = {
+	FIXED_CLK(CK_APMIXED_ARMPLL, CLK_XTAL, 1300000000),
+	FIXED_CLK(CK_APMIXED_NET2PLL, CLK_XTAL, 800000000),
+	FIXED_CLK(CK_APMIXED_MMPLL, CLK_XTAL, 720000000),
+	FIXED_CLK(CK_APMIXED_SGMPLL, CLK_XTAL, 325000000),
+	FIXED_CLK(CK_APMIXED_WEDMCUPLL, CLK_XTAL, 208000000),
+	FIXED_CLK(CK_APMIXED_NET1PLL, CLK_XTAL, 2500000000),
+	FIXED_CLK(CK_APMIXED_MPLL, CLK_XTAL, 416000000),
+	FIXED_CLK(CK_APMIXED_APLL2, CLK_XTAL, 196608000),
+};
+
+/* TOPCKGEN FIXED CLK */
+static const struct mtk_fixed_clk top_fixed_clks[] = {
+	FIXED_CLK(CK_TOP_CB_CKSQ_40M, CLK_XTAL, 40000000),
+};
+
+/* TOPCKGEN FIXED DIV */
+static const struct mtk_fixed_factor top_fixed_divs[] = {
+	PLL_FACTOR(CK_TOP_CB_M_416M, "cb_m_416m", CK_APMIXED_MPLL, 1, 1),
+	PLL_FACTOR(CK_TOP_CB_M_D2, "cb_m_d2", CK_APMIXED_MPLL, 1, 2),
+	PLL_FACTOR(CK_TOP_CB_M_D3, "cb_m_d3", CK_APMIXED_MPLL, 1, 3),
+	PLL_FACTOR(CK_TOP_M_D3_D2, "m_d3_d2", CK_APMIXED_MPLL, 1, 2),
+	PLL_FACTOR(CK_TOP_CB_M_D4, "cb_m_d4", CK_APMIXED_MPLL, 1, 4),
+	PLL_FACTOR(CK_TOP_CB_M_D8, "cb_m_d8", CK_APMIXED_MPLL, 1, 8),
+	PLL_FACTOR(CK_TOP_M_D8_D2, "m_d8_d2", CK_APMIXED_MPLL, 1, 16),
+	PLL_FACTOR(CK_TOP_CB_MM_720M, "cb_mm_720m", CK_APMIXED_MMPLL, 1, 1),
+	PLL_FACTOR(CK_TOP_CB_MM_D2, "cb_mm_d2", CK_APMIXED_MMPLL, 1, 2),
+	PLL_FACTOR(CK_TOP_CB_MM_D3, "cb_mm_d3", CK_APMIXED_MMPLL, 1, 3),
+	PLL_FACTOR(CK_TOP_CB_MM_D3_D5, "cb_mm_d3_d5", CK_APMIXED_MMPLL, 1, 15),
+	PLL_FACTOR(CK_TOP_CB_MM_D4, "cb_mm_d4", CK_APMIXED_MMPLL, 1, 4),
+	PLL_FACTOR(CK_TOP_CB_MM_D6, "cb_mm_d6", CK_APMIXED_MMPLL, 1, 6),
+	PLL_FACTOR(CK_TOP_MM_D6_D2, "mm_d6_d2", CK_APMIXED_MMPLL, 1, 12),
+	PLL_FACTOR(CK_TOP_CB_MM_D8, "cb_mm_d8", CK_APMIXED_MMPLL, 1, 8),
+	PLL_FACTOR(CK_TOP_CB_APLL2_196M, "cb_apll2_196m", CK_APMIXED_APLL2, 1,
+		   1),
+	PLL_FACTOR(CK_TOP_APLL2_D2, "apll2_d2", CK_APMIXED_APLL2, 1, 2),
+	PLL_FACTOR(CK_TOP_APLL2_D4, "apll2_d4", CK_APMIXED_APLL2, 1, 4),
+	PLL_FACTOR(CK_TOP_NET1_2500M, "net1_2500m", CK_APMIXED_NET1PLL, 1, 1),
+	PLL_FACTOR(CK_TOP_CB_NET1_D4, "cb_net1_d4", CK_APMIXED_NET1PLL, 1, 4),
+	PLL_FACTOR(CK_TOP_CB_NET1_D5, "cb_net1_d5", CK_APMIXED_NET1PLL, 1, 5),
+	PLL_FACTOR(CK_TOP_NET1_D5_D2, "net1_d5_d2", CK_APMIXED_NET1PLL, 1, 10),
+	PLL_FACTOR(CK_TOP_NET1_D5_D4, "net1_d5_d4", CK_APMIXED_NET1PLL, 1, 20),
+	PLL_FACTOR(CK_TOP_CB_NET1_D8, "cb_net1_d8", CK_APMIXED_NET1PLL, 1, 8),
+	PLL_FACTOR(CK_TOP_NET1_D8_D2, "net1_d8_d2", CK_APMIXED_NET1PLL, 1, 16),
+	PLL_FACTOR(CK_TOP_NET1_D8_D4, "net1_d8_d4", CK_APMIXED_NET1PLL, 1, 32),
+	PLL_FACTOR(CK_TOP_CB_NET2_800M, "cb_net2_800m", CK_APMIXED_NET2PLL, 1,
+		   1),
+	PLL_FACTOR(CK_TOP_CB_NET2_D2, "cb_net2_d2", CK_APMIXED_NET2PLL, 1, 2),
+	PLL_FACTOR(CK_TOP_CB_NET2_D4, "cb_net2_d4", CK_APMIXED_NET2PLL, 1, 4),
+	PLL_FACTOR(CK_TOP_NET2_D4_D2, "net2_d4_d2", CK_APMIXED_NET2PLL, 1, 8),
+	PLL_FACTOR(CK_TOP_NET2_D4_D4, "net2_d4_d4", CK_APMIXED_NET2PLL, 1, 16),
+	PLL_FACTOR(CK_TOP_CB_NET2_D6, "cb_net2_d6", CK_APMIXED_NET2PLL, 1, 6),
+	PLL_FACTOR(CK_TOP_CB_WEDMCU_208M, "cb_wedmcu_208m",
+		   CK_APMIXED_WEDMCUPLL, 1, 1),
+	PLL_FACTOR(CK_TOP_CB_SGM_325M, "cb_sgm_325m", CK_APMIXED_SGMPLL, 1, 1),
+	TOP_FACTOR(CK_TOP_CKSQ_40M_D2, "cksq_40m_d2", CK_TOP_CB_CKSQ_40M, 1, 2),
+	TOP_FACTOR(CK_TOP_CB_RTC_32K, "cb_rtc_32k", CK_TOP_CB_CKSQ_40M, 1,
+		   1250),
+	TOP_FACTOR(CK_TOP_CB_RTC_32P7K, "cb_rtc_32p7k", CK_TOP_CB_CKSQ_40M, 1,
+		   1220),
+	TOP_FACTOR(CK_TOP_USB_TX250M, "usb_tx250m", CK_TOP_CB_CKSQ_40M, 1, 1),
+	TOP_FACTOR(CK_TOP_FAUD, "faud", CK_TOP_CB_CKSQ_40M, 1, 1),
+	TOP_FACTOR(CK_TOP_NFI1X, "nfi1x", CK_TOP_NFI1X_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_USB_EQ_RX250M, "usb_eq_rx250m", CK_TOP_CB_CKSQ_40M, 1,
+		   1),
+	TOP_FACTOR(CK_TOP_USB_CDR_CK, "usb_cdr", CK_TOP_CB_CKSQ_40M, 1, 1),
+	TOP_FACTOR(CK_TOP_USB_LN0_CK, "usb_ln0", CK_TOP_CB_CKSQ_40M, 1, 1),
+	TOP_FACTOR(CK_TOP_SPINFI_BCK, "spinfi_bck", CK_TOP_SPINFI_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_SPI, "spi", CK_TOP_SPI_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_SPIM_MST, "spim_mst", CK_TOP_SPIM_MST_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_UART_BCK, "uart_bck", CK_TOP_UART_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_PWM_BCK, "pwm_bck", CK_TOP_PWM_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_I2C_BCK, "i2c_bck", CK_TOP_I2C_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_PEXTP_TL, "pextp_tl", CK_TOP_PEXTP_TL_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_EMMC_208M, "emmc_208m", CK_TOP_EMMC_208M_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_EMMC_400M, "emmc_400m", CK_TOP_EMMC_400M_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_DRAMC_REF, "dramc_ref", CK_TOP_DRAMC_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_DRAMC_MD32, "dramc_md32", CK_TOP_DRAMC_MD32_SEL, 1,
+		   1),
+	TOP_FACTOR(CK_TOP_SYSAXI, "sysaxi", CK_TOP_SYSAXI_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_SYSAPB, "sysapb", CK_TOP_SYSAPB_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_ARM_DB_MAIN, "arm_db_main", CK_TOP_ARM_DB_MAIN_SEL, 1,
+		   1),
+	TOP_FACTOR(CK_TOP_AP2CNN_HOST, "ap2cnn_host", CK_TOP_AP2CNN_HOST_SEL, 1,
+		   1),
+	TOP_FACTOR(CK_TOP_NETSYS, "netsys", CK_TOP_NETSYS_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_NETSYS_500M, "netsys_500m", CK_TOP_NETSYS_500M_SEL, 1,
+		   1),
+	TOP_FACTOR(CK_TOP_NETSYS_WED_MCU, "netsys_wed_mcu",
+		   CK_TOP_NETSYS_MCU_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_NETSYS_2X, "netsys_2x", CK_TOP_NETSYS_2X_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_SGM_325M, "sgm_325m", CK_TOP_SGM_325M_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_SGM_REG, "sgm_reg", CK_TOP_SGM_REG_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_F26M, "csw_f26m", CK_TOP_F26M_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_EIP97B, "eip97b", CK_TOP_EIP97B_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_USB3_PHY, "usb3_phy", CK_TOP_USB3_PHY_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_AUD, "aud", CK_TOP_FAUD, 1, 1),
+	TOP_FACTOR(CK_TOP_A1SYS, "a1sys", CK_TOP_A1SYS_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_AUD_L, "aud_l", CK_TOP_AUD_L_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_A_TUNER, "a_tuner", CK_TOP_A_TUNER_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_U2U3_REF, "u2u3_ref", CK_TOP_U2U3_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_U2U3_SYS, "u2u3_sys", CK_TOP_U2U3_SYS_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_U2U3_XHCI, "u2u3_xhci", CK_TOP_U2U3_XHCI_SEL, 1, 1),
+	TOP_FACTOR(CK_TOP_USB_FRMCNT, "usb_frmcnt", CK_TOP_USB_FRMCNT_SEL, 1,
+		   1),
+};
+
+/* TOPCKGEN MUX PARENTS */
+static const int nfi1x_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_MM_D4,
+				     CK_TOP_NET1_D8_D2,  CK_TOP_CB_NET2_D6,
+				     CK_TOP_CB_M_D4,     CK_TOP_CB_MM_D8,
+				     CK_TOP_NET1_D8_D4,  CK_TOP_CB_M_D8 };
+
+static const int spinfi_parents[] = { CK_TOP_CKSQ_40M_D2,
 CK_TOP_CB_CKSQ_40M,
+				      CK_TOP_NET1_D5_D4,  CK_TOP_CB_M_D4,
+				      CK_TOP_CB_MM_D8,    CK_TOP_NET1_D8_D4,
+				      CK_TOP_MM_D6_D2,    CK_TOP_CB_M_D8 };
+
+static const int spi_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D2,
+				   CK_TOP_CB_MM_D4,    CK_TOP_NET1_D8_D2,
+				   CK_TOP_CB_NET2_D6,  CK_TOP_NET1_D5_D4,
+				   CK_TOP_CB_M_D4,     CK_TOP_NET1_D8_D4 };
+
+static const int uart_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D8,
+				    CK_TOP_M_D8_D2 };
+
+static const int pwm_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D8_D2,
+				   CK_TOP_NET1_D5_D4,  CK_TOP_CB_M_D4,
+				   CK_TOP_M_D8_D2,     CK_TOP_CB_RTC_32K };
+
+static const int i2c_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D5_D4,
+				   CK_TOP_CB_M_D4, CK_TOP_NET1_D8_D4 };
+
+static const int pextp_tl_ck_parents[] = { CK_TOP_CB_CKSQ_40M,
+					   CK_TOP_NET1_D5_D4, CK_TOP_CB_M_D4,
+					   CK_TOP_CB_RTC_32K };
+
+static const int emmc_208m_parents[] = {
+	CK_TOP_CB_CKSQ_40M,   CK_TOP_CB_M_D2,  CK_TOP_CB_NET2_D4,
+	CK_TOP_CB_APLL2_196M, CK_TOP_CB_MM_D4, CK_TOP_NET1_D8_D2,
+	CK_TOP_CB_MM_D6
+};
+
+static const int emmc_400m_parents[] = { CK_TOP_CB_CKSQ_40M,
 CK_TOP_CB_NET2_D2,
+					 CK_TOP_CB_MM_D2, CK_TOP_CB_NET2_D2 };
+
+static const int csw_f26m_parents[] = { CK_TOP_CKSQ_40M_D2, CK_TOP_M_D8_D2
 };
+
+static const int dramc_md32_parents[] = { CK_TOP_CB_CKSQ_40M,
 CK_TOP_CB_M_D2,
+					  CK_TOP_CB_WEDMCU_208M };
+
+static const int sysaxi_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D8_D2
 };
+
+static const int sysapb_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_M_D3_D2 };
+
+static const int arm_db_main_parents[] = { CK_TOP_CB_CKSQ_40M,
+					   CK_TOP_CB_NET2_D6 };
+
+static const int ap2cnn_host_parents[] = { CK_TOP_CB_CKSQ_40M,
+					   CK_TOP_NET1_D8_D4 };
+
+static const int netsys_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_MM_D2
 };
+
+static const int netsys_500m_parents[] = { CK_TOP_CB_CKSQ_40M,
+					   CK_TOP_CB_NET1_D5 };
+
+static const int netsys_mcu_parents[] = { CK_TOP_CB_CKSQ_40M,
 CK_TOP_CB_MM_720M,
+					  CK_TOP_CB_NET1_D4, CK_TOP_CB_NET1_D5,
+					  CK_TOP_CB_M_416M };
+
+static const int netsys_2x_parents[] = { CK_TOP_CB_CKSQ_40M,
+					 CK_TOP_CB_NET2_800M,
+					 CK_TOP_CB_MM_720M };
+
+static const int sgm_325m_parents[] = { CK_TOP_CB_CKSQ_40M,
+					CK_TOP_CB_SGM_325M };
+
+static const int sgm_reg_parents[] = { CK_TOP_CB_CKSQ_40M,
 CK_TOP_CB_NET2_D4 };
+
+static const int eip97b_parents[] = { CK_TOP_CB_CKSQ_40M,
 CK_TOP_CB_NET1_D5,
+				      CK_TOP_CB_M_416M, CK_TOP_CB_MM_D2,
+				      CK_TOP_NET1_D5_D2 };
+
+static const int aud_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_APLL2_196M
 };
+
+static const int a1sys_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_APLL2_D4 };
+
+static const int aud_l_parents[] = { CK_TOP_CB_CKSQ_40M,
 CK_TOP_CB_APLL2_196M,
+				     CK_TOP_M_D8_D2 };
+
+static const int a_tuner_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_APLL2_D4,
+				       CK_TOP_M_D8_D2 };
+
+static const int u2u3_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_M_D8_D2 };
+
+static const int u2u3_sys_parents[] = { CK_TOP_CB_CKSQ_40M,
 CK_TOP_NET1_D5_D4 };
+
+static const int usb_frmcnt_parents[] = { CK_TOP_CB_CKSQ_40M,
+					  CK_TOP_CB_MM_D3_D5 };
+
+#define TOP_MUX(_id, _name, _parents, _mux_ofs, _mux_set_ofs, _mux_clr_ofs,
    \
+		_shift, _width, _gate, _upd_ofs, _upd)                         \
+	{                                                                      \
+		.id = _id, .mux_reg = _mux_ofs, .mux_set_reg = _mux_set_ofs,   \
+		.mux_clr_reg = _mux_clr_ofs, .upd_reg = _upd_ofs,              \
+		.upd_shift = _upd, .mux_shift = _shift,                        \
+		.mux_mask = BIT(_width) - 1, .gate_reg = _mux_ofs,             \
+		.gate_shift = _gate, .parent = _parents,                       \
+		.num_parents = ARRAY_SIZE(_parents),                           \
+		.flags = CLK_MUX_SETCLR_UPD,                                   \
+	}
+
+/* TOPCKGEN MUX_GATE */
+static const struct mtk_composite top_muxes[] = {
+	TOP_MUX(CK_TOP_NFI1X_SEL, "nfi1x_sel", nfi1x_parents, 0x0, 0x4, 0x8, 0,
+		3, 7, 0x1c0, 0),
+	TOP_MUX(CK_TOP_SPINFI_SEL, "spinfi_sel", spinfi_parents, 0x0, 0x4, 0x8,
+		8, 3, 15, 0x1c0, 1),
+	TOP_MUX(CK_TOP_SPI_SEL, "spi_sel", spi_parents, 0x0, 0x4, 0x8, 16, 3,
+		23, 0x1c0, 2),
+	TOP_MUX(CK_TOP_SPIM_MST_SEL, "spim_mst_sel", spi_parents, 0x0, 0x4, 0x8,
+		24, 3, 31, 0x1c0, 3),
+	TOP_MUX(CK_TOP_UART_SEL, "uart_sel", uart_parents, 0x10, 0x14, 0x18, 0,
+		2, 7, 0x1c0, 4),
+	TOP_MUX(CK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x10, 0x14, 0x18, 8, 3,
+		15, 0x1c0, 5),
+	TOP_MUX(CK_TOP_I2C_SEL, "i2c_sel", i2c_parents, 0x10, 0x14, 0x18, 16, 2,
+		23, 0x1c0, 6),
+	TOP_MUX(CK_TOP_PEXTP_TL_SEL, "pextp_tl_ck_sel", pextp_tl_ck_parents,
+		0x10, 0x14, 0x18, 24, 2, 31, 0x1c0, 7),
+	TOP_MUX(CK_TOP_EMMC_208M_SEL, "emmc_208m_sel", emmc_208m_parents, 0x20,
+		0x24, 0x28, 0, 3, 7, 0x1c0, 8),
+	TOP_MUX(CK_TOP_EMMC_400M_SEL, "emmc_400m_sel", emmc_400m_parents, 0x20,
+		0x24, 0x28, 8, 2, 15, 0x1c0, 9),
+	TOP_MUX(CK_TOP_F26M_SEL, "csw_f26m_sel", csw_f26m_parents, 0x20, 0x24,
+		0x28, 16, 1, 23, 0x1c0, 10),
+	TOP_MUX(CK_TOP_DRAMC_SEL, "dramc_sel", csw_f26m_parents, 0x20, 0x24,
+		0x28, 24, 1, 31, 0x1c0, 11),
+	TOP_MUX(CK_TOP_DRAMC_MD32_SEL, "dramc_md32_sel", dramc_md32_parents,
+		0x30, 0x34, 0x38, 0, 2, 7, 0x1c0, 12),
+	TOP_MUX(CK_TOP_SYSAXI_SEL, "sysaxi_sel", sysaxi_parents, 0x30, 0x34,
+		0x38, 8, 1, 15, 0x1c0, 13),
+	TOP_MUX(CK_TOP_SYSAPB_SEL, "sysapb_sel", sysapb_parents, 0x30, 0x34,
+		0x38, 16, 1, 23, 0x1c0, 14),
+	TOP_MUX(CK_TOP_ARM_DB_MAIN_SEL, "arm_db_main_sel", arm_db_main_parents,
+		0x30, 0x34, 0x38, 24, 1, 31, 0x1c0, 15),
+	TOP_MUX(CK_TOP_AP2CNN_HOST_SEL, "ap2cnn_host_sel", ap2cnn_host_parents,
+		0x40, 0x44, 0x48, 0, 1, 7, 0x1c0, 16),
+	TOP_MUX(CK_TOP_NETSYS_SEL, "netsys_sel", netsys_parents, 0x40, 0x44,
+		0x48, 8, 1, 15, 0x1c0, 17),
+	TOP_MUX(CK_TOP_NETSYS_500M_SEL, "netsys_500m_sel", netsys_500m_parents,
+		0x40, 0x44, 0x48, 16, 1, 23, 0x1c0, 18),
+	TOP_MUX(CK_TOP_NETSYS_MCU_SEL, "netsys_mcu_sel", netsys_mcu_parents,
+		0x40, 0x44, 0x48, 24, 3, 31, 0x1c0, 19),
+	TOP_MUX(CK_TOP_NETSYS_2X_SEL, "netsys_2x_sel", netsys_2x_parents, 0x50,
+		0x54, 0x58, 0, 2, 7, 0x1c0, 20),
+	TOP_MUX(CK_TOP_SGM_325M_SEL, "sgm_325m_sel", sgm_325m_parents, 0x50,
+		0x54, 0x58, 8, 1, 15, 0x1c0, 21),
+	TOP_MUX(CK_TOP_SGM_REG_SEL, "sgm_reg_sel", sgm_reg_parents, 0x50, 0x54,
+		0x58, 16, 1, 23, 0x1c0, 22),
+	TOP_MUX(CK_TOP_EIP97B_SEL, "eip97b_sel", eip97b_parents, 0x50, 0x54,
+		0x58, 24, 3, 31, 0x1c0, 23),
+	TOP_MUX(CK_TOP_USB3_PHY_SEL, "usb3_phy_sel", csw_f26m_parents, 0x60,
+		0x64, 0x68, 0, 1, 7, 0x1c0, 24),
+	TOP_MUX(CK_TOP_AUD_SEL, "aud_sel", aud_parents, 0x60, 0x64, 0x68, 8, 1,
+		15, 0x1c0, 25),
+	TOP_MUX(CK_TOP_A1SYS_SEL, "a1sys_sel", a1sys_parents, 0x60, 0x64, 0x68,
+		16, 1, 23, 0x1c0, 26),
+	TOP_MUX(CK_TOP_AUD_L_SEL, "aud_l_sel", aud_l_parents, 0x60, 0x64, 0x68,
+		24, 2, 31, 0x1c0, 27),
+	TOP_MUX(CK_TOP_A_TUNER_SEL, "a_tuner_sel", a_tuner_parents, 0x70, 0x74,
+		0x78, 0, 2, 7, 0x1c0, 28),
+	TOP_MUX(CK_TOP_U2U3_SEL, "u2u3_sel", u2u3_parents, 0x70, 0x74, 0x78, 8,
+		1, 15, 0x1c0, 29),
+	TOP_MUX(CK_TOP_U2U3_SYS_SEL, "u2u3_sys_sel", u2u3_sys_parents, 0x70,
+		0x74, 0x78, 16, 1, 23, 0x1c0, 30),
+	TOP_MUX(CK_TOP_U2U3_XHCI_SEL, "u2u3_xhci_sel", u2u3_sys_parents, 0x70,
+		0x74, 0x78, 24, 1, 31, 0x1c4, 0),
+	TOP_MUX(CK_TOP_USB_FRMCNT_SEL, "usb_frmcnt_sel", usb_frmcnt_parents,
+		0x80, 0x84, 0x88, 0, 1, 7, 0x1c4, 1),
+};
+
+/* INFRA FIXED DIV */
+static const struct mtk_fixed_factor infra_fixed_divs[] = {
+	TOP_FACTOR(CK_INFRA_CK_F26M, "infra_ck_f26m", CK_TOP_F26M_SEL, 1, 1),
+	TOP_FACTOR(CK_INFRA_UART, "infra_uart", CK_TOP_UART_SEL, 1, 1),
+	TOP_FACTOR(CK_INFRA_ISPI0, "infra_ispi0", CK_TOP_SPI_SEL, 1, 1),
+	TOP_FACTOR(CK_INFRA_I2C, "infra_i2c", CK_TOP_I2C_SEL, 1, 1),
+	TOP_FACTOR(CK_INFRA_ISPI1, "infra_ispi1", CK_TOP_SPIM_MST_SEL, 1, 1),
+	TOP_FACTOR(CK_INFRA_PWM, "infra_pwm", CK_TOP_PWM_SEL, 1, 1),
+	TOP_FACTOR(CK_INFRA_66M_MCK, "infra_66m_mck", CK_TOP_SYSAXI_SEL, 1, 2),
+	TOP_FACTOR(CK_INFRA_CK_F32K, "infra_ck_f32k", CK_TOP_CB_RTC_32P7K, 1,
+		   1),
+	TOP_FACTOR(CK_INFRA_PCIE_CK, "infra_pcie", CK_TOP_PEXTP_TL_SEL, 1, 1),
+	INFRA_FACTOR(CK_INFRA_PWM_BCK, "infra_pwm_bck", CK_INFRA_PWM_BSEL, 1,
+		     1),
+	INFRA_FACTOR(CK_INFRA_PWM_CK1, "infra_pwm_ck1", CK_INFRA_PWM1_SEL, 1,
+		     1),
+	INFRA_FACTOR(CK_INFRA_PWM_CK2, "infra_pwm_ck2", CK_INFRA_PWM2_SEL, 1,
+		     1),
+	TOP_FACTOR(CK_INFRA_133M_HCK, "infra_133m_hck", CK_TOP_SYSAXI, 1, 1),
+	INFRA_FACTOR(CK_INFRA_66M_PHCK, "infra_66m_phck", CK_INFRA_133M_HCK, 1,
+		     1),
+	TOP_FACTOR(CK_INFRA_FAUD_L_CK, "infra_faud_l", CK_TOP_AUD_L, 1, 1),
+	TOP_FACTOR(CK_INFRA_FAUD_AUD_CK, "infra_faud_aud", CK_TOP_A1SYS, 1, 1),
+	TOP_FACTOR(CK_INFRA_FAUD_EG2_CK, "infra_faud_eg2", CK_TOP_A_TUNER, 1,
+		   1),
+	TOP_FACTOR(CK_INFRA_I2CS_CK, "infra_i2cs", CK_TOP_I2C_BCK, 1, 1),
+	INFRA_FACTOR(CK_INFRA_MUX_UART0, "infra_mux_uart0", CK_INFRA_UART0_SEL,
+		     1, 1),
+	INFRA_FACTOR(CK_INFRA_MUX_UART1, "infra_mux_uart1", CK_INFRA_UART1_SEL,
+		     1, 1),
+	INFRA_FACTOR(CK_INFRA_MUX_UART2, "infra_mux_uart2", CK_INFRA_UART2_SEL,
+		     1, 1),
+	TOP_FACTOR(CK_INFRA_NFI_CK, "infra_nfi", CK_TOP_NFI1X, 1, 1),
+	TOP_FACTOR(CK_INFRA_SPINFI_CK, "infra_spinfi", CK_TOP_SPINFI_BCK, 1, 1),
+	INFRA_FACTOR(CK_INFRA_MUX_SPI0, "infra_mux_spi0", CK_INFRA_SPI0_SEL, 1,
+		     1),
+	INFRA_FACTOR(CK_INFRA_MUX_SPI1, "infra_mux_spi1", CK_INFRA_SPI1_SEL, 1,
+		     1),
+	INFRA_FACTOR(CK_INFRA_MUX_SPI2, "infra_mux_spi2", CK_INFRA_SPI2_SEL, 1,
+		     1),
+	TOP_FACTOR(CK_INFRA_RTC_32K, "infra_rtc_32k", CK_TOP_CB_RTC_32K, 1, 1),
+	TOP_FACTOR(CK_INFRA_FMSDC_CK, "infra_fmsdc", CK_TOP_EMMC_400M, 1, 1),
+	TOP_FACTOR(CK_INFRA_FMSDC_HCK_CK, "infra_fmsdc_hck", CK_TOP_EMMC_208M,
+		   1, 1),
+	TOP_FACTOR(CK_INFRA_PERI_133M, "infra_peri_133m", CK_TOP_SYSAXI, 1, 1),
+	TOP_FACTOR(CK_INFRA_133M_PHCK, "infra_133m_phck", CK_TOP_SYSAXI, 1, 1),
+	TOP_FACTOR(CK_INFRA_USB_SYS_CK, "infra_usb_sys", CK_TOP_U2U3_SYS, 1, 1),
+	TOP_FACTOR(CK_INFRA_USB_CK, "infra_usb", CK_TOP_U2U3_REF, 1, 1),
+	TOP_FACTOR(CK_INFRA_USB_XHCI_CK, "infra_usb_xhci", CK_TOP_U2U3_XHCI, 1,
+		   1),
+	TOP_FACTOR(CK_INFRA_PCIE_GFMUX_TL_O_PRE, "infra_pcie_mux",
+		   CK_TOP_PEXTP_TL, 1, 1),
+	TOP_FACTOR(CK_INFRA_F26M_CK0, "infra_f26m_ck0", CK_TOP_F26M, 1, 1),
+	TOP_FACTOR(CK_INFRA_133M_MCK, "infra_133m_mck", CK_TOP_SYSAXI, 1, 1),
+};
+
+/* INFRASYS MUX PARENTS */
+static const int infra_uart0_parents[] = { CK_INFRA_CK_F26M, CK_INFRA_UART
 };
+
+static const int infra_spi0_parents[] = { CK_INFRA_I2C, CK_INFRA_ISPI0 };
+
+static const int infra_spi1_parents[] = { CK_INFRA_I2C, CK_INFRA_ISPI1 };
+
+static const int infra_pwm1_parents[] = { -1, -1, -1, CK_INFRA_PWM };
+
+static const int infra_pwm_bsel_parents[] = { -1, -1, -1, CK_INFRA_PWM };
+
+static const int infra_pcie_parents[] = { CK_INFRA_CK_F32K,
 CK_INFRA_CK_F26M,
+					  CK_TOP_CB_CKSQ_40M, CK_INFRA_PCIE_CK};
+
+#define INFRA_MUX(_id, _name, _parents, _reg, _shift, _width)              
    \
+	{                                                                      \
+		.id = _id, .mux_reg = (_reg) + 0x8,                            \
+		.mux_set_reg = (_reg) + 0x0, .mux_clr_reg = (_reg) + 0x4,      \
+		.mux_shift = _shift, .mux_mask = BIT(_width) - 1,              \
+		.parent = _parents, .num_parents = ARRAY_SIZE(_parents),       \
+		.flags = CLK_MUX_SETCLR_UPD | CLK_PARENT_INFRASYS,             \
+	}
+
+/* INFRA MUX */
+static const struct mtk_composite infra_muxes[] = {
+	INFRA_MUX(CK_INFRA_UART0_SEL, "infra_uart0_sel", infra_uart0_parents,
+		  0x10, 0, 1),
+	INFRA_MUX(CK_INFRA_UART1_SEL, "infra_uart1_sel", infra_uart0_parents,
+		  0x10, 1, 1),
+	INFRA_MUX(CK_INFRA_UART2_SEL, "infra_uart2_sel", infra_uart0_parents,
+		  0x10, 2, 1),
+	INFRA_MUX(CK_INFRA_SPI0_SEL, "infra_spi0_sel", infra_spi0_parents, 0x10,
+		  4, 1),
+	INFRA_MUX(CK_INFRA_SPI1_SEL, "infra_spi1_sel", infra_spi1_parents, 0x10,
+		  5, 1),
+	INFRA_MUX(CK_INFRA_SPI2_SEL, "infra_spi2_sel", infra_spi0_parents, 0x10,
+		  6, 1),
+	INFRA_MUX(CK_INFRA_PWM1_SEL, "infra_pwm1_sel", infra_pwm1_parents, 0x10,
+		  9, 2),
+	INFRA_MUX(CK_INFRA_PWM2_SEL, "infra_pwm2_sel", infra_pwm1_parents, 0x10,
+		  11, 2),
+	INFRA_MUX(CK_INFRA_PWM_BSEL, "infra_pwm_bsel", infra_pwm_bsel_parents,
+		  0x10, 13, 2),
+	INFRA_MUX(CK_INFRA_PCIE_SEL, "infra_pcie_sel", infra_pcie_parents, 0x20,
+		  0, 2),
+};
+
+static const struct mtk_gate_regs infra_0_cg_regs = {
+	.set_ofs = 0x40,
+	.clr_ofs = 0x44,
+	.sta_ofs = 0x48,
+};
+
+static const struct mtk_gate_regs infra_1_cg_regs = {
+	.set_ofs = 0x50,
+	.clr_ofs = 0x54,
+	.sta_ofs = 0x58,
+};
+
+static const struct mtk_gate_regs infra_2_cg_regs = {
+	.set_ofs = 0x60,
+	.clr_ofs = 0x64,
+	.sta_ofs = 0x68,
+};
+
+#define GATE_INFRA0(_id, _name, _parent, _shift)                           
    \
+	{                                                                      \
+		.id = _id, .parent = _parent, .regs = &infra_0_cg_regs,        \
+		.shift = _shift,                                               \
+		.flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS,                \
+	}
+
+#define GATE_INFRA1(_id, _name, _parent, _shift)                           
    \
+	{                                                                      \
+		.id = _id, .parent = _parent, .regs = &infra_1_cg_regs,        \
+		.shift = _shift,                                               \
+		.flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS,                \
+	}
+
+#define GATE_INFRA2(_id, _name, _parent, _shift)                           
    \
+	{                                                                      \
+		.id = _id, .parent = _parent, .regs = &infra_2_cg_regs,        \
+		.shift = _shift,                                               \
+		.flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS,                \
+	}
+
+/* INFRA GATE */
+static const struct mtk_gate infracfg_ao_gates[] = {
+	GATE_INFRA0(CK_INFRA_GPT_STA, "infra_gpt_sta", CK_INFRA_66M_MCK, 0),
+	GATE_INFRA0(CK_INFRA_PWM_HCK, "infra_pwm_hck", CK_INFRA_66M_MCK, 1),
+	GATE_INFRA0(CK_INFRA_PWM_STA, "infra_pwm_sta", CK_INFRA_PWM_BCK, 2),
+	GATE_INFRA0(CK_INFRA_PWM1_CK, "infra_pwm1", CK_INFRA_PWM_CK1, 3),
+	GATE_INFRA0(CK_INFRA_PWM2_CK, "infra_pwm2", CK_INFRA_PWM_CK2, 4),
+	GATE_INFRA0(CK_INFRA_CQ_DMA_CK, "infra_cq_dma", CK_INFRA_133M_HCK, 6),
+	GATE_INFRA0(CK_INFRA_AUD_BUS_CK, "infra_aud_bus", CK_INFRA_66M_PHCK, 8),
+	GATE_INFRA0(CK_INFRA_AUD_26M_CK, "infra_aud_26m", CK_INFRA_CK_F26M, 9),
+	GATE_INFRA0(CK_INFRA_AUD_L_CK, "infra_aud_l", CK_INFRA_FAUD_L_CK, 10),
+	GATE_INFRA0(CK_INFRA_AUD_AUD_CK, "infra_aud_aud", CK_INFRA_FAUD_AUD_CK,
+		    11),
+	GATE_INFRA0(CK_INFRA_AUD_EG2_CK, "infra_aud_eg2", CK_INFRA_FAUD_EG2_CK,
+		    13),
+	GATE_INFRA0(CK_INFRA_DRAMC_26M_CK, "infra_dramc_26m", CK_INFRA_CK_F26M,
+		    14),
+	GATE_INFRA0(CK_INFRA_DBG_CK, "infra_dbg", CK_INFRA_66M_MCK, 15),
+	GATE_INFRA0(CK_INFRA_AP_DMA_CK, "infra_ap_dma", CK_INFRA_66M_MCK, 16),
+	GATE_INFRA0(CK_INFRA_SEJ_CK, "infra_sej", CK_INFRA_66M_MCK, 24),
+	GATE_INFRA0(CK_INFRA_SEJ_13M_CK, "infra_sej_13m", CK_INFRA_CK_F26M, 25),
+	GATE_INFRA1(CK_INFRA_THERM_CK, "infra_therm", CK_INFRA_CK_F26M, 0),
+	GATE_INFRA1(CK_INFRA_I2CO_CK, "infra_i2co", CK_INFRA_I2CS_CK, 1),
+	GATE_INFRA1(CK_INFRA_UART0_CK, "infra_uart0", CK_INFRA_MUX_UART0, 2),
+	GATE_INFRA1(CK_INFRA_UART1_CK, "infra_uart1", CK_INFRA_MUX_UART1, 3),
+	GATE_INFRA1(CK_INFRA_UART2_CK, "infra_uart2", CK_INFRA_MUX_UART2, 4),
+	GATE_INFRA1(CK_INFRA_SPI2_CK, "infra_spi2", CK_INFRA_MUX_SPI2, 6),
+	GATE_INFRA1(CK_INFRA_SPI2_HCK_CK, "infra_spi2_hck", CK_INFRA_66M_MCK,
+		    7),
+	GATE_INFRA1(CK_INFRA_NFI1_CK, "infra_nfi1", CK_INFRA_NFI_CK, 8),
+	GATE_INFRA1(CK_INFRA_SPINFI1_CK, "infra_spinfi1", CK_INFRA_SPINFI_CK,
+		    9),
+	GATE_INFRA1(CK_INFRA_NFI_HCK_CK, "infra_nfi_hck", CK_INFRA_66M_MCK, 10),
+	GATE_INFRA1(CK_INFRA_SPI0_CK, "infra_spi0", CK_INFRA_MUX_SPI0, 11),
+	GATE_INFRA1(CK_INFRA_SPI1_CK, "infra_spi1", CK_INFRA_MUX_SPI1, 12),
+	GATE_INFRA1(CK_INFRA_SPI0_HCK_CK, "infra_spi0_hck", CK_INFRA_66M_MCK,
+		    13),
+	GATE_INFRA1(CK_INFRA_SPI1_HCK_CK, "infra_spi1_hck", CK_INFRA_66M_MCK,
+		    14),
+	GATE_INFRA1(CK_INFRA_FRTC_CK, "infra_frtc", CK_INFRA_RTC_32K, 15),
+	GATE_INFRA1(CK_INFRA_MSDC_CK, "infra_msdc", CK_INFRA_FMSDC_CK, 16),
+	GATE_INFRA1(CK_INFRA_MSDC_HCK_CK, "infra_msdc_hck",
+		    CK_INFRA_FMSDC_HCK_CK, 17),
+	GATE_INFRA1(CK_INFRA_MSDC_133M_CK, "infra_msdc_133m",
+		    CK_INFRA_PERI_133M, 18),
+	GATE_INFRA1(CK_INFRA_MSDC_66M_CK, "infra_msdc_66m", CK_INFRA_66M_PHCK,
+		    19),
+	GATE_INFRA1(CK_INFRA_ADC_26M_CK, "infra_adc_26m", CK_TOP_F26M, 20),
+	GATE_INFRA1(CK_INFRA_ADC_FRC_CK, "infra_adc_frc", CK_TOP_F26M, 21),
+	GATE_INFRA1(CK_INFRA_FBIST2FPC_CK, "infra_fbist2fpc", CK_INFRA_NFI_CK,
+		    23),
+	GATE_INFRA1(CK_INFRA_I2C_MCK_CK, "infra_i2c_mck", CK_INFRA_133M_MCK,
+		    25),
+	GATE_INFRA1(CK_INFRA_I2C_PCK_CK, "infra_i2c_pck", CK_INFRA_66M_MCK, 26),
+	GATE_INFRA2(CK_INFRA_IUSB_133_CK, "infra_iusb_133", CK_INFRA_133M_PHCK,
+		    0),
+	GATE_INFRA2(CK_INFRA_IUSB_66M_CK, "infra_iusb_66m", CK_INFRA_66M_PHCK,
+		    1),
+	GATE_INFRA2(CK_INFRA_IUSB_SYS_CK, "infra_iusb_sys", CK_INFRA_USB_SYS_CK,
+		    2),
+	GATE_INFRA2(CK_INFRA_IUSB_CK, "infra_iusb", CK_INFRA_USB_CK, 3),
+	GATE_INFRA2(CK_INFRA_IPCIE_CK, "infra_ipcie",
+		    CK_INFRA_PCIE_GFMUX_TL_O_PRE, 12),
+	GATE_INFRA2(CK_INFRA_IPCIER_CK, "infra_ipcier", CK_INFRA_F26M_CK0, 14),
+	GATE_INFRA2(CK_INFRA_IPCIEB_CK, "infra_ipcieb", CK_INFRA_133M_PHCK, 15),
+};
+
+static const struct mtk_clk_tree mt7981_fixed_pll_clk_tree = {
+	.fdivs_offs = CLK_APMIXED_NR_CLK,
+	.xtal_rate = 40 * MHZ,
+	.fclks = fixed_pll_clks,
+};
+
+static const struct mtk_clk_tree mt7981_topckgen_clk_tree = {
+	.fdivs_offs = CK_TOP_CB_M_416M,
+	.muxes_offs = CK_TOP_NFI1X_SEL,
+	.fclks = top_fixed_clks,
+	.fdivs = top_fixed_divs,
+	.muxes = top_muxes,
+	.flags = CLK_BYPASS_XTAL,
+};
+
+static const struct mtk_clk_tree mt7981_infracfg_clk_tree = {
+	.fdivs_offs = CK_INFRA_CK_F26M,
+	.muxes_offs = CK_INFRA_UART0_SEL,
+	.fdivs = infra_fixed_divs,
+	.muxes = infra_muxes,
+};
+
+static const struct udevice_id mt7981_fixed_pll_compat[] = {
+	{ .compatible = "mediatek,mt7981-fixed-plls" },
+	{}
+};
+
+static const struct udevice_id mt7981_topckgen_compat[] = {
+	{ .compatible = "mediatek,mt7981-topckgen" },
+	{}
+};
+
+static int mt7981_fixed_pll_probe(struct udevice *dev)
+{
+	return mtk_common_clk_init(dev, &mt7981_fixed_pll_clk_tree);
+}
+
+static int mt7981_topckgen_probe(struct udevice *dev)
+{
+	struct mtk_clk_priv *priv = dev_get_priv(dev);
+
+	priv->base = dev_read_addr_ptr(dev);
+	writel(MT7981_CLK_PDN_EN_WRITE, priv->base + MT7981_CLK_PDN);
+	return mtk_common_clk_init(dev, &mt7981_topckgen_clk_tree);
+}
+
+U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
+	.name = "mt7981-clock-fixed-pll",
+	.id = UCLASS_CLK,
+	.of_match = mt7981_fixed_pll_compat,
+	.probe = mt7981_fixed_pll_probe,
+	.priv_auto = sizeof(struct mtk_clk_priv),
+	.ops = &mtk_clk_topckgen_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(mtk_clk_topckgen) = {
+	.name = "mt7981-clock-topckgen",
+	.id = UCLASS_CLK,
+	.of_match = mt7981_topckgen_compat,
+	.probe = mt7981_topckgen_probe,
+	.priv_auto = sizeof(struct mtk_clk_priv),
+	.ops = &mtk_clk_topckgen_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
+
+static const struct udevice_id mt7981_infracfg_compat[] = {
+	{ .compatible = "mediatek,mt7981-infracfg" },
+	{}
+};
+
+static const struct udevice_id mt7981_infracfg_ao_compat[] = {
+	{ .compatible = "mediatek,mt7981-infracfg_ao" },
+	{}
+};
+
+static int mt7981_infracfg_probe(struct udevice *dev)
+{
+	return mtk_common_clk_init(dev, &mt7981_infracfg_clk_tree);
+}
+
+static int mt7981_infracfg_ao_probe(struct udevice *dev)
+{
+	return mtk_common_clk_gate_init(dev, &mt7981_infracfg_clk_tree,
+					infracfg_ao_gates);
+}
+
+U_BOOT_DRIVER(mtk_clk_infracfg) = {
+	.name = "mt7981-clock-infracfg",
+	.id = UCLASS_CLK,
+	.of_match = mt7981_infracfg_compat,
+	.probe = mt7981_infracfg_probe,
+	.priv_auto = sizeof(struct mtk_clk_priv),
+	.ops = &mtk_clk_infrasys_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(mtk_clk_infracfg_ao) = {
+	.name = "mt7981-clock-infracfg-ao",
+	.id = UCLASS_CLK,
+	.of_match = mt7981_infracfg_ao_compat,
+	.probe = mt7981_infracfg_ao_probe,
+	.priv_auto = sizeof(struct mtk_cg_priv),
+	.ops = &mtk_clk_gate_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
+
+/* ethsys */
+static const struct mtk_gate_regs eth_cg_regs = {
+	.set_ofs = 0x30,
+	.clr_ofs = 0x30,
+	.sta_ofs = 0x30,
+};
+
+#define GATE_ETH(_id, _name, _parent, _shift)                              
    \
+	{                                                                      \
+		.id = _id, .parent = _parent, .regs = &eth_cg_regs,            \
+		.shift = _shift,                                               \
+		.flags = CLK_GATE_NO_SETCLR_INV | CLK_PARENT_TOPCKGEN,         \
+	}
+
+static const struct mtk_gate eth_cgs[] = {
+	GATE_ETH(CK_ETH_FE_EN, "eth_fe_en", CK_TOP_NETSYS_2X, 6),
+	GATE_ETH(CK_ETH_GP2_EN, "eth_gp2_en", CK_TOP_SGM_325M, 7),
+	GATE_ETH(CK_ETH_GP1_EN, "eth_gp1_en", CK_TOP_SGM_325M, 8),
+	GATE_ETH(CK_ETH_WOCPU0_EN, "eth_wocpu0_en", CK_TOP_NETSYS_WED_MCU, 15),
+};
+
+static int mt7981_ethsys_probe(struct udevice *dev)
+{
+	return mtk_common_clk_gate_init(dev, &mt7981_topckgen_clk_tree,
+					eth_cgs);
+}
+
+static int mt7981_ethsys_bind(struct udevice *dev)
+{
+	int ret = 0;
+
+#if CONFIG_IS_ENABLED(RESET_MEDIATEK)
+	ret = mediatek_reset_bind(dev, ETHSYS_HIFSYS_RST_CTRL_OFS, 1);
+	if (ret)
+		debug("Warning: failed to bind reset controller\n");
+#endif
+
+	return ret;
+}
+
+static const struct udevice_id mt7981_ethsys_compat[] = {
+	{ .compatible = "mediatek,mt7981-ethsys", },
+	{}
+};
+
+U_BOOT_DRIVER(mtk_clk_ethsys) = {
+	.name = "mt7981-clock-ethsys",
+	.id = UCLASS_CLK,
+	.of_match = mt7981_ethsys_compat,
+	.probe = mt7981_ethsys_probe,
+	.bind = mt7981_ethsys_bind,
+	.priv_auto = sizeof(struct mtk_cg_priv),
+	.ops = &mtk_clk_gate_ops,
+};
diff --git a/include/dt-bindings/clock/mt7981-clk.h
 b/include/dt-bindings/clock/mt7981-clk.h
new file mode 100644
index 0000000000..e24c759e49
--- /dev/null
+++ b/include/dt-bindings/clock/mt7981-clk.h
@@ -0,0 +1,267 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2022 MediaTek Inc. All rights reserved.
+ *
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_MT7981_H
+#define _DT_BINDINGS_CLK_MT7981_H
+
+/* INFRACFG */
+
+#define CK_INFRA_CK_F26M		0
+#define CK_INFRA_UART			1
+#define CK_INFRA_ISPI0			2
+#define CK_INFRA_I2C			3
+#define CK_INFRA_ISPI1			4
+#define CK_INFRA_PWM			5
+#define CK_INFRA_66M_MCK		6
+#define CK_INFRA_CK_F32K		7
+#define CK_INFRA_PCIE_CK		8
+#define CK_INFRA_PWM_BCK		9
+#define CK_INFRA_PWM_CK1		10
+#define CK_INFRA_PWM_CK2		11
+#define CK_INFRA_133M_HCK		12
+#define CK_INFRA_66M_PHCK		13
+#define CK_INFRA_FAUD_L_CK		14
+#define CK_INFRA_FAUD_AUD_CK		15
+#define CK_INFRA_FAUD_EG2_CK		16
+#define CK_INFRA_I2CS_CK		17
+#define CK_INFRA_MUX_UART0		18
+#define CK_INFRA_MUX_UART1		19
+#define CK_INFRA_MUX_UART2		20
+#define CK_INFRA_NFI_CK			21
+#define CK_INFRA_SPINFI_CK		22
+#define CK_INFRA_MUX_SPI0		23
+#define CK_INFRA_MUX_SPI1		24
+#define CK_INFRA_MUX_SPI2		25
+#define CK_INFRA_RTC_32K		26
+#define CK_INFRA_FMSDC_CK		27
+#define CK_INFRA_FMSDC_HCK_CK		28
+#define CK_INFRA_PERI_133M		29
+#define CK_INFRA_133M_PHCK		30
+#define CK_INFRA_USB_SYS_CK		31
+#define CK_INFRA_USB_CK			32
+#define CK_INFRA_USB_XHCI_CK		33
+#define CK_INFRA_PCIE_GFMUX_TL_O_PRE	34
+#define CK_INFRA_F26M_CK0		35
+#define CK_INFRA_133M_MCK		36
+#define CLK_INFRA_NR_CLK		37
+
+/* TOPCKGEN */
+
+#define CK_TOP_CB_CKSQ_40M		0
+#define CK_TOP_CB_M_416M		1
+#define CK_TOP_CB_M_D2			2
+#define CK_TOP_CB_M_D3			3
+#define CK_TOP_M_D3_D2			4
+#define CK_TOP_CB_M_D4			5
+#define CK_TOP_CB_M_D8			6
+#define CK_TOP_M_D8_D2			7
+#define CK_TOP_CB_MM_720M		8
+#define CK_TOP_CB_MM_D2			9
+#define CK_TOP_CB_MM_D3			10
+#define CK_TOP_CB_MM_D3_D5		11
+#define CK_TOP_CB_MM_D4			12
+#define CK_TOP_CB_MM_D6			13
+#define CK_TOP_MM_D6_D2			14
+#define CK_TOP_CB_MM_D8			15
+#define CK_TOP_CB_APLL2_196M		16
+#define CK_TOP_APLL2_D2			17
+#define CK_TOP_APLL2_D4			18
+#define CK_TOP_NET1_2500M		19
+#define CK_TOP_CB_NET1_D4		20
+#define CK_TOP_CB_NET1_D5		21
+#define CK_TOP_NET1_D5_D2		22
+#define CK_TOP_NET1_D5_D4		23
+#define CK_TOP_CB_NET1_D8		24
+#define CK_TOP_NET1_D8_D2		25
+#define CK_TOP_NET1_D8_D4		26
+#define CK_TOP_CB_NET2_800M		27
+#define CK_TOP_CB_NET2_D2		28
+#define CK_TOP_CB_NET2_D4		29
+#define CK_TOP_NET2_D4_D2		30
+#define CK_TOP_NET2_D4_D4		31
+#define CK_TOP_CB_NET2_D6		32
+#define CK_TOP_CB_WEDMCU_208M		33
+#define CK_TOP_CB_SGM_325M		34
+#define CK_TOP_CKSQ_40M_D2		35
+#define CK_TOP_CB_RTC_32K		36
+#define CK_TOP_CB_RTC_32P7K		37
+#define CK_TOP_USB_TX250M		38
+#define CK_TOP_FAUD			39
+#define CK_TOP_NFI1X			40
+#define CK_TOP_USB_EQ_RX250M		41
+#define CK_TOP_USB_CDR_CK		42
+#define CK_TOP_USB_LN0_CK		43
+#define CK_TOP_SPINFI_BCK		44
+#define CK_TOP_SPI			45
+#define CK_TOP_SPIM_MST			46
+#define CK_TOP_UART_BCK			47
+#define CK_TOP_PWM_BCK			48
+#define CK_TOP_I2C_BCK			49
+#define CK_TOP_PEXTP_TL			50
+#define CK_TOP_EMMC_208M		51
+#define CK_TOP_EMMC_400M		52
+#define CK_TOP_DRAMC_REF		53
+#define CK_TOP_DRAMC_MD32		54
+#define CK_TOP_SYSAXI			55
+#define CK_TOP_SYSAPB			56
+#define CK_TOP_ARM_DB_MAIN		57
+#define CK_TOP_AP2CNN_HOST		58
+#define CK_TOP_NETSYS			59
+#define CK_TOP_NETSYS_500M		60
+#define CK_TOP_NETSYS_WED_MCU		61
+#define CK_TOP_NETSYS_2X		62
+#define CK_TOP_SGM_325M			63
+#define CK_TOP_SGM_REG			64
+#define CK_TOP_F26M			65
+#define CK_TOP_EIP97B			66
+#define CK_TOP_USB3_PHY			67
+#define CK_TOP_AUD			68
+#define CK_TOP_A1SYS			69
+#define CK_TOP_AUD_L			70
+#define CK_TOP_A_TUNER			71
+#define CK_TOP_U2U3_REF			72
+#define CK_TOP_U2U3_SYS			73
+#define CK_TOP_U2U3_XHCI		74
+#define CK_TOP_USB_FRMCNT		75
+#define CK_TOP_NFI1X_SEL		76
+#define CK_TOP_SPINFI_SEL		77
+#define CK_TOP_SPI_SEL			78
+#define CK_TOP_SPIM_MST_SEL		79
+#define CK_TOP_UART_SEL			80
+#define CK_TOP_PWM_SEL			81
+#define CK_TOP_I2C_SEL			82
+#define CK_TOP_PEXTP_TL_SEL		83
+#define CK_TOP_EMMC_208M_SEL		84
+#define CK_TOP_EMMC_400M_SEL		85
+#define CK_TOP_F26M_SEL			86
+#define CK_TOP_DRAMC_SEL		87
+#define CK_TOP_DRAMC_MD32_SEL		88
+#define CK_TOP_SYSAXI_SEL		89
+#define CK_TOP_SYSAPB_SEL		90
+#define CK_TOP_ARM_DB_MAIN_SEL		91
+#define CK_TOP_AP2CNN_HOST_SEL		92
+#define CK_TOP_NETSYS_SEL		93
+#define CK_TOP_NETSYS_500M_SEL		94
+#define CK_TOP_NETSYS_MCU_SEL		95
+#define CK_TOP_NETSYS_2X_SEL		96
+#define CK_TOP_SGM_325M_SEL		97
+#define CK_TOP_SGM_REG_SEL		98
+#define CK_TOP_EIP97B_SEL		99
+#define CK_TOP_USB3_PHY_SEL		100
+#define CK_TOP_AUD_SEL			101
+#define CK_TOP_A1SYS_SEL		102
+#define CK_TOP_AUD_L_SEL		103
+#define CK_TOP_A_TUNER_SEL		104
+#define CK_TOP_U2U3_SEL			105
+#define CK_TOP_U2U3_SYS_SEL		106
+#define CK_TOP_U2U3_XHCI_SEL		107
+#define CK_TOP_USB_FRMCNT_SEL		108
+#define CLK_TOP_NR_CLK			109
+
+/*
+ * INFRACFG_AO
+ * clock muxes need to be append to infracfg domain, and clock gates
+ * need to be keep in infracgh_ao domain
+ */
+#define INFRACFG_AO_OFFSET		10
+
+#define CK_INFRA_UART0_SEL		(0 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_UART1_SEL		(1 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_UART2_SEL		(2 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_SPI0_SEL		(3 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_SPI1_SEL		(4 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_SPI2_SEL		(5 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_PWM1_SEL		(6 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_PWM2_SEL		(7 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_PWM_BSEL		(8 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_PCIE_SEL		(9 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_GPT_STA		(10 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_PWM_HCK		(11 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_PWM_STA		(12 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_PWM1_CK		(13 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_PWM2_CK		(14 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_CQ_DMA_CK		(15 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_AUD_BUS_CK		(16 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_AUD_26M_CK		(17 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_AUD_L_CK		(18 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_AUD_AUD_CK		(19 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_AUD_EG2_CK		(20 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_DRAMC_26M_CK		(21 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_DBG_CK			(22 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_AP_DMA_CK		(23 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_SEJ_CK			(24 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_SEJ_13M_CK		(25 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_THERM_CK		(26 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_I2CO_CK		(27 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_UART0_CK		(28 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_UART1_CK		(29 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_UART2_CK		(30 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_SPI2_CK		(31 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_SPI2_HCK_CK		(32 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_NFI1_CK		(33 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_SPINFI1_CK		(34 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_NFI_HCK_CK		(35 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_SPI0_CK		(36 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_SPI1_CK		(37 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_SPI0_HCK_CK		(38 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_SPI1_HCK_CK		(39 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_FRTC_CK		(40 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_MSDC_CK		(41 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_MSDC_HCK_CK		(42 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_MSDC_133M_CK		(43 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_MSDC_66M_CK		(44 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_ADC_26M_CK		(45 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_ADC_FRC_CK		(46 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_FBIST2FPC_CK		(47 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_I2C_MCK_CK		(48 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_I2C_PCK_CK		(49 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_IUSB_133_CK		(50 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_IUSB_66M_CK		(51 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_IUSB_SYS_CK		(52 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_IUSB_CK		(53 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_IPCIE_CK		(54 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_IPCIER_CK		(55 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_IPCIEB_CK		(56 - INFRACFG_AO_OFFSET)
+#define CLK_INFRA_AO_NR_CLK		(57 - INFRACFG_AO_OFFSET)
+
+/* APMIXEDSYS */
+
+#define CK_APMIXED_ARMPLL		0
+#define CK_APMIXED_NET2PLL		1
+#define CK_APMIXED_MMPLL		2
+#define CK_APMIXED_SGMPLL		3
+#define CK_APMIXED_WEDMCUPLL		4
+#define CK_APMIXED_NET1PLL		5
+#define CK_APMIXED_MPLL			6
+#define CK_APMIXED_APLL2		7
+#define CLK_APMIXED_NR_CLK		8
+
+/* SGMIISYS_0 */
+
+#define CK_SGM0_TX_EN			0
+#define CK_SGM0_RX_EN			1
+#define CK_SGM0_CK0_EN			2
+#define CK_SGM0_CDR_CK0_EN		3
+#define CLK_SGMII0_NR_CLK		4
+
+/* SGMIISYS_1 */
+
+#define CK_SGM1_TX_EN			0
+#define CK_SGM1_RX_EN			1
+#define CK_SGM1_CK1_EN			2
+#define CK_SGM1_CDR_CK1_EN		3
+#define CLK_SGMII1_NR_CLK		4
+
+/* ETHSYS */
+
+#define CK_ETH_FE_EN			0
+#define CK_ETH_GP2_EN			1
+#define CK_ETH_GP1_EN			2
+#define CK_ETH_WOCPU0_EN		3
+#define CLK_ETH_NR_CLK			4
+
+#endif /* _DT_BINDINGS_CLK_MT7981_H */
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 28/31] tools: mtk_image: split gfh header verification into a new function
  2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
                   ` (26 preceding siblings ...)
  2022-08-04  3:36 ` [PATCH 27/31] clk: mediatek: add clock driver support for MediaTek MT7981 SoC Weijie Gao
@ 2022-08-04  3:36 ` Weijie Gao
  2022-08-04 13:57   ` Simon Glass
  2022-08-04  3:36 ` [PATCH 29/31] tools: mtk_image: split the code of generating NAND header into a new file Weijie Gao
                   ` (2 subsequent siblings)
  30 siblings, 1 reply; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:36 UTC (permalink / raw)
  To: u-boot; +Cc: GSS_MTK_Uboot_upstream, Weijie Gao

The verification code of gfh header for NAND and non-NAND are identical.
It's better to define a individual function to reduce redundancy.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 tools/mtk_image.c | 51 +++++++++++++++++++----------------------------
 1 file changed, 21 insertions(+), 30 deletions(-)

diff --git a/tools/mtk_image.c b/tools/mtk_image.c
index de5ce4d964..dcd6525f32 100644
--- a/tools/mtk_image.c
+++ b/tools/mtk_image.c
@@ -480,6 +480,25 @@ static int mtk_image_vrec_header(struct
 image_tool_params *params,
 	return SHA256_SUM_LEN;
 }
 
+static int mtk_image_verify_gfh(struct gfh_header *gfh, uint32_t type, int
 print)
+{
+	if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME))
+		return -1;
+
+	if (le32_to_cpu(gfh->file_info.flash_type) != type)
+		return -1;
+
+	if (print)
+		printf("Load Address: %08x\n",
+		       le32_to_cpu(gfh->file_info.load_addr) +
+		       le32_to_cpu(gfh->file_info.jump_offset));
+
+	if (print)
+		printf("Architecture: %s\n", is_arm64_image ? "ARM64" : "ARM");
+
+	return 0;
+}
+
 static int mtk_image_verify_gen_header(const uint8_t *ptr, int print)
 {
 	union gen_boot_header *gbh = (union gen_boot_header *)ptr;
@@ -542,21 +561,7 @@ static int mtk_image_verify_gen_header(const uint8_t
 *ptr, int print)
 
 	gfh = (struct gfh_header *)(ptr + gfh_offset);
 
-	if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME))
-		return -1;
-
-	if (le32_to_cpu(gfh->file_info.flash_type) != GFH_FLASH_TYPE_GEN)
-		return -1;
-
-	if (print)
-		printf("Load Address: %08x\n",
-		       le32_to_cpu(gfh->file_info.load_addr) +
-		       le32_to_cpu(gfh->file_info.jump_offset));
-
-	if (print)
-		printf("Architecture: %s\n", is_arm64_image ? "ARM64" : "ARM");
-
-	return 0;
+	return mtk_image_verify_gfh(gfh, GFH_FLASH_TYPE_GEN, print);
 }
 
 static int mtk_image_verify_nand_header(const uint8_t *ptr, int print)
@@ -610,21 +615,7 @@ static int mtk_image_verify_nand_header(const uint8_t
 *ptr, int print)
 
 	gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(nh->pagesize));
 
-	if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME))
-		return -1;
-
-	if (le32_to_cpu(gfh->file_info.flash_type) != GFH_FLASH_TYPE_NAND)
-		return -1;
-
-	if (print)
-		printf("Load Address: %08x\n",
-		       le32_to_cpu(gfh->file_info.load_addr) +
-		       le32_to_cpu(gfh->file_info.jump_offset));
-
-	if (print)
-		printf("Architecture: %s\n", is_arm64_image ? "ARM64" : "ARM");
-
-	return 0;
+	return mtk_image_verify_gfh(gfh, GFH_FLASH_TYPE_NAND, print);
 }
 
 static uint32_t crc32be_cal(const void *data, size_t length)
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 29/31] tools: mtk_image: split the code of generating NAND header into a new file
  2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
                   ` (27 preceding siblings ...)
  2022-08-04  3:36 ` [PATCH 28/31] tools: mtk_image: split gfh header verification into a new function Weijie Gao
@ 2022-08-04  3:36 ` Weijie Gao
  2022-08-04 13:57   ` Simon Glass
  2022-08-05 18:26   ` Daniel Golle
  2022-08-04  3:36 ` [PATCH 30/31] tools: mtk_image: add support for nand headers used by newer chips Weijie Gao
  2022-08-04  3:36 ` [PATCH 31/31] MAINTAINERS: update maintainer for MediaTek ARM platform Weijie Gao
  30 siblings, 2 replies; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:36 UTC (permalink / raw)
  To: u-boot
  Cc: GSS_MTK_Uboot_upstream, Simon Glass, AKASHI Takahiro,
	Pali Rohár, Stefan Roese, Andre Przywara, Samuel Holland,
	Weijie Gao

The predefined NAND headers take too much spaces in the mtk_image.c.
Moving them into a new file can significantly improve the readability of
both mtk_image.c and the new mtk_nand_headers.c.

This is a preparation for adding more NAND headers.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 tools/Makefile           |   1 +
 tools/mtk_image.c        | 304 ++++++---------------------------------
 tools/mtk_image.h        |  25 ----
 tools/mtk_nand_headers.c | 286 ++++++++++++++++++++++++++++++++++++
 tools/mtk_nand_headers.h |  52 +++++++
 5 files changed, 379 insertions(+), 289 deletions(-)
 create mode 100644 tools/mtk_nand_headers.c
 create mode 100644 tools/mtk_nand_headers.h

diff --git a/tools/Makefile b/tools/Makefile
index 9f2339666a..4f27ed1ab1 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -147,6 +147,7 @@ dumpimage-mkimage-objs := aisimage.o \
 			gpimage.o \
 			gpimage-common.o \
 			mtk_image.o \
+			mtk_nand_headers.o \
 			$(ECDSA_OBJS-y) \
 			$(RSA_OBJS-y) \
 			$(AES_OBJS-y)
diff --git a/tools/mtk_image.c b/tools/mtk_image.c
index dcd6525f32..3701d1564a 100644
--- a/tools/mtk_image.c
+++ b/tools/mtk_image.c
@@ -12,216 +12,7 @@
 #include <u-boot/sha256.h>
 #include "imagetool.h"
 #include "mtk_image.h"
-
-/* NAND header for SPI-NAND with 2KB page + 64B spare */
-static const union nand_boot_header snand_hdr_2k_64_data = {
-	.data = {
-		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
-		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
-		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
-		0x00, 0x00, 0x00, 0x08, 0x03, 0x00, 0x40, 0x00,
-		0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x7B, 0xC4, 0x17, 0x9D,
-		0xCA, 0x42, 0x90, 0xD0, 0x98, 0xD0, 0xE0, 0xF7,
-		0xDB, 0xCD, 0x16, 0xF6, 0x03, 0x73, 0xD2, 0xB8,
-		0x93, 0xB2, 0x56, 0x5A, 0x84, 0x6E, 0x00, 0x00
-	}
-};
-
-/* NAND header for SPI-NAND with 2KB page + 120B/128B spare */
-static const union nand_boot_header snand_hdr_2k_128_data = {
-	.data = {
-		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
-		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
-		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
-		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
-		0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x90, 0x28, 0xED, 0x13,
-		0x7F, 0x12, 0x22, 0xCD, 0x3D, 0x06, 0xF1, 0xB3,
-		0x6F, 0x2E, 0xD9, 0xA0, 0x9D, 0x7A, 0xBD, 0xD7,
-		0xB3, 0x28, 0x3C, 0x13, 0xDB, 0x4E, 0x00, 0x00
-	}
-};
-
-/* NAND header for SPI-NAND with 4KB page + 256B spare */
-static const union nand_boot_header snand_hdr_4k_256_data = {
-	.data = {
-		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
-		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
-		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
-		0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0xE0, 0x00,
-		0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x47, 0xED, 0x0E, 0xC3,
-		0x83, 0xBF, 0x41, 0xD2, 0x85, 0x21, 0x97, 0x57,
-		0xC4, 0x2E, 0x6B, 0x7A, 0x40, 0xE0, 0xCF, 0x8F,
-		0x37, 0xBD, 0x17, 0xB6, 0xC7, 0xFE, 0x00, 0x00
-	}
-};
-
-/* NAND header for Parallel NAND 1Gb with 2KB page + 64B spare */
-static const union nand_boot_header nand_hdr_1gb_2k_64_data = {
-	.data = {
-		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
-		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
-		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
-		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
-		0x40, 0x00, 0x00, 0x04, 0x0B, 0x00, 0x11, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x1C, 0x12,
-		0x8F, 0xFD, 0xF8, 0x32, 0x6F, 0x6D, 0xCF, 0x6C,
-		0xDA, 0x21, 0x70, 0x8C, 0xDA, 0x0A, 0x22, 0x82,
-		0xAA, 0x59, 0xFA, 0x7C, 0x42, 0x2D, 0x00, 0x00
-	}
-};
-
-/* NAND header for Parallel NAND 2Gb with 2KB page + 64B spare */
-static const union nand_boot_header nand_hdr_2gb_2k_64_data = {
-	.data = {
-		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
-		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
-		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
-		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
-		0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x20, 0x9C, 0x3D, 0x2D,
-		0x7B, 0x68, 0x63, 0x52, 0x2E, 0x04, 0x63, 0xF1,
-		0x35, 0x4E, 0x44, 0x3E, 0xF8, 0xAC, 0x9B, 0x95,
-		0xAB, 0xFE, 0xE4, 0xE1, 0xD5, 0xF9, 0x00, 0x00
-	}
-};
-
-/* NAND header for Parallel NAND 4Gb with 2KB page + 64B spare */
-static const union nand_boot_header nand_hdr_4gb_2k_64_data = {
-	.data = {
-		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
-		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
-		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
-		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
-		0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0xE3, 0x0F, 0x86, 0x32,
-		0x68, 0x05, 0xD9, 0xC8, 0x13, 0xDF, 0xC5, 0x0B,
-		0x35, 0x3A, 0x68, 0xA5, 0x3C, 0x0C, 0x73, 0x87,
-		0x63, 0xB0, 0xBE, 0xCC, 0x84, 0x47, 0x00, 0x00
-	}
-};
-
-/* NAND header for Parallel NAND 2Gb with 2KB page + 128B spare */
-static const union nand_boot_header nand_hdr_2gb_2k_128_data = {
-	.data = {
-		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
-		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
-		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
-		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
-		0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x01, 0xA5, 0xE9, 0x5A,
-		0xDF, 0x58, 0x62, 0x41, 0xD6, 0x26, 0x77, 0xBC,
-		0x76, 0x1F, 0x27, 0x4E, 0x4F, 0x6C, 0xC3, 0xF0,
-		0x36, 0xDE, 0xD9, 0xB3, 0xFF, 0x93, 0x00, 0x00
-	}
-};
-
-/* NAND header for Parallel NAND 4Gb with 2KB page + 128B spare */
-static const union nand_boot_header nand_hdr_4gb_2k_128_data = {
-	.data = {
-		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
-		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
-		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
-		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
-		0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0xC2, 0x36, 0x52, 0x45,
-		0xCC, 0x35, 0xD8, 0xDB, 0xEB, 0xFD, 0xD1, 0x46,
-		0x76, 0x6B, 0x0B, 0xD5, 0x8B, 0xCC, 0x2B, 0xE2,
-		0xFE, 0x90, 0x83, 0x9E, 0xAE, 0x2D, 0x00, 0x00
-	}
-};
-
-static const struct nand_header_type {
-	const char *name;
-	const union nand_boot_header *data;
-} nand_headers[] = {
-	{
-		.name = "2k+64",
-		.data = &snand_hdr_2k_64_data
-	}, {
-		.name = "2k+120",
-		.data = &snand_hdr_2k_128_data
-	}, {
-		.name = "2k+128",
-		.data = &snand_hdr_2k_128_data
-	}, {
-		.name = "4k+256",
-		.data = &snand_hdr_4k_256_data
-	}, {
-		.name = "1g:2k+64",
-		.data = &nand_hdr_1gb_2k_64_data
-	}, {
-		.name = "2g:2k+64",
-		.data = &nand_hdr_2gb_2k_64_data
-	}, {
-		.name = "4g:2k+64",
-		.data = &nand_hdr_4gb_2k_64_data
-	}, {
-		.name = "2g:2k+128",
-		.data = &nand_hdr_2gb_2k_128_data
-	}, {
-		.name = "4g:2k+128",
-		.data = &nand_hdr_4gb_2k_128_data
-	}
-};
+#include "mtk_nand_headers.h"
 
 static const struct brom_img_type {
 	const char *name;
@@ -264,6 +55,7 @@ static uint32_t crc32tbl[256];
 
 /* NAND header selected by user */
 static const union nand_boot_header *hdr_nand;
+static uint32_t hdr_nand_size;
 
 /* GFH header + 2 * 4KB pages of NAND */
 static char hdr_tmp[sizeof(struct gfh_header) + 0x2000];
@@ -402,12 +194,7 @@ static int mtk_brom_parse_imagename(const char
 *imagename)
 	}
 
 	/* parse nand header type */
-	for (i = 0; i < ARRAY_SIZE(nand_headers); i++) {
-		if (!strcmp(nand_headers[i].name, nandinfo)) {
-			hdr_nand = nand_headers[i].data;
-			break;
-		}
-	}
+	hdr_nand = mtk_nand_header_find(nandinfo);
 
 	/* parse device header offset */
 	if (hdr_offs && hdr_offs[0])
@@ -432,6 +219,8 @@ static int mtk_brom_parse_imagename(const char
 *imagename)
 		return -EINVAL;
 	}
 
+	hdr_nand_size = mtk_nand_header_size(hdr_nand);
+
 	return 0;
 }
 
@@ -468,7 +257,7 @@ static int mtk_image_vrec_header(struct
 image_tool_params *params,
 	}
 
 	if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND)
-		tparams->header_size = 2 * le16_to_cpu(hdr_nand->pagesize);
+		tparams->header_size = hdr_nand_size;
 	else
 		tparams->header_size = sizeof(struct gen_device_header);
 
@@ -566,16 +355,17 @@ static int mtk_image_verify_gen_header(const uint8_t
 *ptr, int print)
 
 static int mtk_image_verify_nand_header(const uint8_t *ptr, int print)
 {
-	union nand_boot_header *nh = (union nand_boot_header *)ptr;
 	struct brom_layout_header *bh;
+	struct nand_header_info info;
 	struct gfh_header *gfh;
 	const char *bootmedia;
+	int ret;
 
-	if (strncmp(nh->version, NAND_BOOT_VERSION, sizeof(nh->version)) ||
-	    strcmp(nh->id, NAND_BOOT_ID))
-		return -1;
+	ret = mtk_nand_header_info(ptr, &info);
+	if (ret < 0)
+		return ret;
 
-	bh = (struct brom_layout_header *)(ptr + le16_to_cpu(nh->pagesize));
+	bh = (struct brom_layout_header *)(ptr + info.page_size);
 
 	if (strcmp(bh->name, BRLYT_NAME))
 		return -1;
@@ -586,34 +376,23 @@ static int mtk_image_verify_nand_header(const uint8_t
 *ptr, int print)
 		if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND)
 			bootmedia = "Parallel NAND";
 		else if (le32_to_cpu(bh->type) == BRLYT_TYPE_SNAND)
-			bootmedia = "Serial NAND";
+			bootmedia = "Serial NAND (SNFI/AP)";
 		else
 			return -1;
 	}
 
 	if (print) {
-		printf("Boot Media: %s\n", bootmedia);
-
-		if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND) {
-			uint64_t capacity =
-				(uint64_t)le16_to_cpu(nh->numblocks) *
-				(uint64_t)le16_to_cpu(nh->pages_of_block) *
-				(uint64_t)le16_to_cpu(nh->pagesize) * 8;
-			printf("Capacity:     %dGb\n",
-			       (uint32_t)(capacity >> 30));
-		}
+		printf("Boot Media:   %s\n", bootmedia);
 
-		if (le16_to_cpu(nh->pagesize) >= 1024)
-			printf("Page Size:    %dKB\n",
-			       le16_to_cpu(nh->pagesize) >> 10);
+		if (info.page_size >= 1024)
+			printf("Page Size:    %dKB\n", info.page_size >> 10);
 		else
-			printf("Page Size:    %dB\n",
-			       le16_to_cpu(nh->pagesize));
+			printf("Page Size:    %dB\n", info.page_size);
 
-		printf("Spare Size:   %dB\n", le16_to_cpu(nh->oobsize));
+		printf("Spare Size:   %dB\n", info.spare_size);
 	}
 
-	gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(nh->pagesize));
+	gfh = (struct gfh_header *)(ptr + info.gfh_offset);
 
 	return mtk_image_verify_gfh(gfh, GFH_FLASH_TYPE_NAND, print);
 }
@@ -713,7 +492,7 @@ static int mtk_image_verify_header(unsigned char *ptr,
 int image_size,
 	if (image_get_magic(hdr) == IH_MAGIC)
 		return mtk_image_verify_mt7621_header(ptr, 0);
 
-	if (!strcmp((char *)ptr, NAND_BOOT_NAME))
+	if (is_mtk_nand_header(ptr))
 		return mtk_image_verify_nand_header(ptr, 0);
 	else
 		return mtk_image_verify_gen_header(ptr, 0);
@@ -739,7 +518,7 @@ static void mtk_image_print_header(const void *ptr)
 		return;
 	}
 
-	if (!strcmp((char *)ptr, NAND_BOOT_NAME))
+	if (is_mtk_nand_header(ptr))
 		mtk_image_verify_nand_header(ptr, 1);
 	else
 		mtk_image_verify_gen_header(ptr, 1);
@@ -870,36 +649,33 @@ static void mtk_image_set_gen_header(void *ptr, off_t
 filesize,
 static void mtk_image_set_nand_header(void *ptr, off_t filesize,
 				      uint32_t loadaddr)
 {
-	union nand_boot_header *nh = (union nand_boot_header *)ptr;
 	struct brom_layout_header *brlyt;
 	struct gfh_header *gfh;
-	uint32_t payload_pages;
-	int i;
+	uint32_t payload_pages, nand_page_size;
 
-	/* NAND device header, repeat 4 times */
-	for (i = 0; i < 4; i++)
-		memcpy(nh + i, hdr_nand, sizeof(union nand_boot_header));
+	/* NAND header */
+	nand_page_size = mtk_nand_header_put(hdr_nand, ptr);
 
-	/* BRLYT header */
-	payload_pages = (filesize + le16_to_cpu(hdr_nand->pagesize) - 1) /
-			le16_to_cpu(hdr_nand->pagesize);
-	brlyt = (struct brom_layout_header *)
-		(ptr + le16_to_cpu(hdr_nand->pagesize));
-	put_brom_layout_header(brlyt, hdr_media);
-	brlyt->header_size = cpu_to_le32(2);
-	brlyt->total_size = cpu_to_le32(payload_pages);
-	brlyt->header_size_2 = brlyt->header_size;
-	brlyt->total_size_2 = brlyt->total_size;
-	brlyt->unused = cpu_to_le32(1);
+	if (nand_page_size) {
+		/* BRLYT header */
+		payload_pages = (filesize + nand_page_size - 1) /
+				nand_page_size;
+		brlyt = (struct brom_layout_header *)(ptr + nand_page_size);
+		put_brom_layout_header(brlyt, hdr_media);
+		brlyt->header_size = cpu_to_le32(2);
+		brlyt->total_size = cpu_to_le32(payload_pages);
+		brlyt->header_size_2 = brlyt->header_size;
+		brlyt->total_size_2 = brlyt->total_size;
+		brlyt->unused = cpu_to_le32(1);
+	}
 
 	/* GFH header */
-	gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(hdr_nand->pagesize));
-	put_ghf_header(gfh, filesize, 2 * le16_to_cpu(hdr_nand->pagesize),
-		       loadaddr, GFH_FLASH_TYPE_NAND);
+	gfh = (struct gfh_header *)(ptr + hdr_nand_size);
+	put_ghf_header(gfh, filesize, hdr_nand_size, loadaddr,
+		       GFH_FLASH_TYPE_NAND);
 
 	/* Generate SHA256 hash */
-	put_hash((uint8_t *)gfh,
-		 filesize - 2 * le16_to_cpu(hdr_nand->pagesize) - SHA256_SUM_LEN);
+	put_hash((uint8_t *)gfh, filesize - hdr_nand_size - SHA256_SUM_LEN);
 }
 
 static void mtk_image_set_mt7621_header(void *ptr, off_t filesize,
diff --git a/tools/mtk_image.h b/tools/mtk_image.h
index d868545a33..fad9372100 100644
--- a/tools/mtk_image.h
+++ b/tools/mtk_image.h
@@ -26,31 +26,6 @@ union gen_boot_header {
 #define SF_BOOT_NAME		"SF_BOOT"
 #define SDMMC_BOOT_NAME		"SDMMC_BOOT"
 
-/* Header for NAND */
-union nand_boot_header {
-	struct {
-		char name[12];
-		char version[4];
-		char id[8];
-		uint16_t ioif;
-		uint16_t pagesize;
-		uint16_t addrcycles;
-		uint16_t oobsize;
-		uint16_t pages_of_block;
-		uint16_t numblocks;
-		uint16_t writesize_shift;
-		uint16_t erasesize_shift;
-		uint8_t dummy[60];
-		uint8_t ecc_parity[28];
-	};
-
-	uint8_t data[0x80];
-};
-
-#define NAND_BOOT_NAME		"BOOTLOADER!"
-#define NAND_BOOT_VERSION	"V006"
-#define NAND_BOOT_ID		"NFIINFO"
-
 /* BootROM layout header */
 struct brom_layout_header {
 	char name[8];
diff --git a/tools/mtk_nand_headers.c b/tools/mtk_nand_headers.c
new file mode 100644
index 0000000000..12f827c39f
--- /dev/null
+++ b/tools/mtk_nand_headers.c
@@ -0,0 +1,286 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * MediaTek BootROM NAND header definitions
+ *
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "imagetool.h"
+#include "mtk_image.h"
+#include "mtk_nand_headers.h"
+
+/* NAND header for SPI-NAND with 2KB page + 64B spare */
+static const union nand_boot_header snand_hdr_2k_64_data = {
+	.data = {
+		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+		0x00, 0x00, 0x00, 0x08, 0x03, 0x00, 0x40, 0x00,
+		0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x7B, 0xC4, 0x17, 0x9D,
+		0xCA, 0x42, 0x90, 0xD0, 0x98, 0xD0, 0xE0, 0xF7,
+		0xDB, 0xCD, 0x16, 0xF6, 0x03, 0x73, 0xD2, 0xB8,
+		0x93, 0xB2, 0x56, 0x5A, 0x84, 0x6E, 0x00, 0x00
+	}
+};
+
+/* NAND header for SPI-NAND with 2KB page + 120B/128B spare */
+static const union nand_boot_header snand_hdr_2k_128_data = {
+	.data = {
+		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
+		0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x90, 0x28, 0xED, 0x13,
+		0x7F, 0x12, 0x22, 0xCD, 0x3D, 0x06, 0xF1, 0xB3,
+		0x6F, 0x2E, 0xD9, 0xA0, 0x9D, 0x7A, 0xBD, 0xD7,
+		0xB3, 0x28, 0x3C, 0x13, 0xDB, 0x4E, 0x00, 0x00
+	}
+};
+
+/* NAND header for SPI-NAND with 4KB page + 256B spare */
+static const union nand_boot_header snand_hdr_4k_256_data = {
+	.data = {
+		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+		0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0xE0, 0x00,
+		0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x47, 0xED, 0x0E, 0xC3,
+		0x83, 0xBF, 0x41, 0xD2, 0x85, 0x21, 0x97, 0x57,
+		0xC4, 0x2E, 0x6B, 0x7A, 0x40, 0xE0, 0xCF, 0x8F,
+		0x37, 0xBD, 0x17, 0xB6, 0xC7, 0xFE, 0x00, 0x00
+	}
+};
+
+/* NAND header for Parallel NAND 1Gb with 2KB page + 64B spare */
+static const union nand_boot_header nand_hdr_1gb_2k_64_data = {
+	.data = {
+		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
+		0x40, 0x00, 0x00, 0x04, 0x0B, 0x00, 0x11, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x1C, 0x12,
+		0x8F, 0xFD, 0xF8, 0x32, 0x6F, 0x6D, 0xCF, 0x6C,
+		0xDA, 0x21, 0x70, 0x8C, 0xDA, 0x0A, 0x22, 0x82,
+		0xAA, 0x59, 0xFA, 0x7C, 0x42, 0x2D, 0x00, 0x00
+	}
+};
+
+/* NAND header for Parallel NAND 2Gb with 2KB page + 64B spare */
+static const union nand_boot_header nand_hdr_2gb_2k_64_data = {
+	.data = {
+		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
+		0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x20, 0x9C, 0x3D, 0x2D,
+		0x7B, 0x68, 0x63, 0x52, 0x2E, 0x04, 0x63, 0xF1,
+		0x35, 0x4E, 0x44, 0x3E, 0xF8, 0xAC, 0x9B, 0x95,
+		0xAB, 0xFE, 0xE4, 0xE1, 0xD5, 0xF9, 0x00, 0x00
+	}
+};
+
+/* NAND header for Parallel NAND 4Gb with 2KB page + 64B spare */
+static const union nand_boot_header nand_hdr_4gb_2k_64_data = {
+	.data = {
+		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
+		0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0xE3, 0x0F, 0x86, 0x32,
+		0x68, 0x05, 0xD9, 0xC8, 0x13, 0xDF, 0xC5, 0x0B,
+		0x35, 0x3A, 0x68, 0xA5, 0x3C, 0x0C, 0x73, 0x87,
+		0x63, 0xB0, 0xBE, 0xCC, 0x84, 0x47, 0x00, 0x00
+	}
+};
+
+/* NAND header for Parallel NAND 2Gb with 2KB page + 128B spare */
+static const union nand_boot_header nand_hdr_2gb_2k_128_data = {
+	.data = {
+		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
+		0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x01, 0xA5, 0xE9, 0x5A,
+		0xDF, 0x58, 0x62, 0x41, 0xD6, 0x26, 0x77, 0xBC,
+		0x76, 0x1F, 0x27, 0x4E, 0x4F, 0x6C, 0xC3, 0xF0,
+		0x36, 0xDE, 0xD9, 0xB3, 0xFF, 0x93, 0x00, 0x00
+	}
+};
+
+/* NAND header for Parallel NAND 4Gb with 2KB page + 128B spare */
+static const union nand_boot_header nand_hdr_4gb_2k_128_data = {
+	.data = {
+		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
+		0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0xC2, 0x36, 0x52, 0x45,
+		0xCC, 0x35, 0xD8, 0xDB, 0xEB, 0xFD, 0xD1, 0x46,
+		0x76, 0x6B, 0x0B, 0xD5, 0x8B, 0xCC, 0x2B, 0xE2,
+		0xFE, 0x90, 0x83, 0x9E, 0xAE, 0x2D, 0x00, 0x00
+	}
+};
+
+static const struct nand_header_type {
+	const char *name;
+	const union nand_boot_header *data;
+} nand_headers[] = {
+	{
+		.name = "2k+64",
+		.data = &snand_hdr_2k_64_data
+	}, {
+		.name = "2k+120",
+		.data = &snand_hdr_2k_128_data
+	}, {
+		.name = "2k+128",
+		.data = &snand_hdr_2k_128_data
+	}, {
+		.name = "4k+256",
+		.data = &snand_hdr_4k_256_data
+	}, {
+		.name = "1g:2k+64",
+		.data = &nand_hdr_1gb_2k_64_data
+	}, {
+		.name = "2g:2k+64",
+		.data = &nand_hdr_2gb_2k_64_data
+	}, {
+		.name = "4g:2k+64",
+		.data = &nand_hdr_4gb_2k_64_data
+	}, {
+		.name = "2g:2k+128",
+		.data = &nand_hdr_2gb_2k_128_data
+	}, {
+		.name = "4g:2k+128",
+		.data = &nand_hdr_4gb_2k_128_data
+	}
+};
+
+const union nand_boot_header *mtk_nand_header_find(const char *name)
+{
+	uint32_t i;
+
+	for (i = 0; i < ARRAY_SIZE(nand_headers); i++) {
+		if (!strcmp(nand_headers[i].name, name))
+			return nand_headers[i].data;
+	}
+
+	return NULL;
+}
+
+uint32_t mtk_nand_header_size(const union nand_boot_header *hdr_nand)
+{
+	return 2 * le16_to_cpu(hdr_nand->pagesize);
+}
+
+static int mtk_nand_header_ap_info(const void *ptr,
+				   struct nand_header_info *info)
+{
+	union nand_boot_header *nh = (union nand_boot_header *)ptr;
+
+	if (strncmp(nh->version, NAND_BOOT_VERSION, sizeof(nh->version)) ||
+	    strcmp(nh->id, NAND_BOOT_ID))
+		return -1;
+
+	info->page_size = le16_to_cpu(nh->pagesize);
+	info->spare_size = le16_to_cpu(nh->oobsize);
+	info->gfh_offset = 2 * info->page_size;
+
+	return 0;
+}
+
+int mtk_nand_header_info(const void *ptr, struct nand_header_info *info)
+{
+	if (!strcmp((char *)ptr, NAND_BOOT_NAME))
+		return mtk_nand_header_ap_info(ptr, info);
+
+	return -1;
+}
+
+bool is_mtk_nand_header(const void *ptr)
+{
+	struct nand_header_info info;
+
+	if (mtk_nand_header_info(ptr, &info) >= 0)
+		return true;
+
+	return false;
+}
+
+uint32_t mtk_nand_header_put(const union nand_boot_header *hdr_nand, void
 *ptr)
+{
+	union nand_boot_header *nh = (union nand_boot_header *)ptr;
+	int i;
+
+	/* NAND device header, repeat 4 times */
+	for (i = 0; i < 4; i++)
+		memcpy(nh + i, hdr_nand, sizeof(union nand_boot_header));
+
+	return le16_to_cpu(hdr_nand->pagesize);
+}
diff --git a/tools/mtk_nand_headers.h b/tools/mtk_nand_headers.h
new file mode 100644
index 0000000000..691db85005
--- /dev/null
+++ b/tools/mtk_nand_headers.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * MediaTek BootROM NAND header definitions
+ *
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#ifndef _MTK_NAND_HEADERS_H
+#define _MTK_NAND_HEADERS_H
+
+#include <stdint.h>
+#include <stdbool.h>
+
+struct nand_header_info {
+	uint32_t page_size;
+	uint32_t spare_size;
+	uint32_t gfh_offset;
+};
+
+/* AP BROM Header for NAND */
+union nand_boot_header {
+	struct {
+		char name[12];
+		char version[4];
+		char id[8];
+		uint16_t ioif;
+		uint16_t pagesize;
+		uint16_t addrcycles;
+		uint16_t oobsize;
+		uint16_t pages_of_block;
+		uint16_t numblocks;
+		uint16_t writesize_shift;
+		uint16_t erasesize_shift;
+		uint8_t dummy[60];
+		uint8_t ecc_parity[28];
+	};
+
+	uint8_t data[0x80];
+};
+
+#define NAND_BOOT_NAME		"BOOTLOADER!"
+#define NAND_BOOT_VERSION	"V006"
+#define NAND_BOOT_ID		"NFIINFO"
+
+const union nand_boot_header *mtk_nand_header_find(const char *name);
+uint32_t mtk_nand_header_size(const union nand_boot_header *hdr_nand);
+int mtk_nand_header_info(const void *ptr, struct nand_header_info *info);
+bool is_mtk_nand_header(const void *ptr);
+uint32_t mtk_nand_header_put(const union nand_boot_header *hdr_nand, void
 *ptr);
+
+#endif /* _MTK_NAND_HEADERS_H */
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 30/31] tools: mtk_image: add support for nand headers used by newer chips
  2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
                   ` (28 preceding siblings ...)
  2022-08-04  3:36 ` [PATCH 29/31] tools: mtk_image: split the code of generating NAND header into a new file Weijie Gao
@ 2022-08-04  3:36 ` Weijie Gao
  2022-08-04 13:57   ` Simon Glass
  2022-08-04  3:36 ` [PATCH 31/31] MAINTAINERS: update maintainer for MediaTek ARM platform Weijie Gao
  30 siblings, 1 reply; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:36 UTC (permalink / raw)
  To: u-boot; +Cc: GSS_MTK_Uboot_upstream, Weijie Gao

This patch adds more nand headers in two new types:
1. HSM header, used for spi-nand thru SNFI interface
2. SPIM header, used for spi-nand thru spi-mem interface

The original nand header is renamed to AP header.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 tools/mtk_image.c        |  23 ++-
 tools/mtk_nand_headers.c | 422 +++++++++++++++++++++++++++++++++++++--
 tools/mtk_nand_headers.h | 110 +++++++++-
 3 files changed, 525 insertions(+), 30 deletions(-)

diff --git a/tools/mtk_image.c b/tools/mtk_image.c
index 3701d1564a..ac39334994 100644
--- a/tools/mtk_image.c
+++ b/tools/mtk_image.c
@@ -33,6 +33,9 @@ static const struct brom_img_type {
 	}, {
 		.name = "snand",
 		.type = BRLYT_TYPE_SNAND
+	}, {
+		.name = "spim-nand",
+		.type = BRLYT_TYPE_SNAND
 	}
 };
 
@@ -54,7 +57,7 @@ static char lk_name[32] = "U-Boot";
 static uint32_t crc32tbl[256];
 
 /* NAND header selected by user */
-static const union nand_boot_header *hdr_nand;
+static const struct nand_header_type *hdr_nand;
 static uint32_t hdr_nand_size;
 
 /* GFH header + 2 * 4KB pages of NAND */
@@ -365,20 +368,26 @@ static int mtk_image_verify_nand_header(const uint8_t
 *ptr, int print)
 	if (ret < 0)
 		return ret;
 
-	bh = (struct brom_layout_header *)(ptr + info.page_size);
+	if (!ret) {
+		bh = (struct brom_layout_header *)(ptr + info.page_size);
 
-	if (strcmp(bh->name, BRLYT_NAME))
-		return -1;
+		if (strcmp(bh->name, BRLYT_NAME))
+			return -1;
+
+		if (le32_to_cpu(bh->magic) != BRLYT_MAGIC)
+			return -1;
 
-	if (le32_to_cpu(bh->magic) != BRLYT_MAGIC) {
-		return -1;
-	} else {
 		if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND)
 			bootmedia = "Parallel NAND";
 		else if (le32_to_cpu(bh->type) == BRLYT_TYPE_SNAND)
 			bootmedia = "Serial NAND (SNFI/AP)";
 		else
 			return -1;
+	} else {
+		if (info.snfi)
+			bootmedia = "Serial NAND (SNFI/HSM)";
+		else
+			bootmedia = "Serial NAND (SPIM)";
 	}
 
 	if (print) {
diff --git a/tools/mtk_nand_headers.c b/tools/mtk_nand_headers.c
index 12f827c39f..2fa91e7af0 100644
--- a/tools/mtk_nand_headers.c
+++ b/tools/mtk_nand_headers.c
@@ -188,55 +188,346 @@ static const union nand_boot_header
 nand_hdr_4gb_2k_128_data = {
 	}
 };
 
-static const struct nand_header_type {
+/* HSM BROM NAND header for SPI NAND with 2KB page + 64B spare */
+static const union hsm_nand_boot_header hsm_nand_hdr_2k_64_data = {
+	.data = {
+		0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21,
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x08, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
+		0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+		0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+		0xFF, 0x00, 0x00, 0x00, 0x21, 0xD2, 0xEE, 0xF6,
+		0xAE, 0xDD, 0x5E, 0xC2, 0x82, 0x8E, 0x9A, 0x62,
+		0x09, 0x8E, 0x80, 0xE2, 0x37, 0x0D, 0xC9, 0xFA,
+		0xA9, 0xDD, 0xFC, 0x92, 0x34, 0x2A, 0xED, 0x51,
+		0xA4, 0x1B, 0xF7, 0x63, 0xCC, 0x5A, 0xC7, 0xFB,
+		0xED, 0x21, 0x02, 0x23, 0x51, 0x31
+	}
+};
+
+/* HSM BROM NAND header for SPI NAND with 2KB page + 128B spare */
+static const union hsm_nand_boot_header hsm_nand_hdr_2k_128_data = {
+	.data = {
+		0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21,
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+		0x40, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+		0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+		0xFF, 0x00, 0x00, 0x00, 0x71, 0x7f, 0x71, 0xAC,
+		0x42, 0xD0, 0x5B, 0xD2, 0x12, 0x81, 0x15, 0x0A,
+		0x0C, 0xD4, 0xF6, 0x32, 0x1E, 0x63, 0xE7, 0x81,
+		0x8A, 0x7F, 0xDE, 0xF9, 0x4B, 0x91, 0xEC, 0xC2,
+		0x70, 0x00, 0x7F, 0x57, 0xAF, 0xDC, 0xE4, 0x24,
+		0x57, 0x09, 0xBC, 0xC5, 0x35, 0xDC
+	}
+};
+
+/* HSM BROM NAND header for SPI NAND with 4KB page + 256B spare */
+static const union hsm_nand_boot_header hsm_nand_hdr_4k_256_data = {
+	.data = {
+		0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21,
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+		0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+		0x0C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+		0xFF, 0x00, 0x00, 0x00, 0x62, 0x04, 0xD6, 0x1F,
+		0x2B, 0x57, 0x7A, 0x2D, 0xFE, 0xBB, 0x4A, 0x50,
+		0xEC, 0xF8, 0x70, 0x1A, 0x44, 0x15, 0xF6, 0xA2,
+		0x8E, 0xB0, 0xFD, 0xFA, 0xDC, 0xAA, 0x5A, 0x4E,
+		0xCB, 0x8E, 0xC9, 0x72, 0x08, 0xDC, 0x20, 0xB9,
+		0x98, 0xC8, 0x82, 0xD8, 0xBE, 0x44
+	}
+};
+
+/* HSM2.0 BROM NAND header for SPI NAND with 2KB page + 64B spare */
+static const union hsm20_nand_boot_header hsm20_nand_hdr_2k_64_data = {
+	.data = {
+		0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21,
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+		0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x08, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
+		0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+		0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+		0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x5F, 0x4B, 0xB2, 0x5B, 0x8B, 0x1C, 0x35, 0xDA,
+		0x83, 0xE6, 0x6C, 0xC3, 0xFB, 0x8C, 0x78, 0x23,
+		0xD0, 0x89, 0x24, 0xD9, 0x6C, 0x35, 0x2C, 0x5D,
+		0x8F, 0xBB, 0xFC, 0x10, 0xD0, 0xE2, 0x22, 0x7D,
+		0xC8, 0x97, 0x9A, 0xEF, 0xC6, 0xB5, 0xA7, 0x4E,
+		0x4E, 0x0E
+	}
+};
+
+/* HSM2.0 BROM NAND header for SPI NAND with 2KB page + 128B spare */
+static const union hsm20_nand_boot_header hsm20_nand_hdr_2k_128_data = {
+	.data = {
+		0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21,
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+		0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+		0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+		0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+		0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0xF8, 0x7E, 0xC1, 0x5D, 0x61, 0x54, 0xEA, 0x9F,
+		0x5E, 0x66, 0x39, 0x66, 0x21, 0xFF, 0x8C, 0x3B,
+		0xBE, 0xA7, 0x5A, 0x9E, 0xD7, 0xBD, 0x9E, 0x89,
+		0xEE, 0x7E, 0x10, 0x31, 0x9A, 0x1D, 0x82, 0x49,
+		0xA3, 0x4E, 0xD8, 0x47, 0xD7, 0x19, 0xF4, 0x2D,
+		0x8E, 0x53
+	}
+};
+
+/* HSM2.0 BROM NAND header for SPI NAND with 4KB page + 256B spare */
+static const union hsm20_nand_boot_header hsm20_nand_hdr_4k_256_data = {
+	.data = {
+		0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21,
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+		0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+		0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+		0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+		0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x79, 0x01, 0x1F, 0x86, 0x62, 0x6A, 0x43, 0xAE,
+		0xE6, 0xF8, 0xDD, 0x5B, 0x29, 0xB7, 0xA2, 0x7F,
+		0x29, 0x72, 0x54, 0x37, 0xBE, 0x50, 0xD4, 0x24,
+		0xAB, 0x60, 0xF4, 0x44, 0x97, 0x3B, 0x65, 0x21,
+		0x73, 0x24, 0x1F, 0x93, 0x0E, 0x9E, 0x96, 0x88,
+		0x78, 0x6C
+	}
+};
+
+/* SPIM-NAND header for SPI NAND with 2KB page + 64B spare */
+static const union spim_nand_boot_header spim_nand_hdr_2k_64_data = {
+	.data = {
+		0x53, 0x50, 0x49, 0x4e, 0x41, 0x4e, 0x44, 0x21,
+		0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+		0x00, 0x08, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
+		0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x20, 0x30,
+		0x01, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	}
+};
+
+/* SPIM-NAND header for SPI NAND with 2KB page + 128B spare */
+static const union spim_nand_boot_header spim_nand_hdr_2k_128_data = {
+	.data = {
+		0x53, 0x50, 0x49, 0x4e, 0x41, 0x4e, 0x44, 0x21,
+		0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+		0x00, 0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+		0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x20, 0x30,
+		0x01, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	}
+};
+
+/* SPIM-NAND header for SPI NAND with 4KB page + 256B spare */
+static const union spim_nand_boot_header spim_nand_hdr_4k_256_data = {
+	.data = {
+		0x53, 0x50, 0x49, 0x4e, 0x41, 0x4e, 0x44, 0x21,
+		0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+		0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+		0x40, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x20, 0x30,
+		0x01, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	}
+};
+
+struct nand_header_type {
 	const char *name;
-	const union nand_boot_header *data;
+	enum nand_boot_header_type type;
+	union {
+		const union nand_boot_header *ap;
+		const union hsm_nand_boot_header *hsm;
+		const union hsm20_nand_boot_header *hsm20;
+		const union spim_nand_boot_header *spim;
+	};
 } nand_headers[] = {
 	{
 		.name = "2k+64",
-		.data = &snand_hdr_2k_64_data
+		.type = NAND_BOOT_AP_HEADER,
+		.ap = &snand_hdr_2k_64_data,
 	}, {
 		.name = "2k+120",
-		.data = &snand_hdr_2k_128_data
+		.type = NAND_BOOT_AP_HEADER,
+		.ap = &snand_hdr_2k_128_data,
 	}, {
 		.name = "2k+128",
-		.data = &snand_hdr_2k_128_data
+		.type = NAND_BOOT_AP_HEADER,
+		.ap = &snand_hdr_2k_128_data,
 	}, {
 		.name = "4k+256",
-		.data = &snand_hdr_4k_256_data
+		.type = NAND_BOOT_AP_HEADER,
+		.ap = &snand_hdr_4k_256_data,
 	}, {
 		.name = "1g:2k+64",
-		.data = &nand_hdr_1gb_2k_64_data
+		.type = NAND_BOOT_AP_HEADER,
+		.ap = &nand_hdr_1gb_2k_64_data,
 	}, {
 		.name = "2g:2k+64",
-		.data = &nand_hdr_2gb_2k_64_data
+		.type = NAND_BOOT_AP_HEADER,
+		.ap = &nand_hdr_2gb_2k_64_data,
 	}, {
 		.name = "4g:2k+64",
-		.data = &nand_hdr_4gb_2k_64_data
+		.type = NAND_BOOT_AP_HEADER,
+		.ap = &nand_hdr_4gb_2k_64_data,
 	}, {
 		.name = "2g:2k+128",
-		.data = &nand_hdr_2gb_2k_128_data
+		.type = NAND_BOOT_AP_HEADER,
+		.ap = &nand_hdr_2gb_2k_128_data,
 	}, {
 		.name = "4g:2k+128",
-		.data = &nand_hdr_4gb_2k_128_data
+		.type = NAND_BOOT_AP_HEADER,
+		.ap = &nand_hdr_4gb_2k_128_data,
+	}, {
+		.name = "hsm:2k+64",
+		.type = NAND_BOOT_HSM_HEADER,
+		.hsm = &hsm_nand_hdr_2k_64_data,
+	}, {
+		.name = "hsm:2k+128",
+		.type = NAND_BOOT_HSM_HEADER,
+		.hsm = &hsm_nand_hdr_2k_128_data,
+	}, {
+		.name = "hsm:4k+256",
+		.type = NAND_BOOT_HSM_HEADER,
+		.hsm = &hsm_nand_hdr_4k_256_data,
+	},  {
+		.name = "hsm20:2k+64",
+		.type = NAND_BOOT_HSM20_HEADER,
+		.hsm20 = &hsm20_nand_hdr_2k_64_data,
+	}, {
+		.name = "hsm20:2k+128",
+		.type = NAND_BOOT_HSM20_HEADER,
+		.hsm20 = &hsm20_nand_hdr_2k_128_data,
+	}, {
+		.name = "hsm20:4k+256",
+		.type = NAND_BOOT_HSM20_HEADER,
+		.hsm20 = &hsm20_nand_hdr_4k_256_data,
+	}, {
+		.name = "spim:2k+64",
+		.type = NAND_BOOT_SPIM_HEADER,
+		.spim = &spim_nand_hdr_2k_64_data,
+	}, {
+		.name = "spim:2k+128",
+		.type = NAND_BOOT_SPIM_HEADER,
+		.spim = &spim_nand_hdr_2k_128_data,
+	}, {
+		.name = "spim:4k+256",
+		.type = NAND_BOOT_SPIM_HEADER,
+		.spim = &spim_nand_hdr_4k_256_data,
 	}
 };
 
-const union nand_boot_header *mtk_nand_header_find(const char *name)
+const struct nand_header_type *mtk_nand_header_find(const char *name)
 {
 	uint32_t i;
 
 	for (i = 0; i < ARRAY_SIZE(nand_headers); i++) {
 		if (!strcmp(nand_headers[i].name, name))
-			return nand_headers[i].data;
+			return &nand_headers[i];
 	}
 
 	return NULL;
 }
 
-uint32_t mtk_nand_header_size(const union nand_boot_header *hdr_nand)
+uint32_t mtk_nand_header_size(const struct nand_header_type *hdr_nand)
 {
-	return 2 * le16_to_cpu(hdr_nand->pagesize);
+	switch (hdr_nand->type) {
+	case NAND_BOOT_HSM_HEADER:
+		return le32_to_cpu(hdr_nand->hsm->page_size);
+
+	case NAND_BOOT_HSM20_HEADER:
+		return le32_to_cpu(hdr_nand->hsm20->page_size);
+
+	case NAND_BOOT_SPIM_HEADER:
+		return le32_to_cpu(hdr_nand->spim->page_size);
+
+	default:
+		return 2 * le16_to_cpu(hdr_nand->ap->pagesize);
+	}
 }
 
 static int mtk_nand_header_ap_info(const void *ptr,
@@ -251,14 +542,45 @@ static int mtk_nand_header_ap_info(const void *ptr,
 	info->page_size = le16_to_cpu(nh->pagesize);
 	info->spare_size = le16_to_cpu(nh->oobsize);
 	info->gfh_offset = 2 * info->page_size;
+	info->snfi = true;
 
 	return 0;
 }
 
+static int mtk_nand_header_hsm_info(const void *ptr,
+				    struct nand_header_info *info)
+{
+	union hsm_nand_boot_header *nh = (union hsm_nand_boot_header *)ptr;
+
+	info->page_size = le16_to_cpu(nh->page_size);
+	info->spare_size = le16_to_cpu(nh->spare_size);
+	info->gfh_offset = info->page_size;
+	info->snfi = true;
+
+	return 1;
+}
+
+static int mtk_nand_header_spim_info(const void *ptr,
+				     struct nand_header_info *info)
+{
+	union spim_nand_boot_header *nh = (union spim_nand_boot_header *)ptr;
+
+	info->page_size = le16_to_cpu(nh->page_size);
+	info->spare_size = le16_to_cpu(nh->spare_size);
+	info->gfh_offset = info->page_size;
+	info->snfi = false;
+
+	return 1;
+}
+
 int mtk_nand_header_info(const void *ptr, struct nand_header_info *info)
 {
 	if (!strcmp((char *)ptr, NAND_BOOT_NAME))
 		return mtk_nand_header_ap_info(ptr, info);
+	else if (!strncmp((char *)ptr, HSM_NAND_BOOT_NAME, 8))
+		return mtk_nand_header_hsm_info(ptr, info);
+	else if (!strncmp((char *)ptr, SPIM_NAND_BOOT_NAME, 8))
+		return mtk_nand_header_spim_info(ptr, info);
 
 	return -1;
 }
@@ -273,14 +595,74 @@ bool is_mtk_nand_header(const void *ptr)
 	return false;
 }
 
-uint32_t mtk_nand_header_put(const union nand_boot_header *hdr_nand, void
 *ptr)
+static uint16_t crc16(const uint8_t *p, uint32_t len)
+{
+	uint16_t crc = 0x4f4e;
+	uint32_t i;
+
+	while (len--) {
+		crc ^= *p++ << 8;
+		for (i = 0; i < 8; i++)
+			crc = (crc << 1) ^ ((crc & 0x8000) ? 0x8005 : 0);
+	}
+
+	return crc;
+}
+
+static uint32_t mtk_nand_header_put_ap(const struct nand_header_type
 *hdr_nand,
+				       void *ptr)
 {
-	union nand_boot_header *nh = (union nand_boot_header *)ptr;
 	int i;
 
 	/* NAND device header, repeat 4 times */
-	for (i = 0; i < 4; i++)
-		memcpy(nh + i, hdr_nand, sizeof(union nand_boot_header));
+	for (i = 0; i < 4; i++) {
+		memcpy(ptr, hdr_nand->ap, sizeof(*hdr_nand->ap));
+		ptr += sizeof(*hdr_nand->ap);
+	}
 
-	return le16_to_cpu(hdr_nand->pagesize);
+	return le16_to_cpu(hdr_nand->ap->pagesize);
+}
+
+static uint32_t mtk_nand_header_put_hsm(const struct nand_header_type
 *hdr_nand,
+					void *ptr)
+{
+	memcpy(ptr, hdr_nand->hsm, sizeof(*hdr_nand->hsm));
+	return 0;
+}
+
+static uint32_t mtk_nand_header_put_hsm20(const struct nand_header_type
 *hdr_nand,
+					  void *ptr)
+{
+	memcpy(ptr, hdr_nand->hsm20, sizeof(*hdr_nand->hsm20));
+	return 0;
+}
+
+static uint32_t mtk_nand_header_put_spim(const struct nand_header_type
 *hdr_nand,
+					 void *ptr)
+{
+	uint16_t crc;
+
+	memcpy(ptr, hdr_nand->spim, sizeof(*hdr_nand->spim));
+
+	crc = crc16(ptr, 0x4e);
+	memcpy(ptr + 0x4e, &crc, sizeof(uint16_t));
+
+	return 0;
+}
+
+uint32_t mtk_nand_header_put(const struct nand_header_type *hdr_nand, void
 *ptr)
+{
+	switch (hdr_nand->type) {
+	case NAND_BOOT_HSM_HEADER:
+		return mtk_nand_header_put_hsm(hdr_nand, ptr);
+
+	case NAND_BOOT_HSM20_HEADER:
+		return mtk_nand_header_put_hsm20(hdr_nand, ptr);
+
+	case NAND_BOOT_SPIM_HEADER:
+		return mtk_nand_header_put_spim(hdr_nand, ptr);
+
+	default:
+		return mtk_nand_header_put_ap(hdr_nand, ptr);
+	}
 }
diff --git a/tools/mtk_nand_headers.h b/tools/mtk_nand_headers.h
index 691db85005..ce4a824e29 100644
--- a/tools/mtk_nand_headers.h
+++ b/tools/mtk_nand_headers.h
@@ -16,6 +16,7 @@ struct nand_header_info {
 	uint32_t page_size;
 	uint32_t spare_size;
 	uint32_t gfh_offset;
+	bool snfi;
 };
 
 /* AP BROM Header for NAND */
@@ -39,14 +40,117 @@ union nand_boot_header {
 	uint8_t data[0x80];
 };
 
+/* HSM BROM Header for NAND */
+union hsm_nand_boot_header {
+	struct {
+		char id[8];
+		uint32_t version;
+		uint32_t config;
+		uint32_t sector_size;
+		uint32_t fdm_size;
+		uint32_t fdm_ecc_size;
+		uint32_t lbs;
+		uint32_t page_size;
+		uint32_t spare_size;
+		uint32_t page_per_block;
+		uint32_t blocks;
+		uint32_t plane_sel_position;
+		uint32_t pll;
+		uint32_t acccon;
+		uint32_t strobe_sel;
+		uint32_t acccon1;
+		uint32_t dqs_mux;
+		uint32_t dqs_ctrl;
+		uint32_t delay_ctrl;
+		uint32_t latch_lat;
+		uint32_t sample_delay;
+		uint32_t driving;
+		uint32_t bl_start;
+		uint32_t bl_end;
+		uint8_t ecc_parity[42];
+	};
+
+	uint8_t data[0x8E];
+};
+
+/* HSM2.0 BROM Header for NAND */
+union hsm20_nand_boot_header {
+	struct {
+		char id[8];
+		uint32_t version;
+		uint32_t config;
+		uint32_t sector_size;
+		uint32_t fdm_size;
+		uint32_t fdm_ecc_size;
+		uint32_t lbs;
+		uint32_t page_size;
+		uint32_t spare_size;
+		uint32_t page_per_block;
+		uint32_t blocks;
+		uint32_t plane_sel_position;
+		uint32_t pll;
+		uint32_t acccon;
+		uint32_t strobe_sel;
+		uint32_t acccon1;
+		uint32_t dqs_mux;
+		uint32_t dqs_ctrl;
+		uint32_t delay_ctrl;
+		uint32_t latch_lat;
+		uint32_t sample_delay;
+		uint32_t driving;
+		uint32_t reserved;
+		uint32_t bl0_start;
+		uint32_t bl0_end;
+		uint32_t bl0_type;
+		uint8_t bl_reserve[84];
+		uint8_t ecc_parity[42];
+	};
+
+	uint8_t data[0xEA];
+};
+
+/* SPIM BROM Header for NAND */
+union spim_nand_boot_header {
+	struct {
+		char id[8];
+		uint32_t version;
+		uint32_t config;
+		uint32_t page_size;
+		uint32_t spare_size;
+		uint16_t page_per_block;
+		uint16_t plane_sel_position;
+		uint16_t reserve_reg;
+		uint16_t reserve_val;
+		uint16_t ecc_error;
+		uint16_t ecc_mask;
+		uint32_t bl_start;
+		uint32_t bl_end;
+		uint8_t ecc_parity[32];
+		uint32_t integrity_crc;
+	};
+
+	uint8_t data[0x50];
+};
+
+enum nand_boot_header_type {
+	NAND_BOOT_AP_HEADER,
+	NAND_BOOT_HSM_HEADER,
+	NAND_BOOT_HSM20_HEADER,
+	NAND_BOOT_SPIM_HEADER
+};
+
 #define NAND_BOOT_NAME		"BOOTLOADER!"
 #define NAND_BOOT_VERSION	"V006"
 #define NAND_BOOT_ID		"NFIINFO"
 
-const union nand_boot_header *mtk_nand_header_find(const char *name);
-uint32_t mtk_nand_header_size(const union nand_boot_header *hdr_nand);
+#define HSM_NAND_BOOT_NAME	"NANDCFG!"
+#define SPIM_NAND_BOOT_NAME	"SPINAND!"
+
+const struct nand_header_type *mtk_nand_header_find(const char *name);
+uint32_t mtk_nand_header_size(const struct nand_header_type *hdr_nand);
 int mtk_nand_header_info(const void *ptr, struct nand_header_info *info);
 bool is_mtk_nand_header(const void *ptr);
-uint32_t mtk_nand_header_put(const union nand_boot_header *hdr_nand, void
 *ptr);
+uint32_t mtk_nand_header_put(const struct nand_header_type *hdr_nand,
+			     void *ptr);
 
 #endif /* _MTK_NAND_HEADERS_H */
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 31/31] MAINTAINERS: update maintainer for MediaTek ARM platform
  2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
                   ` (29 preceding siblings ...)
  2022-08-04  3:36 ` [PATCH 30/31] tools: mtk_image: add support for nand headers used by newer chips Weijie Gao
@ 2022-08-04  3:36 ` Weijie Gao
  2022-08-04 13:57   ` Simon Glass
  30 siblings, 1 reply; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  3:36 UTC (permalink / raw)
  To: u-boot; +Cc: GSS_MTK_Uboot_upstream, Weijie Gao

Add new filed for MediaTek ARM platform

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 MAINTAINERS | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 4d1930f76e..515047db05 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -355,20 +355,25 @@ F:	doc/device-tree-bindings/phy/phy-mtk-*
 F:	doc/device-tree-bindings/usb/mediatek,*
 F:	doc/README.mediatek
 F:	drivers/clk/mediatek/
+F:	drivers/i2c/mtk_i2c.c
 F:	drivers/mmc/mtk-sd.c
 F:	drivers/phy/phy-mtk-*
 F:	drivers/pinctrl/mediatek/
 F:	drivers/power/domain/mtk-power-domain.c
 F:	drivers/ram/mediatek/
 F:	drivers/spi/mtk_snfi_spi.c
+F:	drivers/spi/mtk_spim.c
 F:	drivers/timer/mtk_timer.c
 F:	drivers/usb/host/xhci-mtk.c
 F:	drivers/usb/mtu3/
 F:	drivers/watchdog/mtk_wdt.c
 F:	drivers/net/mtk_eth.c
+F:	drivers/net/mtk_eth.h
 F:	drivers/reset/reset-mediatek.c
 F:	tools/mtk_image.c
 F:	tools/mtk_image.h
+F:	tools/mtk_nand_headers.c
+F:	tools/mtk_nand_headers.h
 N:	mediatek
 
 ARM METHODE SUPPORT
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* Re: [PATCH 01/31] arm: mediatek: add support for MediaTek MT7986 SoC
  2022-08-04  3:34 ` [PATCH 01/31] arm: mediatek: add support for MediaTek MT7986 SoC Weijie Gao
@ 2022-08-04  8:37   ` Daniel Golle
  2022-08-04  8:50     ` Weijie Gao
  0 siblings, 1 reply; 100+ messages in thread
From: Daniel Golle @ 2022-08-04  8:37 UTC (permalink / raw)
  To: Weijie Gao; +Cc: u-boot, GSS_MTK_Uboot_upstream

Hi Weijie,

happy to see this series posted!
Trying to apply it unfortunately fails due to errornous line-breaks,
supposedly inserted by your MUA, see below.

I didn't go beyond the first patch and it'd be nice if you report the
whole series without the wrong line-breaks.

Cheers


Daniel


On Thu, Aug 04, 2022 at 11:34:28AM +0800, Weijie Gao wrote:
> This patch adds basic support for MediaTek MT7986 SoC.
> This include the file that will initialize the SoC after boot and its
> device tree.
> 
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  arch/arm/dts/mt7986-u-boot.dtsi               |  33 ++
>  arch/arm/dts/mt7986.dtsi                      | 341 ++++++++++++++++++
>  arch/arm/mach-mediatek/Kconfig                |  11 +
>  arch/arm/mach-mediatek/Makefile               |   1 +
>  arch/arm/mach-mediatek/mt7986/Makefile        |   4 +
>  arch/arm/mach-mediatek/mt7986/init.c          |  53 +++
>  arch/arm/mach-mediatek/mt7986/lowlevel_init.S |  30 ++
>  7 files changed, 473 insertions(+)
>  create mode 100644 arch/arm/dts/mt7986-u-boot.dtsi
>  create mode 100644 arch/arm/dts/mt7986.dtsi
>  create mode 100644 arch/arm/mach-mediatek/mt7986/Makefile
>  create mode 100644 arch/arm/mach-mediatek/mt7986/init.c
>  create mode 100644 arch/arm/mach-mediatek/mt7986/lowlevel_init.S
> 
> diff --git a/arch/arm/dts/mt7986-u-boot.dtsi
>  b/arch/arm/dts/mt7986-u-boot.dtsi

The above two lines should be a single line.

> new file mode 100644
> index 0000000000..95671f8afa
> --- /dev/null
> +++ b/arch/arm/dts/mt7986-u-boot.dtsi
> @@ -0,0 +1,33 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2022 MediaTek Inc.
> + * Author: Sam Shih <sam.shih@mediatek.com>
> + */
> +
> +&topckgen {
> +	u-boot,dm-pre-reloc;
> +};
> +
> +&pericfg {
> +	u-boot,dm-pre-reloc;
> +};
> +
> +&apmixedsys {
> +	u-boot,dm-pre-reloc;
> +};
> +
> +&timer0 {
> +	u-boot,dm-pre-reloc;
> +};
> +
> +&uart0 {
> +	u-boot,dm-pre-reloc;
> +};
> +
> +&snand {
> +	u-boot,dm-pre-reloc;
> +};
> +
> +&pinctrl {
> +	u-boot,dm-pre-reloc;
> +};
> diff --git a/arch/arm/dts/mt7986.dtsi b/arch/arm/dts/mt7986.dtsi
> new file mode 100644
> index 0000000000..f235bd8b8c
> --- /dev/null
> +++ b/arch/arm/dts/mt7986.dtsi
> @@ -0,0 +1,341 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2022 MediaTek Inc.
> + * Author: Sam Shih <sam.shih@mediatek.com>
> + */
> +
> +#include <dt-bindings/interrupt-controller/irq.h>
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/phy/phy.h>
> +#include <dt-bindings/clock/mt7986-clk.h>
> +#include <dt-bindings/reset/mt7629-reset.h>
> +#include <dt-bindings/pinctrl/mt65xx.h>
> +
> +/ {
> +	compatible = "mediatek,mt7986";
> +	interrupt-parent = <&gic>;
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +
> +	config {
> +		u-boot,mmc-env-partition = "u-boot-env";
> +	};
> +
> +	cpus {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		cpu0: cpu@0 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a53";
> +			reg = <0x0>;
> +		};
> +		cpu1: cpu@1 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a53";
> +			reg = <0x1>;
> +		};
> +		cpu2: cpu@2 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a53";
> +			reg = <0x1>;
> +		};
> +		cpu3: cpu@3 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a53";
> +			reg = <0x1>;
> +		};
> +	};
> +
> +	dummy_clk: dummy12m {
> +		compatible = "fixed-clock";
> +		clock-frequency = <12000000>;
> +		#clock-cells = <0>;
> +		/* must need this line, or uart uanable to get dummy_clk */
> +		u-boot,dm-pre-reloc;
> +	};
> +
> +	timer {
> +		compatible = "arm,armv8-timer";
> +		interrupt-parent = <&gic>;
> +		clock-frequency = <13000000>;
> +		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
> +			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
> +			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
> +			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
> +		arm,cpu-registers-not-fw-configured;
> +	};
> +
> +	timer0: timer@10008000 {
> +		compatible = "mediatek,mt7986-timer";
> +		reg = <0x10008000 0x1000>;
> +		interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&infracfg CK_INFRA_CK_F26M>;
> +		clock-names = "gpt-clk";
> +		u-boot,dm-pre-reloc;
> +	};
> +
> +	watchdog: watchdog@1001c000 {
> +		compatible = "mediatek,mt7986-wdt";
> +		reg = <0x1001c000 0x1000>;
> +		interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
> +		#reset-cells = <1>;
> +		status = "disabled";
> +	};
> +
> +	gic: interrupt-controller@c000000 {
> +		compatible = "arm,gic-v3";
> +		#interrupt-cells = <3>;
> +		interrupt-parent = <&gic>;
> +		interrupt-controller;
> +		reg = <0x0c000000 0x40000>,  /* GICD */
> +		      <0x0c080000 0x200000>; /* GICR */
> +
> +		interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
> +	};
> +
> +	fixed_plls: apmixedsys@1001E000 {
> +		compatible = "mediatek,mt7986-fixed-plls";
> +		reg = <0x1001E000 0x1000>;
> +		#clock-cells = <1>;
> +	};
> +
> +	topckgen: topckgen@1001B000 {
> +		compatible = "mediatek,mt7986-topckgen";
> +		reg = <0x1001B000 0x1000>;
> +		clock-parent = <&fixed_plls>;
> +		#clock-cells = <1>;
> +	};
> +
> +	infracfg_ao: infracfg_ao@10001000 {
> +		compatible = "mediatek,mt7986-infracfg_ao";
> +		reg = <0x10001000 0x68>;
> +		clock-parent = <&infracfg>;
> +		#clock-cells = <1>;
> +	};
> +
> +	infracfg: infracfg@10001040 {
> +		compatible = "mediatek,mt7986-infracfg";
> +		reg = <0x10001000 0x1000>;
> +		clock-parent = <&topckgen>;
> +		#clock-cells = <1>;
> +	};
> +
> +	pinctrl: pinctrl@1001f000 {
> +		compatible = "mediatek,mt7986-pinctrl";
> +		reg = <0x1001f000 0x1000>,
> +		      <0x11c30000 0x1000>,
> +		      <0x11c40000 0x1000>,
> +		      <0x11e20000 0x1000>,
> +		      <0x11e30000 0x1000>,
> +		      <0x11f00000 0x1000>,
> +		      <0x11f10000 0x1000>,
> +		      <0x1000b000 0x1000>;
> +		reg-names = "gpio_base", "iocfg_rt_base", "iocfg_rb_base",
> +			    "iocfg_lt_base", "iocfg_lb_base", "iocfg_tr_base",
> +			    "iocfg_tl_base", "eint";
> +		gpio: gpio-controller {
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +		};
> +	};
> +
> +	pwm: pwm@10048000 {
> +		compatible = "mediatek,mt7986-pwm";
> +		reg = <0x10048000 0x1000>;
> +		#clock-cells = <1>;
> +		#pwm-cells = <2>;
> +		interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&infracfg CK_INFRA_PWM>,
> +			 <&infracfg_ao CK_INFRA_PWM_BSEL>,
> +			 <&infracfg_ao CK_INFRA_PWM1_CK>,
> +			 <&infracfg_ao CK_INFRA_PWM2_CK>;
> +		assigned-clocks = <&topckgen CK_TOP_PWM_SEL>,
> +				  <&infracfg CK_INFRA_PWM_BSEL>,
> +				  <&infracfg CK_INFRA_PWM1_SEL>,
> +				  <&infracfg CK_INFRA_PWM2_SEL>;
> +		assigned-clock-parents = <&topckgen CK_TOP_CB_M_D4>,
> +					 <&infracfg CK_INFRA_PWM>,
> +					 <&infracfg CK_INFRA_PWM>,
> +					 <&infracfg CK_INFRA_PWM>;
> +		clock-names = "top", "main", "pwm1", "pwm2";
> +		status = "disabled";
> +		u-boot,dm-pre-reloc;
> +	};
> +
> +	uart0: serial@11002000 {
> +		compatible = "mediatek,hsuart";
> +		reg = <0x11002000 0x400>;
> +		interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&infracfg_ao CK_INFRA_UART0_CK>;
> +		assigned-clocks = <&topckgen CK_TOP_UART_SEL>,
> +				  <&infracfg_ao CK_INFRA_UART0_SEL>;
> +		assigned-clock-parents = <&topckgen CK_TOP_CB_CKSQ_40M>,
> +					 <&infracfg CK_INFRA_UART>;
> +		mediatek,force-highspeed;
> +		status = "disabled";
> +		u-boot,dm-pre-reloc;
> +	};
> +
> +	uart1: serial@11003000 {
> +		compatible = "mediatek,hsuart";
> +		reg = <0x11003000 0x400>;
> +		interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&infracfg_ao CK_INFRA_UART1_CK>;
> +		assigned-clocks = <&infracfg CK_INFRA_UART1_SEL>;
> +		assigned-clock-parents = <&infracfg CK_INFRA_CK_F26M>;
> +		mediatek,force-highspeed;
> +		status = "disabled";
> +	};
> +
> +	uart2: serial@11004000 {
> +		compatible = "mediatek,hsuart";
> +		reg = <0x11004000 0x400>;
> +		interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&infracfg_ao CK_INFRA_UART2_CK>;
> +		assigned-clocks = <&infracfg CK_INFRA_UART2_SEL>;
> +		assigned-clock-parents = <&infracfg CK_INFRA_CK_F26M>;
> +		mediatek,force-highspeed;
> +		status = "disabled";
> +	};
> +
> +	snand: snand@11005000 {
> +		compatible = "mediatek,mt7986-snand";
> +		reg = <0x11005000 0x1000>,
> +		      <0x11006000 0x1000>;
> +		reg-names = "nfi", "ecc";
> +		clocks = <&infracfg_ao CK_INFRA_SPINFI1_CK>,
> +			 <&infracfg_ao CK_INFRA_NFI1_CK>,
> +			 <&infracfg_ao CK_INFRA_NFI_HCK_CK>;
> +		clock-names = "pad_clk", "nfi_clk", "nfi_hclk";
> +		assigned-clocks = <&topckgen CK_TOP_SPINFI_SEL>,
> +				  <&topckgen CK_TOP_NFI1X_SEL>;
> +		assigned-clock-parents = <&topckgen CK_TOP_CB_M_D8>,
> +					 <&topckgen CK_TOP_CB_M_D8>;
> +		status = "disabled";
> +	};
> +
> +	ethsys: syscon@15000000 {
> +		compatible = "mediatek,mt7986-ethsys", "syscon";
> +		reg = <0x15000000 0x1000>;
> +		clock-parent = <&topckgen>;
> +		#clock-cells = <1>;
> +		#reset-cells = <1>;
> +	};
> +
> +	eth: ethernet@15100000 {
> +		compatible = "mediatek,mt7986-eth", "syscon";
> +		reg = <0x15100000 0x20000>;
> +		resets = <&ethsys ETHSYS_FE_RST>;
> +		reset-names = "fe";
> +		mediatek,ethsys = <&ethsys>;
> +		mediatek,sgmiisys = <&sgmiisys0>;
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		status = "disabled";
> +	};
> +
> +	sgmiisys0: syscon@10060000 {
> +		compatible = "mediatek,mt7986-sgmiisys", "syscon";
> +		reg = <0x10060000 0x1000>;
> +		#clock-cells = <1>;
> +	};
> +
> +	sgmiisys1: syscon@10070000 {
> +		compatible = "mediatek,mt7986-sgmiisys", "syscon";
> +		reg = <0x10070000 0x1000>;
> +		#clock-cells = <1>;
> +	};
> +
> +	spi0: spi@1100a000 {
> +		compatible = "mediatek,ipm-spi";
> +		reg = <0x1100a000 0x100>;
> +		clocks = <&infracfg_ao CK_INFRA_SPI0_CK>,
> +			 <&topckgen CK_TOP_SPI_SEL>;
> +		assigned-clocks = <&topckgen CK_TOP_SPI_SEL>,
> +				  <&infracfg CK_INFRA_SPI0_SEL>;
> +		assigned-clock-parents = <&topckgen CK_TOP_CB_M_D2>,
> +					 <&topckgen CK_INFRA_ISPI0>;
> +		clock-names = "sel-clk", "spi-clk";
> +		interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
> +		status = "disabled";
> +	};
> +
> +	spi1: spi@1100b000 {
> +		compatible = "mediatek,ipm-spi";
> +		reg = <0x1100b000 0x100>;
> +		interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
> +		status = "disabled";
> +	};
> +
> +	mmc0: mmc@11230000 {
> +		compatible = "mediatek,mt7986-mmc";
> +		reg = <0x11230000 0x1000>,
> +		      <0x11C20000 0x1000>;
> +		interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&topckgen CK_TOP_EMMC_416M>,
> +			<&topckgen CK_TOP_EMMC_250M>,
> +			<&infracfg_ao CK_INFRA_MSDC_CK>;
> +		assigned-clocks = <&topckgen CK_TOP_EMMC_416M_SEL>,
> +				  <&topckgen CK_TOP_EMMC_250M_SEL>;
> +		assigned-clock-parents = <&topckgen CK_TOP_CB_M_416M>,
> +					 <&topckgen CK_TOP_NET1_D5_D2>;
> +		clock-names = "source", "hclk", "source_cg";
> +		status = "disabled";
> +	};
> +
> +	xhci: xhci@11200000 {
> +		compatible = "mediatek,mt7986-xhci",
> +			     "mediatek,mtk-xhci";
> +		reg = <0x11200000 0x2e00>,
> +		      <0x11203e00 0x0100>;
> +		reg-names = "mac", "ippc";
> +		interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
> +		phys = <&u2port0 PHY_TYPE_USB2>,
> +		       <&u3port0 PHY_TYPE_USB3>,
> +		       <&u2port1 PHY_TYPE_USB2>;
> +		clocks = <&dummy_clk>,
> +			 <&dummy_clk>,
> +			 <&dummy_clk>,
> +			 <&dummy_clk>,
> +			 <&dummy_clk>;
> +		clock-names = "sys_ck",
> +			      "xhci_ck",
> +			      "ref_ck",
> +			      "mcu_ck",
> +			      "dma_ck";
> +		tpl-support;
> +		status = "okay";
> +	};
> +
> +	usbtphy: usb-phy@11e10000 {
> +		compatible = "mediatek,mt7986",
> +			     "mediatek,generic-tphy-v2";
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		status = "okay";
> +
> +		u2port0: usb-phy@11e10000 {
> +			reg = <0x11e10000 0x700>;
> +			clocks = <&dummy_clk>;
> +			clock-names = "ref";
> +			#phy-cells = <1>;
> +			status = "okay";
> +		};
> +
> +		u3port0: usb-phy@11e10700 {
> +			reg = <0x11e10700 0x900>;
> +			clocks = <&dummy_clk>;
> +			clock-names = "ref";
> +			#phy-cells = <1>;
> +			status = "okay";
> +		};
> +
> +		u2port1: usb-phy@11e11000 {
> +			reg = <0x11e11000 0x700>;
> +			clocks = <&dummy_clk>;
> +			clock-names = "ref";
> +			#phy-cells = <1>;
> +			status = "okay";
> +		};
> +	};
> +};
> diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
> index f79a5c62cd..e059a013db 100644
> --- a/arch/arm/mach-mediatek/Kconfig
> +++ b/arch/arm/mach-mediatek/Kconfig
> @@ -40,6 +40,14 @@ config TARGET_MT7629
>  	  including DDR3, crypto engine, 3x3 11n/ac Wi-Fi, Gigabit Ethernet,
>  	  switch, USB3.0, PCIe, UART, SPI, I2C and PWM.
>  
> +config TARGET_MT7986
> +	bool "MediaTek MT7986 SoC"
> +	select ARM64
> +	help
> +	  The MediaTek MT7986 is a ARM64-based SoC with a quad-core Cortex-A53.
> +	  including UART, SPI, SPI flash, USB3.0, MMC, NAND, SNFI, PWM, PCIe,
> +	  Gigabit Ethernet, I2C, built-in 4x4 Wi-Fi, and PCIe.
> +
>  config TARGET_MT8183
>  	bool "MediaTek MT8183 SoC"
>  	select ARM64
> @@ -84,6 +92,7 @@ config SYS_BOARD
>  	default "mt7622" if TARGET_MT7622
>  	default "mt7623" if TARGET_MT7623
>  	default "mt7629" if TARGET_MT7629
> +	default "mt7986" if TARGET_MT7986
>  	default "mt8183" if TARGET_MT8183
>  	default "mt8512" if TARGET_MT8512
>  	default "mt8516" if TARGET_MT8516
> @@ -99,6 +108,7 @@ config SYS_CONFIG_NAME
>  	default "mt7622" if TARGET_MT7622
>  	default "mt7623" if TARGET_MT7623
>  	default "mt7629" if TARGET_MT7629
> +	default "mt7986" if TARGET_MT7986
>  	default "mt8183" if TARGET_MT8183
>  	default "mt8512" if TARGET_MT8512
>  	default "mt8516" if TARGET_MT8516
> @@ -113,6 +123,7 @@ config MTK_BROM_HEADER_INFO
>  	string
>  	default "media=nor" if TARGET_MT8518 || TARGET_MT8512 || TARGET_MT7629 ||
>  TARGET_MT7622

Same here.

>  	default "media=emmc" if TARGET_MT8516 || TARGET_MT8365 || TARGET_MT8183
> +	default "media=snand;nandinfo=2k+64" if TARGET_MT7986
>  	default "lk=1" if TARGET_MT7623
>  
>  endif
> diff --git a/arch/arm/mach-mediatek/Makefile
>  b/arch/arm/mach-mediatek/Makefile

And here.

> index 0f5b0c16d2..fe5c3a837c 100644
> --- a/arch/arm/mach-mediatek/Makefile
> +++ b/arch/arm/mach-mediatek/Makefile
> @@ -7,6 +7,7 @@ obj-$(CONFIG_MT8512) += mt8512/
>  obj-$(CONFIG_TARGET_MT7622) += mt7622/
>  obj-$(CONFIG_TARGET_MT7623) += mt7623/
>  obj-$(CONFIG_TARGET_MT7629) += mt7629/
> +obj-$(CONFIG_TARGET_MT7986) += mt7986/
>  obj-$(CONFIG_TARGET_MT8183) += mt8183/
>  obj-$(CONFIG_TARGET_MT8516) += mt8516/
>  obj-$(CONFIG_TARGET_MT8518) += mt8518/
> diff --git a/arch/arm/mach-mediatek/mt7986/Makefile
>  b/arch/arm/mach-mediatek/mt7986/Makefile

And here.

> new file mode 100644
> index 0000000000..007eb4a367
> --- /dev/null
> +++ b/arch/arm/mach-mediatek/mt7986/Makefile
> @@ -0,0 +1,4 @@
> +# SPDX-License-Identifier:	GPL-2.0
> +
> +obj-y += init.o
> +obj-y += lowlevel_init.o
> diff --git a/arch/arm/mach-mediatek/mt7986/init.c
>  b/arch/arm/mach-mediatek/mt7986/init.c

And here again.

> new file mode 100644
> index 0000000000..4884cbdc67
> --- /dev/null
> +++ b/arch/arm/mach-mediatek/mt7986/init.c
> @@ -0,0 +1,53 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2022 MediaTek Inc.
> + * Author: Sam Shih <sam.shih@mediatek.com>
> + */
> +
> +#include <fdtdec.h>
> +#include <asm/armv8/mmu.h>
> +#include <init.h>
> +#include <asm/system.h>
> +#include <asm/global_data.h>
> +#include <linux/sizes.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +int print_cpuinfo(void)
> +{
> +	printf("CPU:   MediaTek MT7986\n");
> +	return 0;
> +}
> +
> +int dram_init(void)
> +{
> +	gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, SZ_2G);
> +
> +	return 0;
> +}
> +
> +void reset_cpu(ulong addr)
> +{
> +	psci_system_reset();
> +}
> +
> +static struct mm_region mt7986_mem_map[] = {
> +	{
> +		/* DDR */
> +		.virt = 0x40000000UL,
> +		.phys = 0x40000000UL,
> +		.size = 0x80000000UL,
> +		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE,
> +	}, {
> +		.virt = 0x00000000UL,
> +		.phys = 0x00000000UL,
> +		.size = 0x40000000UL,
> +		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
> +			 PTE_BLOCK_NON_SHARE |
> +			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
> +	}, {
> +		0,
> +	}
> +};
> +
> +struct mm_region *mem_map = mt7986_mem_map;
> diff --git a/arch/arm/mach-mediatek/mt7986/lowlevel_init.S
>  b/arch/arm/mach-mediatek/mt7986/lowlevel_init.S

And here.

> new file mode 100644
> index 0000000000..244d2c1385
> --- /dev/null
> +++ b/arch/arm/mach-mediatek/mt7986/lowlevel_init.S
> @@ -0,0 +1,30 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2022 MediaTek Inc.
> + * Author: Sam Shih <sam.shih@mediatek.com>
> + */
> +
> +/*
> + * Switch from AArch64 EL2 to AArch32 EL2
> + * @param inputs:
> + * x0: argument, zero
> + * x1: machine nr
> + * x2: fdt address
> + * x3: input argument
> + * x4: kernel entry point
> + * @param outputs for secure firmware:
> + * x0: function id
> + * x1: kernel entry point
> + * x2: machine nr
> + * x3: fdt address
> +*/
> +
> +.global armv8_el2_to_aarch32
> +armv8_el2_to_aarch32:
> +	mov     x3, x2
> +	mov     x2, x1
> +	mov     x1, x4
> +	mov	x4, #0
> +	ldr x0, =0x82000200
> +	SMC #0
> +	ret
> -- 
> 2.17.1
> 

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 01/31] arm: mediatek: add support for MediaTek MT7986 SoC
  2022-08-04  8:37   ` Daniel Golle
@ 2022-08-04  8:50     ` Weijie Gao
  2022-08-05  8:43       ` Weijie Gao
  0 siblings, 1 reply; 100+ messages in thread
From: Weijie Gao @ 2022-08-04  8:50 UTC (permalink / raw)
  To: Daniel Golle; +Cc: u-boot, GSS_MTK_Uboot_upstream

Hi Daniel,

Thanks for the reminder.
I found more errornous line-breaks in other patches...
I'll find a way to fix that.

Best Regards,
Weijie

On Thu, 2022-08-04 at 10:37 +0200, Daniel Golle wrote:
> Hi Weijie,
> 
> happy to see this series posted!
> Trying to apply it unfortunately fails due to errornous line-breaks,
> supposedly inserted by your MUA, see below.
> 
> I didn't go beyond the first patch and it'd be nice if you report the
> whole series without the wrong line-breaks.
> 
> Cheers
> 
> 
> Daniel
> 
> 
> On Thu, Aug 04, 2022 at 11:34:28AM +0800, Weijie Gao wrote:
> > This patch adds basic support for MediaTek MT7986 SoC.
> > This include the file that will initialize the SoC after boot and
> > its
> > device tree.
> > 
> > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> > ---
> >  arch/arm/dts/mt7986-u-boot.dtsi               |  33 ++
> >  arch/arm/dts/mt7986.dtsi                      | 341
> > ++++++++++++++++++
> >  arch/arm/mach-mediatek/Kconfig                |  11 +
> >  arch/arm/mach-mediatek/Makefile               |   1 +
> >  arch/arm/mach-mediatek/mt7986/Makefile        |   4 +
> >  arch/arm/mach-mediatek/mt7986/init.c          |  53 +++
> >  arch/arm/mach-mediatek/mt7986/lowlevel_init.S |  30 ++
> >  7 files changed, 473 insertions(+)
> >  create mode 100644 arch/arm/dts/mt7986-u-boot.dtsi
> >  create mode 100644 arch/arm/dts/mt7986.dtsi
> >  create mode 100644 arch/arm/mach-mediatek/mt7986/Makefile
> >  create mode 100644 arch/arm/mach-mediatek/mt7986/init.c
> >  create mode 100644 arch/arm/mach-mediatek/mt7986/lowlevel_init.S
> > 
> > diff --git a/arch/arm/dts/mt7986-u-boot.dtsi
> >  b/arch/arm/dts/mt7986-u-boot.dtsi
> 
> The above two lines should be a single line.
> 
> > new file mode 100644
> > index 0000000000..95671f8afa
> > --- /dev/null
> > +++ b/arch/arm/dts/mt7986-u-boot.dtsi
> > @@ -0,0 +1,33 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2022 MediaTek Inc.
> > + * Author: Sam Shih <sam.shih@mediatek.com>
> > + */
> > +
> > +&topckgen {
> > +	u-boot,dm-pre-reloc;
> > +};
> > +
> > +&pericfg {
> > +	u-boot,dm-pre-reloc;
> > +};
> > +
> > +&apmixedsys {
> > +	u-boot,dm-pre-reloc;
> > +};
> > +
> > +&timer0 {
> > +	u-boot,dm-pre-reloc;
> > +};
> > +
> > +&uart0 {
> > +	u-boot,dm-pre-reloc;
> > +};
> > +
> > +&snand {
> > +	u-boot,dm-pre-reloc;
> > +};
> > +
> > +&pinctrl {
> > +	u-boot,dm-pre-reloc;
> > +};
> > diff --git a/arch/arm/dts/mt7986.dtsi b/arch/arm/dts/mt7986.dtsi
> > new file mode 100644
> > index 0000000000..f235bd8b8c
> > --- /dev/null
> > +++ b/arch/arm/dts/mt7986.dtsi
> > @@ -0,0 +1,341 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2022 MediaTek Inc.
> > + * Author: Sam Shih <sam.shih@mediatek.com>
> > + */
> > +
> > +#include <dt-bindings/interrupt-controller/irq.h>
> > +#include <dt-bindings/interrupt-controller/arm-gic.h>
> > +#include <dt-bindings/phy/phy.h>
> > +#include <dt-bindings/clock/mt7986-clk.h>
> > +#include <dt-bindings/reset/mt7629-reset.h>
> > +#include <dt-bindings/pinctrl/mt65xx.h>
> > +
> > +/ {
> > +	compatible = "mediatek,mt7986";
> > +	interrupt-parent = <&gic>;
> > +	#address-cells = <1>;
> > +	#size-cells = <1>;
> > +
> > +	config {
> > +		u-boot,mmc-env-partition = "u-boot-env";
> > +	};
> > +
> > +	cpus {
> > +		#address-cells = <1>;
> > +		#size-cells = <0>;
> > +		cpu0: cpu@0 {
> > +			device_type = "cpu";
> > +			compatible = "arm,cortex-a53";
> > +			reg = <0x0>;
> > +		};
> > +		cpu1: cpu@1 {
> > +			device_type = "cpu";
> > +			compatible = "arm,cortex-a53";
> > +			reg = <0x1>;
> > +		};
> > +		cpu2: cpu@2 {
> > +			device_type = "cpu";
> > +			compatible = "arm,cortex-a53";
> > +			reg = <0x1>;
> > +		};
> > +		cpu3: cpu@3 {
> > +			device_type = "cpu";
> > +			compatible = "arm,cortex-a53";
> > +			reg = <0x1>;
> > +		};
> > +	};
> > +
> > +	dummy_clk: dummy12m {
> > +		compatible = "fixed-clock";
> > +		clock-frequency = <12000000>;
> > +		#clock-cells = <0>;
> > +		/* must need this line, or uart uanable to get
> > dummy_clk */
> > +		u-boot,dm-pre-reloc;
> > +	};
> > +
> > +	timer {
> > +		compatible = "arm,armv8-timer";
> > +		interrupt-parent = <&gic>;
> > +		clock-frequency = <13000000>;
> > +		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
> > +			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
> > +			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
> > +			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
> > +		arm,cpu-registers-not-fw-configured;
> > +	};
> > +
> > +	timer0: timer@10008000 {
> > +		compatible = "mediatek,mt7986-timer";
> > +		reg = <0x10008000 0x1000>;
> > +		interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
> > +		clocks = <&infracfg CK_INFRA_CK_F26M>;
> > +		clock-names = "gpt-clk";
> > +		u-boot,dm-pre-reloc;
> > +	};
> > +
> > +	watchdog: watchdog@1001c000 {
> > +		compatible = "mediatek,mt7986-wdt";
> > +		reg = <0x1001c000 0x1000>;
> > +		interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
> > +		#reset-cells = <1>;
> > +		status = "disabled";
> > +	};
> > +
> > +	gic: interrupt-controller@c000000 {
> > +		compatible = "arm,gic-v3";
> > +		#interrupt-cells = <3>;
> > +		interrupt-parent = <&gic>;
> > +		interrupt-controller;
> > +		reg = <0x0c000000 0x40000>,  /* GICD */
> > +		      <0x0c080000 0x200000>; /* GICR */
> > +
> > +		interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
> > +	};
> > +
> > +	fixed_plls: apmixedsys@1001E000 {
> > +		compatible = "mediatek,mt7986-fixed-plls";
> > +		reg = <0x1001E000 0x1000>;
> > +		#clock-cells = <1>;
> > +	};
> > +
> > +	topckgen: topckgen@1001B000 {
> > +		compatible = "mediatek,mt7986-topckgen";
> > +		reg = <0x1001B000 0x1000>;
> > +		clock-parent = <&fixed_plls>;
> > +		#clock-cells = <1>;
> > +	};
> > +
> > +	infracfg_ao: infracfg_ao@10001000 {
> > +		compatible = "mediatek,mt7986-infracfg_ao";
> > +		reg = <0x10001000 0x68>;
> > +		clock-parent = <&infracfg>;
> > +		#clock-cells = <1>;
> > +	};
> > +
> > +	infracfg: infracfg@10001040 {
> > +		compatible = "mediatek,mt7986-infracfg";
> > +		reg = <0x10001000 0x1000>;
> > +		clock-parent = <&topckgen>;
> > +		#clock-cells = <1>;
> > +	};
> > +
> > +	pinctrl: pinctrl@1001f000 {
> > +		compatible = "mediatek,mt7986-pinctrl";
> > +		reg = <0x1001f000 0x1000>,
> > +		      <0x11c30000 0x1000>,
> > +		      <0x11c40000 0x1000>,
> > +		      <0x11e20000 0x1000>,
> > +		      <0x11e30000 0x1000>,
> > +		      <0x11f00000 0x1000>,
> > +		      <0x11f10000 0x1000>,
> > +		      <0x1000b000 0x1000>;
> > +		reg-names = "gpio_base", "iocfg_rt_base",
> > "iocfg_rb_base",
> > +			    "iocfg_lt_base", "iocfg_lb_base",
> > "iocfg_tr_base",
> > +			    "iocfg_tl_base", "eint";
> > +		gpio: gpio-controller {
> > +			gpio-controller;
> > +			#gpio-cells = <2>;
> > +		};
> > +	};
> > +
> > +	pwm: pwm@10048000 {
> > +		compatible = "mediatek,mt7986-pwm";
> > +		reg = <0x10048000 0x1000>;
> > +		#clock-cells = <1>;
> > +		#pwm-cells = <2>;
> > +		interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
> > +		clocks = <&infracfg CK_INFRA_PWM>,
> > +			 <&infracfg_ao CK_INFRA_PWM_BSEL>,
> > +			 <&infracfg_ao CK_INFRA_PWM1_CK>,
> > +			 <&infracfg_ao CK_INFRA_PWM2_CK>;
> > +		assigned-clocks = <&topckgen CK_TOP_PWM_SEL>,
> > +				  <&infracfg CK_INFRA_PWM_BSEL>,
> > +				  <&infracfg CK_INFRA_PWM1_SEL>,
> > +				  <&infracfg CK_INFRA_PWM2_SEL>;
> > +		assigned-clock-parents = <&topckgen
> > CK_TOP_CB_M_D4>,
> > +					 <&infracfg CK_INFRA_PWM>,
> > +					 <&infracfg CK_INFRA_PWM>,
> > +					 <&infracfg CK_INFRA_PWM>;
> > +		clock-names = "top", "main", "pwm1", "pwm2";
> > +		status = "disabled";
> > +		u-boot,dm-pre-reloc;
> > +	};
> > +
> > +	uart0: serial@11002000 {
> > +		compatible = "mediatek,hsuart";
> > +		reg = <0x11002000 0x400>;
> > +		interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
> > +		clocks = <&infracfg_ao CK_INFRA_UART0_CK>;
> > +		assigned-clocks = <&topckgen CK_TOP_UART_SEL>,
> > +				  <&infracfg_ao
> > CK_INFRA_UART0_SEL>;
> > +		assigned-clock-parents = <&topckgen
> > CK_TOP_CB_CKSQ_40M>,
> > +					 <&infracfg
> > CK_INFRA_UART>;
> > +		mediatek,force-highspeed;
> > +		status = "disabled";
> > +		u-boot,dm-pre-reloc;
> > +	};
> > +
> > +	uart1: serial@11003000 {
> > +		compatible = "mediatek,hsuart";
> > +		reg = <0x11003000 0x400>;
> > +		interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
> > +		clocks = <&infracfg_ao CK_INFRA_UART1_CK>;
> > +		assigned-clocks = <&infracfg CK_INFRA_UART1_SEL>;
> > +		assigned-clock-parents = <&infracfg
> > CK_INFRA_CK_F26M>;
> > +		mediatek,force-highspeed;
> > +		status = "disabled";
> > +	};
> > +
> > +	uart2: serial@11004000 {
> > +		compatible = "mediatek,hsuart";
> > +		reg = <0x11004000 0x400>;
> > +		interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
> > +		clocks = <&infracfg_ao CK_INFRA_UART2_CK>;
> > +		assigned-clocks = <&infracfg CK_INFRA_UART2_SEL>;
> > +		assigned-clock-parents = <&infracfg
> > CK_INFRA_CK_F26M>;
> > +		mediatek,force-highspeed;
> > +		status = "disabled";
> > +	};
> > +
> > +	snand: snand@11005000 {
> > +		compatible = "mediatek,mt7986-snand";
> > +		reg = <0x11005000 0x1000>,
> > +		      <0x11006000 0x1000>;
> > +		reg-names = "nfi", "ecc";
> > +		clocks = <&infracfg_ao CK_INFRA_SPINFI1_CK>,
> > +			 <&infracfg_ao CK_INFRA_NFI1_CK>,
> > +			 <&infracfg_ao CK_INFRA_NFI_HCK_CK>;
> > +		clock-names = "pad_clk", "nfi_clk", "nfi_hclk";
> > +		assigned-clocks = <&topckgen CK_TOP_SPINFI_SEL>,
> > +				  <&topckgen CK_TOP_NFI1X_SEL>;
> > +		assigned-clock-parents = <&topckgen
> > CK_TOP_CB_M_D8>,
> > +					 <&topckgen
> > CK_TOP_CB_M_D8>;
> > +		status = "disabled";
> > +	};
> > +
> > +	ethsys: syscon@15000000 {
> > +		compatible = "mediatek,mt7986-ethsys", "syscon";
> > +		reg = <0x15000000 0x1000>;
> > +		clock-parent = <&topckgen>;
> > +		#clock-cells = <1>;
> > +		#reset-cells = <1>;
> > +	};
> > +
> > +	eth: ethernet@15100000 {
> > +		compatible = "mediatek,mt7986-eth", "syscon";
> > +		reg = <0x15100000 0x20000>;
> > +		resets = <&ethsys ETHSYS_FE_RST>;
> > +		reset-names = "fe";
> > +		mediatek,ethsys = <&ethsys>;
> > +		mediatek,sgmiisys = <&sgmiisys0>;
> > +		#address-cells = <1>;
> > +		#size-cells = <0>;
> > +		status = "disabled";
> > +	};
> > +
> > +	sgmiisys0: syscon@10060000 {
> > +		compatible = "mediatek,mt7986-sgmiisys", "syscon";
> > +		reg = <0x10060000 0x1000>;
> > +		#clock-cells = <1>;
> > +	};
> > +
> > +	sgmiisys1: syscon@10070000 {
> > +		compatible = "mediatek,mt7986-sgmiisys", "syscon";
> > +		reg = <0x10070000 0x1000>;
> > +		#clock-cells = <1>;
> > +	};
> > +
> > +	spi0: spi@1100a000 {
> > +		compatible = "mediatek,ipm-spi";
> > +		reg = <0x1100a000 0x100>;
> > +		clocks = <&infracfg_ao CK_INFRA_SPI0_CK>,
> > +			 <&topckgen CK_TOP_SPI_SEL>;
> > +		assigned-clocks = <&topckgen CK_TOP_SPI_SEL>,
> > +				  <&infracfg CK_INFRA_SPI0_SEL>;
> > +		assigned-clock-parents = <&topckgen
> > CK_TOP_CB_M_D2>,
> > +					 <&topckgen
> > CK_INFRA_ISPI0>;
> > +		clock-names = "sel-clk", "spi-clk";
> > +		interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
> > +		status = "disabled";
> > +	};
> > +
> > +	spi1: spi@1100b000 {
> > +		compatible = "mediatek,ipm-spi";
> > +		reg = <0x1100b000 0x100>;
> > +		interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
> > +		status = "disabled";
> > +	};
> > +
> > +	mmc0: mmc@11230000 {
> > +		compatible = "mediatek,mt7986-mmc";
> > +		reg = <0x11230000 0x1000>,
> > +		      <0x11C20000 0x1000>;
> > +		interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
> > +		clocks = <&topckgen CK_TOP_EMMC_416M>,
> > +			<&topckgen CK_TOP_EMMC_250M>,
> > +			<&infracfg_ao CK_INFRA_MSDC_CK>;
> > +		assigned-clocks = <&topckgen
> > CK_TOP_EMMC_416M_SEL>,
> > +				  <&topckgen
> > CK_TOP_EMMC_250M_SEL>;
> > +		assigned-clock-parents = <&topckgen
> > CK_TOP_CB_M_416M>,
> > +					 <&topckgen
> > CK_TOP_NET1_D5_D2>;
> > +		clock-names = "source", "hclk", "source_cg";
> > +		status = "disabled";
> > +	};
> > +
> > +	xhci: xhci@11200000 {
> > +		compatible = "mediatek,mt7986-xhci",
> > +			     "mediatek,mtk-xhci";
> > +		reg = <0x11200000 0x2e00>,
> > +		      <0x11203e00 0x0100>;
> > +		reg-names = "mac", "ippc";
> > +		interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
> > +		phys = <&u2port0 PHY_TYPE_USB2>,
> > +		       <&u3port0 PHY_TYPE_USB3>,
> > +		       <&u2port1 PHY_TYPE_USB2>;
> > +		clocks = <&dummy_clk>,
> > +			 <&dummy_clk>,
> > +			 <&dummy_clk>,
> > +			 <&dummy_clk>,
> > +			 <&dummy_clk>;
> > +		clock-names = "sys_ck",
> > +			      "xhci_ck",
> > +			      "ref_ck",
> > +			      "mcu_ck",
> > +			      "dma_ck";
> > +		tpl-support;
> > +		status = "okay";
> > +	};
> > +
> > +	usbtphy: usb-phy@11e10000 {
> > +		compatible = "mediatek,mt7986",
> > +			     "mediatek,generic-tphy-v2";
> > +		#address-cells = <1>;
> > +		#size-cells = <1>;
> > +		status = "okay";
> > +
> > +		u2port0: usb-phy@11e10000 {
> > +			reg = <0x11e10000 0x700>;
> > +			clocks = <&dummy_clk>;
> > +			clock-names = "ref";
> > +			#phy-cells = <1>;
> > +			status = "okay";
> > +		};
> > +
> > +		u3port0: usb-phy@11e10700 {
> > +			reg = <0x11e10700 0x900>;
> > +			clocks = <&dummy_clk>;
> > +			clock-names = "ref";
> > +			#phy-cells = <1>;
> > +			status = "okay";
> > +		};
> > +
> > +		u2port1: usb-phy@11e11000 {
> > +			reg = <0x11e11000 0x700>;
> > +			clocks = <&dummy_clk>;
> > +			clock-names = "ref";
> > +			#phy-cells = <1>;
> > +			status = "okay";
> > +		};
> > +	};
> > +};
> > diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-
> > mediatek/Kconfig
> > index f79a5c62cd..e059a013db 100644
> > --- a/arch/arm/mach-mediatek/Kconfig
> > +++ b/arch/arm/mach-mediatek/Kconfig
> > @@ -40,6 +40,14 @@ config TARGET_MT7629
> >  	  including DDR3, crypto engine, 3x3 11n/ac Wi-Fi, Gigabit
> > Ethernet,
> >  	  switch, USB3.0, PCIe, UART, SPI, I2C and PWM.
> >  
> > +config TARGET_MT7986
> > +	bool "MediaTek MT7986 SoC"
> > +	select ARM64
> > +	help
> > +	  The MediaTek MT7986 is a ARM64-based SoC with a quad-
> > core Cortex-A53.
> > +	  including UART, SPI, SPI flash, USB3.0, MMC, NAND, SNFI,
> > PWM, PCIe,
> > +	  Gigabit Ethernet, I2C, built-in 4x4 Wi-Fi, and PCIe.
> > +
> >  config TARGET_MT8183
> >  	bool "MediaTek MT8183 SoC"
> >  	select ARM64
> > @@ -84,6 +92,7 @@ config SYS_BOARD
> >  	default "mt7622" if TARGET_MT7622
> >  	default "mt7623" if TARGET_MT7623
> >  	default "mt7629" if TARGET_MT7629
> > +	default "mt7986" if TARGET_MT7986
> >  	default "mt8183" if TARGET_MT8183
> >  	default "mt8512" if TARGET_MT8512
> >  	default "mt8516" if TARGET_MT8516
> > @@ -99,6 +108,7 @@ config SYS_CONFIG_NAME
> >  	default "mt7622" if TARGET_MT7622
> >  	default "mt7623" if TARGET_MT7623
> >  	default "mt7629" if TARGET_MT7629
> > +	default "mt7986" if TARGET_MT7986
> >  	default "mt8183" if TARGET_MT8183
> >  	default "mt8512" if TARGET_MT8512
> >  	default "mt8516" if TARGET_MT8516
> > @@ -113,6 +123,7 @@ config MTK_BROM_HEADER_INFO
> >  	string
> >  	default "media=nor" if TARGET_MT8518 || TARGET_MT8512 ||
> > TARGET_MT7629 ||
> >  TARGET_MT7622
> 
> Same here.
> 
> >  	default "media=emmc" if TARGET_MT8516 || TARGET_MT8365 ||
> > TARGET_MT8183
> > +	default "media=snand;nandinfo=2k+64" if TARGET_MT7986
> >  	default "lk=1" if TARGET_MT7623
> >  
> >  endif
> > diff --git a/arch/arm/mach-mediatek/Makefile
> >  b/arch/arm/mach-mediatek/Makefile
> 
> And here.
> 
> > index 0f5b0c16d2..fe5c3a837c 100644
> > --- a/arch/arm/mach-mediatek/Makefile
> > +++ b/arch/arm/mach-mediatek/Makefile
> > @@ -7,6 +7,7 @@ obj-$(CONFIG_MT8512) += mt8512/
> >  obj-$(CONFIG_TARGET_MT7622) += mt7622/
> >  obj-$(CONFIG_TARGET_MT7623) += mt7623/
> >  obj-$(CONFIG_TARGET_MT7629) += mt7629/
> > +obj-$(CONFIG_TARGET_MT7986) += mt7986/
> >  obj-$(CONFIG_TARGET_MT8183) += mt8183/
> >  obj-$(CONFIG_TARGET_MT8516) += mt8516/
> >  obj-$(CONFIG_TARGET_MT8518) += mt8518/
> > diff --git a/arch/arm/mach-mediatek/mt7986/Makefile
> >  b/arch/arm/mach-mediatek/mt7986/Makefile
> 
> And here.
> 
> > new file mode 100644
> > index 0000000000..007eb4a367
> > --- /dev/null
> > +++ b/arch/arm/mach-mediatek/mt7986/Makefile
> > @@ -0,0 +1,4 @@
> > +# SPDX-License-Identifier:	GPL-2.0
> > +
> > +obj-y += init.o
> > +obj-y += lowlevel_init.o
> > diff --git a/arch/arm/mach-mediatek/mt7986/init.c
> >  b/arch/arm/mach-mediatek/mt7986/init.c
> 
> And here again.
> 
> > new file mode 100644
> > index 0000000000..4884cbdc67
> > --- /dev/null
> > +++ b/arch/arm/mach-mediatek/mt7986/init.c
> > @@ -0,0 +1,53 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2022 MediaTek Inc.
> > + * Author: Sam Shih <sam.shih@mediatek.com>
> > + */
> > +
> > +#include <fdtdec.h>
> > +#include <asm/armv8/mmu.h>
> > +#include <init.h>
> > +#include <asm/system.h>
> > +#include <asm/global_data.h>
> > +#include <linux/sizes.h>
> > +
> > +DECLARE_GLOBAL_DATA_PTR;
> > +
> > +int print_cpuinfo(void)
> > +{
> > +	printf("CPU:   MediaTek MT7986\n");
> > +	return 0;
> > +}
> > +
> > +int dram_init(void)
> > +{
> > +	gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
> > SZ_2G);
> > +
> > +	return 0;
> > +}
> > +
> > +void reset_cpu(ulong addr)
> > +{
> > +	psci_system_reset();
> > +}
> > +
> > +static struct mm_region mt7986_mem_map[] = {
> > +	{
> > +		/* DDR */
> > +		.virt = 0x40000000UL,
> > +		.phys = 0x40000000UL,
> > +		.size = 0x80000000UL,
> > +		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
> > PTE_BLOCK_OUTER_SHARE,
> > +	}, {
> > +		.virt = 0x00000000UL,
> > +		.phys = 0x00000000UL,
> > +		.size = 0x40000000UL,
> > +		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
> > +			 PTE_BLOCK_NON_SHARE |
> > +			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
> > +	}, {
> > +		0,
> > +	}
> > +};
> > +
> > +struct mm_region *mem_map = mt7986_mem_map;
> > diff --git a/arch/arm/mach-mediatek/mt7986/lowlevel_init.S
> >  b/arch/arm/mach-mediatek/mt7986/lowlevel_init.S
> 
> And here.
> 
> > new file mode 100644
> > index 0000000000..244d2c1385
> > --- /dev/null
> > +++ b/arch/arm/mach-mediatek/mt7986/lowlevel_init.S
> > @@ -0,0 +1,30 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Copyright (C) 2022 MediaTek Inc.
> > + * Author: Sam Shih <sam.shih@mediatek.com>
> > + */
> > +
> > +/*
> > + * Switch from AArch64 EL2 to AArch32 EL2
> > + * @param inputs:
> > + * x0: argument, zero
> > + * x1: machine nr
> > + * x2: fdt address
> > + * x3: input argument
> > + * x4: kernel entry point
> > + * @param outputs for secure firmware:
> > + * x0: function id
> > + * x1: kernel entry point
> > + * x2: machine nr
> > + * x3: fdt address
> > +*/
> > +
> > +.global armv8_el2_to_aarch32
> > +armv8_el2_to_aarch32:
> > +	mov     x3, x2
> > +	mov     x2, x1
> > +	mov     x1, x4
> > +	mov	x4, #0
> > +	ldr x0, =0x82000200
> > +	SMC #0
> > +	ret
> > -- 
> > 2.17.1
> > 

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 08/31] net: mediatek: add support for PDMA v2
  2022-08-04  3:35 ` [PATCH 08/31] net: mediatek: add support for PDMA v2 Weijie Gao
@ 2022-08-04 13:56   ` Simon Glass
  2022-08-06 17:49     ` Ramon Fried
  0 siblings, 1 reply; 100+ messages in thread
From: Simon Glass @ 2022-08-04 13:56 UTC (permalink / raw)
  To: Weijie Gao
  Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream, Joe Hershberger,
	Ramon Fried

On Wed, 3 Aug 2022 at 21:36, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> This patch adds support for PDMA v2 hardware. The PDMA v2 has extended the
> DMA descriptor to 8-words, and some of its fields have changed comparing
> to the v1 hardware.
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  drivers/net/mtk_eth.c | 51 ++++++++++++++++++++++++++++++-----------
>  drivers/net/mtk_eth.h | 53 ++++++++++++++++++++++++++++++++++++-------
>  2 files changed, 83 insertions(+), 21 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 10/31] serial: mtk: add support for using dynamic baud clock souce
  2022-08-04  3:35 ` [PATCH 10/31] serial: mtk: add support for using dynamic baud clock souce Weijie Gao
@ 2022-08-04 13:56   ` Simon Glass
  2022-08-08  2:36     ` Weijie Gao
  0 siblings, 1 reply; 100+ messages in thread
From: Simon Glass @ 2022-08-04 13:56 UTC (permalink / raw)
  To: Weijie Gao; +Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream, Pali Rohár

Hi Weijie,

On Wed, 3 Aug 2022 at 21:36, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> The baud clock on some platform may change due to assigned-clock-parent
> set in DT. In current flow the baud clock is only retrieved during probe
> stage. If the parent of the source clock changes after probe stage, the
> setbrg will set wrong baudrate.
>
> To get the right clock rate, this patch records the baud clk struct to the
> driver's priv, and changes the driver's flow to get the clock rate before
> calling _mtk_serial_setbrg().
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  drivers/serial/serial_mtk.c | 72 ++++++++++++++++++++-----------------
>  1 file changed, 39 insertions(+), 33 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

please see below

>
> diff --git a/drivers/serial/serial_mtk.c b/drivers/serial/serial_mtk.c
> index a84f39b3fa..99cf62b8d9 100644
> --- a/drivers/serial/serial_mtk.c
> +++ b/drivers/serial/serial_mtk.c
> @@ -10,6 +10,7 @@
>  #include <common.h>
>  #include <div64.h>
>  #include <dm.h>
> +#include <dm/device_compat.h>
>  #include <errno.h>
>  #include <log.h>
>  #include <serial.h>
> @@ -72,25 +73,27 @@ struct mtk_serial_regs {
>
>  struct mtk_serial_priv {

please add a full comment for this struct

>         struct mtk_serial_regs __iomem *regs;
> -       u32 clock;
> +       struct clk clk;
> +       u32 fixed_clk_rate;
>         bool force_highspeed;
>  };
>
> -static void _mtk_serial_setbrg(struct mtk_serial_priv *priv, int baud)
> +static void _mtk_serial_setbrg(struct mtk_serial_priv *priv, int baud,
> +                              u32 clk_rate)

Why u32? Can you use uint? Generally it is better for parameters to
use natural types unless there is a good reason.

[..]

Regards,
Simon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 07/31] net: mediatek: stop using bitfileds for DMA descriptors
  2022-08-04  3:35 ` [PATCH 07/31] net: mediatek: stop using bitfileds for DMA descriptors Weijie Gao
@ 2022-08-04 13:56   ` Simon Glass
  2022-08-06 17:50   ` Ramon Fried
  1 sibling, 0 replies; 100+ messages in thread
From: Simon Glass @ 2022-08-04 13:56 UTC (permalink / raw)
  To: Weijie Gao
  Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream, Joe Hershberger,
	Ramon Fried

On Wed, 3 Aug 2022 at 21:36, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> This patch is a preparation for adding a new version of PDMA of which the
> DMA descriptor fields has changed. Using bitfields will result in a complex
> modification. Convert bitfields to u32 units can solve this problem easily.
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  drivers/net/mtk_eth.c | 144 ++++++++++++++----------------------------
>  drivers/net/mtk_eth.h |  32 ++++++++++
>  2 files changed, 80 insertions(+), 96 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 06/31] net: mediatek: use a struct to cover variations of all SoCs
  2022-08-04  3:35 ` [PATCH 06/31] net: mediatek: use a struct to cover variations of all SoCs Weijie Gao
@ 2022-08-04 13:56   ` Simon Glass
  2022-08-08  2:28     ` Weijie Gao
  0 siblings, 1 reply; 100+ messages in thread
From: Simon Glass @ 2022-08-04 13:56 UTC (permalink / raw)
  To: Weijie Gao
  Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream, Joe Hershberger,
	Ramon Fried

Hi Weijie,

On Wed, 3 Aug 2022 at 21:36, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> Using a single soc id to control different initialization and TX/RX flow
> for all SoCs is not extensible if more hardware variations are added in
> the future.
>
> This patch introduces a struct to replace the original mtk_soc to allow
> the driver be able handle newer hardwares.
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  drivers/net/mtk_eth.c | 50 +++++++++++++++++++++++++++++--------------
>  drivers/net/mtk_eth.h | 25 +++++++++++++++++++++-
>  2 files changed, 58 insertions(+), 17 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

>
> diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c
> index 4fe7ee0d36..92d2ea4f2a 100644
> --- a/drivers/net/mtk_eth.c
> +++ b/drivers/net/mtk_eth.c
> @@ -142,11 +142,9 @@ enum mtk_switch {
>         SW_MT7531
>  };
>
> -enum mtk_soc {
> -       SOC_MT7623,
> -       SOC_MT7629,
> -       SOC_MT7622,
> -       SOC_MT7621
> +struct mtk_soc_data {
> +       u32 caps;
> +       u32 ana_rgc3;

please comment these
[..]

Regards,
Simon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 05/31] mmc: mediatek: add support for MediaTek MT7891/MT7986 SoCs
  2022-08-04  3:35 ` [PATCH 05/31] mmc: mediatek: add support for MediaTek MT7891/MT7986 SoCs Weijie Gao
@ 2022-08-04 13:57   ` Simon Glass
  2022-08-08  2:22     ` Weijie Gao
  2022-08-11  5:50   ` jh80.chung
  1 sibling, 1 reply; 100+ messages in thread
From: Simon Glass @ 2022-08-04 13:57 UTC (permalink / raw)
  To: Weijie Gao
  Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream, Peng Fan, Jaehoon Chung

Hi Weijie,

On Wed, 3 Aug 2022 at 21:35, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> This patch adds eMMC and SDXC support for MediaTek MT7981/MT7986 SoCs

Add eMMC and SDXC support for MediaTek MT7981/MT7986 SoCs.

(describe your changes in imperative mood)

>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  drivers/mmc/mtk-sd.c | 68 ++++++++++++++++++++++++++++++++++----------
>  1 file changed, 53 insertions(+), 15 deletions(-)
>

Reviewed-by: Simon Glass <sjg@chromium.org>

Regards,
Simon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 11/31] arm: dts: mt7622: force high-speed mode for uart
  2022-08-04  3:35 ` [PATCH 11/31] arm: dts: mt7622: force high-speed mode for uart Weijie Gao
@ 2022-08-04 13:57   ` Simon Glass
  0 siblings, 0 replies; 100+ messages in thread
From: Simon Glass @ 2022-08-04 13:57 UTC (permalink / raw)
  To: Weijie Gao; +Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream

On Wed, 3 Aug 2022 at 21:37, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> The input clock for uart is too slow (25MHz) which introduces frequent data
> error on both receiving and transmitting even if the baudrate is 115200.
>
> Using high-speed can significantly solve this issue.
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  arch/arm/dts/mt7622.dtsi | 1 +
>  1 file changed, 1 insertion(+)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 04/31] board: mediatek: add MT7981 reference boards
  2022-08-04  3:35 ` [PATCH 04/31] board: mediatek: add MT7981 " Weijie Gao
@ 2022-08-04 13:57   ` Simon Glass
  0 siblings, 0 replies; 100+ messages in thread
From: Simon Glass @ 2022-08-04 13:57 UTC (permalink / raw)
  To: Weijie Gao
  Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream, Marcel Ziswiler,
	Andre Przywara, Fabio Estevam, Samuel Holland, Marek Vasut,
	Ying-Chun Liu (PaulLiu),
	Christian Hewitt

Hi Weijie,

On Wed, 3 Aug 2022 at 21:35, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> This patch adds general board files based on MT7981 SoCs.

"Add general board files..." - same for other patches.

Are the dts files from a particular Linux version?

>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  arch/arm/dts/Makefile                  |   5 +
>  arch/arm/dts/mt7981-emmc-rfb.dts       | 139 +++++++++++++++++++++++++
>  arch/arm/dts/mt7981-rfb.dts            | 133 +++++++++++++++++++++++
>  arch/arm/dts/mt7981-sd-rfb.dts         | 139 +++++++++++++++++++++++++
>  arch/arm/dts/mt7981-spim-nand-rfb.dts  | 138 ++++++++++++++++++++++++
>  arch/arm/dts/mt7981-spim-nor-rfb.dts   | 133 +++++++++++++++++++++++
>  board/mediatek/mt7981/MAINTAINERS      |  10 ++
>  board/mediatek/mt7981/Makefile         |   3 +
>  board/mediatek/mt7981/mt7981_rfb.c     |  10 ++
>  configs/mt7981_emmc_rfb_defconfig      |  64 ++++++++++++
>  configs/mt7981_rfb_defconfig           |  65 ++++++++++++
>  configs/mt7981_sd_rfb_defconfig        |  64 ++++++++++++
>  configs/mt7981_spim_nand_rfb_defconfig |  59 +++++++++++
>  configs/mt7981_spim_nor_rfb_defconfig  |  70 +++++++++++++
>  include/configs/mt7981.h               |  26 +++++
>  15 files changed, 1058 insertions(+)
>  create mode 100644 arch/arm/dts/mt7981-emmc-rfb.dts
>  create mode 100644 arch/arm/dts/mt7981-rfb.dts
>  create mode 100644 arch/arm/dts/mt7981-sd-rfb.dts
>  create mode 100644 arch/arm/dts/mt7981-spim-nand-rfb.dts
>  create mode 100644 arch/arm/dts/mt7981-spim-nor-rfb.dts
>  create mode 100644 board/mediatek/mt7981/MAINTAINERS
>  create mode 100644 board/mediatek/mt7981/Makefile
>  create mode 100644 board/mediatek/mt7981/mt7981_rfb.c
>  create mode 100644 configs/mt7981_emmc_rfb_defconfig
>  create mode 100644 configs/mt7981_rfb_defconfig
>  create mode 100644 configs/mt7981_sd_rfb_defconfig
>  create mode 100644 configs/mt7981_spim_nand_rfb_defconfig
>  create mode 100644 configs/mt7981_spim_nor_rfb_defconfig
>  create mode 100644 include/configs/mt7981.h
>

Regards,
Simon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 03/31] board: mediatek: add MT7986 reference boards
  2022-08-04  3:35 ` [PATCH 03/31] board: mediatek: add MT7986 reference boards Weijie Gao
@ 2022-08-04 13:57   ` Simon Glass
  2022-08-09  9:10   ` Daniel Golle
  1 sibling, 0 replies; 100+ messages in thread
From: Simon Glass @ 2022-08-04 13:57 UTC (permalink / raw)
  To: Weijie Gao
  Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream, Marcel Ziswiler,
	Andre Przywara, Fabio Estevam, Samuel Holland, Marek Vasut,
	Ying-Chun Liu (PaulLiu),
	Christian Hewitt

On Wed, 3 Aug 2022 at 21:35, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> This patch adds general board files based on MT7986 SoCs.
>
> The SD/eMMC controller on MT7986A and MT7986B have different pin
> configurations so that four different reference board configs has to be
> added.
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  arch/arm/dts/Makefile              |   4 +
>  arch/arm/dts/mt7986a-rfb.dts       | 218 +++++++++++++++++++++++++++++
>  arch/arm/dts/mt7986a-sd-rfb.dts    | 177 +++++++++++++++++++++++
>  arch/arm/dts/mt7986b-rfb.dts       | 204 +++++++++++++++++++++++++++
>  arch/arm/dts/mt7986b-sd-rfb.dts    | 173 +++++++++++++++++++++++
>  board/mediatek/mt7986/MAINTAINERS  |  10 ++
>  board/mediatek/mt7986/Makefile     |   3 +
>  board/mediatek/mt7986/mt7986_rfb.c |  10 ++
>  configs/mt7986_rfb_defconfig       |  66 +++++++++
>  configs/mt7986a_emmc_rfb_defconfig |  64 +++++++++
>  configs/mt7986a_sd_rfb_defconfig   |  64 +++++++++
>  configs/mt7986b_emmc_rfb_defconfig |  64 +++++++++
>  configs/mt7986b_sd_rfb_defconfig   |  64 +++++++++
>  include/configs/mt7986.h           |  26 ++++
>  14 files changed, 1147 insertions(+)
>  create mode 100644 arch/arm/dts/mt7986a-rfb.dts
>  create mode 100644 arch/arm/dts/mt7986a-sd-rfb.dts
>  create mode 100644 arch/arm/dts/mt7986b-rfb.dts
>  create mode 100644 arch/arm/dts/mt7986b-sd-rfb.dts
>  create mode 100644 board/mediatek/mt7986/MAINTAINERS
>  create mode 100644 board/mediatek/mt7986/Makefile
>  create mode 100644 board/mediatek/mt7986/mt7986_rfb.c
>  create mode 100644 configs/mt7986_rfb_defconfig
>  create mode 100644 configs/mt7986a_emmc_rfb_defconfig
>  create mode 100644 configs/mt7986a_sd_rfb_defconfig
>  create mode 100644 configs/mt7986b_emmc_rfb_defconfig
>  create mode 100644 configs/mt7986b_sd_rfb_defconfig
>  create mode 100644 include/configs/mt7986.h
>

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 02/31] arm: mediatek: add support for MediaTek MT7981 SoC
  2022-08-04  3:34 ` [PATCH 02/31] arm: mediatek: add support for MediaTek MT7981 SoC Weijie Gao
@ 2022-08-04 13:57   ` Simon Glass
  2022-08-08  2:17     ` Weijie Gao
  0 siblings, 1 reply; 100+ messages in thread
From: Simon Glass @ 2022-08-04 13:57 UTC (permalink / raw)
  To: Weijie Gao; +Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream

Hi Weijie,

On Wed, 3 Aug 2022 at 21:35, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> This patch adds basic support for MediaTek MT7981 SoC.
> This include the file that will initialize the SoC after boot and its
> device tree.
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  arch/arm/dts/mt7981.dtsi                      | 288 ++++++++++++++++++
>  arch/arm/mach-mediatek/Kconfig                |  12 +-
>  arch/arm/mach-mediatek/Makefile               |   1 +
>  arch/arm/mach-mediatek/mt7981/Makefile        |   4 +
>  arch/arm/mach-mediatek/mt7981/init.c          |  52 ++++
>  arch/arm/mach-mediatek/mt7981/lowlevel_init.S |  30 ++
>  6 files changed, 386 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm/dts/mt7981.dtsi
>  create mode 100644 arch/arm/mach-mediatek/mt7981/Makefile
>  create mode 100644 arch/arm/mach-mediatek/mt7981/init.c
>  create mode 100644 arch/arm/mach-mediatek/mt7981/lowlevel_init.S
>


[..]

> diff --git a/arch/arm/mach-mediatek/mt7981/init.c
>  b/arch/arm/mach-mediatek/mt7981/init.c
> new file mode 100644
> index 0000000000..f503bb804b
> --- /dev/null
> +++ b/arch/arm/mach-mediatek/mt7981/init.c
> @@ -0,0 +1,52 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2022 MediaTek Inc.
> + * Author: Sam Shih <sam.shih@mediatek.com>
> + */
> +
> +#include <fdtdec.h>

Do you need that?

> +#include <asm/armv8/mmu.h>
> +#include <init.h>

Move up one

> +#include <asm/system.h>
> +#include <asm/global_data.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +int print_cpuinfo(void)

Can you use the CPU uclass and DISPLAY_CPUINFO instead/

> +{
> +       printf("CPU:   MediaTek MT7981\n");
> +       return 0;
> +}
> +

[..]

> diff --git a/arch/arm/mach-mediatek/mt7981/lowlevel_init.S
>  b/arch/arm/mach-mediatek/mt7981/lowlevel_init.S
> new file mode 100644
> index 0000000000..244d2c1385
> --- /dev/null
> +++ b/arch/arm/mach-mediatek/mt7981/lowlevel_init.S
> @@ -0,0 +1,30 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2022 MediaTek Inc.
> + * Author: Sam Shih <sam.shih@mediatek.com>
> + */
> +
> +/*
> + * Switch from AArch64 EL2 to AArch32 EL2
> + * @param inputs:
> + * x0: argument, zero
> + * x1: machine nr
> + * x2: fdt address
> + * x3: input argument
> + * x4: kernel entry point
> + * @param outputs for secure firmware:
> + * x0: function id
> + * x1: kernel entry point
> + * x2: machine nr
> + * x3: fdt address
> +*/
> +
> +.global armv8_el2_to_aarch32
> +armv8_el2_to_aarch32:
> +       mov     x3, x2
> +       mov     x2, x1
> +       mov     x1, x4
> +       mov     x4, #0
> +       ldr x0, =0x82000200

Please comment or add a symbol for this

> +       SMC #0
> +       ret
> --
> 2.17.1
>

Regards,
Simon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 12/31] pwm: mtk: add support for MediaTek MT7986 SoC
  2022-08-04  3:35 ` [PATCH 12/31] pwm: mtk: add support for MediaTek MT7986 SoC Weijie Gao
@ 2022-08-04 13:57   ` Simon Glass
  0 siblings, 0 replies; 100+ messages in thread
From: Simon Glass @ 2022-08-04 13:57 UTC (permalink / raw)
  To: Weijie Gao; +Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream

On Wed, 3 Aug 2022 at 21:37, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> This patch adds PWM support for MediaTek MT7986 SoC.
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  drivers/pwm/pwm-mtk.c | 6 ++++++
>  1 file changed, 6 insertions(+)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 13/31] pwm: mtk: add support for MediaTek MT7981 SoC
  2022-08-04  3:35 ` [PATCH 13/31] pwm: mtk: add support for MediaTek MT7981 SoC Weijie Gao
@ 2022-08-04 13:57   ` Simon Glass
  0 siblings, 0 replies; 100+ messages in thread
From: Simon Glass @ 2022-08-04 13:57 UTC (permalink / raw)
  To: Weijie Gao; +Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream

On Wed, 3 Aug 2022 at 21:37, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> This patch adds PWM support for MediaTek MT7981 SoC.
> MT7981 uses a different register offset so we have to add a version field
> to indicate the IP core version.
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  drivers/pwm/pwm-mtk.c | 34 ++++++++++++++++++++++++++++++++--
>  1 file changed, 32 insertions(+), 2 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 14/31] timer: mtk: add support for MediaTek MT7981/MT7986 SoCs
  2022-08-04  3:35 ` [PATCH 14/31] timer: mtk: add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
@ 2022-08-04 13:57   ` Simon Glass
  0 siblings, 0 replies; 100+ messages in thread
From: Simon Glass @ 2022-08-04 13:57 UTC (permalink / raw)
  To: Weijie Gao; +Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream

On Wed, 3 Aug 2022 at 21:37, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> This patch add general-purpose timer support for MediaTek MT7981/MT7986.
> These two SoCs uses a newer version of timer with its register definition
> slightly changed.
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  drivers/timer/mtk_timer.c | 59 ++++++++++++++++++++++++---------------
>  1 file changed, 37 insertions(+), 22 deletions(-)
>

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 15/31] watchdog: mediatek: add support for MediaTek MT7986 SoC
  2022-08-04  3:35 ` [PATCH 15/31] watchdog: mediatek: add support for MediaTek MT7986 SoC Weijie Gao
@ 2022-08-04 13:57   ` Simon Glass
  0 siblings, 0 replies; 100+ messages in thread
From: Simon Glass @ 2022-08-04 13:57 UTC (permalink / raw)
  To: Weijie Gao; +Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream, Stefan Roese

On Wed, 3 Aug 2022 at 21:37, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> This patch adds watchdog support for MediaTek MT7986 SoC
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  drivers/watchdog/mtk_wdt.c | 1 +
>  1 file changed, 1 insertion(+)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 18/31] arm: dts: mt7622: add i2c support
  2022-08-04  3:36 ` [PATCH 18/31] arm: dts: mt7622: add i2c support Weijie Gao
@ 2022-08-04 13:57   ` Simon Glass
  0 siblings, 0 replies; 100+ messages in thread
From: Simon Glass @ 2022-08-04 13:57 UTC (permalink / raw)
  To: Weijie Gao; +Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream

On Wed, 3 Aug 2022 at 21:38, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> Add both hardware and software i2c support for mt7622.
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  arch/arm/dts/mt7622-rfb.dts | 18 ++++++++++++++++++
>  arch/arm/dts/mt7622.dtsi    | 24 ++++++++++++++++++++++++
>  2 files changed, 42 insertions(+)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 16/31] spi: add support for MediaTek spi-mem controller
  2022-08-04  3:36 ` [PATCH 16/31] spi: add support for MediaTek spi-mem controller Weijie Gao
@ 2022-08-04 13:57   ` Simon Glass
  0 siblings, 0 replies; 100+ messages in thread
From: Simon Glass @ 2022-08-04 13:57 UTC (permalink / raw)
  To: Weijie Gao
  Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream, Jagan Teki, SkyLake . Huang

Hi Weijie,

On Wed, 3 Aug 2022 at 21:38, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> This patch adds support for spi-mem controller found on newer MediaTek SoCs
> This controller supports Single/Dual/Quad SPI mode.
>
> Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
> ---
>  drivers/spi/Kconfig    |   8 +
>  drivers/spi/Makefile   |   1 +
>  drivers/spi/mtk_spim.c | 705 +++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 714 insertions(+)
>  create mode 100644 drivers/spi/mtk_spim.c

Reviewed-by: Simon Glass <sjg@chromium.org>



[..]

> diff --git a/drivers/spi/mtk_spim.c b/drivers/spi/mtk_spim.c
> new file mode 100644
> index 0000000000..b0f63c3c3f
> --- /dev/null
> +++ b/drivers/spi/mtk_spim.c
> @@ -0,0 +1,705 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2022 MediaTek Inc. All Rights Reserved.
> + *
> + * Author: SkyLake.Huang <skylake.huang@mediatek.com>
> + */
> +
> +#include <clk.h>
> +#include <cpu_func.h>
> +#include <div64.h>
> +#include <dm.h>
> +#include <dm/device.h>
> +#include <dm/device_compat.h>
> +#include <dm/devres.h>
> +#include <dm/pinctrl.h>
> +#include <linux/bitops.h>
> +#include <linux/completion.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/io.h>
> +#include <linux/iopoll.h>
> +#include <spi.h>
> +#include <spi-mem.h>
> +#include <stdbool.h>
> +#include <watchdog.h>

Please check header order:

https://u-boot.readthedocs.io/en/latest/develop/codingstyle.html#include-files

> +
> +#define SPI_CFG0_REG                           0x0000
> +#define SPI_CFG1_REG                           0x0004
> +#define SPI_TX_SRC_REG                         0x0008
> +#define SPI_RX_DST_REG                         0x000c
> +#define SPI_TX_DATA_REG                                0x0010
> +#define SPI_RX_DATA_REG                                0x0014
> +#define SPI_CMD_REG                            0x0018
> +#define SPI_IRQ_REG                            0x001c
> +#define SPI_STATUS_REG                         0x0020
> +#define SPI_PAD_SEL_REG                                0x0024
> +#define SPI_CFG2_REG                           0x0028
> +#define SPI_TX_SRC_REG_64                      0x002c
> +#define SPI_RX_DST_REG_64                      0x0030
> +#define SPI_CFG3_IPM_REG                       0x0040
> +
> +#define SPI_CFG0_SCK_HIGH_OFFSET               0
> +#define SPI_CFG0_SCK_LOW_OFFSET                        8
> +#define SPI_CFG0_CS_HOLD_OFFSET                        16
> +#define SPI_CFG0_CS_SETUP_OFFSET               24
> +#define SPI_ADJUST_CFG0_CS_HOLD_OFFSET         0
> +#define SPI_ADJUST_CFG0_CS_SETUP_OFFSET                16
> +
> +#define SPI_CFG1_CS_IDLE_OFFSET                        0
> +#define SPI_CFG1_PACKET_LOOP_OFFSET            8
> +#define SPI_CFG1_PACKET_LENGTH_OFFSET          16
> +#define SPI_CFG1_GET_TICKDLY_OFFSET            29
> +
> +#define SPI_CFG1_GET_TICKDLY_MASK              GENMASK(31, 29)
> +#define SPI_CFG1_CS_IDLE_MASK                  0xff
> +#define SPI_CFG1_PACKET_LOOP_MASK              0xff00
> +#define SPI_CFG1_PACKET_LENGTH_MASK            0x3ff0000
> +#define SPI_CFG1_IPM_PACKET_LENGTH_MASK                GENMASK(31, 16)
> +#define SPI_CFG2_SCK_HIGH_OFFSET               0
> +#define SPI_CFG2_SCK_LOW_OFFSET                        16
> +#define SPI_CFG2_SCK_HIGH_MASK                 GENMASK(15, 0)
> +#define SPI_CFG2_SCK_LOW_MASK                  GENMASK(31, 16)
> +
> +#define SPI_CMD_ACT                            BIT(0)
> +#define SPI_CMD_RESUME                         BIT(1)
> +#define SPI_CMD_RST                            BIT(2)
> +#define SPI_CMD_PAUSE_EN                       BIT(4)
> +#define SPI_CMD_DEASSERT                       BIT(5)
> +#define SPI_CMD_SAMPLE_SEL                     BIT(6)
> +#define SPI_CMD_CS_POL                         BIT(7)
> +#define SPI_CMD_CPHA                           BIT(8)
> +#define SPI_CMD_CPOL                           BIT(9)
> +#define SPI_CMD_RX_DMA                         BIT(10)
> +#define SPI_CMD_TX_DMA                         BIT(11)
> +#define SPI_CMD_TXMSBF                         BIT(12)
> +#define SPI_CMD_RXMSBF                         BIT(13)
> +#define SPI_CMD_RX_ENDIAN                      BIT(14)
> +#define SPI_CMD_TX_ENDIAN                      BIT(15)
> +#define SPI_CMD_FINISH_IE                      BIT(16)
> +#define SPI_CMD_PAUSE_IE                       BIT(17)
> +#define SPI_CMD_IPM_NONIDLE_MODE               BIT(19)
> +#define SPI_CMD_IPM_SPIM_LOOP                  BIT(21)
> +#define SPI_CMD_IPM_GET_TICKDLY_OFFSET         22
> +
> +#define SPI_CMD_IPM_GET_TICKDLY_MASK           GENMASK(24, 22)
> +
> +#define PIN_MODE_CFG(x)                                ((x) / 2)
> +
> +#define SPI_CFG3_IPM_PIN_MODE_OFFSET           0
> +#define SPI_CFG3_IPM_HALF_DUPLEX_DIR           BIT(2)
> +#define SPI_CFG3_IPM_HALF_DUPLEX_EN            BIT(3)
> +#define SPI_CFG3_IPM_XMODE_EN                  BIT(4)
> +#define SPI_CFG3_IPM_NODATA_FLAG               BIT(5)
> +#define SPI_CFG3_IPM_CMD_BYTELEN_OFFSET                8
> +#define SPI_CFG3_IPM_ADDR_BYTELEN_OFFSET       12
> +#define SPI_CFG3_IPM_DUMMY_BYTELEN_OFFSET      16
> +
> +#define SPI_CFG3_IPM_CMD_PIN_MODE_MASK         GENMASK(1, 0)
> +#define SPI_CFG3_IPM_CMD_BYTELEN_MASK          GENMASK(11, 8)
> +#define SPI_CFG3_IPM_ADDR_BYTELEN_MASK         GENMASK(15, 12)
> +#define SPI_CFG3_IPM_DUMMY_BYTELEN_MASK                GENMASK(19, 16)
> +
> +#define MT8173_SPI_MAX_PAD_SEL                 3
> +
> +#define MTK_SPI_PAUSE_INT_STATUS               0x2
> +
> +#define MTK_SPI_IDLE                           0
> +#define MTK_SPI_PAUSED                         1
> +
> +#define MTK_SPI_MAX_FIFO_SIZE                  32U
> +#define MTK_SPI_PACKET_SIZE                    1024
> +#define MTK_SPI_IPM_PACKET_SIZE                        SZ_64K
> +#define MTK_SPI_IPM_PACKET_LOOP                        SZ_256
> +
> +#define MTK_SPI_32BITS_MASK                    0xffffffff
> +
> +#define DMA_ADDR_EXT_BITS                      36
> +#define DMA_ADDR_DEF_BITS                      32
> +
> +#define CLK_TO_US(freq, clkcnt) DIV_ROUND_UP((clkcnt), (freq) / 1000000)
> +
> +struct mtk_spim_capability {
> +       bool need_pad_sel;
> +       /* Must explicitly send dummy Tx bytes to do Rx only transfer */
> +       bool must_tx;
> +       /* some IC design adjust cfg register to enhance time accuracy */
> +       bool enhance_timing;
> +       /* some IC support DMA addr extension */
> +       bool dma_ext;
> +       /* the IPM IP design improve some feature, and support dual/quad mode */
> +       bool ipm_design;
> +       bool support_quad;

comment?

> +};
> +
> +struct mtk_spim_priv {

Needs comments

> +       void __iomem *base;
> +       u32 state;
> +       int pad_num;
> +       u32 *pad_sel;
> +       struct clk sel_clk, spi_clk;
> +       struct spi_transfer *cur_transfer;
> +       u32 xfer_len;
> +       u32 num_xfered;
> +       struct scatterlist *tx_sgl, *rx_sgl;
> +       u32 tx_sgl_len, rx_sgl_len;
> +       struct mtk_spim_capability hw_cap;
> +       u32 tick_dly;
> +       u32 sample_sel;
> +
> +       struct completion spimem_done;
> +       bool use_spimem;
> +       struct device *dev;
> +       dma_addr_t tx_dma;
> +       dma_addr_t rx_dma;
> +};
> +
> +static void mtk_spim_reset(struct mtk_spim_priv *priv)
> +{
> +       u32 reg_val;
> +
> +       /* set the software reset bit in SPI_CMD_REG. */
> +       reg_val = readl(priv->base + SPI_CMD_REG);
> +       reg_val |= SPI_CMD_RST;
> +       writel(reg_val, priv->base + SPI_CMD_REG);

set_le32()

> +
> +       reg_val = readl(priv->base + SPI_CMD_REG);
> +       reg_val &= ~SPI_CMD_RST;

clear_le32()

> +       writel(reg_val, priv->base + SPI_CMD_REG);
> +}
> +
> +static int mtk_spim_hw_init(struct spi_slave *slave)
> +{
> +       struct udevice *bus = dev_get_parent(slave->dev);
> +       struct mtk_spim_priv *priv = dev_get_priv(bus);
> +       u16 cpha, cpol;
> +       u32 reg_val;
> +
> +       cpha = slave->mode & SPI_CPHA ? 1 : 0;
> +       cpol = slave->mode & SPI_CPOL ? 1 : 0;
> +
> +       if (priv->hw_cap.enhance_timing) {
> +               if (priv->hw_cap.ipm_design) {
> +                       /* CFG3 reg only used for spi-mem,
> +                        * here write to default value
> +                        */
> +                       writel(0x0, priv->base + SPI_CFG3_IPM_REG);
> +
> +                       reg_val = readl(priv->base + SPI_CMD_REG);
> +                       reg_val &= ~SPI_CMD_IPM_GET_TICKDLY_MASK;
> +                       reg_val |= priv->tick_dly
> +                                  << SPI_CMD_IPM_GET_TICKDLY_OFFSET;
> +                       writel(reg_val, priv->base + SPI_CMD_REG);
> +               } else {
> +                       reg_val = readl(priv->base + SPI_CFG1_REG);
> +                       reg_val &= ~SPI_CFG1_GET_TICKDLY_MASK;
> +                       reg_val |= priv->tick_dly
> +                                  << SPI_CFG1_GET_TICKDLY_OFFSET;
> +                       writel(reg_val, priv->base + SPI_CFG1_REG);
> +               }
> +       }
> +
> +       reg_val = readl(priv->base + SPI_CMD_REG);
> +       if (priv->hw_cap.ipm_design) {
> +               /* SPI transfer without idle time until packet length done */
> +               reg_val |= SPI_CMD_IPM_NONIDLE_MODE;
> +               if (slave->mode & SPI_LOOP)
> +                       reg_val |= SPI_CMD_IPM_SPIM_LOOP;
> +               else
> +                       reg_val &= ~SPI_CMD_IPM_SPIM_LOOP;
> +       }
> +
> +       if (cpha)
> +               reg_val |= SPI_CMD_CPHA;
> +       else
> +               reg_val &= ~SPI_CMD_CPHA;
> +       if (cpol)
> +               reg_val |= SPI_CMD_CPOL;
> +       else
> +               reg_val &= ~SPI_CMD_CPOL;
> +
> +       /* set the mlsbx and mlsbtx */
> +       if (slave->mode & SPI_LSB_FIRST) {
> +               reg_val &= ~SPI_CMD_TXMSBF;
> +               reg_val &= ~SPI_CMD_RXMSBF;
> +       } else {
> +               reg_val |= SPI_CMD_TXMSBF;
> +               reg_val |= SPI_CMD_RXMSBF;
> +       }
> +
> +       /* set the tx/rx endian */
> +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__

Can this be done with the compatible string?

> +       reg_val &= ~SPI_CMD_TX_ENDIAN;
> +       reg_val &= ~SPI_CMD_RX_ENDIAN;
> +#else
> +       reg_val |= SPI_CMD_TX_ENDIAN;
> +       reg_val |= SPI_CMD_RX_ENDIAN;
> +#endif
> +
> +       if (priv->hw_cap.enhance_timing) {
> +               /* set CS polarity */
> +               if (slave->mode & SPI_CS_HIGH)
> +                       reg_val |= SPI_CMD_CS_POL;
> +               else
> +                       reg_val &= ~SPI_CMD_CS_POL;
> +
> +               if (priv->sample_sel)
> +                       reg_val |= SPI_CMD_SAMPLE_SEL;
> +               else
> +                       reg_val &= ~SPI_CMD_SAMPLE_SEL;
> +       }
> +
> +       /* disable dma mode */
> +       reg_val &= ~(SPI_CMD_TX_DMA | SPI_CMD_RX_DMA);
> +
> +       /* disable deassert mode */
> +       reg_val &= ~SPI_CMD_DEASSERT;
> +
> +       writel(reg_val, priv->base + SPI_CMD_REG);
> +
> +#if !CONFIG_IS_ENABLED(DM_SPI)

Should use DM_SPI always

> +       /* pad select, we don't need this in IPM design. */
> +       if (priv->hw_cap.need_pad_sel)
> +               writel(priv->pad_sel[slave->cs],
> +                      priv->base + SPI_PAD_SEL_REG);
> +#endif
> +
> +       return 0;
> +}
> +
> +static void mtk_spim_prepare_transfer(struct mtk_spim_priv *priv,
> +                                     u32 speed_hz)
> +{
> +       u32 spi_clk_hz, div, sck_time, cs_time, reg_val;
> +
> +       spi_clk_hz = clk_get_rate(&priv->spi_clk);
> +       if (speed_hz <= spi_clk_hz / 4)
> +               div = DIV_ROUND_UP(spi_clk_hz, speed_hz);
> +       else
> +               div = 4;
> +
> +       sck_time = (div + 1) / 2;
> +       cs_time = sck_time * 2;
> +
> +       if (priv->hw_cap.enhance_timing) {
> +               reg_val = (((sck_time - 1) & 0xffff)
> +                          << SPI_CFG2_SCK_HIGH_OFFSET);

Drop outer brackets, and below also

> +               reg_val |= (((sck_time - 1) & 0xffff)
> +                          << SPI_CFG2_SCK_LOW_OFFSET);
> +               writel(reg_val, priv->base + SPI_CFG2_REG);
> +               reg_val = (((cs_time - 1) & 0xffff)
> +                          << SPI_ADJUST_CFG0_CS_HOLD_OFFSET);
> +               reg_val |= (((cs_time - 1) & 0xffff)
> +                          << SPI_ADJUST_CFG0_CS_SETUP_OFFSET);
> +               writel(reg_val, priv->base + SPI_CFG0_REG);
> +       } else {
> +               reg_val = (((sck_time - 1) & 0xff)
> +                          << SPI_CFG0_SCK_HIGH_OFFSET);
> +               reg_val |= (((sck_time - 1) & 0xff) << SPI_CFG0_SCK_LOW_OFFSET);
> +               reg_val |= (((cs_time - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET);
> +               reg_val |= (((cs_time - 1) & 0xff) << SPI_CFG0_CS_SETUP_OFFSET);
> +               writel(reg_val, priv->base + SPI_CFG0_REG);
> +       }
> +
> +       reg_val = readl(priv->base + SPI_CFG1_REG);
> +       reg_val &= ~SPI_CFG1_CS_IDLE_MASK;
> +       reg_val |= (((cs_time - 1) & 0xff) << SPI_CFG1_CS_IDLE_OFFSET);
> +       writel(reg_val, priv->base + SPI_CFG1_REG);
> +}
> +
> +static void mtk_spim_setup_packet(struct mtk_spim_priv *priv)

comment? What doe sthis function do?

> +{
> +       u32 packet_size, packet_loop, reg_val;
> +
> +       if (priv->hw_cap.ipm_design)
> +               packet_size = min_t(u32,
> +                                   priv->xfer_len,
> +                                   MTK_SPI_IPM_PACKET_SIZE);
> +       else
> +               packet_size = min_t(u32,
> +                                   priv->xfer_len,
> +                                   MTK_SPI_PACKET_SIZE);
> +
> +       packet_loop = priv->xfer_len / packet_size;
> +
> +       reg_val = readl(priv->base + SPI_CFG1_REG);
> +       if (priv->hw_cap.ipm_design)
> +               reg_val &= ~SPI_CFG1_IPM_PACKET_LENGTH_MASK;
> +       else
> +               reg_val &= ~SPI_CFG1_PACKET_LENGTH_MASK;
> +
> +       reg_val |= (packet_size - 1) << SPI_CFG1_PACKET_LENGTH_OFFSET;
> +
> +       reg_val &= ~SPI_CFG1_PACKET_LOOP_MASK;
> +
> +       reg_val |= (packet_loop - 1) << SPI_CFG1_PACKET_LOOP_OFFSET;
> +
> +       writel(reg_val, priv->base + SPI_CFG1_REG);
> +}
> +
> +static void mtk_spim_enable_transfer(struct mtk_spim_priv *priv)
> +{
> +       u32 cmd;
> +
> +       cmd = readl(priv->base + SPI_CMD_REG);
> +       if (priv->state == MTK_SPI_IDLE)
> +               cmd |= SPI_CMD_ACT;
> +       else
> +               cmd |= SPI_CMD_RESUME;
> +       writel(cmd, priv->base + SPI_CMD_REG);
> +}
> +
> +static bool mtk_spim_supports_op(struct spi_slave *slave,
> +                                const struct spi_mem_op *op)
> +{
> +       if (op->cmd.buswidth == 0 || op->cmd.buswidth > 4 ||
> +           op->addr.buswidth > 4 || op->dummy.buswidth > 4 ||
> +           op->data.buswidth > 4)
> +               return false;
> +
> +       if (op->addr.nbytes && op->dummy.nbytes &&
> +           op->addr.buswidth != op->dummy.buswidth)
> +               return false;
> +
> +       if (op->addr.nbytes + op->dummy.nbytes > 16)
> +               return false;
> +
> +       if (op->data.nbytes > MTK_SPI_IPM_PACKET_SIZE) {
> +               if (op->data.nbytes / MTK_SPI_IPM_PACKET_SIZE >
> +                   MTK_SPI_IPM_PACKET_LOOP ||
> +                   op->data.nbytes % MTK_SPI_IPM_PACKET_SIZE != 0)
> +                       return false;
> +       }
> +
> +       return true;
> +}
> +
> +static void mtk_spim_setup_dma_xfer(struct mtk_spim_priv *priv,
> +                                   const struct spi_mem_op *op)
> +{
> +       writel((u32)(priv->tx_dma & MTK_SPI_32BITS_MASK),
> +              priv->base + SPI_TX_SRC_REG);
> +
> +#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT

I'm not sure if there is a way to avoid an #ifdef here?

> +       if (priv->dev_comp->dma_ext)
> +               writel((u32)(priv->tx_dma >> 32),
> +                      priv->base + SPI_TX_SRC_REG_64);
> +#endif
> +
> +       if (op->data.dir == SPI_MEM_DATA_IN) {
> +               writel((u32)(priv->rx_dma & MTK_SPI_32BITS_MASK),
> +                      priv->base + SPI_RX_DST_REG);
> +#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
> +               if (priv->dev_comp->dma_ext)
> +                       writel((u32)(priv->rx_dma >> 32),
> +                              priv->base + SPI_RX_DST_REG_64);
> +#endif
> +       }
> +}
> +
> +static int mtk_spim_transfer_wait(struct spi_slave *slave,
> +                                 const struct spi_mem_op *op)
> +{
> +       struct udevice *bus = dev_get_parent(slave->dev);
> +       struct mtk_spim_priv *priv = dev_get_priv(bus);
> +       u32 sck_l, sck_h, spi_bus_clk, clk_count, reg;
> +       ulong us = 1;
> +       int ret = 0;
> +
> +       if (op->data.dir == SPI_MEM_NO_DATA)
> +               clk_count = 32;
> +       else
> +               clk_count = op->data.nbytes;
> +
> +       spi_bus_clk = clk_get_rate(&priv->spi_clk);
> +       sck_l = readl(priv->base + SPI_CFG2_REG) >> SPI_CFG2_SCK_LOW_OFFSET;
> +       sck_h = readl(priv->base + SPI_CFG2_REG) & SPI_CFG2_SCK_HIGH_MASK;
> +       do_div(spi_bus_clk, sck_l + sck_h + 2);
> +
> +       us = CLK_TO_US(spi_bus_clk, clk_count * 8);
> +       us += 1000 * 1000; /* 1s tolerance */
> +
> +       if (us > UINT_MAX)
> +               us = UINT_MAX;
> +
> +       ret = readl_poll_timeout(priv->base + SPI_STATUS_REG, reg,
> +                                reg & 0x1, us);
> +       if (ret < 0) {
> +               dev_err(priv->dev, "transfer timeout, val: 0x%lx\n", us);
> +               return -ETIMEDOUT;
> +       }
> +
> +       return 0;
> +}
> +
> +static int mtk_spim_exec_op(struct spi_slave *slave,
> +                           const struct spi_mem_op *op)
> +{
> +       struct udevice *bus = dev_get_parent(slave->dev);
> +       struct mtk_spim_priv *priv = dev_get_priv(bus);
> +       u32 reg_val, nio = 1, tx_size;
> +       char *tx_tmp_buf;
> +       char *rx_tmp_buf;
> +       int i, ret = 0;
> +
> +       priv->use_spimem = true;
> +
> +       mtk_spim_reset(priv);
> +       mtk_spim_hw_init(slave);
> +       mtk_spim_prepare_transfer(priv, slave->max_hz);
> +
> +       reg_val = readl(priv->base + SPI_CFG3_IPM_REG);
> +       /* opcode byte len */
> +       reg_val &= ~SPI_CFG3_IPM_CMD_BYTELEN_MASK;
> +       reg_val |= 1 << SPI_CFG3_IPM_CMD_BYTELEN_OFFSET;
> +
> +       /* addr & dummy byte len */
> +       if (op->addr.nbytes || op->dummy.nbytes)
> +               reg_val |= (op->addr.nbytes + op->dummy.nbytes) <<
> +                           SPI_CFG3_IPM_ADDR_BYTELEN_OFFSET;
> +
> +       /* data byte len */
> +       if (!op->data.nbytes) {
> +               reg_val |= SPI_CFG3_IPM_NODATA_FLAG;
> +               writel(0, priv->base + SPI_CFG1_REG);
> +       } else {
> +               reg_val &= ~SPI_CFG3_IPM_NODATA_FLAG;
> +               priv->xfer_len = op->data.nbytes;
> +               mtk_spim_setup_packet(priv);
> +       }
> +
> +       if (op->addr.nbytes || op->dummy.nbytes) {
> +               if (op->addr.buswidth == 1 || op->dummy.buswidth == 1)
> +                       reg_val |= SPI_CFG3_IPM_XMODE_EN;
> +               else
> +                       reg_val &= ~SPI_CFG3_IPM_XMODE_EN;
> +       }
> +
> +       if (op->addr.buswidth == 2 ||
> +           op->dummy.buswidth == 2 ||
> +           op->data.buswidth == 2)
> +               nio = 2;
> +       else if (op->addr.buswidth == 4 ||
> +                op->dummy.buswidth == 4 ||
> +                op->data.buswidth == 4)
> +               nio = 4;
> +
> +       reg_val &= ~SPI_CFG3_IPM_CMD_PIN_MODE_MASK;
> +       reg_val |= PIN_MODE_CFG(nio) << SPI_CFG3_IPM_PIN_MODE_OFFSET;
> +
> +       reg_val |= SPI_CFG3_IPM_HALF_DUPLEX_EN;
> +       if (op->data.dir == SPI_MEM_DATA_IN)
> +               reg_val |= SPI_CFG3_IPM_HALF_DUPLEX_DIR;
> +       else
> +               reg_val &= ~SPI_CFG3_IPM_HALF_DUPLEX_DIR;
> +       writel(reg_val, priv->base + SPI_CFG3_IPM_REG);
> +
> +       tx_size = 1 + op->addr.nbytes + op->dummy.nbytes;
> +       if (op->data.dir == SPI_MEM_DATA_OUT)
> +               tx_size += op->data.nbytes;
> +
> +       tx_size = max(tx_size, (u32)32);
> +
> +       /* Fill up tx data*/
> +       tx_tmp_buf = kzalloc(tx_size, GFP_KERNEL);
> +       if (!tx_tmp_buf) {
> +               ret = -ENOMEM;
> +               goto exit;
> +       }
> +
> +       tx_tmp_buf[0] = op->cmd.opcode;
> +
> +       if (op->addr.nbytes) {
> +               for (i = 0; i < op->addr.nbytes; i++)
> +                       tx_tmp_buf[i + 1] = op->addr.val >>
> +                                       (8 * (op->addr.nbytes - i - 1));
> +       }
> +
> +       if (op->dummy.nbytes)
> +               memset(tx_tmp_buf + op->addr.nbytes + 1, 0xff,
> +                      op->dummy.nbytes);
> +
> +       if (op->data.nbytes && op->data.dir == SPI_MEM_DATA_OUT)
> +               memcpy(tx_tmp_buf + op->dummy.nbytes + op->addr.nbytes + 1,
> +                      op->data.buf.out, op->data.nbytes);
> +       /* Finish filling up tx data*/

space before */

> +
> +       priv->tx_dma = dma_map_single(tx_tmp_buf, tx_size, DMA_TO_DEVICE);
> +       if (dma_mapping_error(priv->dev, priv->tx_dma)) {
> +               ret = -ENOMEM;
> +               goto tx_free;
> +       }
> +
> +       if (op->data.dir == SPI_MEM_DATA_IN) {
> +               if (!IS_ALIGNED((size_t)op->data.buf.in, 4)) {
> +                       rx_tmp_buf = kzalloc(op->data.nbytes, GFP_KERNEL);
> +                       if (!rx_tmp_buf) {
> +                               ret = -ENOMEM;
> +                               goto tx_unmap;
> +                       }
> +               } else {
> +                       rx_tmp_buf = op->data.buf.in;
> +               }
> +
> +               priv->rx_dma = dma_map_single(rx_tmp_buf, op->data.nbytes,
> +                                             DMA_FROM_DEVICE);
> +               if (dma_mapping_error(priv->dev, priv->rx_dma)) {
> +                       ret = -ENOMEM;
> +                       goto rx_free;
> +               }
> +       }
> +
> +       reg_val = readl(priv->base + SPI_CMD_REG);
> +       reg_val |= SPI_CMD_TX_DMA;
> +       if (op->data.dir == SPI_MEM_DATA_IN)
> +               reg_val |= SPI_CMD_RX_DMA;
> +
> +       writel(reg_val, priv->base + SPI_CMD_REG);
> +
> +       mtk_spim_setup_dma_xfer(priv, op);
> +
> +       mtk_spim_enable_transfer(priv);
> +
> +       /* Wait for the interrupt. */
> +       ret = mtk_spim_transfer_wait(slave, op);
> +       if (ret)
> +               goto rx_unmap;
> +
> +       if (op->data.dir == SPI_MEM_DATA_IN &&
> +           !IS_ALIGNED((size_t)op->data.buf.in, 4))
> +               memcpy(op->data.buf.in, rx_tmp_buf, op->data.nbytes);
> +
> +rx_unmap:
> +       /* spi disable dma */
> +       reg_val = readl(priv->base + SPI_CMD_REG);
> +       reg_val &= ~SPI_CMD_TX_DMA;
> +       if (op->data.dir == SPI_MEM_DATA_IN)
> +               reg_val &= ~SPI_CMD_RX_DMA;
> +       writel(reg_val, priv->base + SPI_CMD_REG);
> +
> +       writel(0, priv->base + SPI_TX_SRC_REG);
> +       writel(0, priv->base + SPI_RX_DST_REG);
> +
> +       if (op->data.dir == SPI_MEM_DATA_IN)
> +               dma_unmap_single(priv->rx_dma,
> +                                op->data.nbytes, DMA_FROM_DEVICE);
> +rx_free:
> +       if (op->data.dir == SPI_MEM_DATA_IN &&
> +           !IS_ALIGNED((size_t)op->data.buf.in, 4))
> +               kfree(rx_tmp_buf);
> +tx_unmap:
> +       dma_unmap_single(priv->tx_dma,
> +                        tx_size, DMA_TO_DEVICE);
> +tx_free:
> +       kfree(tx_tmp_buf);
> +exit:
> +       priv->use_spimem = false;
> +
> +       return ret;
> +}
> +
> +static int mtk_spim_adjust_op_size(struct spi_slave *slave,
> +                                  struct spi_mem_op *op)
> +{
> +       int opcode_len;
> +
> +       if (!op->data.nbytes)
> +               return 0;
> +
> +       if (op->data.dir != SPI_MEM_NO_DATA) {
> +               opcode_len = 1 + op->addr.nbytes + op->dummy.nbytes;
> +               if (opcode_len + op->data.nbytes > MTK_SPI_IPM_PACKET_SIZE) {
> +                       op->data.nbytes = MTK_SPI_IPM_PACKET_SIZE - opcode_len;
> +                       /* force data buffer dma-aligned. */
> +                       op->data.nbytes -= op->data.nbytes % 4;
> +               }
> +       }
> +
> +       return 0;
> +}
> +
> +static int mtk_spim_get_attr(struct mtk_spim_priv *priv, struct udevice
>  *dev)

Can this use the of_to_plat() method?

> +{
> +       int ret;
> +
> +       priv->hw_cap.need_pad_sel = dev_read_bool(dev, "need_pad_sel");
> +       priv->hw_cap.must_tx = dev_read_bool(dev, "must_tx");
> +       priv->hw_cap.enhance_timing = dev_read_bool(dev, "enhance_timing");
> +       priv->hw_cap.dma_ext = dev_read_bool(dev, "dma_ext");
> +       priv->hw_cap.ipm_design = dev_read_bool(dev, "ipm_design");
> +       priv->hw_cap.support_quad = dev_read_bool(dev, "support_quad");
> +
> +       ret = dev_read_u32(dev, "tick_dly", &priv->tick_dly);
> +       if (ret < 0)
> +               dev_err(priv->dev, "tick dly not set.\n");
> +
> +       ret = dev_read_u32(dev, "sample_sel", &priv->sample_sel);
> +       if (ret < 0)
> +               dev_err(priv->dev, "sample sel not set.\n");
> +
> +       return ret;
> +}
> +
> +static int mtk_spim_probe(struct udevice *dev)
> +{
> +       struct mtk_spim_priv *priv = dev_get_priv(dev);
> +       int ret;
> +
> +       priv->base = (void __iomem *)devfdt_get_addr(dev);
> +       if (!priv->base)
> +               return -EINVAL;
> +
> +       mtk_spim_get_attr(priv, dev);
> +
> +       ret = clk_get_by_name(dev, "sel-clk", &priv->sel_clk);
> +       if (ret < 0) {
> +               dev_err(dev, "failed to get sel-clk\n");

For code size, do you want this string? Could be a debug message since
it shouldn't happen in production code.

> +               return ret;
> +       }
> +
> +       ret = clk_get_by_name(dev, "spi-clk", &priv->spi_clk);
> +       if (ret < 0) {
> +               dev_err(dev, "failed to get spi-clk\n");
> +               return ret;
> +       }
> +
> +       clk_enable(&priv->sel_clk);
> +       clk_enable(&priv->spi_clk);
> +
> +       return 0;
> +}
> +
[..]

Regards,
Simon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 17/31] i2c: add support for MediaTek I2C interface
  2022-08-04  3:36 ` [PATCH 17/31] i2c: add support for MediaTek I2C interface Weijie Gao
@ 2022-08-04 13:57   ` Simon Glass
  2022-08-08  3:00     ` Weijie Gao
  2022-08-10 11:12   ` Heiko Schocher
  2022-08-10 11:24   ` Michael Nazzareno Trimarchi
  2 siblings, 1 reply; 100+ messages in thread
From: Simon Glass @ 2022-08-04 13:57 UTC (permalink / raw)
  To: Weijie Gao; +Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream, Heiko Schocher

Hi Weijie,

On Wed, 3 Aug 2022 at 21:38, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> This patch adds support for MediaTek I2C interface
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  drivers/i2c/Kconfig   |   9 +
>  drivers/i2c/Makefile  |   1 +
>  drivers/i2c/mtk_i2c.c | 822 ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 832 insertions(+)
>  create mode 100644 drivers/i2c/mtk_i2c.c
>

Reviewed-by: Simon Glass <sjg@chromium.org>

[..]

> diff --git a/drivers/i2c/mtk_i2c.c b/drivers/i2c/mtk_i2c.c
> new file mode 100644
> index 0000000000..1d4a93f8c9
> --- /dev/null
> +++ b/drivers/i2c/mtk_i2c.c
> @@ -0,0 +1,822 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2022 MediaTek Inc. All Rights Reserved.
> + *
> + * Author: Mingming Lee <Mingming.Lee@mediatek.com>
> + *
> + * MediaTek I2C Interface driver
> + */
> +
> +#include <clk.h>
> +#include <cpu_func.h>
> +#include <dm.h>
> +#include <i2c.h>
> +#include <log.h>
> +#include <asm/cache.h>
> +#include <asm/io.h>
> +#include <linux/delay.h>
> +#include <linux/errno.h>
> +

[..]

> +
> +U_BOOT_DRIVER(mtk_i2c) = {
> +       .name           = "mtk_i2c",
> +       .id             = UCLASS_I2C,
> +       .of_match       = mtk_i2c_ids,
> +       .of_to_plat     = mtk_i2c_ofdata_to_platdata,

mtk_i2c_of_to_plat (for consistency)

> +       .probe          = mtk_i2c_probe,
> +       .priv_auto      = sizeof(struct mtk_i2c_priv),
> +       .ops            = &mtk_i2c_ops,
> +};
> --
> 2.17.1
>

Regards,
Simon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 19/31] dt-bindings: pinctrl: mediatek: add a header for common pinconf parameters
  2022-08-04  3:36 ` [PATCH 19/31] dt-bindings: pinctrl: mediatek: add a header for common pinconf parameters Weijie Gao
@ 2022-08-04 13:57   ` Simon Glass
  0 siblings, 0 replies; 100+ messages in thread
From: Simon Glass @ 2022-08-04 13:57 UTC (permalink / raw)
  To: Weijie Gao; +Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream

On Wed, 3 Aug 2022 at 21:38, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> This patch adds a pinctrl header for common pinconf parameters such as
> pull-up/pull-down resistors and drive strengths.
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  include/dt-bindings/pinctrl/mt65xx.h | 41 ++++++++++++++++++++++++++++
>  1 file changed, 41 insertions(+)
>  create mode 100644 include/dt-bindings/pinctrl/mt65xx.h

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 20/31] pinctrl: mediatek: add pinctrl driver for MT7981 SoC
  2022-08-04  3:36 ` [PATCH 20/31] pinctrl: mediatek: add pinctrl driver for MT7981 SoC Weijie Gao
@ 2022-08-04 13:57   ` Simon Glass
  0 siblings, 0 replies; 100+ messages in thread
From: Simon Glass @ 2022-08-04 13:57 UTC (permalink / raw)
  To: Weijie Gao; +Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream

On Wed, 3 Aug 2022 at 21:39, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> This patch adds pinctrl and gpio support for MT7981 SoC
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  drivers/pinctrl/mediatek/Kconfig          |    4 +
>  drivers/pinctrl/mediatek/Makefile         |    1 +
>  drivers/pinctrl/mediatek/pinctrl-mt7981.c | 1049 +++++++++++++++++++++
>  3 files changed, 1054 insertions(+)
>  create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt7981.c

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 22/31] clk: mediatek: add CLK_BYPASS_XTAL flag to allow bypassing searching clock parent of xtal clock
  2022-08-04  3:36 ` [PATCH 22/31] clk: mediatek: add CLK_BYPASS_XTAL flag to allow bypassing searching clock parent of xtal clock Weijie Gao
@ 2022-08-04 13:57   ` Simon Glass
  2022-08-08  3:01     ` Weijie Gao
  0 siblings, 1 reply; 100+ messages in thread
From: Simon Glass @ 2022-08-04 13:57 UTC (permalink / raw)
  To: Weijie Gao
  Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream, Lukasz Majewski,
	Sean Anderson

Hi Weijie,

On Wed, 3 Aug 2022 at 21:39, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> The mtk clock framework in u-boot uses array index for searching clock
> parent (kernel uses strings for search), so we need to specify a special
> clock with ID=0 for CLK_XTAL in u-boot.
>
> In the mt7622/mt7629 clock tree, the clocks with ID=0 never call
> mtk_topckgen_get_mux_rate, adn return xtal clock directly. This what we
> expected.
>
> However for newer chips, they may have some clocks with ID=0 not
> representing the xtal clock and still needs mtk_topckgen_get_mux_rate be
> called. Current logic will make entire clock driver not working.
>
> This patch adds a flag to indicate that whether a clock driver needs clocks
> with ID=0 to call mtk_topckgen_get_mux_rate.
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  drivers/clk/mediatek/clk-mtk.c | 5 ++++-
>  drivers/clk/mediatek/clk-mtk.h | 3 +++
>  2 files changed, 7 insertions(+), 1 deletion(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

>
> diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
> index d43b8a0648..d99ea55df0 100644
> --- a/drivers/clk/mediatek/clk-mtk.c
> +++ b/drivers/clk/mediatek/clk-mtk.c
> @@ -314,12 +314,15 @@ static ulong mtk_topckgen_get_mux_rate(struct clk
>  *clk, u32 off)
>         struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
>         const struct mtk_composite *mux = &priv->tree->muxes[off];
>         u32 index;
> +       u32 flag = 0;
>
>         index = readl(priv->base + mux->mux_reg);
>         index &= mux->mux_mask << mux->mux_shift;
>         index = index >> mux->mux_shift;
>
> -       if (mux->parent[index])
> +       if (mux->parent[index] == CLK_XTAL && priv->tree->flags & CLK_BYPASS_XTAL)
> +               flag = 1;
> +       if (mux->parent[index] > 0 || flag == 1)
>                 return mtk_clk_find_parent_rate(clk, mux->parent[index],
>                                                 NULL);
>
> diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
> index 95a23d14a8..0ab6912bf0 100644
> --- a/drivers/clk/mediatek/clk-mtk.h
> +++ b/drivers/clk/mediatek/clk-mtk.h
> @@ -11,6 +11,8 @@
>  #define CLK_XTAL                       0
>  #define MHZ                            (1000 * 1000)
>
> +#define CLK_BYPASS_XTAL                        BIT(0)
> +
>  #define HAVE_RST_BAR                   BIT(0)
>  #define CLK_DOMAIN_SCPSYS              BIT(0)
>  #define CLK_MUX_SETCLR_UPD             BIT(1)
> @@ -197,6 +199,7 @@ struct mtk_clk_tree {
>         const struct mtk_fixed_clk *fclks;
>         const struct mtk_fixed_factor *fdivs;
>         const struct mtk_composite *muxes;
> +       u32 flags;

This needs a comment as to what the flags mean

>  };
>
>  struct mtk_clk_priv {
> --
> 2.17.1
>

Regards,
Simon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 23/31] clk: mediatek: add support to configure clock driver parent
  2022-08-04  3:36 ` [PATCH 23/31] clk: mediatek: add support to configure clock driver parent Weijie Gao
@ 2022-08-04 13:57   ` Simon Glass
  2022-08-13  4:18   ` Sean Anderson
  1 sibling, 0 replies; 100+ messages in thread
From: Simon Glass @ 2022-08-04 13:57 UTC (permalink / raw)
  To: Weijie Gao
  Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream, Lukasz Majewski,
	Sean Anderson

On Wed, 3 Aug 2022 at 21:39, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> This patch adds support for a clock node to configure its parent clock
> where possible.
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  drivers/clk/mediatek/clk-mtk.c | 79 ++++++++++++++++++++--------------
>  drivers/clk/mediatek/clk-mtk.h |  2 +
>  2 files changed, 48 insertions(+), 33 deletions(-)
>

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 21/31] pinctrl: mediatek: add pinctrl driver for MT7986 SoC
  2022-08-04  3:36 ` [PATCH 21/31] pinctrl: mediatek: add pinctrl driver for MT7986 SoC Weijie Gao
@ 2022-08-04 13:57   ` Simon Glass
  0 siblings, 0 replies; 100+ messages in thread
From: Simon Glass @ 2022-08-04 13:57 UTC (permalink / raw)
  To: Weijie Gao; +Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream

On Wed, 3 Aug 2022 at 21:39, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> This patch adds pinctrl and gpio support for MT7986 SoC
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  drivers/pinctrl/mediatek/Kconfig          |   4 +
>  drivers/pinctrl/mediatek/Makefile         |   1 +
>  drivers/pinctrl/mediatek/pinctrl-mt7986.c | 775 ++++++++++++++++++++++
>  3 files changed, 780 insertions(+)
>  create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt7986.c

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 24/31] clk: mediatek: add infrasys clock mux support
  2022-08-04  3:36 ` [PATCH 24/31] clk: mediatek: add infrasys clock mux support Weijie Gao
@ 2022-08-04 13:57   ` Simon Glass
  2022-08-13  4:21   ` Sean Anderson
  1 sibling, 0 replies; 100+ messages in thread
From: Simon Glass @ 2022-08-04 13:57 UTC (permalink / raw)
  To: Weijie Gao
  Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream, Lukasz Majewski,
	Sean Anderson

On Wed, 3 Aug 2022 at 21:39, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> This patch adds infrasys clock mux support for mediatek clock drivers.
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  drivers/clk/mediatek/clk-mtk.c | 72 ++++++++++++++++++++++++++++++++++
>  drivers/clk/mediatek/clk-mtk.h |  4 +-
>  2 files changed, 75 insertions(+), 1 deletion(-)
>

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 25/31] clk: mediatek: add CLK_XTAL support for clock driver
  2022-08-04  3:36 ` [PATCH 25/31] clk: mediatek: add CLK_XTAL support for clock driver Weijie Gao
@ 2022-08-04 13:57   ` Simon Glass
  2022-08-08  3:10     ` Weijie Gao
  2022-08-13  4:25   ` Sean Anderson
  1 sibling, 1 reply; 100+ messages in thread
From: Simon Glass @ 2022-08-04 13:57 UTC (permalink / raw)
  To: Weijie Gao
  Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream, Lukasz Majewski,
	Sean Anderson

Hi Weijie,

On Wed, 3 Aug 2022 at 21:40, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> This add CLK_XTAL macro and flag to mediatek clock driver common part,
> to make thi SoC that has clock directlly connect to XTAL working.
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  drivers/clk/mediatek/clk-mtk.c | 3 +++
>  drivers/clk/mediatek/clk-mtk.h | 3 ++-
>  2 files changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
> index be3846c85b..5a4650d137 100644
> --- a/drivers/clk/mediatek/clk-mtk.c
> +++ b/drivers/clk/mediatek/clk-mtk.c
> @@ -296,6 +296,7 @@ static ulong mtk_topckgen_get_factor_rate(struct clk
>  *clk, u32 off)
>                 rate = mtk_clk_find_parent_rate(clk, fdiv->parent, NULL);
>                 break;
>
> +       case CLK_PARENT_XTAL:
>         default:
>                 rate = priv->tree->xtal_rate;
>         }
> @@ -314,6 +315,8 @@ static ulong mtk_infrasys_get_factor_rate(struct clk
>  *clk, u32 off)
>                 rate = mtk_clk_find_parent_rate(clk, fdiv->parent,
>                                                 priv->parent);
>                 break;
> +       case CLK_PARENT_XTAL:
> +               rate = priv->tree->xtal_rate;

Please document the fall-through here, if it is not a bug.

>         default:
>                 rate = mtk_clk_find_parent_rate(clk, fdiv->parent, NULL);
>         }
> diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
> index 8536275671..211356697b 100644
> --- a/drivers/clk/mediatek/clk-mtk.h
> +++ b/drivers/clk/mediatek/clk-mtk.h
> @@ -26,7 +26,8 @@
>  #define CLK_PARENT_APMIXED             BIT(4)
>  #define CLK_PARENT_TOPCKGEN            BIT(5)
>  #define CLK_PARENT_INFRASYS            BIT(6)
> -#define CLK_PARENT_MASK                        GENMASK(6, 4)
> +#define CLK_PARENT_XTAL                        BIT(7)
> +#define CLK_PARENT_MASK                        GENMASK(7, 4)
>
>  #define ETHSYS_HIFSYS_RST_CTRL_OFS     0x34
>
> --
> 2.17.1
>

REgards,
Simon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 26/31] clk: mediatek: add clock driver support for MediaTek MT7986 SoC
  2022-08-04  3:36 ` [PATCH 26/31] clk: mediatek: add clock driver support for MediaTek MT7986 SoC Weijie Gao
@ 2022-08-04 13:57   ` Simon Glass
  2022-08-08  3:13     ` Weijie Gao
  0 siblings, 1 reply; 100+ messages in thread
From: Simon Glass @ 2022-08-04 13:57 UTC (permalink / raw)
  To: Weijie Gao
  Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream, Lukasz Majewski,
	Sean Anderson

Hi Weijie,

On Wed, 3 Aug 2022 at 21:40, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> This patch adds clock driver support for MediaTek MT7986 SoC
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  drivers/clk/mediatek/Makefile          |   1 +
>  drivers/clk/mediatek/clk-mt7986.c      | 671 +++++++++++++++++++++++++
>  include/dt-bindings/clock/mt7986-clk.h | 249 +++++++++
>  3 files changed, 921 insertions(+)
>  create mode 100644 drivers/clk/mediatek/clk-mt7986.c
>  create mode 100644 include/dt-bindings/clock/mt7986-clk.h
>

Reviewed-by: Simon Glass <sjg@chromium.org>

[..]

> new file mode 100644
> index 0000000000..11c489cd50
> --- /dev/null
> +++ b/drivers/clk/mediatek/clk-mt7986.c
> @@ -0,0 +1,671 @@


[..]

> +static int mt7986_topckgen_probe(struct udevice *dev)
> +{
> +       struct mtk_clk_priv *priv = dev_get_priv(dev);
> +
> +       priv->base = dev_read_addr_ptr(dev);
> +       writel(MT7986_CLK_PDN_EN_WRITE, priv->base + MT7986_CLK_PDN);

blank line here

> +       return mtk_common_clk_init(dev, &mt7986_topckgen_clk_tree);
> +}
> +
> +U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
> +       .name = "mt7986-clock-fixed-pll",
> +       .id = UCLASS_CLK,
> +       .of_match = mt7986_fixed_pll_compat,
> +       .probe = mt7986_fixed_pll_probe,
> +       .priv_auto = sizeof(struct mtk_clk_priv),
> +       .ops = &mtk_clk_topckgen_ops,
> +       .flags = DM_FLAG_PRE_RELOC,
> +};
> +
> +U_BOOT_DRIVER(mtk_clk_topckgen) = {
> +       .name = "mt7986-clock-topckgen",
> +       .id = UCLASS_CLK,
> +       .of_match = mt7986_topckgen_compat,
> +       .probe = mt7986_topckgen_probe,
> +       .priv_auto = sizeof(struct mtk_clk_priv),
> +       .ops = &mtk_clk_topckgen_ops,
> +       .flags = DM_FLAG_PRE_RELOC,
> +};
> +
> +static const struct udevice_id mt7986_infracfg_compat[] = {
> +       { .compatible = "mediatek,mt7986-infracfg" },
> +       {}
> +};
> +
> +static const struct udevice_id mt7986_infracfg_ao_compat[] = {
> +       { .compatible = "mediatek,mt7986-infracfg_ao" },
> +       {}
> +};
> +
> +static int mt7986_infracfg_probe(struct udevice *dev)
> +{
> +       return mtk_common_clk_init(dev, &mt7986_infracfg_clk_tree);
> +}
> +
> +static int mt7986_infracfg_ao_probe(struct udevice *dev)
> +{
> +       return mtk_common_clk_gate_init(dev, &mt7986_infracfg_clk_tree,
> +                                       infracfg_ao_gates);
> +}
> +
> +U_BOOT_DRIVER(mtk_clk_infracfg) = {
> +       .name = "mt7986-clock-infracfg",
> +       .id = UCLASS_CLK,
> +       .of_match = mt7986_infracfg_compat,
> +       .probe = mt7986_infracfg_probe,
> +       .priv_auto = sizeof(struct mtk_clk_priv),
> +       .ops = &mtk_clk_infrasys_ops,
> +       .flags = DM_FLAG_PRE_RELOC,
> +};
> +
> +U_BOOT_DRIVER(mtk_clk_infracfg_ao) = {
> +       .name = "mt7986-clock-infracfg-ao",
> +       .id = UCLASS_CLK,
> +       .of_match = mt7986_infracfg_ao_compat,
> +       .probe = mt7986_infracfg_ao_probe,
> +       .priv_auto = sizeof(struct mtk_cg_priv),
> +       .ops = &mtk_clk_gate_ops,
> +       .flags = DM_FLAG_PRE_RELOC,
> +};
> +
> +/* ethsys */
> +static const struct mtk_gate_regs eth_cg_regs = {
> +       .sta_ofs = 0x30,
> +};
> +
> +#define GATE_ETH(_id, _name, _parent, _shift)
>     \
> +       {                                                                      \
> +               .id = _id, .parent = _parent, .regs = &eth_cg_regs,            \
> +               .shift = _shift,                                               \
> +               .flags = CLK_GATE_NO_SETCLR_INV | CLK_PARENT_TOPCKGEN,         \
> +       }
> +
> +static const struct mtk_gate eth_cgs[] = {
> +       GATE_ETH(CK_ETH_FE_EN, "eth_fe_en", CK_TOP_NETSYS_2X, 7),
> +       GATE_ETH(CK_ETH_GP2_EN, "eth_gp2_en", CK_TOP_SGM_325M, 8),
> +       GATE_ETH(CK_ETH_GP1_EN, "eth_gp1_en", CK_TOP_SGM_325M, 8),
> +       GATE_ETH(CK_ETH_WOCPU1_EN, "eth_wocpu1_en", CK_TOP_NETSYS_WED_MCU, 14),
> +       GATE_ETH(CK_ETH_WOCPU0_EN, "eth_wocpu0_en", CK_TOP_NETSYS_WED_MCU, 15),
> +};
> +
> +static int mt7986_ethsys_probe(struct udevice *dev)
> +{
> +       return mtk_common_clk_gate_init(dev, &mt7986_topckgen_clk_tree,
> +                                       eth_cgs);
> +}
> +
> +static int mt7986_ethsys_bind(struct udevice *dev)
> +{
> +       int ret = 0;
> +
> +#if CONFIG_IS_ENABLED(RESET_MEDIATEK)

if (CONFIG_IS_ENABLED()...

> +       ret = mediatek_reset_bind(dev, ETHSYS_HIFSYS_RST_CTRL_OFS, 1);
> +       if (ret)
> +               debug("Warning: failed to bind reset controller\n");
> +#endif
> +
> +       return ret;
> +}
> +
> +static const struct udevice_id mt7986_ethsys_compat[] = {
> +       { .compatible = "mediatek,mt7986-ethsys" },
> +       { }
> +};
> +
> +U_BOOT_DRIVER(mtk_clk_ethsys) = {
> +       .name = "mt7986-clock-ethsys",
> +       .id = UCLASS_CLK,
> +       .of_match = mt7986_ethsys_compat,
> +       .probe = mt7986_ethsys_probe,
> +       .bind = mt7986_ethsys_bind,
> +       .priv_auto = sizeof(struct mtk_cg_priv),
> +       .ops = &mtk_clk_gate_ops,
> +};

Regards,
Simon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 27/31] clk: mediatek: add clock driver support for MediaTek MT7981 SoC
  2022-08-04  3:36 ` [PATCH 27/31] clk: mediatek: add clock driver support for MediaTek MT7981 SoC Weijie Gao
@ 2022-08-04 13:57   ` Simon Glass
  2022-08-08  3:18     ` Weijie Gao
  2022-08-13  4:31   ` Sean Anderson
  1 sibling, 1 reply; 100+ messages in thread
From: Simon Glass @ 2022-08-04 13:57 UTC (permalink / raw)
  To: Weijie Gao
  Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream, Lukasz Majewski,
	Sean Anderson

Hi Weijie,

On Wed, 3 Aug 2022 at 21:40, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> This patch adds clock driver support for MediaTek MT7981 SoC
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  drivers/clk/mediatek/Makefile          |   1 +
>  drivers/clk/mediatek/clk-mt7981.c      | 682 +++++++++++++++++++++++++
>  include/dt-bindings/clock/mt7981-clk.h | 267 ++++++++++
>  3 files changed, 950 insertions(+)
>  create mode 100644 drivers/clk/mediatek/clk-mt7981.c
>  create mode 100644 include/dt-bindings/clock/mt7981-clk.h

Reviewed-by: Simon Glass <sjg@chromium.org>

use if CONFIG_IS_ENABLED(RESET_MEDIATEK)

Regards,
Simon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 28/31] tools: mtk_image: split gfh header verification into a new function
  2022-08-04  3:36 ` [PATCH 28/31] tools: mtk_image: split gfh header verification into a new function Weijie Gao
@ 2022-08-04 13:57   ` Simon Glass
  0 siblings, 0 replies; 100+ messages in thread
From: Simon Glass @ 2022-08-04 13:57 UTC (permalink / raw)
  To: Weijie Gao; +Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream

On Wed, 3 Aug 2022 at 21:40, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> The verification code of gfh header for NAND and non-NAND are identical.
> It's better to define a individual function to reduce redundancy.
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  tools/mtk_image.c | 51 +++++++++++++++++++----------------------------
>  1 file changed, 21 insertions(+), 30 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 31/31] MAINTAINERS: update maintainer for MediaTek ARM platform
  2022-08-04  3:36 ` [PATCH 31/31] MAINTAINERS: update maintainer for MediaTek ARM platform Weijie Gao
@ 2022-08-04 13:57   ` Simon Glass
  0 siblings, 0 replies; 100+ messages in thread
From: Simon Glass @ 2022-08-04 13:57 UTC (permalink / raw)
  To: Weijie Gao; +Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream

On Wed, 3 Aug 2022 at 21:41, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> Add new filed for MediaTek ARM platform

files

>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  MAINTAINERS | 5 +++++
>  1 file changed, 5 insertions(+)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 29/31] tools: mtk_image: split the code of generating NAND header into a new file
  2022-08-04  3:36 ` [PATCH 29/31] tools: mtk_image: split the code of generating NAND header into a new file Weijie Gao
@ 2022-08-04 13:57   ` Simon Glass
  2022-08-08  3:23     ` Weijie Gao
  2022-08-05 18:26   ` Daniel Golle
  1 sibling, 1 reply; 100+ messages in thread
From: Simon Glass @ 2022-08-04 13:57 UTC (permalink / raw)
  To: Weijie Gao
  Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream, AKASHI Takahiro,
	Pali Rohár, Stefan Roese, Andre Przywara, Samuel Holland

Hi Weijie,

On Wed, 3 Aug 2022 at 21:37, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> The predefined NAND headers take too much spaces in the mtk_image.c.
> Moving them into a new file can significantly improve the readability of
> both mtk_image.c and the new mtk_nand_headers.c.
>
> This is a preparation for adding more NAND headers.
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  tools/Makefile           |   1 +
>  tools/mtk_image.c        | 304 ++++++---------------------------------
>  tools/mtk_image.h        |  25 ----
>  tools/mtk_nand_headers.c | 286 ++++++++++++++++++++++++++++++++++++
>  tools/mtk_nand_headers.h |  52 +++++++
>  5 files changed, 379 insertions(+), 289 deletions(-)
>  create mode 100644 tools/mtk_nand_headers.c
>  create mode 100644 tools/mtk_nand_headers.h

Reviewed-by: Simon Glass <sjg@chromium.org>

[..]

> new file mode 100644
> index 0000000000..691db85005
> --- /dev/null
> +++ b/tools/mtk_nand_headers.h
> @@ -0,0 +1,52 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * MediaTek BootROM NAND header definitions
> + *
> + * Copyright (C) 2022 MediaTek Inc.
> + * Author: Weijie Gao <weijie.gao@mediatek.com>
> + */
> +
> +#ifndef _MTK_NAND_HEADERS_H
> +#define _MTK_NAND_HEADERS_H
> +
> +#include <stdint.h>
> +#include <stdbool.h>
> +
> +struct nand_header_info {
> +       uint32_t page_size;
> +       uint32_t spare_size;
> +       uint32_t gfh_offset;
> +};
> +
> +/* AP BROM Header for NAND */

Where is this documented?

> +union nand_boot_header {
> +       struct {
> +               char name[12];
> +               char version[4];
> +               char id[8];
> +               uint16_t ioif;
> +               uint16_t pagesize;
> +               uint16_t addrcycles;
> +               uint16_t oobsize;
> +               uint16_t pages_of_block;
> +               uint16_t numblocks;
> +               uint16_t writesize_shift;
> +               uint16_t erasesize_shift;
> +               uint8_t dummy[60];
> +               uint8_t ecc_parity[28];
> +       };
> +
> +       uint8_t data[0x80];
> +};
> +
> +#define NAND_BOOT_NAME         "BOOTLOADER!"
> +#define NAND_BOOT_VERSION      "V006"
> +#define NAND_BOOT_ID           "NFIINFO"
> +
> +const union nand_boot_header *mtk_nand_header_find(const char *name);
> +uint32_t mtk_nand_header_size(const union nand_boot_header *hdr_nand);
> +int mtk_nand_header_info(const void *ptr, struct nand_header_info *info);
> +bool is_mtk_nand_header(const void *ptr);
> +uint32_t mtk_nand_header_put(const union nand_boot_header *hdr_nand, void
>  *ptr);

Please comment each of these.

> +
> +#endif /* _MTK_NAND_HEADERS_H */
> --
> 2.17.1
>

Regards,
SImon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 30/31] tools: mtk_image: add support for nand headers used by newer chips
  2022-08-04  3:36 ` [PATCH 30/31] tools: mtk_image: add support for nand headers used by newer chips Weijie Gao
@ 2022-08-04 13:57   ` Simon Glass
  2022-08-08  3:31     ` Weijie Gao
  0 siblings, 1 reply; 100+ messages in thread
From: Simon Glass @ 2022-08-04 13:57 UTC (permalink / raw)
  To: Weijie Gao; +Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream

Hi Weijie,

On Wed, 3 Aug 2022 at 21:41, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> This patch adds more nand headers in two new types:
> 1. HSM header, used for spi-nand thru SNFI interface
> 2. SPIM header, used for spi-nand thru spi-mem interface
>
> The original nand header is renamed to AP header.
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  tools/mtk_image.c        |  23 ++-
>  tools/mtk_nand_headers.c | 422 +++++++++++++++++++++++++++++++++++++--
>  tools/mtk_nand_headers.h | 110 +++++++++-
>  3 files changed, 525 insertions(+), 30 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

[..]

> diff --git a/tools/mtk_nand_headers.h b/tools/mtk_nand_headers.h
> index 691db85005..ce4a824e29 100644
> --- a/tools/mtk_nand_headers.h
> +++ b/tools/mtk_nand_headers.h
> @@ -16,6 +16,7 @@ struct nand_header_info {
>         uint32_t page_size;
>         uint32_t spare_size;
>         uint32_t gfh_offset;
> +       bool snfi;
>  };
>
>  /* AP BROM Header for NAND */
> @@ -39,14 +40,117 @@ union nand_boot_header {
>         uint8_t data[0x80];
>  };
>
> +/* HSM BROM Header for NAND */
> +union hsm_nand_boot_header {
> +       struct {
> +               char id[8];
> +               uint32_t version;
> +               uint32_t config;
> +               uint32_t sector_size;
> +               uint32_t fdm_size;
> +               uint32_t fdm_ecc_size;
> +               uint32_t lbs;
> +               uint32_t page_size;
> +               uint32_t spare_size;
> +               uint32_t page_per_block;
> +               uint32_t blocks;
> +               uint32_t plane_sel_position;
> +               uint32_t pll;
> +               uint32_t acccon;
> +               uint32_t strobe_sel;
> +               uint32_t acccon1;
> +               uint32_t dqs_mux;
> +               uint32_t dqs_ctrl;
> +               uint32_t delay_ctrl;
> +               uint32_t latch_lat;
> +               uint32_t sample_delay;
> +               uint32_t driving;
> +               uint32_t bl_start;
> +               uint32_t bl_end;
> +               uint8_t ecc_parity[42];
> +       };
> +
> +       uint8_t data[0x8E];
> +};
> +
> +/* HSM2.0 BROM Header for NAND */
> +union hsm20_nand_boot_header {
> +       struct {
> +               char id[8];
> +               uint32_t version;
> +               uint32_t config;
> +               uint32_t sector_size;
> +               uint32_t fdm_size;
> +               uint32_t fdm_ecc_size;
> +               uint32_t lbs;
> +               uint32_t page_size;
> +               uint32_t spare_size;
> +               uint32_t page_per_block;
> +               uint32_t blocks;
> +               uint32_t plane_sel_position;
> +               uint32_t pll;
> +               uint32_t acccon;
> +               uint32_t strobe_sel;
> +               uint32_t acccon1;
> +               uint32_t dqs_mux;
> +               uint32_t dqs_ctrl;
> +               uint32_t delay_ctrl;
> +               uint32_t latch_lat;
> +               uint32_t sample_delay;
> +               uint32_t driving;
> +               uint32_t reserved;
> +               uint32_t bl0_start;
> +               uint32_t bl0_end;
> +               uint32_t bl0_type;
> +               uint8_t bl_reserve[84];
> +               uint8_t ecc_parity[42];
> +       };
> +
> +       uint8_t data[0xEA];
> +};
> +
> +/* SPIM BROM Header for NAND */
> +union spim_nand_boot_header {
> +       struct {
> +               char id[8];
> +               uint32_t version;
> +               uint32_t config;
> +               uint32_t page_size;
> +               uint32_t spare_size;
> +               uint16_t page_per_block;
> +               uint16_t plane_sel_position;
> +               uint16_t reserve_reg;
> +               uint16_t reserve_val;
> +               uint16_t ecc_error;
> +               uint16_t ecc_mask;
> +               uint32_t bl_start;
> +               uint32_t bl_end;
> +               uint8_t ecc_parity[32];
> +               uint32_t integrity_crc;
> +       };
> +
> +       uint8_t data[0x50];
> +};
> +
> +enum nand_boot_header_type {
> +       NAND_BOOT_AP_HEADER,
> +       NAND_BOOT_HSM_HEADER,
> +       NAND_BOOT_HSM20_HEADER,
> +       NAND_BOOT_SPIM_HEADER
> +};
> +
>  #define NAND_BOOT_NAME         "BOOTLOADER!"
>  #define NAND_BOOT_VERSION      "V006"
>  #define NAND_BOOT_ID           "NFIINFO"
>
> -const union nand_boot_header *mtk_nand_header_find(const char *name);
> -uint32_t mtk_nand_header_size(const union nand_boot_header *hdr_nand);
> +#define HSM_NAND_BOOT_NAME     "NANDCFG!"
> +#define SPIM_NAND_BOOT_NAME    "SPINAND!"
> +
> +const struct nand_header_type *mtk_nand_header_find(const char *name);
> +uint32_t mtk_nand_header_size(const struct nand_header_type *hdr_nand);
>  int mtk_nand_header_info(const void *ptr, struct nand_header_info *info);
>  bool is_mtk_nand_header(const void *ptr);
> -uint32_t mtk_nand_header_put(const union nand_boot_header *hdr_nand, void
>  *ptr);
> +uint32_t mtk_nand_header_put(const struct nand_header_type *hdr_nand,
> +                            void *ptr);

functions and structs need documentation

>
>  #endif /* _MTK_NAND_HEADERS_H */
> --
> 2.17.1
>

Regards,
Simon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 01/31] arm: mediatek: add support for MediaTek MT7986 SoC
  2022-08-04  8:50     ` Weijie Gao
@ 2022-08-05  8:43       ` Weijie Gao
  2022-08-06 16:09         ` Daniel Golle
  0 siblings, 1 reply; 100+ messages in thread
From: Weijie Gao @ 2022-08-05  8:43 UTC (permalink / raw)
  To: Daniel Golle; +Cc: u-boot, GSS_MTK_Uboot_upstream

Hi Daniel,

It turns out that this was caused by a setting change of company's mail
gateway.
I'll send v2 later.

Best Regards,

Weijie

On Thu, 2022-08-04 at 16:50 +0800, Weijie Gao wrote:
> Hi Daniel,
> 
> Thanks for the reminder.
> I found more errornous line-breaks in other patches...
> I'll find a way to fix that.
> 
> Best Regards,
> Weijie
> 
> On Thu, 2022-08-04 at 10:37 +0200, Daniel Golle wrote:
> > Hi Weijie,
> > 
> > happy to see this series posted!
> > Trying to apply it unfortunately fails due to errornous line-
> > breaks,
> > supposedly inserted by your MUA, see below.
> > 
> > I didn't go beyond the first patch and it'd be nice if you report
> > the
> > whole series without the wrong line-breaks.
> > 
> > Cheers
> > 
> > 
> > Daniel
> > 
> > 
> > On Thu, Aug 04, 2022 at 11:34:28AM +0800, Weijie Gao wrote:
> > > This patch adds basic support for MediaTek MT7986 SoC.
> > > This include the file that will initialize the SoC after boot and
> > > its
> > > device tree.
> > > 
> > > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> > > ---
> > >  arch/arm/dts/mt7986-u-boot.dtsi               |  33 ++
> > >  arch/arm/dts/mt7986.dtsi                      | 341
> > > ++++++++++++++++++
> > >  arch/arm/mach-mediatek/Kconfig                |  11 +
> > >  arch/arm/mach-mediatek/Makefile               |   1 +
> > >  arch/arm/mach-mediatek/mt7986/Makefile        |   4 +
> > >  arch/arm/mach-mediatek/mt7986/init.c          |  53 +++
> > >  arch/arm/mach-mediatek/mt7986/lowlevel_init.S |  30 ++
> > >  7 files changed, 473 insertions(+)
> > >  create mode 100644 arch/arm/dts/mt7986-u-boot.dtsi
> > >  create mode 100644 arch/arm/dts/mt7986.dtsi
> > >  create mode 100644 arch/arm/mach-mediatek/mt7986/Makefile
> > >  create mode 100644 arch/arm/mach-mediatek/mt7986/init.c
> > >  create mode 100644 arch/arm/mach-mediatek/mt7986/lowlevel_init.S
> > > 
> > > diff --git a/arch/arm/dts/mt7986-u-boot.dtsi
> > >  b/arch/arm/dts/mt7986-u-boot.dtsi
> > 
> > The above two lines should be a single line.
> > 
> > > new file mode 100644
> > > index 0000000000..95671f8afa
> > > --- /dev/null
> > > +++ b/arch/arm/dts/mt7986-u-boot.dtsi
> > > @@ -0,0 +1,33 @@
> > > +// SPDX-License-Identifier: GPL-2.0
> > > +/*
> > > + * Copyright (c) 2022 MediaTek Inc.
> > > + * Author: Sam Shih <sam.shih@mediatek.com>
> > > + */
> > > +
> > > +&topckgen {
> > > +	u-boot,dm-pre-reloc;
> > > +};
> > > +
> > > +&pericfg {
> > > +	u-boot,dm-pre-reloc;
> > > +};
> > > +
> > > +&apmixedsys {
> > > +	u-boot,dm-pre-reloc;
> > > +};
> > > +
> > > +&timer0 {
> > > +	u-boot,dm-pre-reloc;
> > > +};
> > > +
> > > +&uart0 {
> > > +	u-boot,dm-pre-reloc;
> > > +};
> > > +
> > > +&snand {
> > > +	u-boot,dm-pre-reloc;
> > > +};
> > > +
> > > +&pinctrl {
> > > +	u-boot,dm-pre-reloc;
> > > +};
> > > diff --git a/arch/arm/dts/mt7986.dtsi b/arch/arm/dts/mt7986.dtsi
> > > new file mode 100644
> > > index 0000000000..f235bd8b8c
> > > --- /dev/null
> > > +++ b/arch/arm/dts/mt7986.dtsi
> > > @@ -0,0 +1,341 @@
> > > +// SPDX-License-Identifier: GPL-2.0
> > > +/*
> > > + * Copyright (c) 2022 MediaTek Inc.
> > > + * Author: Sam Shih <sam.shih@mediatek.com>
> > > + */
> > > +
> > > +#include <dt-bindings/interrupt-controller/irq.h>
> > > +#include <dt-bindings/interrupt-controller/arm-gic.h>
> > > +#include <dt-bindings/phy/phy.h>
> > > +#include <dt-bindings/clock/mt7986-clk.h>
> > > +#include <dt-bindings/reset/mt7629-reset.h>
> > > +#include <dt-bindings/pinctrl/mt65xx.h>
> > > +
> > > +/ {
> > > +	compatible = "mediatek,mt7986";
> > > +	interrupt-parent = <&gic>;
> > > +	#address-cells = <1>;
> > > +	#size-cells = <1>;
> > > +
> > > +	config {
> > > +		u-boot,mmc-env-partition = "u-boot-env";
> > > +	};
> > > +
> > > +	cpus {
> > > +		#address-cells = <1>;
> > > +		#size-cells = <0>;
> > > +		cpu0: cpu@0 {
> > > +			device_type = "cpu";
> > > +			compatible = "arm,cortex-a53";
> > > +			reg = <0x0>;
> > > +		};
> > > +		cpu1: cpu@1 {
> > > +			device_type = "cpu";
> > > +			compatible = "arm,cortex-a53";
> > > +			reg = <0x1>;
> > > +		};
> > > +		cpu2: cpu@2 {
> > > +			device_type = "cpu";
> > > +			compatible = "arm,cortex-a53";
> > > +			reg = <0x1>;
> > > +		};
> > > +		cpu3: cpu@3 {
> > > +			device_type = "cpu";
> > > +			compatible = "arm,cortex-a53";
> > > +			reg = <0x1>;
> > > +		};
> > > +	};
> > > +
> > > +	dummy_clk: dummy12m {
> > > +		compatible = "fixed-clock";
> > > +		clock-frequency = <12000000>;
> > > +		#clock-cells = <0>;
> > > +		/* must need this line, or uart uanable to get
> > > dummy_clk */
> > > +		u-boot,dm-pre-reloc;
> > > +	};
> > > +
> > > +	timer {
> > > +		compatible = "arm,armv8-timer";
> > > +		interrupt-parent = <&gic>;
> > > +		clock-frequency = <13000000>;
> > > +		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
> > > +			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
> > > +			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
> > > +			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
> > > +		arm,cpu-registers-not-fw-configured;
> > > +	};
> > > +
> > > +	timer0: timer@10008000 {
> > > +		compatible = "mediatek,mt7986-timer";
> > > +		reg = <0x10008000 0x1000>;
> > > +		interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
> > > +		clocks = <&infracfg CK_INFRA_CK_F26M>;
> > > +		clock-names = "gpt-clk";
> > > +		u-boot,dm-pre-reloc;
> > > +	};
> > > +
> > > +	watchdog: watchdog@1001c000 {
> > > +		compatible = "mediatek,mt7986-wdt";
> > > +		reg = <0x1001c000 0x1000>;
> > > +		interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
> > > +		#reset-cells = <1>;
> > > +		status = "disabled";
> > > +	};
> > > +
> > > +	gic: interrupt-controller@c000000 {
> > > +		compatible = "arm,gic-v3";
> > > +		#interrupt-cells = <3>;
> > > +		interrupt-parent = <&gic>;
> > > +		interrupt-controller;
> > > +		reg = <0x0c000000 0x40000>,  /* GICD */
> > > +		      <0x0c080000 0x200000>; /* GICR */
> > > +
> > > +		interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
> > > +	};
> > > +
> > > +	fixed_plls: apmixedsys@1001E000 {
> > > +		compatible = "mediatek,mt7986-fixed-plls";
> > > +		reg = <0x1001E000 0x1000>;
> > > +		#clock-cells = <1>;
> > > +	};
> > > +
> > > +	topckgen: topckgen@1001B000 {
> > > +		compatible = "mediatek,mt7986-topckgen";
> > > +		reg = <0x1001B000 0x1000>;
> > > +		clock-parent = <&fixed_plls>;
> > > +		#clock-cells = <1>;
> > > +	};
> > > +
> > > +	infracfg_ao: infracfg_ao@10001000 {
> > > +		compatible = "mediatek,mt7986-infracfg_ao";
> > > +		reg = <0x10001000 0x68>;
> > > +		clock-parent = <&infracfg>;
> > > +		#clock-cells = <1>;
> > > +	};
> > > +
> > > +	infracfg: infracfg@10001040 {
> > > +		compatible = "mediatek,mt7986-infracfg";
> > > +		reg = <0x10001000 0x1000>;
> > > +		clock-parent = <&topckgen>;
> > > +		#clock-cells = <1>;
> > > +	};
> > > +
> > > +	pinctrl: pinctrl@1001f000 {
> > > +		compatible = "mediatek,mt7986-pinctrl";
> > > +		reg = <0x1001f000 0x1000>,
> > > +		      <0x11c30000 0x1000>,
> > > +		      <0x11c40000 0x1000>,
> > > +		      <0x11e20000 0x1000>,
> > > +		      <0x11e30000 0x1000>,
> > > +		      <0x11f00000 0x1000>,
> > > +		      <0x11f10000 0x1000>,
> > > +		      <0x1000b000 0x1000>;
> > > +		reg-names = "gpio_base", "iocfg_rt_base",
> > > "iocfg_rb_base",
> > > +			    "iocfg_lt_base", "iocfg_lb_base",
> > > "iocfg_tr_base",
> > > +			    "iocfg_tl_base", "eint";
> > > +		gpio: gpio-controller {
> > > +			gpio-controller;
> > > +			#gpio-cells = <2>;
> > > +		};
> > > +	};
> > > +
> > > +	pwm: pwm@10048000 {
> > > +		compatible = "mediatek,mt7986-pwm";
> > > +		reg = <0x10048000 0x1000>;
> > > +		#clock-cells = <1>;
> > > +		#pwm-cells = <2>;
> > > +		interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
> > > +		clocks = <&infracfg CK_INFRA_PWM>,
> > > +			 <&infracfg_ao CK_INFRA_PWM_BSEL>,
> > > +			 <&infracfg_ao CK_INFRA_PWM1_CK>,
> > > +			 <&infracfg_ao CK_INFRA_PWM2_CK>;
> > > +		assigned-clocks = <&topckgen CK_TOP_PWM_SEL>,
> > > +				  <&infracfg CK_INFRA_PWM_BSEL>,
> > > +				  <&infracfg CK_INFRA_PWM1_SEL>,
> > > +				  <&infracfg CK_INFRA_PWM2_SEL>;
> > > +		assigned-clock-parents = <&topckgen
> > > CK_TOP_CB_M_D4>,
> > > +					 <&infracfg
> > > CK_INFRA_PWM>,
> > > +					 <&infracfg
> > > CK_INFRA_PWM>,
> > > +					 <&infracfg
> > > CK_INFRA_PWM>;
> > > +		clock-names = "top", "main", "pwm1", "pwm2";
> > > +		status = "disabled";
> > > +		u-boot,dm-pre-reloc;
> > > +	};
> > > +
> > > +	uart0: serial@11002000 {
> > > +		compatible = "mediatek,hsuart";
> > > +		reg = <0x11002000 0x400>;
> > > +		interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
> > > +		clocks = <&infracfg_ao CK_INFRA_UART0_CK>;
> > > +		assigned-clocks = <&topckgen CK_TOP_UART_SEL>,
> > > +				  <&infracfg_ao
> > > CK_INFRA_UART0_SEL>;
> > > +		assigned-clock-parents = <&topckgen
> > > CK_TOP_CB_CKSQ_40M>,
> > > +					 <&infracfg
> > > CK_INFRA_UART>;
> > > +		mediatek,force-highspeed;
> > > +		status = "disabled";
> > > +		u-boot,dm-pre-reloc;
> > > +	};
> > > +
> > > +	uart1: serial@11003000 {
> > > +		compatible = "mediatek,hsuart";
> > > +		reg = <0x11003000 0x400>;
> > > +		interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
> > > +		clocks = <&infracfg_ao CK_INFRA_UART1_CK>;
> > > +		assigned-clocks = <&infracfg
> > > CK_INFRA_UART1_SEL>;
> > > +		assigned-clock-parents = <&infracfg
> > > CK_INFRA_CK_F26M>;
> > > +		mediatek,force-highspeed;
> > > +		status = "disabled";
> > > +	};
> > > +
> > > +	uart2: serial@11004000 {
> > > +		compatible = "mediatek,hsuart";
> > > +		reg = <0x11004000 0x400>;
> > > +		interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
> > > +		clocks = <&infracfg_ao CK_INFRA_UART2_CK>;
> > > +		assigned-clocks = <&infracfg
> > > CK_INFRA_UART2_SEL>;
> > > +		assigned-clock-parents = <&infracfg
> > > CK_INFRA_CK_F26M>;
> > > +		mediatek,force-highspeed;
> > > +		status = "disabled";
> > > +	};
> > > +
> > > +	snand: snand@11005000 {
> > > +		compatible = "mediatek,mt7986-snand";
> > > +		reg = <0x11005000 0x1000>,
> > > +		      <0x11006000 0x1000>;
> > > +		reg-names = "nfi", "ecc";
> > > +		clocks = <&infracfg_ao CK_INFRA_SPINFI1_CK>,
> > > +			 <&infracfg_ao CK_INFRA_NFI1_CK>,
> > > +			 <&infracfg_ao CK_INFRA_NFI_HCK_CK>;
> > > +		clock-names = "pad_clk", "nfi_clk", "nfi_hclk";
> > > +		assigned-clocks = <&topckgen CK_TOP_SPINFI_SEL>,
> > > +				  <&topckgen CK_TOP_NFI1X_SEL>;
> > > +		assigned-clock-parents = <&topckgen
> > > CK_TOP_CB_M_D8>,
> > > +					 <&topckgen
> > > CK_TOP_CB_M_D8>;
> > > +		status = "disabled";
> > > +	};
> > > +
> > > +	ethsys: syscon@15000000 {
> > > +		compatible = "mediatek,mt7986-ethsys", "syscon";
> > > +		reg = <0x15000000 0x1000>;
> > > +		clock-parent = <&topckgen>;
> > > +		#clock-cells = <1>;
> > > +		#reset-cells = <1>;
> > > +	};
> > > +
> > > +	eth: ethernet@15100000 {
> > > +		compatible = "mediatek,mt7986-eth", "syscon";
> > > +		reg = <0x15100000 0x20000>;
> > > +		resets = <&ethsys ETHSYS_FE_RST>;
> > > +		reset-names = "fe";
> > > +		mediatek,ethsys = <&ethsys>;
> > > +		mediatek,sgmiisys = <&sgmiisys0>;
> > > +		#address-cells = <1>;
> > > +		#size-cells = <0>;
> > > +		status = "disabled";
> > > +	};
> > > +
> > > +	sgmiisys0: syscon@10060000 {
> > > +		compatible = "mediatek,mt7986-sgmiisys",
> > > "syscon";
> > > +		reg = <0x10060000 0x1000>;
> > > +		#clock-cells = <1>;
> > > +	};
> > > +
> > > +	sgmiisys1: syscon@10070000 {
> > > +		compatible = "mediatek,mt7986-sgmiisys",
> > > "syscon";
> > > +		reg = <0x10070000 0x1000>;
> > > +		#clock-cells = <1>;
> > > +	};
> > > +
> > > +	spi0: spi@1100a000 {
> > > +		compatible = "mediatek,ipm-spi";
> > > +		reg = <0x1100a000 0x100>;
> > > +		clocks = <&infracfg_ao CK_INFRA_SPI0_CK>,
> > > +			 <&topckgen CK_TOP_SPI_SEL>;
> > > +		assigned-clocks = <&topckgen CK_TOP_SPI_SEL>,
> > > +				  <&infracfg CK_INFRA_SPI0_SEL>;
> > > +		assigned-clock-parents = <&topckgen
> > > CK_TOP_CB_M_D2>,
> > > +					 <&topckgen
> > > CK_INFRA_ISPI0>;
> > > +		clock-names = "sel-clk", "spi-clk";
> > > +		interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
> > > +		status = "disabled";
> > > +	};
> > > +
> > > +	spi1: spi@1100b000 {
> > > +		compatible = "mediatek,ipm-spi";
> > > +		reg = <0x1100b000 0x100>;
> > > +		interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
> > > +		status = "disabled";
> > > +	};
> > > +
> > > +	mmc0: mmc@11230000 {
> > > +		compatible = "mediatek,mt7986-mmc";
> > > +		reg = <0x11230000 0x1000>,
> > > +		      <0x11C20000 0x1000>;
> > > +		interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
> > > +		clocks = <&topckgen CK_TOP_EMMC_416M>,
> > > +			<&topckgen CK_TOP_EMMC_250M>,
> > > +			<&infracfg_ao CK_INFRA_MSDC_CK>;
> > > +		assigned-clocks = <&topckgen
> > > CK_TOP_EMMC_416M_SEL>,
> > > +				  <&topckgen
> > > CK_TOP_EMMC_250M_SEL>;
> > > +		assigned-clock-parents = <&topckgen
> > > CK_TOP_CB_M_416M>,
> > > +					 <&topckgen
> > > CK_TOP_NET1_D5_D2>;
> > > +		clock-names = "source", "hclk", "source_cg";
> > > +		status = "disabled";
> > > +	};
> > > +
> > > +	xhci: xhci@11200000 {
> > > +		compatible = "mediatek,mt7986-xhci",
> > > +			     "mediatek,mtk-xhci";
> > > +		reg = <0x11200000 0x2e00>,
> > > +		      <0x11203e00 0x0100>;
> > > +		reg-names = "mac", "ippc";
> > > +		interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
> > > +		phys = <&u2port0 PHY_TYPE_USB2>,
> > > +		       <&u3port0 PHY_TYPE_USB3>,
> > > +		       <&u2port1 PHY_TYPE_USB2>;
> > > +		clocks = <&dummy_clk>,
> > > +			 <&dummy_clk>,
> > > +			 <&dummy_clk>,
> > > +			 <&dummy_clk>,
> > > +			 <&dummy_clk>;
> > > +		clock-names = "sys_ck",
> > > +			      "xhci_ck",
> > > +			      "ref_ck",
> > > +			      "mcu_ck",
> > > +			      "dma_ck";
> > > +		tpl-support;
> > > +		status = "okay";
> > > +	};
> > > +
> > > +	usbtphy: usb-phy@11e10000 {
> > > +		compatible = "mediatek,mt7986",
> > > +			     "mediatek,generic-tphy-v2";
> > > +		#address-cells = <1>;
> > > +		#size-cells = <1>;
> > > +		status = "okay";
> > > +
> > > +		u2port0: usb-phy@11e10000 {
> > > +			reg = <0x11e10000 0x700>;
> > > +			clocks = <&dummy_clk>;
> > > +			clock-names = "ref";
> > > +			#phy-cells = <1>;
> > > +			status = "okay";
> > > +		};
> > > +
> > > +		u3port0: usb-phy@11e10700 {
> > > +			reg = <0x11e10700 0x900>;
> > > +			clocks = <&dummy_clk>;
> > > +			clock-names = "ref";
> > > +			#phy-cells = <1>;
> > > +			status = "okay";
> > > +		};
> > > +
> > > +		u2port1: usb-phy@11e11000 {
> > > +			reg = <0x11e11000 0x700>;
> > > +			clocks = <&dummy_clk>;
> > > +			clock-names = "ref";
> > > +			#phy-cells = <1>;
> > > +			status = "okay";
> > > +		};
> > > +	};
> > > +};
> > > diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-
> > > mediatek/Kconfig
> > > index f79a5c62cd..e059a013db 100644
> > > --- a/arch/arm/mach-mediatek/Kconfig
> > > +++ b/arch/arm/mach-mediatek/Kconfig
> > > @@ -40,6 +40,14 @@ config TARGET_MT7629
> > >  	  including DDR3, crypto engine, 3x3 11n/ac Wi-Fi,
> > > Gigabit
> > > Ethernet,
> > >  	  switch, USB3.0, PCIe, UART, SPI, I2C and PWM.
> > >  
> > > +config TARGET_MT7986
> > > +	bool "MediaTek MT7986 SoC"
> > > +	select ARM64
> > > +	help
> > > +	  The MediaTek MT7986 is a ARM64-based SoC with a quad-
> > > core Cortex-A53.
> > > +	  including UART, SPI, SPI flash, USB3.0, MMC, NAND,
> > > SNFI,
> > > PWM, PCIe,
> > > +	  Gigabit Ethernet, I2C, built-in 4x4 Wi-Fi, and PCIe.
> > > +
> > >  config TARGET_MT8183
> > >  	bool "MediaTek MT8183 SoC"
> > >  	select ARM64
> > > @@ -84,6 +92,7 @@ config SYS_BOARD
> > >  	default "mt7622" if TARGET_MT7622
> > >  	default "mt7623" if TARGET_MT7623
> > >  	default "mt7629" if TARGET_MT7629
> > > +	default "mt7986" if TARGET_MT7986
> > >  	default "mt8183" if TARGET_MT8183
> > >  	default "mt8512" if TARGET_MT8512
> > >  	default "mt8516" if TARGET_MT8516
> > > @@ -99,6 +108,7 @@ config SYS_CONFIG_NAME
> > >  	default "mt7622" if TARGET_MT7622
> > >  	default "mt7623" if TARGET_MT7623
> > >  	default "mt7629" if TARGET_MT7629
> > > +	default "mt7986" if TARGET_MT7986
> > >  	default "mt8183" if TARGET_MT8183
> > >  	default "mt8512" if TARGET_MT8512
> > >  	default "mt8516" if TARGET_MT8516
> > > @@ -113,6 +123,7 @@ config MTK_BROM_HEADER_INFO
> > >  	string
> > >  	default "media=nor" if TARGET_MT8518 || TARGET_MT8512 ||
> > > TARGET_MT7629 ||
> > >  TARGET_MT7622
> > 
> > Same here.
> > 
> > >  	default "media=emmc" if TARGET_MT8516 || TARGET_MT8365
> > > ||
> > > TARGET_MT8183
> > > +	default "media=snand;nandinfo=2k+64" if TARGET_MT7986
> > >  	default "lk=1" if TARGET_MT7623
> > >  
> > >  endif
> > > diff --git a/arch/arm/mach-mediatek/Makefile
> > >  b/arch/arm/mach-mediatek/Makefile
> > 
> > And here.
> > 
> > > index 0f5b0c16d2..fe5c3a837c 100644
> > > --- a/arch/arm/mach-mediatek/Makefile
> > > +++ b/arch/arm/mach-mediatek/Makefile
> > > @@ -7,6 +7,7 @@ obj-$(CONFIG_MT8512) += mt8512/
> > >  obj-$(CONFIG_TARGET_MT7622) += mt7622/
> > >  obj-$(CONFIG_TARGET_MT7623) += mt7623/
> > >  obj-$(CONFIG_TARGET_MT7629) += mt7629/
> > > +obj-$(CONFIG_TARGET_MT7986) += mt7986/
> > >  obj-$(CONFIG_TARGET_MT8183) += mt8183/
> > >  obj-$(CONFIG_TARGET_MT8516) += mt8516/
> > >  obj-$(CONFIG_TARGET_MT8518) += mt8518/
> > > diff --git a/arch/arm/mach-mediatek/mt7986/Makefile
> > >  b/arch/arm/mach-mediatek/mt7986/Makefile
> > 
> > And here.
> > 
> > > new file mode 100644
> > > index 0000000000..007eb4a367
> > > --- /dev/null
> > > +++ b/arch/arm/mach-mediatek/mt7986/Makefile
> > > @@ -0,0 +1,4 @@
> > > +# SPDX-License-Identifier:	GPL-2.0
> > > +
> > > +obj-y += init.o
> > > +obj-y += lowlevel_init.o
> > > diff --git a/arch/arm/mach-mediatek/mt7986/init.c
> > >  b/arch/arm/mach-mediatek/mt7986/init.c
> > 
> > And here again.
> > 
> > > new file mode 100644
> > > index 0000000000..4884cbdc67
> > > --- /dev/null
> > > +++ b/arch/arm/mach-mediatek/mt7986/init.c
> > > @@ -0,0 +1,53 @@
> > > +// SPDX-License-Identifier: GPL-2.0
> > > +/*
> > > + * Copyright (C) 2022 MediaTek Inc.
> > > + * Author: Sam Shih <sam.shih@mediatek.com>
> > > + */
> > > +
> > > +#include <fdtdec.h>
> > > +#include <asm/armv8/mmu.h>
> > > +#include <init.h>
> > > +#include <asm/system.h>
> > > +#include <asm/global_data.h>
> > > +#include <linux/sizes.h>
> > > +
> > > +DECLARE_GLOBAL_DATA_PTR;
> > > +
> > > +int print_cpuinfo(void)
> > > +{
> > > +	printf("CPU:   MediaTek MT7986\n");
> > > +	return 0;
> > > +}
> > > +
> > > +int dram_init(void)
> > > +{
> > > +	gd->ram_size = get_ram_size((void
> > > *)CONFIG_SYS_SDRAM_BASE,
> > > SZ_2G);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +void reset_cpu(ulong addr)
> > > +{
> > > +	psci_system_reset();
> > > +}
> > > +
> > > +static struct mm_region mt7986_mem_map[] = {
> > > +	{
> > > +		/* DDR */
> > > +		.virt = 0x40000000UL,
> > > +		.phys = 0x40000000UL,
> > > +		.size = 0x80000000UL,
> > > +		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
> > > PTE_BLOCK_OUTER_SHARE,
> > > +	}, {
> > > +		.virt = 0x00000000UL,
> > > +		.phys = 0x00000000UL,
> > > +		.size = 0x40000000UL,
> > > +		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
> > > +			 PTE_BLOCK_NON_SHARE |
> > > +			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
> > > +	}, {
> > > +		0,
> > > +	}
> > > +};
> > > +
> > > +struct mm_region *mem_map = mt7986_mem_map;
> > > diff --git a/arch/arm/mach-mediatek/mt7986/lowlevel_init.S
> > >  b/arch/arm/mach-mediatek/mt7986/lowlevel_init.S
> > 
> > And here.
> > 
> > > new file mode 100644
> > > index 0000000000..244d2c1385
> > > --- /dev/null
> > > +++ b/arch/arm/mach-mediatek/mt7986/lowlevel_init.S
> > > @@ -0,0 +1,30 @@
> > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > +/*
> > > + * Copyright (C) 2022 MediaTek Inc.
> > > + * Author: Sam Shih <sam.shih@mediatek.com>
> > > + */
> > > +
> > > +/*
> > > + * Switch from AArch64 EL2 to AArch32 EL2
> > > + * @param inputs:
> > > + * x0: argument, zero
> > > + * x1: machine nr
> > > + * x2: fdt address
> > > + * x3: input argument
> > > + * x4: kernel entry point
> > > + * @param outputs for secure firmware:
> > > + * x0: function id
> > > + * x1: kernel entry point
> > > + * x2: machine nr
> > > + * x3: fdt address
> > > +*/
> > > +
> > > +.global armv8_el2_to_aarch32
> > > +armv8_el2_to_aarch32:
> > > +	mov     x3, x2
> > > +	mov     x2, x1
> > > +	mov     x1, x4
> > > +	mov	x4, #0
> > > +	ldr x0, =0x82000200
> > > +	SMC #0
> > > +	ret
> > > -- 
> > > 2.17.1
> > > 

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 29/31] tools: mtk_image: split the code of generating NAND header into a new file
  2022-08-04  3:36 ` [PATCH 29/31] tools: mtk_image: split the code of generating NAND header into a new file Weijie Gao
  2022-08-04 13:57   ` Simon Glass
@ 2022-08-05 18:26   ` Daniel Golle
  2022-08-08  3:26     ` Weijie Gao
  1 sibling, 1 reply; 100+ messages in thread
From: Daniel Golle @ 2022-08-05 18:26 UTC (permalink / raw)
  To: Weijie Gao
  Cc: u-boot, GSS_MTK_Uboot_upstream, Simon Glass, AKASHI Takahiro,
	Pali Rohár, Stefan Roese, Andre Przywara, Samuel Holland

Hi Weijie,

please see one comment in-line below:

On Thu, Aug 04, 2022 at 11:36:50AM +0800, Weijie Gao wrote:
> The predefined NAND headers take too much spaces in the mtk_image.c.
> Moving them into a new file can significantly improve the readability of
> both mtk_image.c and the new mtk_nand_headers.c.
> 
> This is a preparation for adding more NAND headers.
> 
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  tools/Makefile           |   1 +
>  tools/mtk_image.c        | 304 ++++++---------------------------------
>  tools/mtk_image.h        |  25 ----
>  tools/mtk_nand_headers.c | 286 ++++++++++++++++++++++++++++++++++++
>  tools/mtk_nand_headers.h |  52 +++++++
>  5 files changed, 379 insertions(+), 289 deletions(-)
>  create mode 100644 tools/mtk_nand_headers.c
>  create mode 100644 tools/mtk_nand_headers.h
> 
> diff --git a/tools/Makefile b/tools/Makefile
> index 9f2339666a..4f27ed1ab1 100644
> --- a/tools/Makefile
> +++ b/tools/Makefile
> @@ -147,6 +147,7 @@ dumpimage-mkimage-objs := aisimage.o \
>  			gpimage.o \
>  			gpimage-common.o \
>  			mtk_image.o \
> +			mtk_nand_headers.o \
>  			$(ECDSA_OBJS-y) \
>  			$(RSA_OBJS-y) \
>  			$(AES_OBJS-y)
> diff --git a/tools/mtk_image.c b/tools/mtk_image.c
> index dcd6525f32..3701d1564a 100644
> --- a/tools/mtk_image.c
> +++ b/tools/mtk_image.c
> @@ -12,216 +12,7 @@
>  #include <u-boot/sha256.h>
>  #include "imagetool.h"
>  #include "mtk_image.h"
> -
> -/* NAND header for SPI-NAND with 2KB page + 64B spare */
> -static const union nand_boot_header snand_hdr_2k_64_data = {
> -	.data = {
> -		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> -		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> -		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> -		0x00, 0x00, 0x00, 0x08, 0x03, 0x00, 0x40, 0x00,
> -		0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x7B, 0xC4, 0x17, 0x9D,
> -		0xCA, 0x42, 0x90, 0xD0, 0x98, 0xD0, 0xE0, 0xF7,
> -		0xDB, 0xCD, 0x16, 0xF6, 0x03, 0x73, 0xD2, 0xB8,
> -		0x93, 0xB2, 0x56, 0x5A, 0x84, 0x6E, 0x00, 0x00
> -	}
> -};
> -
> -/* NAND header for SPI-NAND with 2KB page + 120B/128B spare */
> -static const union nand_boot_header snand_hdr_2k_128_data = {
> -	.data = {
> -		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> -		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> -		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> -		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
> -		0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x90, 0x28, 0xED, 0x13,
> -		0x7F, 0x12, 0x22, 0xCD, 0x3D, 0x06, 0xF1, 0xB3,
> -		0x6F, 0x2E, 0xD9, 0xA0, 0x9D, 0x7A, 0xBD, 0xD7,
> -		0xB3, 0x28, 0x3C, 0x13, 0xDB, 0x4E, 0x00, 0x00
> -	}
> -};
> -
> -/* NAND header for SPI-NAND with 4KB page + 256B spare */
> -static const union nand_boot_header snand_hdr_4k_256_data = {
> -	.data = {
> -		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> -		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> -		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> -		0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0xE0, 0x00,
> -		0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x47, 0xED, 0x0E, 0xC3,
> -		0x83, 0xBF, 0x41, 0xD2, 0x85, 0x21, 0x97, 0x57,
> -		0xC4, 0x2E, 0x6B, 0x7A, 0x40, 0xE0, 0xCF, 0x8F,
> -		0x37, 0xBD, 0x17, 0xB6, 0xC7, 0xFE, 0x00, 0x00
> -	}
> -};
> -
> -/* NAND header for Parallel NAND 1Gb with 2KB page + 64B spare */
> -static const union nand_boot_header nand_hdr_1gb_2k_64_data = {
> -	.data = {
> -		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> -		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> -		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> -		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
> -		0x40, 0x00, 0x00, 0x04, 0x0B, 0x00, 0x11, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x1C, 0x12,
> -		0x8F, 0xFD, 0xF8, 0x32, 0x6F, 0x6D, 0xCF, 0x6C,
> -		0xDA, 0x21, 0x70, 0x8C, 0xDA, 0x0A, 0x22, 0x82,
> -		0xAA, 0x59, 0xFA, 0x7C, 0x42, 0x2D, 0x00, 0x00
> -	}
> -};
> -
> -/* NAND header for Parallel NAND 2Gb with 2KB page + 64B spare */
> -static const union nand_boot_header nand_hdr_2gb_2k_64_data = {
> -	.data = {
> -		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> -		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> -		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> -		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
> -		0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x20, 0x9C, 0x3D, 0x2D,
> -		0x7B, 0x68, 0x63, 0x52, 0x2E, 0x04, 0x63, 0xF1,
> -		0x35, 0x4E, 0x44, 0x3E, 0xF8, 0xAC, 0x9B, 0x95,
> -		0xAB, 0xFE, 0xE4, 0xE1, 0xD5, 0xF9, 0x00, 0x00
> -	}
> -};
> -
> -/* NAND header for Parallel NAND 4Gb with 2KB page + 64B spare */
> -static const union nand_boot_header nand_hdr_4gb_2k_64_data = {
> -	.data = {
> -		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> -		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> -		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> -		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
> -		0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0xE3, 0x0F, 0x86, 0x32,
> -		0x68, 0x05, 0xD9, 0xC8, 0x13, 0xDF, 0xC5, 0x0B,
> -		0x35, 0x3A, 0x68, 0xA5, 0x3C, 0x0C, 0x73, 0x87,
> -		0x63, 0xB0, 0xBE, 0xCC, 0x84, 0x47, 0x00, 0x00
> -	}
> -};
> -
> -/* NAND header for Parallel NAND 2Gb with 2KB page + 128B spare */
> -static const union nand_boot_header nand_hdr_2gb_2k_128_data = {
> -	.data = {
> -		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> -		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> -		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> -		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
> -		0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x01, 0xA5, 0xE9, 0x5A,
> -		0xDF, 0x58, 0x62, 0x41, 0xD6, 0x26, 0x77, 0xBC,
> -		0x76, 0x1F, 0x27, 0x4E, 0x4F, 0x6C, 0xC3, 0xF0,
> -		0x36, 0xDE, 0xD9, 0xB3, 0xFF, 0x93, 0x00, 0x00
> -	}
> -};
> -
> -/* NAND header for Parallel NAND 4Gb with 2KB page + 128B spare */
> -static const union nand_boot_header nand_hdr_4gb_2k_128_data = {
> -	.data = {
> -		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> -		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> -		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> -		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
> -		0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -		0x00, 0x00, 0x00, 0x00, 0xC2, 0x36, 0x52, 0x45,
> -		0xCC, 0x35, 0xD8, 0xDB, 0xEB, 0xFD, 0xD1, 0x46,
> -		0x76, 0x6B, 0x0B, 0xD5, 0x8B, 0xCC, 0x2B, 0xE2,
> -		0xFE, 0x90, 0x83, 0x9E, 0xAE, 0x2D, 0x00, 0x00
> -	}
> -};
> -
> -static const struct nand_header_type {
> -	const char *name;
> -	const union nand_boot_header *data;
> -} nand_headers[] = {
> -	{
> -		.name = "2k+64",
> -		.data = &snand_hdr_2k_64_data
> -	}, {
> -		.name = "2k+120",
> -		.data = &snand_hdr_2k_128_data
> -	}, {
> -		.name = "2k+128",
> -		.data = &snand_hdr_2k_128_data
> -	}, {
> -		.name = "4k+256",
> -		.data = &snand_hdr_4k_256_data
> -	}, {
> -		.name = "1g:2k+64",
> -		.data = &nand_hdr_1gb_2k_64_data
> -	}, {
> -		.name = "2g:2k+64",
> -		.data = &nand_hdr_2gb_2k_64_data
> -	}, {
> -		.name = "4g:2k+64",
> -		.data = &nand_hdr_4gb_2k_64_data
> -	}, {
> -		.name = "2g:2k+128",
> -		.data = &nand_hdr_2gb_2k_128_data
> -	}, {
> -		.name = "4g:2k+128",
> -		.data = &nand_hdr_4gb_2k_128_data
> -	}
> -};
> +#include "mtk_nand_headers.h"
>  
>  static const struct brom_img_type {
>  	const char *name;
> @@ -264,6 +55,7 @@ static uint32_t crc32tbl[256];
>  
>  /* NAND header selected by user */
>  static const union nand_boot_header *hdr_nand;
> +static uint32_t hdr_nand_size;
>  
>  /* GFH header + 2 * 4KB pages of NAND */
>  static char hdr_tmp[sizeof(struct gfh_header) + 0x2000];
> @@ -402,12 +194,7 @@ static int mtk_brom_parse_imagename(const char
>  *imagename)
>  	}
>  
>  	/* parse nand header type */
> -	for (i = 0; i < ARRAY_SIZE(nand_headers); i++) {
> -		if (!strcmp(nand_headers[i].name, nandinfo)) {
> -			hdr_nand = nand_headers[i].data;
> -			break;
> -		}
> -	}
> +	hdr_nand = mtk_nand_header_find(nandinfo);
>  
>  	/* parse device header offset */
>  	if (hdr_offs && hdr_offs[0])
> @@ -432,6 +219,8 @@ static int mtk_brom_parse_imagename(const char
>  *imagename)
>  		return -EINVAL;
>  	}
>  
> +	hdr_nand_size = mtk_nand_header_size(hdr_nand);

This call has to be guarded and only happen in case of NAND or SNAND,
otherwise we get segfault because of NULL pointer here in case of
non-NAND boot media.

> +
>  	return 0;
>  }
>  
> @@ -468,7 +257,7 @@ static int mtk_image_vrec_header(struct
>  image_tool_params *params,
>  	}
>  
>  	if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND)
> -		tparams->header_size = 2 * le16_to_cpu(hdr_nand->pagesize);
> +		tparams->header_size = hdr_nand_size;
>  	else
>  		tparams->header_size = sizeof(struct gen_device_header);
>  
> @@ -566,16 +355,17 @@ static int mtk_image_verify_gen_header(const uint8_t
>  *ptr, int print)
>  
>  static int mtk_image_verify_nand_header(const uint8_t *ptr, int print)
>  {
> -	union nand_boot_header *nh = (union nand_boot_header *)ptr;
>  	struct brom_layout_header *bh;
> +	struct nand_header_info info;
>  	struct gfh_header *gfh;
>  	const char *bootmedia;
> +	int ret;
>  
> -	if (strncmp(nh->version, NAND_BOOT_VERSION, sizeof(nh->version)) ||
> -	    strcmp(nh->id, NAND_BOOT_ID))
> -		return -1;
> +	ret = mtk_nand_header_info(ptr, &info);
> +	if (ret < 0)
> +		return ret;
>  
> -	bh = (struct brom_layout_header *)(ptr + le16_to_cpu(nh->pagesize));
> +	bh = (struct brom_layout_header *)(ptr + info.page_size);
>  
>  	if (strcmp(bh->name, BRLYT_NAME))
>  		return -1;
> @@ -586,34 +376,23 @@ static int mtk_image_verify_nand_header(const uint8_t
>  *ptr, int print)
>  		if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND)
>  			bootmedia = "Parallel NAND";
>  		else if (le32_to_cpu(bh->type) == BRLYT_TYPE_SNAND)
> -			bootmedia = "Serial NAND";
> +			bootmedia = "Serial NAND (SNFI/AP)";
>  		else
>  			return -1;
>  	}
>  
>  	if (print) {
> -		printf("Boot Media: %s\n", bootmedia);
> -
> -		if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND) {
> -			uint64_t capacity =
> -				(uint64_t)le16_to_cpu(nh->numblocks) *
> -				(uint64_t)le16_to_cpu(nh->pages_of_block) *
> -				(uint64_t)le16_to_cpu(nh->pagesize) * 8;
> -			printf("Capacity:     %dGb\n",
> -			       (uint32_t)(capacity >> 30));
> -		}
> +		printf("Boot Media:   %s\n", bootmedia);
>  
> -		if (le16_to_cpu(nh->pagesize) >= 1024)
> -			printf("Page Size:    %dKB\n",
> -			       le16_to_cpu(nh->pagesize) >> 10);
> +		if (info.page_size >= 1024)
> +			printf("Page Size:    %dKB\n", info.page_size >> 10);
>  		else
> -			printf("Page Size:    %dB\n",
> -			       le16_to_cpu(nh->pagesize));
> +			printf("Page Size:    %dB\n", info.page_size);
>  
> -		printf("Spare Size:   %dB\n", le16_to_cpu(nh->oobsize));
> +		printf("Spare Size:   %dB\n", info.spare_size);
>  	}
>  
> -	gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(nh->pagesize));
> +	gfh = (struct gfh_header *)(ptr + info.gfh_offset);
>  
>  	return mtk_image_verify_gfh(gfh, GFH_FLASH_TYPE_NAND, print);
>  }
> @@ -713,7 +492,7 @@ static int mtk_image_verify_header(unsigned char *ptr,
>  int image_size,
>  	if (image_get_magic(hdr) == IH_MAGIC)
>  		return mtk_image_verify_mt7621_header(ptr, 0);
>  
> -	if (!strcmp((char *)ptr, NAND_BOOT_NAME))
> +	if (is_mtk_nand_header(ptr))
>  		return mtk_image_verify_nand_header(ptr, 0);
>  	else
>  		return mtk_image_verify_gen_header(ptr, 0);
> @@ -739,7 +518,7 @@ static void mtk_image_print_header(const void *ptr)
>  		return;
>  	}
>  
> -	if (!strcmp((char *)ptr, NAND_BOOT_NAME))
> +	if (is_mtk_nand_header(ptr))
>  		mtk_image_verify_nand_header(ptr, 1);
>  	else
>  		mtk_image_verify_gen_header(ptr, 1);
> @@ -870,36 +649,33 @@ static void mtk_image_set_gen_header(void *ptr, off_t
>  filesize,
>  static void mtk_image_set_nand_header(void *ptr, off_t filesize,
>  				      uint32_t loadaddr)
>  {
> -	union nand_boot_header *nh = (union nand_boot_header *)ptr;
>  	struct brom_layout_header *brlyt;
>  	struct gfh_header *gfh;
> -	uint32_t payload_pages;
> -	int i;
> +	uint32_t payload_pages, nand_page_size;
>  
> -	/* NAND device header, repeat 4 times */
> -	for (i = 0; i < 4; i++)
> -		memcpy(nh + i, hdr_nand, sizeof(union nand_boot_header));
> +	/* NAND header */
> +	nand_page_size = mtk_nand_header_put(hdr_nand, ptr);
>  
> -	/* BRLYT header */
> -	payload_pages = (filesize + le16_to_cpu(hdr_nand->pagesize) - 1) /
> -			le16_to_cpu(hdr_nand->pagesize);
> -	brlyt = (struct brom_layout_header *)
> -		(ptr + le16_to_cpu(hdr_nand->pagesize));
> -	put_brom_layout_header(brlyt, hdr_media);
> -	brlyt->header_size = cpu_to_le32(2);
> -	brlyt->total_size = cpu_to_le32(payload_pages);
> -	brlyt->header_size_2 = brlyt->header_size;
> -	brlyt->total_size_2 = brlyt->total_size;
> -	brlyt->unused = cpu_to_le32(1);
> +	if (nand_page_size) {
> +		/* BRLYT header */
> +		payload_pages = (filesize + nand_page_size - 1) /
> +				nand_page_size;
> +		brlyt = (struct brom_layout_header *)(ptr + nand_page_size);
> +		put_brom_layout_header(brlyt, hdr_media);
> +		brlyt->header_size = cpu_to_le32(2);
> +		brlyt->total_size = cpu_to_le32(payload_pages);
> +		brlyt->header_size_2 = brlyt->header_size;
> +		brlyt->total_size_2 = brlyt->total_size;
> +		brlyt->unused = cpu_to_le32(1);
> +	}
>  
>  	/* GFH header */
> -	gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(hdr_nand->pagesize));
> -	put_ghf_header(gfh, filesize, 2 * le16_to_cpu(hdr_nand->pagesize),
> -		       loadaddr, GFH_FLASH_TYPE_NAND);
> +	gfh = (struct gfh_header *)(ptr + hdr_nand_size);
> +	put_ghf_header(gfh, filesize, hdr_nand_size, loadaddr,
> +		       GFH_FLASH_TYPE_NAND);
>  
>  	/* Generate SHA256 hash */
> -	put_hash((uint8_t *)gfh,
> -		 filesize - 2 * le16_to_cpu(hdr_nand->pagesize) - SHA256_SUM_LEN);
> +	put_hash((uint8_t *)gfh, filesize - hdr_nand_size - SHA256_SUM_LEN);
>  }
>  
>  static void mtk_image_set_mt7621_header(void *ptr, off_t filesize,
> diff --git a/tools/mtk_image.h b/tools/mtk_image.h
> index d868545a33..fad9372100 100644
> --- a/tools/mtk_image.h
> +++ b/tools/mtk_image.h
> @@ -26,31 +26,6 @@ union gen_boot_header {
>  #define SF_BOOT_NAME		"SF_BOOT"
>  #define SDMMC_BOOT_NAME		"SDMMC_BOOT"
>  
> -/* Header for NAND */
> -union nand_boot_header {
> -	struct {
> -		char name[12];
> -		char version[4];
> -		char id[8];
> -		uint16_t ioif;
> -		uint16_t pagesize;
> -		uint16_t addrcycles;
> -		uint16_t oobsize;
> -		uint16_t pages_of_block;
> -		uint16_t numblocks;
> -		uint16_t writesize_shift;
> -		uint16_t erasesize_shift;
> -		uint8_t dummy[60];
> -		uint8_t ecc_parity[28];
> -	};
> -
> -	uint8_t data[0x80];
> -};
> -
> -#define NAND_BOOT_NAME		"BOOTLOADER!"
> -#define NAND_BOOT_VERSION	"V006"
> -#define NAND_BOOT_ID		"NFIINFO"
> -
>  /* BootROM layout header */
>  struct brom_layout_header {
>  	char name[8];
> diff --git a/tools/mtk_nand_headers.c b/tools/mtk_nand_headers.c
> new file mode 100644
> index 0000000000..12f827c39f
> --- /dev/null
> +++ b/tools/mtk_nand_headers.c
> @@ -0,0 +1,286 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * MediaTek BootROM NAND header definitions
> + *
> + * Copyright (C) 2022 MediaTek Inc.
> + * Author: Weijie Gao <weijie.gao@mediatek.com>
> + */
> +
> +#include <stdint.h>
> +#include <string.h>
> +#include "imagetool.h"
> +#include "mtk_image.h"
> +#include "mtk_nand_headers.h"
> +
> +/* NAND header for SPI-NAND with 2KB page + 64B spare */
> +static const union nand_boot_header snand_hdr_2k_64_data = {
> +	.data = {
> +		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> +		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> +		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> +		0x00, 0x00, 0x00, 0x08, 0x03, 0x00, 0x40, 0x00,
> +		0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x7B, 0xC4, 0x17, 0x9D,
> +		0xCA, 0x42, 0x90, 0xD0, 0x98, 0xD0, 0xE0, 0xF7,
> +		0xDB, 0xCD, 0x16, 0xF6, 0x03, 0x73, 0xD2, 0xB8,
> +		0x93, 0xB2, 0x56, 0x5A, 0x84, 0x6E, 0x00, 0x00
> +	}
> +};
> +
> +/* NAND header for SPI-NAND with 2KB page + 120B/128B spare */
> +static const union nand_boot_header snand_hdr_2k_128_data = {
> +	.data = {
> +		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> +		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> +		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> +		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
> +		0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x90, 0x28, 0xED, 0x13,
> +		0x7F, 0x12, 0x22, 0xCD, 0x3D, 0x06, 0xF1, 0xB3,
> +		0x6F, 0x2E, 0xD9, 0xA0, 0x9D, 0x7A, 0xBD, 0xD7,
> +		0xB3, 0x28, 0x3C, 0x13, 0xDB, 0x4E, 0x00, 0x00
> +	}
> +};
> +
> +/* NAND header for SPI-NAND with 4KB page + 256B spare */
> +static const union nand_boot_header snand_hdr_4k_256_data = {
> +	.data = {
> +		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> +		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> +		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> +		0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0xE0, 0x00,
> +		0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x47, 0xED, 0x0E, 0xC3,
> +		0x83, 0xBF, 0x41, 0xD2, 0x85, 0x21, 0x97, 0x57,
> +		0xC4, 0x2E, 0x6B, 0x7A, 0x40, 0xE0, 0xCF, 0x8F,
> +		0x37, 0xBD, 0x17, 0xB6, 0xC7, 0xFE, 0x00, 0x00
> +	}
> +};
> +
> +/* NAND header for Parallel NAND 1Gb with 2KB page + 64B spare */
> +static const union nand_boot_header nand_hdr_1gb_2k_64_data = {
> +	.data = {
> +		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> +		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> +		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> +		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
> +		0x40, 0x00, 0x00, 0x04, 0x0B, 0x00, 0x11, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x1C, 0x12,
> +		0x8F, 0xFD, 0xF8, 0x32, 0x6F, 0x6D, 0xCF, 0x6C,
> +		0xDA, 0x21, 0x70, 0x8C, 0xDA, 0x0A, 0x22, 0x82,
> +		0xAA, 0x59, 0xFA, 0x7C, 0x42, 0x2D, 0x00, 0x00
> +	}
> +};
> +
> +/* NAND header for Parallel NAND 2Gb with 2KB page + 64B spare */
> +static const union nand_boot_header nand_hdr_2gb_2k_64_data = {
> +	.data = {
> +		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> +		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> +		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> +		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
> +		0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x20, 0x9C, 0x3D, 0x2D,
> +		0x7B, 0x68, 0x63, 0x52, 0x2E, 0x04, 0x63, 0xF1,
> +		0x35, 0x4E, 0x44, 0x3E, 0xF8, 0xAC, 0x9B, 0x95,
> +		0xAB, 0xFE, 0xE4, 0xE1, 0xD5, 0xF9, 0x00, 0x00
> +	}
> +};
> +
> +/* NAND header for Parallel NAND 4Gb with 2KB page + 64B spare */
> +static const union nand_boot_header nand_hdr_4gb_2k_64_data = {
> +	.data = {
> +		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> +		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> +		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> +		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
> +		0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0xE3, 0x0F, 0x86, 0x32,
> +		0x68, 0x05, 0xD9, 0xC8, 0x13, 0xDF, 0xC5, 0x0B,
> +		0x35, 0x3A, 0x68, 0xA5, 0x3C, 0x0C, 0x73, 0x87,
> +		0x63, 0xB0, 0xBE, 0xCC, 0x84, 0x47, 0x00, 0x00
> +	}
> +};
> +
> +/* NAND header for Parallel NAND 2Gb with 2KB page + 128B spare */
> +static const union nand_boot_header nand_hdr_2gb_2k_128_data = {
> +	.data = {
> +		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> +		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> +		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> +		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
> +		0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x01, 0xA5, 0xE9, 0x5A,
> +		0xDF, 0x58, 0x62, 0x41, 0xD6, 0x26, 0x77, 0xBC,
> +		0x76, 0x1F, 0x27, 0x4E, 0x4F, 0x6C, 0xC3, 0xF0,
> +		0x36, 0xDE, 0xD9, 0xB3, 0xFF, 0x93, 0x00, 0x00
> +	}
> +};
> +
> +/* NAND header for Parallel NAND 4Gb with 2KB page + 128B spare */
> +static const union nand_boot_header nand_hdr_4gb_2k_128_data = {
> +	.data = {
> +		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> +		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> +		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> +		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
> +		0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +		0x00, 0x00, 0x00, 0x00, 0xC2, 0x36, 0x52, 0x45,
> +		0xCC, 0x35, 0xD8, 0xDB, 0xEB, 0xFD, 0xD1, 0x46,
> +		0x76, 0x6B, 0x0B, 0xD5, 0x8B, 0xCC, 0x2B, 0xE2,
> +		0xFE, 0x90, 0x83, 0x9E, 0xAE, 0x2D, 0x00, 0x00
> +	}
> +};
> +
> +static const struct nand_header_type {
> +	const char *name;
> +	const union nand_boot_header *data;
> +} nand_headers[] = {
> +	{
> +		.name = "2k+64",
> +		.data = &snand_hdr_2k_64_data
> +	}, {
> +		.name = "2k+120",
> +		.data = &snand_hdr_2k_128_data
> +	}, {
> +		.name = "2k+128",
> +		.data = &snand_hdr_2k_128_data
> +	}, {
> +		.name = "4k+256",
> +		.data = &snand_hdr_4k_256_data
> +	}, {
> +		.name = "1g:2k+64",
> +		.data = &nand_hdr_1gb_2k_64_data
> +	}, {
> +		.name = "2g:2k+64",
> +		.data = &nand_hdr_2gb_2k_64_data
> +	}, {
> +		.name = "4g:2k+64",
> +		.data = &nand_hdr_4gb_2k_64_data
> +	}, {
> +		.name = "2g:2k+128",
> +		.data = &nand_hdr_2gb_2k_128_data
> +	}, {
> +		.name = "4g:2k+128",
> +		.data = &nand_hdr_4gb_2k_128_data
> +	}
> +};
> +
> +const union nand_boot_header *mtk_nand_header_find(const char *name)
> +{
> +	uint32_t i;
> +
> +	for (i = 0; i < ARRAY_SIZE(nand_headers); i++) {
> +		if (!strcmp(nand_headers[i].name, name))
> +			return nand_headers[i].data;
> +	}
> +
> +	return NULL;
> +}
> +
> +uint32_t mtk_nand_header_size(const union nand_boot_header *hdr_nand)
> +{
> +	return 2 * le16_to_cpu(hdr_nand->pagesize);
> +}
> +
> +static int mtk_nand_header_ap_info(const void *ptr,
> +				   struct nand_header_info *info)
> +{
> +	union nand_boot_header *nh = (union nand_boot_header *)ptr;
> +
> +	if (strncmp(nh->version, NAND_BOOT_VERSION, sizeof(nh->version)) ||
> +	    strcmp(nh->id, NAND_BOOT_ID))
> +		return -1;
> +
> +	info->page_size = le16_to_cpu(nh->pagesize);
> +	info->spare_size = le16_to_cpu(nh->oobsize);
> +	info->gfh_offset = 2 * info->page_size;
> +
> +	return 0;
> +}
> +
> +int mtk_nand_header_info(const void *ptr, struct nand_header_info *info)
> +{
> +	if (!strcmp((char *)ptr, NAND_BOOT_NAME))
> +		return mtk_nand_header_ap_info(ptr, info);
> +
> +	return -1;
> +}
> +
> +bool is_mtk_nand_header(const void *ptr)
> +{
> +	struct nand_header_info info;
> +
> +	if (mtk_nand_header_info(ptr, &info) >= 0)
> +		return true;
> +
> +	return false;
> +}
> +
> +uint32_t mtk_nand_header_put(const union nand_boot_header *hdr_nand, void
>  *ptr)
> +{
> +	union nand_boot_header *nh = (union nand_boot_header *)ptr;
> +	int i;
> +
> +	/* NAND device header, repeat 4 times */
> +	for (i = 0; i < 4; i++)
> +		memcpy(nh + i, hdr_nand, sizeof(union nand_boot_header));
> +
> +	return le16_to_cpu(hdr_nand->pagesize);
> +}
> diff --git a/tools/mtk_nand_headers.h b/tools/mtk_nand_headers.h
> new file mode 100644
> index 0000000000..691db85005
> --- /dev/null
> +++ b/tools/mtk_nand_headers.h
> @@ -0,0 +1,52 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * MediaTek BootROM NAND header definitions
> + *
> + * Copyright (C) 2022 MediaTek Inc.
> + * Author: Weijie Gao <weijie.gao@mediatek.com>
> + */
> +
> +#ifndef _MTK_NAND_HEADERS_H
> +#define _MTK_NAND_HEADERS_H
> +
> +#include <stdint.h>
> +#include <stdbool.h>
> +
> +struct nand_header_info {
> +	uint32_t page_size;
> +	uint32_t spare_size;
> +	uint32_t gfh_offset;
> +};
> +
> +/* AP BROM Header for NAND */
> +union nand_boot_header {
> +	struct {
> +		char name[12];
> +		char version[4];
> +		char id[8];
> +		uint16_t ioif;
> +		uint16_t pagesize;
> +		uint16_t addrcycles;
> +		uint16_t oobsize;
> +		uint16_t pages_of_block;
> +		uint16_t numblocks;
> +		uint16_t writesize_shift;
> +		uint16_t erasesize_shift;
> +		uint8_t dummy[60];
> +		uint8_t ecc_parity[28];
> +	};
> +
> +	uint8_t data[0x80];
> +};
> +
> +#define NAND_BOOT_NAME		"BOOTLOADER!"
> +#define NAND_BOOT_VERSION	"V006"
> +#define NAND_BOOT_ID		"NFIINFO"
> +
> +const union nand_boot_header *mtk_nand_header_find(const char *name);
> +uint32_t mtk_nand_header_size(const union nand_boot_header *hdr_nand);
> +int mtk_nand_header_info(const void *ptr, struct nand_header_info *info);
> +bool is_mtk_nand_header(const void *ptr);
> +uint32_t mtk_nand_header_put(const union nand_boot_header *hdr_nand, void
>  *ptr);
> +
> +#endif /* _MTK_NAND_HEADERS_H */
> -- 
> 2.17.1
> 

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 01/31] arm: mediatek: add support for MediaTek MT7986 SoC
  2022-08-05  8:43       ` Weijie Gao
@ 2022-08-06 16:09         ` Daniel Golle
  2022-08-08  1:37           ` Weijie Gao
  0 siblings, 1 reply; 100+ messages in thread
From: Daniel Golle @ 2022-08-06 16:09 UTC (permalink / raw)
  To: Weijie Gao; +Cc: u-boot, GSS_MTK_Uboot_upstream

Hi Weijie,

I manually fixed the last 3 patches in the series adding support for
newer SoCs to mkimage/mtk_image.

On my BPi-R3 (mt7986a) I was now trying to use mkimage instead of
bromimage in the same way you introduced that option for mt7622[1]:

The resulting bl2.img works fine on SPI-NAND and eMMC, however,
booting from SPI-NOR or SD card doesn't work.

On SPI-NOR:
F0: 102B 0000
FA: 0000 0000
V0: 7027 6006 [0001]
00: 1017 0000
FA: 5100 0000
01: 102A 0001
02: 5100 0000
BP: 2000 00C0 [0001]
EC: 0000 0000 [0000]
T0: 0000 0213 [010F]
System halt!

On SD card:
F0: 102B 0000
FA: 1040 0000
FA: 1040 0000 [0200]
F9: 103F 0000
F3: 1001 0000 [0200]
F3: 1001 0000
F6: 300C 0028
F5: 0000 0000
L0: 8005 0000 [0001]
00: 1012 0000
BP: 2000 00C0 [0001]
EC: 0000 0000 [3000]
T0: 0000 00E8 [010F]
System halt!

All generate image headers also differ from the ones generated by
bromimage, however, for SPI-NAND and eMMC they still work.

hexdiff of SD card bl2.img
@@ -65,7 +65,7 @@
 00004420  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
 *
 00004600  42 52 4c 59 54 00 00 00  01 00 00 00 00 4a 00 00  |BRLYT........J..|
-00004610  88 51 03 00 42 42 42 42  08 00 01 00 00 06 00 00  |.Q..BBBB........|
+00004610  88 51 03 00 42 42 42 42  08 00 01 00 00 4a 00 00  |.Q..BBBB.....J..|
 00004620  88 51 03 00 ff ff ff ff  ff ff ff ff ff ff ff ff  |.Q..............|
 00004630  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
 *
@@ -73,15 +73,15 @@
 00004a10  4f 00 00 00 01 00 00 00  01 00 05 01 00 0d 20 00  |O............. .|
 00004a20  88 07 03 00 88 0d 03 00  00 03 00 00 20 00 00 00  |............ ...|
 00004a30  00 03 00 00 01 00 00 00  4d 4d 4d 01 0c 00 01 00  |........MMM.....|
-00004a40  01 00 00 00 4d 4d 4d 01  14 00 02 00 00 00 00 00  |....MMM.........|
-00004a50  10 00 00 00 80 00 00 00  4d 4d 4d 01 14 02 03 00  |........MMM.....|
-00004a60  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-*
-00004c60  00 00 00 00 00 00 00 00  00 00 00 00 4d 4d 4d 03  |............MMM.|
-00004c70  64 00 07 00 90 11 00 00  00 00 00 00 00 00 00 00  |d...............|
-00004c80  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
+00004a40  01 00 00 00 4d 4d 4d 03  64 00 07 00 90 11 00 00  |....MMM.d.......|
+00004a50  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 *
-00004cc0  00 64 00 00 88 13 00 00  00 00 00 00 00 00 00 00  |.d..............|
+00004a90  00 00 00 00 00 00 00 00  00 64 00 00 88 13 00 00  |.........d......|
+00004aa0  00 00 00 00 00 00 00 00  4d 4d 4d 01 14 02 03 00  |........MMM.....|
+00004ab0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
+*
+00004cb0  00 00 00 00 00 00 00 00  00 00 00 00 4d 4d 4d 01  |............MMM.|
+00004cc0  14 00 02 00 00 00 00 00  10 00 00 00 80 00 00 00  |................|
 00004cd0  4d 4d 4d 01 30 00 08 00  03 00 00 00 00 00 00 00  |MMM.0...........|
 00004ce0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 *

hexdiff of SPI-NOR bl2.img
@@ -11,15 +11,15 @@
 00000610  4f 00 00 00 01 00 00 00  01 00 05 01 00 0d 20 00  |O............. .|
 00000620  70 0a 03 00 70 10 03 00  00 03 00 00 20 00 00 00  |p...p....... ...|
 00000630  00 03 00 00 01 00 00 00  4d 4d 4d 01 0c 00 01 00  |........MMM.....|
-00000640  01 00 00 00 4d 4d 4d 03  64 00 07 00 90 11 00 00  |....MMM.d.......|
-00000650  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
+00000640  01 00 00 00 4d 4d 4d 01  14 00 02 00 00 00 00 00  |....MMM.........|
+00000650  10 00 00 00 80 00 00 00  4d 4d 4d 01 14 02 03 00  |........MMM.....|
+00000660  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 *
-00000690  00 00 00 00 00 00 00 00  00 64 00 00 88 13 00 00  |.........d......|
-000006a0  00 00 00 00 00 00 00 00  4d 4d 4d 01 14 02 03 00  |........MMM.....|
-000006b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
+00000860  00 00 00 00 00 00 00 00  00 00 00 00 4d 4d 4d 03  |............MMM.|
+00000870  64 00 07 00 90 11 00 00  00 00 00 00 00 00 00 00  |d...............|
+00000880  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 *
-000008b0  00 00 00 00 00 00 00 00  00 00 00 00 4d 4d 4d 01  |............MMM.|
-000008c0  14 00 02 00 00 00 00 00  10 00 00 00 80 00 00 00  |................|
+000008c0  00 64 00 00 88 13 00 00  00 00 00 00 00 00 00 00  |.d..............|
 000008d0  4d 4d 4d 01 30 00 08 00  03 00 00 00 00 00 00 00  |MMM.0...........|
 000008e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 *

I'll try to have a look at this more deepply in the next days, but if
you already spot the error I'd also be glad ;)


Cheers


Daniel


[1]: https://github.com/dangowrt/arm-trusted-firmware/commit/3b8a17bd847d864379fe9953a82991b522f64add


On Fri, Aug 05, 2022 at 04:43:39PM +0800, Weijie Gao wrote:
> Hi Daniel,
> 
> It turns out that this was caused by a setting change of company's mail
> gateway.
> I'll send v2 later.
> 
> Best Regards,
> 
> Weijie
> 
> On Thu, 2022-08-04 at 16:50 +0800, Weijie Gao wrote:
> > Hi Daniel,
> > 
> > Thanks for the reminder.
> > I found more errornous line-breaks in other patches...
> > I'll find a way to fix that.
> > 
> > Best Regards,
> > Weijie
> > 
> > On Thu, 2022-08-04 at 10:37 +0200, Daniel Golle wrote:
> > > Hi Weijie,
> > > 
> > > happy to see this series posted!
> > > Trying to apply it unfortunately fails due to errornous line-
> > > breaks,
> > > supposedly inserted by your MUA, see below.
> > > 
> > > I didn't go beyond the first patch and it'd be nice if you report
> > > the
> > > whole series without the wrong line-breaks.
> > > 
> > > Cheers
> > > 
> > > 
> > > Daniel
> > > 
> > > 
> > > On Thu, Aug 04, 2022 at 11:34:28AM +0800, Weijie Gao wrote:
> > > > This patch adds basic support for MediaTek MT7986 SoC.
> > > > This include the file that will initialize the SoC after boot and
> > > > its
> > > > device tree.
> > > > 
> > > > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> > > > ---
> > > >  arch/arm/dts/mt7986-u-boot.dtsi               |  33 ++
> > > >  arch/arm/dts/mt7986.dtsi                      | 341
> > > > ++++++++++++++++++
> > > >  arch/arm/mach-mediatek/Kconfig                |  11 +
> > > >  arch/arm/mach-mediatek/Makefile               |   1 +
> > > >  arch/arm/mach-mediatek/mt7986/Makefile        |   4 +
> > > >  arch/arm/mach-mediatek/mt7986/init.c          |  53 +++
> > > >  arch/arm/mach-mediatek/mt7986/lowlevel_init.S |  30 ++
> > > >  7 files changed, 473 insertions(+)
> > > >  create mode 100644 arch/arm/dts/mt7986-u-boot.dtsi
> > > >  create mode 100644 arch/arm/dts/mt7986.dtsi
> > > >  create mode 100644 arch/arm/mach-mediatek/mt7986/Makefile
> > > >  create mode 100644 arch/arm/mach-mediatek/mt7986/init.c
> > > >  create mode 100644 arch/arm/mach-mediatek/mt7986/lowlevel_init.S
> > > > 
> > > > diff --git a/arch/arm/dts/mt7986-u-boot.dtsi
> > > >  b/arch/arm/dts/mt7986-u-boot.dtsi
> > > 
> > > The above two lines should be a single line.
> > > 
> > > > new file mode 100644
> > > > index 0000000000..95671f8afa
> > > > --- /dev/null
> > > > +++ b/arch/arm/dts/mt7986-u-boot.dtsi
> > > > @@ -0,0 +1,33 @@
> > > > +// SPDX-License-Identifier: GPL-2.0
> > > > +/*
> > > > + * Copyright (c) 2022 MediaTek Inc.
> > > > + * Author: Sam Shih <sam.shih@mediatek.com>
> > > > + */
> > > > +
> > > > +&topckgen {
> > > > +	u-boot,dm-pre-reloc;
> > > > +};
> > > > +
> > > > +&pericfg {
> > > > +	u-boot,dm-pre-reloc;
> > > > +};
> > > > +
> > > > +&apmixedsys {
> > > > +	u-boot,dm-pre-reloc;
> > > > +};
> > > > +
> > > > +&timer0 {
> > > > +	u-boot,dm-pre-reloc;
> > > > +};
> > > > +
> > > > +&uart0 {
> > > > +	u-boot,dm-pre-reloc;
> > > > +};
> > > > +
> > > > +&snand {
> > > > +	u-boot,dm-pre-reloc;
> > > > +};
> > > > +
> > > > +&pinctrl {
> > > > +	u-boot,dm-pre-reloc;
> > > > +};
> > > > diff --git a/arch/arm/dts/mt7986.dtsi b/arch/arm/dts/mt7986.dtsi
> > > > new file mode 100644
> > > > index 0000000000..f235bd8b8c
> > > > --- /dev/null
> > > > +++ b/arch/arm/dts/mt7986.dtsi
> > > > @@ -0,0 +1,341 @@
> > > > +// SPDX-License-Identifier: GPL-2.0
> > > > +/*
> > > > + * Copyright (c) 2022 MediaTek Inc.
> > > > + * Author: Sam Shih <sam.shih@mediatek.com>
> > > > + */
> > > > +
> > > > +#include <dt-bindings/interrupt-controller/irq.h>
> > > > +#include <dt-bindings/interrupt-controller/arm-gic.h>
> > > > +#include <dt-bindings/phy/phy.h>
> > > > +#include <dt-bindings/clock/mt7986-clk.h>
> > > > +#include <dt-bindings/reset/mt7629-reset.h>
> > > > +#include <dt-bindings/pinctrl/mt65xx.h>
> > > > +
> > > > +/ {
> > > > +	compatible = "mediatek,mt7986";
> > > > +	interrupt-parent = <&gic>;
> > > > +	#address-cells = <1>;
> > > > +	#size-cells = <1>;
> > > > +
> > > > +	config {
> > > > +		u-boot,mmc-env-partition = "u-boot-env";
> > > > +	};
> > > > +
> > > > +	cpus {
> > > > +		#address-cells = <1>;
> > > > +		#size-cells = <0>;
> > > > +		cpu0: cpu@0 {
> > > > +			device_type = "cpu";
> > > > +			compatible = "arm,cortex-a53";
> > > > +			reg = <0x0>;
> > > > +		};
> > > > +		cpu1: cpu@1 {
> > > > +			device_type = "cpu";
> > > > +			compatible = "arm,cortex-a53";
> > > > +			reg = <0x1>;
> > > > +		};
> > > > +		cpu2: cpu@2 {
> > > > +			device_type = "cpu";
> > > > +			compatible = "arm,cortex-a53";
> > > > +			reg = <0x1>;
> > > > +		};
> > > > +		cpu3: cpu@3 {
> > > > +			device_type = "cpu";
> > > > +			compatible = "arm,cortex-a53";
> > > > +			reg = <0x1>;
> > > > +		};
> > > > +	};
> > > > +
> > > > +	dummy_clk: dummy12m {
> > > > +		compatible = "fixed-clock";
> > > > +		clock-frequency = <12000000>;
> > > > +		#clock-cells = <0>;
> > > > +		/* must need this line, or uart uanable to get
> > > > dummy_clk */
> > > > +		u-boot,dm-pre-reloc;
> > > > +	};
> > > > +
> > > > +	timer {
> > > > +		compatible = "arm,armv8-timer";
> > > > +		interrupt-parent = <&gic>;
> > > > +		clock-frequency = <13000000>;
> > > > +		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
> > > > +			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
> > > > +			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
> > > > +			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
> > > > +		arm,cpu-registers-not-fw-configured;
> > > > +	};
> > > > +
> > > > +	timer0: timer@10008000 {
> > > > +		compatible = "mediatek,mt7986-timer";
> > > > +		reg = <0x10008000 0x1000>;
> > > > +		interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
> > > > +		clocks = <&infracfg CK_INFRA_CK_F26M>;
> > > > +		clock-names = "gpt-clk";
> > > > +		u-boot,dm-pre-reloc;
> > > > +	};
> > > > +
> > > > +	watchdog: watchdog@1001c000 {
> > > > +		compatible = "mediatek,mt7986-wdt";
> > > > +		reg = <0x1001c000 0x1000>;
> > > > +		interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
> > > > +		#reset-cells = <1>;
> > > > +		status = "disabled";
> > > > +	};
> > > > +
> > > > +	gic: interrupt-controller@c000000 {
> > > > +		compatible = "arm,gic-v3";
> > > > +		#interrupt-cells = <3>;
> > > > +		interrupt-parent = <&gic>;
> > > > +		interrupt-controller;
> > > > +		reg = <0x0c000000 0x40000>,  /* GICD */
> > > > +		      <0x0c080000 0x200000>; /* GICR */
> > > > +
> > > > +		interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
> > > > +	};
> > > > +
> > > > +	fixed_plls: apmixedsys@1001E000 {
> > > > +		compatible = "mediatek,mt7986-fixed-plls";
> > > > +		reg = <0x1001E000 0x1000>;
> > > > +		#clock-cells = <1>;
> > > > +	};
> > > > +
> > > > +	topckgen: topckgen@1001B000 {
> > > > +		compatible = "mediatek,mt7986-topckgen";
> > > > +		reg = <0x1001B000 0x1000>;
> > > > +		clock-parent = <&fixed_plls>;
> > > > +		#clock-cells = <1>;
> > > > +	};
> > > > +
> > > > +	infracfg_ao: infracfg_ao@10001000 {
> > > > +		compatible = "mediatek,mt7986-infracfg_ao";
> > > > +		reg = <0x10001000 0x68>;
> > > > +		clock-parent = <&infracfg>;
> > > > +		#clock-cells = <1>;
> > > > +	};
> > > > +
> > > > +	infracfg: infracfg@10001040 {
> > > > +		compatible = "mediatek,mt7986-infracfg";
> > > > +		reg = <0x10001000 0x1000>;
> > > > +		clock-parent = <&topckgen>;
> > > > +		#clock-cells = <1>;
> > > > +	};
> > > > +
> > > > +	pinctrl: pinctrl@1001f000 {
> > > > +		compatible = "mediatek,mt7986-pinctrl";
> > > > +		reg = <0x1001f000 0x1000>,
> > > > +		      <0x11c30000 0x1000>,
> > > > +		      <0x11c40000 0x1000>,
> > > > +		      <0x11e20000 0x1000>,
> > > > +		      <0x11e30000 0x1000>,
> > > > +		      <0x11f00000 0x1000>,
> > > > +		      <0x11f10000 0x1000>,
> > > > +		      <0x1000b000 0x1000>;
> > > > +		reg-names = "gpio_base", "iocfg_rt_base",
> > > > "iocfg_rb_base",
> > > > +			    "iocfg_lt_base", "iocfg_lb_base",
> > > > "iocfg_tr_base",
> > > > +			    "iocfg_tl_base", "eint";
> > > > +		gpio: gpio-controller {
> > > > +			gpio-controller;
> > > > +			#gpio-cells = <2>;
> > > > +		};
> > > > +	};
> > > > +
> > > > +	pwm: pwm@10048000 {
> > > > +		compatible = "mediatek,mt7986-pwm";
> > > > +		reg = <0x10048000 0x1000>;
> > > > +		#clock-cells = <1>;
> > > > +		#pwm-cells = <2>;
> > > > +		interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
> > > > +		clocks = <&infracfg CK_INFRA_PWM>,
> > > > +			 <&infracfg_ao CK_INFRA_PWM_BSEL>,
> > > > +			 <&infracfg_ao CK_INFRA_PWM1_CK>,
> > > > +			 <&infracfg_ao CK_INFRA_PWM2_CK>;
> > > > +		assigned-clocks = <&topckgen CK_TOP_PWM_SEL>,
> > > > +				  <&infracfg CK_INFRA_PWM_BSEL>,
> > > > +				  <&infracfg CK_INFRA_PWM1_SEL>,
> > > > +				  <&infracfg CK_INFRA_PWM2_SEL>;
> > > > +		assigned-clock-parents = <&topckgen
> > > > CK_TOP_CB_M_D4>,
> > > > +					 <&infracfg
> > > > CK_INFRA_PWM>,
> > > > +					 <&infracfg
> > > > CK_INFRA_PWM>,
> > > > +					 <&infracfg
> > > > CK_INFRA_PWM>;
> > > > +		clock-names = "top", "main", "pwm1", "pwm2";
> > > > +		status = "disabled";
> > > > +		u-boot,dm-pre-reloc;
> > > > +	};
> > > > +
> > > > +	uart0: serial@11002000 {
> > > > +		compatible = "mediatek,hsuart";
> > > > +		reg = <0x11002000 0x400>;
> > > > +		interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
> > > > +		clocks = <&infracfg_ao CK_INFRA_UART0_CK>;
> > > > +		assigned-clocks = <&topckgen CK_TOP_UART_SEL>,
> > > > +				  <&infracfg_ao
> > > > CK_INFRA_UART0_SEL>;
> > > > +		assigned-clock-parents = <&topckgen
> > > > CK_TOP_CB_CKSQ_40M>,
> > > > +					 <&infracfg
> > > > CK_INFRA_UART>;
> > > > +		mediatek,force-highspeed;
> > > > +		status = "disabled";
> > > > +		u-boot,dm-pre-reloc;
> > > > +	};
> > > > +
> > > > +	uart1: serial@11003000 {
> > > > +		compatible = "mediatek,hsuart";
> > > > +		reg = <0x11003000 0x400>;
> > > > +		interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
> > > > +		clocks = <&infracfg_ao CK_INFRA_UART1_CK>;
> > > > +		assigned-clocks = <&infracfg
> > > > CK_INFRA_UART1_SEL>;
> > > > +		assigned-clock-parents = <&infracfg
> > > > CK_INFRA_CK_F26M>;
> > > > +		mediatek,force-highspeed;
> > > > +		status = "disabled";
> > > > +	};
> > > > +
> > > > +	uart2: serial@11004000 {
> > > > +		compatible = "mediatek,hsuart";
> > > > +		reg = <0x11004000 0x400>;
> > > > +		interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
> > > > +		clocks = <&infracfg_ao CK_INFRA_UART2_CK>;
> > > > +		assigned-clocks = <&infracfg
> > > > CK_INFRA_UART2_SEL>;
> > > > +		assigned-clock-parents = <&infracfg
> > > > CK_INFRA_CK_F26M>;
> > > > +		mediatek,force-highspeed;
> > > > +		status = "disabled";
> > > > +	};
> > > > +
> > > > +	snand: snand@11005000 {
> > > > +		compatible = "mediatek,mt7986-snand";
> > > > +		reg = <0x11005000 0x1000>,
> > > > +		      <0x11006000 0x1000>;
> > > > +		reg-names = "nfi", "ecc";
> > > > +		clocks = <&infracfg_ao CK_INFRA_SPINFI1_CK>,
> > > > +			 <&infracfg_ao CK_INFRA_NFI1_CK>,
> > > > +			 <&infracfg_ao CK_INFRA_NFI_HCK_CK>;
> > > > +		clock-names = "pad_clk", "nfi_clk", "nfi_hclk";
> > > > +		assigned-clocks = <&topckgen CK_TOP_SPINFI_SEL>,
> > > > +				  <&topckgen CK_TOP_NFI1X_SEL>;
> > > > +		assigned-clock-parents = <&topckgen
> > > > CK_TOP_CB_M_D8>,
> > > > +					 <&topckgen
> > > > CK_TOP_CB_M_D8>;
> > > > +		status = "disabled";
> > > > +	};
> > > > +
> > > > +	ethsys: syscon@15000000 {
> > > > +		compatible = "mediatek,mt7986-ethsys", "syscon";
> > > > +		reg = <0x15000000 0x1000>;
> > > > +		clock-parent = <&topckgen>;
> > > > +		#clock-cells = <1>;
> > > > +		#reset-cells = <1>;
> > > > +	};
> > > > +
> > > > +	eth: ethernet@15100000 {
> > > > +		compatible = "mediatek,mt7986-eth", "syscon";
> > > > +		reg = <0x15100000 0x20000>;
> > > > +		resets = <&ethsys ETHSYS_FE_RST>;
> > > > +		reset-names = "fe";
> > > > +		mediatek,ethsys = <&ethsys>;
> > > > +		mediatek,sgmiisys = <&sgmiisys0>;
> > > > +		#address-cells = <1>;
> > > > +		#size-cells = <0>;
> > > > +		status = "disabled";
> > > > +	};
> > > > +
> > > > +	sgmiisys0: syscon@10060000 {
> > > > +		compatible = "mediatek,mt7986-sgmiisys",
> > > > "syscon";
> > > > +		reg = <0x10060000 0x1000>;
> > > > +		#clock-cells = <1>;
> > > > +	};
> > > > +
> > > > +	sgmiisys1: syscon@10070000 {
> > > > +		compatible = "mediatek,mt7986-sgmiisys",
> > > > "syscon";
> > > > +		reg = <0x10070000 0x1000>;
> > > > +		#clock-cells = <1>;
> > > > +	};
> > > > +
> > > > +	spi0: spi@1100a000 {
> > > > +		compatible = "mediatek,ipm-spi";
> > > > +		reg = <0x1100a000 0x100>;
> > > > +		clocks = <&infracfg_ao CK_INFRA_SPI0_CK>,
> > > > +			 <&topckgen CK_TOP_SPI_SEL>;
> > > > +		assigned-clocks = <&topckgen CK_TOP_SPI_SEL>,
> > > > +				  <&infracfg CK_INFRA_SPI0_SEL>;
> > > > +		assigned-clock-parents = <&topckgen
> > > > CK_TOP_CB_M_D2>,
> > > > +					 <&topckgen
> > > > CK_INFRA_ISPI0>;
> > > > +		clock-names = "sel-clk", "spi-clk";
> > > > +		interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
> > > > +		status = "disabled";
> > > > +	};
> > > > +
> > > > +	spi1: spi@1100b000 {
> > > > +		compatible = "mediatek,ipm-spi";
> > > > +		reg = <0x1100b000 0x100>;
> > > > +		interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
> > > > +		status = "disabled";
> > > > +	};
> > > > +
> > > > +	mmc0: mmc@11230000 {
> > > > +		compatible = "mediatek,mt7986-mmc";
> > > > +		reg = <0x11230000 0x1000>,
> > > > +		      <0x11C20000 0x1000>;
> > > > +		interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
> > > > +		clocks = <&topckgen CK_TOP_EMMC_416M>,
> > > > +			<&topckgen CK_TOP_EMMC_250M>,
> > > > +			<&infracfg_ao CK_INFRA_MSDC_CK>;
> > > > +		assigned-clocks = <&topckgen
> > > > CK_TOP_EMMC_416M_SEL>,
> > > > +				  <&topckgen
> > > > CK_TOP_EMMC_250M_SEL>;
> > > > +		assigned-clock-parents = <&topckgen
> > > > CK_TOP_CB_M_416M>,
> > > > +					 <&topckgen
> > > > CK_TOP_NET1_D5_D2>;
> > > > +		clock-names = "source", "hclk", "source_cg";
> > > > +		status = "disabled";
> > > > +	};
> > > > +
> > > > +	xhci: xhci@11200000 {
> > > > +		compatible = "mediatek,mt7986-xhci",
> > > > +			     "mediatek,mtk-xhci";
> > > > +		reg = <0x11200000 0x2e00>,
> > > > +		      <0x11203e00 0x0100>;
> > > > +		reg-names = "mac", "ippc";
> > > > +		interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
> > > > +		phys = <&u2port0 PHY_TYPE_USB2>,
> > > > +		       <&u3port0 PHY_TYPE_USB3>,
> > > > +		       <&u2port1 PHY_TYPE_USB2>;
> > > > +		clocks = <&dummy_clk>,
> > > > +			 <&dummy_clk>,
> > > > +			 <&dummy_clk>,
> > > > +			 <&dummy_clk>,
> > > > +			 <&dummy_clk>;
> > > > +		clock-names = "sys_ck",
> > > > +			      "xhci_ck",
> > > > +			      "ref_ck",
> > > > +			      "mcu_ck",
> > > > +			      "dma_ck";
> > > > +		tpl-support;
> > > > +		status = "okay";
> > > > +	};
> > > > +
> > > > +	usbtphy: usb-phy@11e10000 {
> > > > +		compatible = "mediatek,mt7986",
> > > > +			     "mediatek,generic-tphy-v2";
> > > > +		#address-cells = <1>;
> > > > +		#size-cells = <1>;
> > > > +		status = "okay";
> > > > +
> > > > +		u2port0: usb-phy@11e10000 {
> > > > +			reg = <0x11e10000 0x700>;
> > > > +			clocks = <&dummy_clk>;
> > > > +			clock-names = "ref";
> > > > +			#phy-cells = <1>;
> > > > +			status = "okay";
> > > > +		};
> > > > +
> > > > +		u3port0: usb-phy@11e10700 {
> > > > +			reg = <0x11e10700 0x900>;
> > > > +			clocks = <&dummy_clk>;
> > > > +			clock-names = "ref";
> > > > +			#phy-cells = <1>;
> > > > +			status = "okay";
> > > > +		};
> > > > +
> > > > +		u2port1: usb-phy@11e11000 {
> > > > +			reg = <0x11e11000 0x700>;
> > > > +			clocks = <&dummy_clk>;
> > > > +			clock-names = "ref";
> > > > +			#phy-cells = <1>;
> > > > +			status = "okay";
> > > > +		};
> > > > +	};
> > > > +};
> > > > diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-
> > > > mediatek/Kconfig
> > > > index f79a5c62cd..e059a013db 100644
> > > > --- a/arch/arm/mach-mediatek/Kconfig
> > > > +++ b/arch/arm/mach-mediatek/Kconfig
> > > > @@ -40,6 +40,14 @@ config TARGET_MT7629
> > > >  	  including DDR3, crypto engine, 3x3 11n/ac Wi-Fi,
> > > > Gigabit
> > > > Ethernet,
> > > >  	  switch, USB3.0, PCIe, UART, SPI, I2C and PWM.
> > > >  
> > > > +config TARGET_MT7986
> > > > +	bool "MediaTek MT7986 SoC"
> > > > +	select ARM64
> > > > +	help
> > > > +	  The MediaTek MT7986 is a ARM64-based SoC with a quad-
> > > > core Cortex-A53.
> > > > +	  including UART, SPI, SPI flash, USB3.0, MMC, NAND,
> > > > SNFI,
> > > > PWM, PCIe,
> > > > +	  Gigabit Ethernet, I2C, built-in 4x4 Wi-Fi, and PCIe.
> > > > +
> > > >  config TARGET_MT8183
> > > >  	bool "MediaTek MT8183 SoC"
> > > >  	select ARM64
> > > > @@ -84,6 +92,7 @@ config SYS_BOARD
> > > >  	default "mt7622" if TARGET_MT7622
> > > >  	default "mt7623" if TARGET_MT7623
> > > >  	default "mt7629" if TARGET_MT7629
> > > > +	default "mt7986" if TARGET_MT7986
> > > >  	default "mt8183" if TARGET_MT8183
> > > >  	default "mt8512" if TARGET_MT8512
> > > >  	default "mt8516" if TARGET_MT8516
> > > > @@ -99,6 +108,7 @@ config SYS_CONFIG_NAME
> > > >  	default "mt7622" if TARGET_MT7622
> > > >  	default "mt7623" if TARGET_MT7623
> > > >  	default "mt7629" if TARGET_MT7629
> > > > +	default "mt7986" if TARGET_MT7986
> > > >  	default "mt8183" if TARGET_MT8183
> > > >  	default "mt8512" if TARGET_MT8512
> > > >  	default "mt8516" if TARGET_MT8516
> > > > @@ -113,6 +123,7 @@ config MTK_BROM_HEADER_INFO
> > > >  	string
> > > >  	default "media=nor" if TARGET_MT8518 || TARGET_MT8512 ||
> > > > TARGET_MT7629 ||
> > > >  TARGET_MT7622
> > > 
> > > Same here.
> > > 
> > > >  	default "media=emmc" if TARGET_MT8516 || TARGET_MT8365
> > > > ||
> > > > TARGET_MT8183
> > > > +	default "media=snand;nandinfo=2k+64" if TARGET_MT7986
> > > >  	default "lk=1" if TARGET_MT7623
> > > >  
> > > >  endif
> > > > diff --git a/arch/arm/mach-mediatek/Makefile
> > > >  b/arch/arm/mach-mediatek/Makefile
> > > 
> > > And here.
> > > 
> > > > index 0f5b0c16d2..fe5c3a837c 100644
> > > > --- a/arch/arm/mach-mediatek/Makefile
> > > > +++ b/arch/arm/mach-mediatek/Makefile
> > > > @@ -7,6 +7,7 @@ obj-$(CONFIG_MT8512) += mt8512/
> > > >  obj-$(CONFIG_TARGET_MT7622) += mt7622/
> > > >  obj-$(CONFIG_TARGET_MT7623) += mt7623/
> > > >  obj-$(CONFIG_TARGET_MT7629) += mt7629/
> > > > +obj-$(CONFIG_TARGET_MT7986) += mt7986/
> > > >  obj-$(CONFIG_TARGET_MT8183) += mt8183/
> > > >  obj-$(CONFIG_TARGET_MT8516) += mt8516/
> > > >  obj-$(CONFIG_TARGET_MT8518) += mt8518/
> > > > diff --git a/arch/arm/mach-mediatek/mt7986/Makefile
> > > >  b/arch/arm/mach-mediatek/mt7986/Makefile
> > > 
> > > And here.
> > > 
> > > > new file mode 100644
> > > > index 0000000000..007eb4a367
> > > > --- /dev/null
> > > > +++ b/arch/arm/mach-mediatek/mt7986/Makefile
> > > > @@ -0,0 +1,4 @@
> > > > +# SPDX-License-Identifier:	GPL-2.0
> > > > +
> > > > +obj-y += init.o
> > > > +obj-y += lowlevel_init.o
> > > > diff --git a/arch/arm/mach-mediatek/mt7986/init.c
> > > >  b/arch/arm/mach-mediatek/mt7986/init.c
> > > 
> > > And here again.
> > > 
> > > > new file mode 100644
> > > > index 0000000000..4884cbdc67
> > > > --- /dev/null
> > > > +++ b/arch/arm/mach-mediatek/mt7986/init.c
> > > > @@ -0,0 +1,53 @@
> > > > +// SPDX-License-Identifier: GPL-2.0
> > > > +/*
> > > > + * Copyright (C) 2022 MediaTek Inc.
> > > > + * Author: Sam Shih <sam.shih@mediatek.com>
> > > > + */
> > > > +
> > > > +#include <fdtdec.h>
> > > > +#include <asm/armv8/mmu.h>
> > > > +#include <init.h>
> > > > +#include <asm/system.h>
> > > > +#include <asm/global_data.h>
> > > > +#include <linux/sizes.h>
> > > > +
> > > > +DECLARE_GLOBAL_DATA_PTR;
> > > > +
> > > > +int print_cpuinfo(void)
> > > > +{
> > > > +	printf("CPU:   MediaTek MT7986\n");
> > > > +	return 0;
> > > > +}
> > > > +
> > > > +int dram_init(void)
> > > > +{
> > > > +	gd->ram_size = get_ram_size((void
> > > > *)CONFIG_SYS_SDRAM_BASE,
> > > > SZ_2G);
> > > > +
> > > > +	return 0;
> > > > +}
> > > > +
> > > > +void reset_cpu(ulong addr)
> > > > +{
> > > > +	psci_system_reset();
> > > > +}
> > > > +
> > > > +static struct mm_region mt7986_mem_map[] = {
> > > > +	{
> > > > +		/* DDR */
> > > > +		.virt = 0x40000000UL,
> > > > +		.phys = 0x40000000UL,
> > > > +		.size = 0x80000000UL,
> > > > +		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
> > > > PTE_BLOCK_OUTER_SHARE,
> > > > +	}, {
> > > > +		.virt = 0x00000000UL,
> > > > +		.phys = 0x00000000UL,
> > > > +		.size = 0x40000000UL,
> > > > +		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
> > > > +			 PTE_BLOCK_NON_SHARE |
> > > > +			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
> > > > +	}, {
> > > > +		0,
> > > > +	}
> > > > +};
> > > > +
> > > > +struct mm_region *mem_map = mt7986_mem_map;
> > > > diff --git a/arch/arm/mach-mediatek/mt7986/lowlevel_init.S
> > > >  b/arch/arm/mach-mediatek/mt7986/lowlevel_init.S
> > > 
> > > And here.
> > > 
> > > > new file mode 100644
> > > > index 0000000000..244d2c1385
> > > > --- /dev/null
> > > > +++ b/arch/arm/mach-mediatek/mt7986/lowlevel_init.S
> > > > @@ -0,0 +1,30 @@
> > > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > > +/*
> > > > + * Copyright (C) 2022 MediaTek Inc.
> > > > + * Author: Sam Shih <sam.shih@mediatek.com>
> > > > + */
> > > > +
> > > > +/*
> > > > + * Switch from AArch64 EL2 to AArch32 EL2
> > > > + * @param inputs:
> > > > + * x0: argument, zero
> > > > + * x1: machine nr
> > > > + * x2: fdt address
> > > > + * x3: input argument
> > > > + * x4: kernel entry point
> > > > + * @param outputs for secure firmware:
> > > > + * x0: function id
> > > > + * x1: kernel entry point
> > > > + * x2: machine nr
> > > > + * x3: fdt address
> > > > +*/
> > > > +
> > > > +.global armv8_el2_to_aarch32
> > > > +armv8_el2_to_aarch32:
> > > > +	mov     x3, x2
> > > > +	mov     x2, x1
> > > > +	mov     x1, x4
> > > > +	mov	x4, #0
> > > > +	ldr x0, =0x82000200
> > > > +	SMC #0
> > > > +	ret
> > > > -- 
> > > > 2.17.1
> > > > 

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 09/31] net: mediatek: add support for MediaTek MT7981/MT7986
  2022-08-04  3:35 ` [PATCH 09/31] net: mediatek: add support for MediaTek MT7981/MT7986 Weijie Gao
@ 2022-08-06 17:48   ` Ramon Fried
  0 siblings, 0 replies; 100+ messages in thread
From: Ramon Fried @ 2022-08-06 17:48 UTC (permalink / raw)
  To: Weijie Gao; +Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream, Joe Hershberger

On Thu, Aug 4, 2022 at 6:35 AM Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> This patch adds support for MediaTek MT7981 and MT7986. Both chips uses
> PDMA v2.
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  drivers/net/mtk_eth.c | 27 +++++++++++++++++++++++++++
>  drivers/net/mtk_eth.h |  5 +++++
>  2 files changed, 32 insertions(+)
>
> diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c
> index 47a4e698c0..7bff0b5b04 100644
> --- a/drivers/net/mtk_eth.c
> +++ b/drivers/net/mtk_eth.c
> @@ -106,6 +106,7 @@ struct mtk_eth_priv {
>         int force_mode;
>         int speed;
>         int duplex;
> +       bool pn_swap;
>
>         struct phy_device *phydev;
>         int phy_interface;
> @@ -1048,6 +1049,12 @@ static void mtk_sgmii_init(struct mtk_eth_priv *priv)
>         /* SGMII force mode setting */
>         writel(SGMII_FORCE_MODE, priv->sgmii_base + SGMSYS_SGMII_MODE);
>
> +       /* SGMII PN SWAP setting */
> +       if (priv->pn_swap) {
> +               setbits_le32(priv->sgmii_base + SGMSYS_QPHY_WRAP_CTRL,
> +                            SGMII_PN_SWAP_TX_RX);
> +       }
> +
>         /* Release PHYA power down state */
>         clrsetbits_le32(priv->sgmii_base + SGMSYS_QPHY_PWR_STATE_CTRL,
>                         SGMII_PHYA_PWD, 0);
> @@ -1461,6 +1468,8 @@ static int mtk_eth_of_to_plat(struct udevice *dev)
>                         dev_err(dev, "Unable to find sgmii\n");
>                         return -ENODEV;
>                 }
> +
> +               priv->pn_swap = ofnode_read_bool(args.node, "pn_swap");
>         }
>
>         /* check for switch first, otherwise phy will be used */
> @@ -1511,6 +1520,22 @@ static int mtk_eth_of_to_plat(struct udevice *dev)
>         return 0;
>  }
>
> +static const struct mtk_soc_data mt7986_data = {
> +       .caps = MT7986_CAPS,
> +       .ana_rgc3 = 0x128,
> +       .pdma_base = PDMA_V2_BASE,
> +       .txd_size = sizeof(struct mtk_tx_dma_v2),
> +       .rxd_size = sizeof(struct mtk_rx_dma_v2),
> +};
> +
> +static const struct mtk_soc_data mt7981_data = {
> +       .caps = MT7986_CAPS,
> +       .ana_rgc3 = 0x128,
> +       .pdma_base = PDMA_V2_BASE,
> +       .txd_size = sizeof(struct mtk_tx_dma_v2),
> +       .rxd_size = sizeof(struct mtk_rx_dma_v2),
> +};
> +
>  static const struct mtk_soc_data mt7629_data = {
>         .ana_rgc3 = 0x128,
>         .pdma_base = PDMA_V1_BASE,
> @@ -1540,6 +1565,8 @@ static const struct mtk_soc_data mt7621_data = {
>  };
>
>  static const struct udevice_id mtk_eth_ids[] = {
> +       { .compatible = "mediatek,mt7986-eth", .data = (ulong)&mt7986_data },
> +       { .compatible = "mediatek,mt7981-eth", .data = (ulong)&mt7981_data },
>         { .compatible = "mediatek,mt7629-eth", .data = (ulong)&mt7629_data },
>         { .compatible = "mediatek,mt7623-eth", .data = (ulong)&mt7623_data },
>         { .compatible = "mediatek,mt7622-eth", .data = (ulong)&mt7622_data },
> diff --git a/drivers/net/mtk_eth.h b/drivers/net/mtk_eth.h
> index 236c498a1b..1382ccbeb2 100644
> --- a/drivers/net/mtk_eth.h
> +++ b/drivers/net/mtk_eth.h
> @@ -36,6 +36,8 @@ enum mkt_eth_capabilities {
>
>  #define MT7623_CAPS  (MTK_GMAC1_TRGMII)
>
> +#define MT7986_CAPS  (MTK_NETSYS_V2)
> +
>  /* Frame Engine Register Bases */
>  #define PDMA_V1_BASE                   0x0800
>  #define PDMA_V2_BASE                   0x6000
> @@ -72,6 +74,9 @@ enum mkt_eth_capabilities {
>  #define SGMSYS_QPHY_PWR_STATE_CTRL     0xe8
>  #define SGMII_PHYA_PWD                 BIT(4)
>
> +#define SGMSYS_QPHY_WRAP_CTRL          0xec
> +#define SGMII_PN_SWAP_TX_RX            0x03
> +
>  #define SGMSYS_GEN2_SPEED              0x2028
>  #define SGMSYS_GEN2_SPEED_V2           0x128
>  #define SGMSYS_SPEED_2500              BIT(2)
> --
> 2.17.1
>
Reviewed-by: Ramon Fried <rfried.dev@gmail.com>

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 08/31] net: mediatek: add support for PDMA v2
  2022-08-04 13:56   ` Simon Glass
@ 2022-08-06 17:49     ` Ramon Fried
  0 siblings, 0 replies; 100+ messages in thread
From: Ramon Fried @ 2022-08-06 17:49 UTC (permalink / raw)
  To: Simon Glass
  Cc: Weijie Gao, U-Boot Mailing List, GSS_MTK_Uboot_upstream, Joe Hershberger

On Thu, Aug 4, 2022 at 4:57 PM Simon Glass <sjg@chromium.org> wrote:
>
> On Wed, 3 Aug 2022 at 21:36, Weijie Gao <weijie.gao@mediatek.com> wrote:
> >
> > This patch adds support for PDMA v2 hardware. The PDMA v2 has extended the
> > DMA descriptor to 8-words, and some of its fields have changed comparing
> > to the v1 hardware.
> >
> > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> > ---
> >  drivers/net/mtk_eth.c | 51 ++++++++++++++++++++++++++++++-----------
> >  drivers/net/mtk_eth.h | 53 ++++++++++++++++++++++++++++++++++++-------
> >  2 files changed, 83 insertions(+), 21 deletions(-)
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Ramon Fried <rfried.dev@gmail.com>

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 07/31] net: mediatek: stop using bitfileds for DMA descriptors
  2022-08-04  3:35 ` [PATCH 07/31] net: mediatek: stop using bitfileds for DMA descriptors Weijie Gao
  2022-08-04 13:56   ` Simon Glass
@ 2022-08-06 17:50   ` Ramon Fried
  2022-08-08  2:29     ` Weijie Gao
  1 sibling, 1 reply; 100+ messages in thread
From: Ramon Fried @ 2022-08-06 17:50 UTC (permalink / raw)
  To: Weijie Gao; +Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream, Joe Hershberger

On Thu, Aug 4, 2022 at 6:35 AM Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> This patch is a preparation for adding a new version of PDMA of which the
> DMA descriptor fields has changed. Using bitfields will result in a complex
> modification. Convert bitfields to u32 units can solve this problem easily.
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  drivers/net/mtk_eth.c | 144 ++++++++++++++----------------------------
>  drivers/net/mtk_eth.h |  32 ++++++++++
>  2 files changed, 80 insertions(+), 96 deletions(-)
>
> diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c
> index 92d2ea4f2a..bfa049cf79 100644
> --- a/drivers/net/mtk_eth.c
> +++ b/drivers/net/mtk_eth.c
> @@ -65,77 +65,6 @@
>         (DP_DISCARD << MC_DP_S) | \
>         (DP_DISCARD << UN_DP_S))
>
> -struct pdma_rxd_info1 {
> -       u32 PDP0;
> -};
> -
> -struct pdma_rxd_info2 {
> -       u32 PLEN1 : 14;
> -       u32 LS1 : 1;
> -       u32 UN_USED : 1;
> -       u32 PLEN0 : 14;
> -       u32 LS0 : 1;
> -       u32 DDONE : 1;
> -};
> -
> -struct pdma_rxd_info3 {
> -       u32 PDP1;
> -};
> -
> -struct pdma_rxd_info4 {
> -       u32 FOE_ENTRY : 14;
> -       u32 CRSN : 5;
> -       u32 SP : 3;
> -       u32 L4F : 1;
> -       u32 L4VLD : 1;
> -       u32 TACK : 1;
> -       u32 IP4F : 1;
> -       u32 IP4 : 1;
> -       u32 IP6 : 1;
> -       u32 UN_USED : 4;
> -};
> -
> -struct pdma_rxdesc {
> -       struct pdma_rxd_info1 rxd_info1;
> -       struct pdma_rxd_info2 rxd_info2;
> -       struct pdma_rxd_info3 rxd_info3;
> -       struct pdma_rxd_info4 rxd_info4;
> -};
> -
> -struct pdma_txd_info1 {
> -       u32 SDP0;
> -};
> -
> -struct pdma_txd_info2 {
> -       u32 SDL1 : 14;
> -       u32 LS1 : 1;
> -       u32 BURST : 1;
> -       u32 SDL0 : 14;
> -       u32 LS0 : 1;
> -       u32 DDONE : 1;
> -};
> -
> -struct pdma_txd_info3 {
> -       u32 SDP1;
> -};
> -
> -struct pdma_txd_info4 {
> -       u32 VLAN_TAG : 16;
> -       u32 INS : 1;
> -       u32 RESV : 2;
> -       u32 UDF : 6;
> -       u32 FPORT : 3;
> -       u32 TSO : 1;
> -       u32 TUI_CO : 3;
> -};
> -
> -struct pdma_txdesc {
> -       struct pdma_txd_info1 txd_info1;
> -       struct pdma_txd_info2 txd_info2;
> -       struct pdma_txd_info3 txd_info3;
> -       struct pdma_txd_info4 txd_info4;
> -};
> -
>  enum mtk_switch {
>         SW_NONE,
>         SW_MT7530,
> @@ -145,13 +74,15 @@ enum mtk_switch {
>  struct mtk_soc_data {
>         u32 caps;
>         u32 ana_rgc3;
> +       u32 txd_size;
> +       u32 rxd_size;
>  };
>
>  struct mtk_eth_priv {
>         char pkt_pool[TOTAL_PKT_BUF_SIZE] __aligned(ARCH_DMA_MINALIGN);
>
> -       struct pdma_txdesc *tx_ring_noc;
> -       struct pdma_rxdesc *rx_ring_noc;
> +       void *tx_ring_noc;
> +       void *rx_ring_noc;
>
>         int rx_dma_owner_idx0;
>         int tx_cpu_owner_idx0;
> @@ -1196,14 +1127,16 @@ static void mtk_mac_init(struct mtk_eth_priv *priv)
>  static void mtk_eth_fifo_init(struct mtk_eth_priv *priv)
>  {
>         char *pkt_base = priv->pkt_pool;
> +       struct mtk_tx_dma *txd;
> +       struct mtk_rx_dma *rxd;
>         int i;
>
>         mtk_pdma_rmw(priv, PDMA_GLO_CFG_REG, 0xffff0000, 0);
>         udelay(500);
>
> -       memset(priv->tx_ring_noc, 0, NUM_TX_DESC * sizeof(struct pdma_txdesc));
> -       memset(priv->rx_ring_noc, 0, NUM_RX_DESC * sizeof(struct pdma_rxdesc));
> -       memset(priv->pkt_pool, 0, TOTAL_PKT_BUF_SIZE);
> +       memset(priv->tx_ring_noc, 0, NUM_TX_DESC * priv->soc->txd_size);
> +       memset(priv->rx_ring_noc, 0, NUM_RX_DESC * priv->soc->rxd_size);
> +       memset(priv->pkt_pool, 0xff, TOTAL_PKT_BUF_SIZE);
>
>         flush_dcache_range((ulong)pkt_base,
>                            (ulong)(pkt_base + TOTAL_PKT_BUF_SIZE));
> @@ -1212,17 +1145,21 @@ static void mtk_eth_fifo_init(struct mtk_eth_priv
>  *priv)
>         priv->tx_cpu_owner_idx0 = 0;
>
>         for (i = 0; i < NUM_TX_DESC; i++) {
> -               priv->tx_ring_noc[i].txd_info2.LS0 = 1;
> -               priv->tx_ring_noc[i].txd_info2.DDONE = 1;
> -               priv->tx_ring_noc[i].txd_info4.FPORT = priv->gmac_id + 1;
> +               txd = priv->tx_ring_noc + i * priv->soc->txd_size;
> +
> +               txd->txd1 = virt_to_phys(pkt_base);
> +               txd->txd2 = PDMA_TXD2_DDONE | PDMA_TXD2_LS0;
> +               txd->txd4 = PDMA_TXD4_FPORT_SET(priv->gmac_id + 1);
>
> -               priv->tx_ring_noc[i].txd_info1.SDP0 = virt_to_phys(pkt_base);
>                 pkt_base += PKTSIZE_ALIGN;
>         }
>
>         for (i = 0; i < NUM_RX_DESC; i++) {
> -               priv->rx_ring_noc[i].rxd_info2.PLEN0 = PKTSIZE_ALIGN;
> -               priv->rx_ring_noc[i].rxd_info1.PDP0 = virt_to_phys(pkt_base);
> +               rxd = priv->rx_ring_noc + i * priv->soc->rxd_size;
> +
> +               rxd->rxd1 = virt_to_phys(pkt_base);
> +               rxd->rxd2 = PDMA_RXD2_PLEN0_SET(PKTSIZE_ALIGN);
> +
>                 pkt_base += PKTSIZE_ALIGN;
>         }
>
> @@ -1309,20 +1246,22 @@ static int mtk_eth_send(struct udevice *dev, void
>  *packet, int length)
>  {
>         struct mtk_eth_priv *priv = dev_get_priv(dev);
>         u32 idx = priv->tx_cpu_owner_idx0;
> +       struct mtk_tx_dma *txd;
>         void *pkt_base;
>
> -       if (!priv->tx_ring_noc[idx].txd_info2.DDONE) {
> +       txd = priv->tx_ring_noc + idx * priv->soc->txd_size;
> +
> +       if (!(txd->txd2 & PDMA_TXD2_DDONE)) {
>                 debug("mtk-eth: TX DMA descriptor ring is full\n");
>                 return -EPERM;
>         }
>
> -       pkt_base = (void *)phys_to_virt(priv->tx_ring_noc[idx].txd_info1.SDP0);
> +       pkt_base = (void *)phys_to_virt(txd->txd1);
>         memcpy(pkt_base, packet, length);
>         flush_dcache_range((ulong)pkt_base, (ulong)pkt_base +
>                            roundup(length, ARCH_DMA_MINALIGN));
>
> -       priv->tx_ring_noc[idx].txd_info2.SDL0 = length;
> -       priv->tx_ring_noc[idx].txd_info2.DDONE = 0;
> +       txd->txd2 = PDMA_TXD2_LS0 | PDMA_TXD2_SDL0_SET(length);
>
>         priv->tx_cpu_owner_idx0 = (priv->tx_cpu_owner_idx0 + 1) % NUM_TX_DESC;
>         mtk_pdma_write(priv, TX_CTX_IDX_REG(0), priv->tx_cpu_owner_idx0);
> @@ -1334,16 +1273,20 @@ static int mtk_eth_recv(struct udevice *dev, int
>  flags, uchar **packetp)
>  {
>         struct mtk_eth_priv *priv = dev_get_priv(dev);
>         u32 idx = priv->rx_dma_owner_idx0;
> +       struct mtk_rx_dma *rxd;
>         uchar *pkt_base;
>         u32 length;
>
> -       if (!priv->rx_ring_noc[idx].rxd_info2.DDONE) {
> +       rxd = priv->rx_ring_noc + idx * priv->soc->rxd_size;
> +
> +       if (!(rxd->rxd2 & PDMA_RXD2_DDONE)) {
>                 debug("mtk-eth: RX DMA descriptor ring is empty\n");
>                 return -EAGAIN;
>         }
>
> -       length = priv->rx_ring_noc[idx].rxd_info2.PLEN0;
> -       pkt_base = (void *)phys_to_virt(priv->rx_ring_noc[idx].rxd_info1.PDP0);
> +       length = PDMA_RXD2_PLEN0_GET(rxd->rxd2);
> +
> +       pkt_base = (void *)phys_to_virt(rxd->rxd1);
>         invalidate_dcache_range((ulong)pkt_base, (ulong)pkt_base +
>                                 roundup(length, ARCH_DMA_MINALIGN));
>
> @@ -1357,10 +1300,11 @@ static int mtk_eth_free_pkt(struct udevice *dev,
>  uchar *packet, int length)
>  {
>         struct mtk_eth_priv *priv = dev_get_priv(dev);
>         u32 idx = priv->rx_dma_owner_idx0;
> +       struct mtk_rx_dma *rxd;
> +
> +       rxd = priv->rx_ring_noc + idx * priv->soc->rxd_size;
>
> -       priv->rx_ring_noc[idx].rxd_info2.DDONE = 0;
> -       priv->rx_ring_noc[idx].rxd_info2.LS0 = 0;
> -       priv->rx_ring_noc[idx].rxd_info2.PLEN0 = PKTSIZE_ALIGN;
> +       rxd->rxd2 = PDMA_RXD2_PLEN0_SET(PKTSIZE_ALIGN);
>
>         mtk_pdma_write(priv, RX_CRX_IDX_REG(0), idx);
>         priv->rx_dma_owner_idx0 = (priv->rx_dma_owner_idx0 + 1) % NUM_RX_DESC;
> @@ -1387,11 +1331,11 @@ static int mtk_eth_probe(struct udevice *dev)
>                 return ret;
>
>         /* Prepare for tx/rx rings */
> -       priv->tx_ring_noc = (struct pdma_txdesc *)
> -               noncached_alloc(sizeof(struct pdma_txdesc) * NUM_TX_DESC,
> +       priv->tx_ring_noc = (void *)
> +               noncached_alloc(priv->soc->txd_size * NUM_TX_DESC,
>                                 ARCH_DMA_MINALIGN);
> -       priv->rx_ring_noc = (struct pdma_rxdesc *)
> -               noncached_alloc(sizeof(struct pdma_rxdesc) * NUM_RX_DESC,
> +       priv->rx_ring_noc = (void *)
> +               noncached_alloc(priv->soc->rxd_size * NUM_RX_DESC,
>                                 ARCH_DMA_MINALIGN);
>
>         /* Set MAC mode */
> @@ -1548,18 +1492,26 @@ static int mtk_eth_of_to_plat(struct udevice *dev)
>
>  static const struct mtk_soc_data mt7629_data = {
>         .ana_rgc3 = 0x128,
> +       .txd_size = sizeof(struct mtk_tx_dma),
> +       .rxd_size = sizeof(struct mtk_rx_dma),
>  };
>
>  static const struct mtk_soc_data mt7623_data = {
>         .caps = MT7623_CAPS,
> +       .txd_size = sizeof(struct mtk_tx_dma),
> +       .rxd_size = sizeof(struct mtk_rx_dma),
>  };
>
>  static const struct mtk_soc_data mt7622_data = {
>         .ana_rgc3 = 0x2028,
> +       .txd_size = sizeof(struct mtk_tx_dma),
> +       .rxd_size = sizeof(struct mtk_rx_dma),
>  };
>
>  static const struct mtk_soc_data mt7621_data = {
>         .caps = MT7621_CAPS,
> +       .txd_size = sizeof(struct mtk_tx_dma),
> +       .rxd_size = sizeof(struct mtk_rx_dma),
>  };
>
>  static const struct udevice_id mtk_eth_ids[] = {
> diff --git a/drivers/net/mtk_eth.h b/drivers/net/mtk_eth.h
> index 15c2030617..65bc9fcc04 100644
> --- a/drivers/net/mtk_eth.h
> +++ b/drivers/net/mtk_eth.h
> @@ -10,6 +10,7 @@
>  #define _MTK_ETH_H_
>
>  #include <linux/bitops.h>
> +#include <linux/bitfield.h>
>
>  enum mkt_eth_capabilities {
>         MTK_TRGMII_BIT,
> @@ -435,4 +436,35 @@ enum mkt_eth_capabilities {
>  #define PHY_POWER_SAVING_M             0x300
>  #define PHY_POWER_SAVING_TX            0x0
>
> +/* PDMA descriptors */
> +struct mtk_rx_dma {
> +       unsigned int rxd1;
> +       unsigned int rxd2;
> +       unsigned int rxd3;
> +       unsigned int rxd4;
> +} __packed __aligned(4);
> +
> +struct mtk_tx_dma {
> +       unsigned int txd1;
> +       unsigned int txd2;
> +       unsigned int txd3;
> +       unsigned int txd4;
> +} __packed __aligned(4);
> +
> +/* PDMA TXD fields */
> +#define PDMA_TXD2_DDONE                        BIT(31)
> +#define PDMA_TXD2_LS0                  BIT(30)
> +#define PDMA_TXD2_SDL0_M               GENMASK(29, 16)
> +#define PDMA_TXD2_SDL0_SET(_v) FIELD_PREP(PDMA_TXD2_SDL0_M, (_v))
> +
> +#define PDMA_TXD4_FPORT_M              GENMASK(27, 25)
> +#define PDMA_TXD4_FPORT_SET(_v)        FIELD_PREP(PDMA_TXD4_FPORT_M, (_v))
> +
> +/* PDMA RXD fields */
> +#define PDMA_RXD2_DDONE                        BIT(31)
> +#define PDMA_RXD2_LS0                  BIT(30)
> +#define PDMA_RXD2_PLEN0_M              GENMASK(29, 16)
> +#define PDMA_RXD2_PLEN0_GET(_v)        FIELD_GET(PDMA_RXD2_PLEN0_M, (_v))
> +#define PDMA_RXD2_PLEN0_SET(_v)        FIELD_PREP(PDMA_RXD2_PLEN0_M, (_v))
> +
>  #endif /* _MTK_ETH_H_ */
> --
> 2.17.1
>
Commit topic has typo in fields

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 01/31] arm: mediatek: add support for MediaTek MT7986 SoC
  2022-08-06 16:09         ` Daniel Golle
@ 2022-08-08  1:37           ` Weijie Gao
  0 siblings, 0 replies; 100+ messages in thread
From: Weijie Gao @ 2022-08-08  1:37 UTC (permalink / raw)
  To: Daniel Golle; +Cc: u-boot, GSS_MTK_Uboot_upstream

Hi Daniel,

There is a design change between MT7986(and later chips) and MT7622:

The bootrom of MT7622 requires the device header offset be set to the
absolute address of the BL2 in the flash device. For SPI-NOR/SPI-NAND
and eMMC, the offset is always zero. But for SD devices, BL2 is stored
in the first active MBR partition which apparently has non-zero offset.

So in platform.mk from mt7622, there's one line for sd-booting:
DEVICE_HEADER_OFFSET	?=	0x80000
and the corresponding commandline for mkimage:
hdroffset=$(DEVICE_HEADER_OFFSET)

However, since MT7986, the bootrom requires the device header offset
be set to the relative offset of the BL2 in its partition. For
SPI-NOR/SPI-NAND and eMMC, the offset is still zero. For SD devices,
BL2 is stored in the first bootable GPT partition, and its offset
related to the partition is also zero.

So the following line in platform.mk from mt7986 must be removed:
DEVICE_HEADER_OFFSET	?=	0x4400
and the following mkimage commandline must also be removed:
hdroffset=$(DEVICE_HEADER_OFFSET)

BTW, I don't know the exact version of atf you're using. I'll upload
new atf to github with all boot device tested, including spi-nor.

Best Regards,

Weijie

On Sat, 2022-08-06 at 18:09 +0200, Daniel Golle wrote:
> Hi Weijie,
> 
> I manually fixed the last 3 patches in the series adding support for
> newer SoCs to mkimage/mtk_image.
> 
> On my BPi-R3 (mt7986a) I was now trying to use mkimage instead of
> bromimage in the same way you introduced that option for mt7622[1]:
> 
> The resulting bl2.img works fine on SPI-NAND and eMMC, however,
> booting from SPI-NOR or SD card doesn't work.
> 
> On SPI-NOR:
> F0: 102B 0000
> FA: 0000 0000
> V0: 7027 6006 [0001]
> 00: 1017 0000
> FA: 5100 0000
> 01: 102A 0001
> 02: 5100 0000
> BP: 2000 00C0 [0001]
> EC: 0000 0000 [0000]
> T0: 0000 0213 [010F]
> System halt!
> 
> On SD card:
> F0: 102B 0000
> FA: 1040 0000
> FA: 1040 0000 [0200]
> F9: 103F 0000
> F3: 1001 0000 [0200]
> F3: 1001 0000
> F6: 300C 0028
> F5: 0000 0000
> L0: 8005 0000 [0001]
> 00: 1012 0000
> BP: 2000 00C0 [0001]
> EC: 0000 0000 [3000]
> T0: 0000 00E8 [010F]
> System halt!
> 
> All generate image headers also differ from the ones generated by
> bromimage, however, for SPI-NAND and eMMC they still work.
> 
> hexdiff of SD card bl2.img
> @@ -65,7 +65,7 @@
>  00004420  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff
> ff  |................|
>  *
>  00004600  42 52 4c 59 54 00 00 00  01 00 00 00 00 4a 00
> 00  |BRLYT........J..|
> -00004610  88 51 03 00 42 42 42 42  08 00 01 00 00 06 00
> 00  |.Q..BBBB........|
> +00004610  88 51 03 00 42 42 42 42  08 00 01 00 00 4a 00
> 00  |.Q..BBBB.....J..|
>  00004620  88 51 03 00 ff ff ff ff  ff ff ff ff ff ff ff
> ff  |.Q..............|
>  00004630  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff
> ff  |................|
>  *
> @@ -73,15 +73,15 @@
>  00004a10  4f 00 00 00 01 00 00 00  01 00 05 01 00 0d 20
> 00  |O............. .|
>  00004a20  88 07 03 00 88 0d 03 00  00 03 00 00 20 00 00
> 00  |............ ...|
>  00004a30  00 03 00 00 01 00 00 00  4d 4d 4d 01 0c 00 01
> 00  |........MMM.....|
> -00004a40  01 00 00 00 4d 4d 4d 01  14 00 02 00 00 00 00
> 00  |....MMM.........|
> -00004a50  10 00 00 00 80 00 00 00  4d 4d 4d 01 14 02 03
> 00  |........MMM.....|
> -00004a60  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00
> 00  |................|
> -*
> -00004c60  00 00 00 00 00 00 00 00  00 00 00 00 4d 4d 4d
> 03  |............MMM.|
> -00004c70  64 00 07 00 90 11 00 00  00 00 00 00 00 00 00
> 00  |d...............|
> -00004c80  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00
> 00  |................|
> +00004a40  01 00 00 00 4d 4d 4d 03  64 00 07 00 90 11 00
> 00  |....MMM.d.......|
> +00004a50  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00
> 00  |................|
>  *
> -00004cc0  00 64 00 00 88 13 00 00  00 00 00 00 00 00 00
> 00  |.d..............|
> +00004a90  00 00 00 00 00 00 00 00  00 64 00 00 88 13 00
> 00  |.........d......|
> +00004aa0  00 00 00 00 00 00 00 00  4d 4d 4d 01 14 02 03
> 00  |........MMM.....|
> +00004ab0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00
> 00  |................|
> +*
> +00004cb0  00 00 00 00 00 00 00 00  00 00 00 00 4d 4d 4d
> 01  |............MMM.|
> +00004cc0  14 00 02 00 00 00 00 00  10 00 00 00 80 00 00
> 00  |................|
>  00004cd0  4d 4d 4d 01 30 00 08 00  03 00 00 00 00 00 00
> 00  |MMM.0...........|
>  00004ce0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00
> 00  |................|
>  *
> 
> hexdiff of SPI-NOR bl2.img
> @@ -11,15 +11,15 @@
>  00000610  4f 00 00 00 01 00 00 00  01 00 05 01 00 0d 20
> 00  |O............. .|
>  00000620  70 0a 03 00 70 10 03 00  00 03 00 00 20 00 00
> 00  |p...p....... ...|
>  00000630  00 03 00 00 01 00 00 00  4d 4d 4d 01 0c 00 01
> 00  |........MMM.....|
> -00000640  01 00 00 00 4d 4d 4d 03  64 00 07 00 90 11 00
> 00  |....MMM.d.......|
> -00000650  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00
> 00  |................|
> +00000640  01 00 00 00 4d 4d 4d 01  14 00 02 00 00 00 00
> 00  |....MMM.........|
> +00000650  10 00 00 00 80 00 00 00  4d 4d 4d 01 14 02 03
> 00  |........MMM.....|
> +00000660  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00
> 00  |................|
>  *
> -00000690  00 00 00 00 00 00 00 00  00 64 00 00 88 13 00
> 00  |.........d......|
> -000006a0  00 00 00 00 00 00 00 00  4d 4d 4d 01 14 02 03
> 00  |........MMM.....|
> -000006b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00
> 00  |................|
> +00000860  00 00 00 00 00 00 00 00  00 00 00 00 4d 4d 4d
> 03  |............MMM.|
> +00000870  64 00 07 00 90 11 00 00  00 00 00 00 00 00 00
> 00  |d...............|
> +00000880  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00
> 00  |................|
>  *
> -000008b0  00 00 00 00 00 00 00 00  00 00 00 00 4d 4d 4d
> 01  |............MMM.|
> -000008c0  14 00 02 00 00 00 00 00  10 00 00 00 80 00 00
> 00  |................|
> +000008c0  00 64 00 00 88 13 00 00  00 00 00 00 00 00 00
> 00  |.d..............|
>  000008d0  4d 4d 4d 01 30 00 08 00  03 00 00 00 00 00 00
> 00  |MMM.0...........|
>  000008e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00
> 00  |................|
>  *
> 
> I'll try to have a look at this more deepply in the next days, but if
> you already spot the error I'd also be glad ;)
> 
> 
> Cheers
> 
> 
> Daniel
> 
> 
> [1]: https://urldefense.com/v3/__https://github.com/dangowrt/arm-trus
> ted-
> firmware/commit/3b8a17bd847d864379fe9953a82991b522f64add__;!!CTRNKA9w
> Mg0ARbw!ybxbFXd18o_0NK-
> 33rzQvf0llAa6qqjA78WFMYoGoSAQ7S5t5wgDu6RHzvV2Id4F6w$ 
> 
> 
> On Fri, Aug 05, 2022 at 04:43:39PM +0800, Weijie Gao wrote:
> > Hi Daniel,
> > 
> > It turns out that this was caused by a setting change of company's
> > mail
> > gateway.
> > I'll send v2 later.
> > 
> > Best Regards,
> > 
> > Weijie
> > 
> > On Thu, 2022-08-04 at 16:50 +0800, Weijie Gao wrote:
> > > Hi Daniel,
> > > 
> > > Thanks for the reminder.
> > > I found more errornous line-breaks in other patches...
> > > I'll find a way to fix that.
> > > 
> > > Best Regards,
> > > Weijie
> > > 
> > > On Thu, 2022-08-04 at 10:37 +0200, Daniel Golle wrote:
> > > > Hi Weijie,
> > > > 
> > > > happy to see this series posted!
> > > > Trying to apply it unfortunately fails due to errornous line-
> > > > breaks,
> > > > supposedly inserted by your MUA, see below.
> > > > 
> > > > I didn't go beyond the first patch and it'd be nice if you
> > > > report
> > > > the
> > > > whole series without the wrong line-breaks.
> > > > 
> > > > Cheers
> > > > 
> > > > 
> > > > Daniel
> > > > 
> > > > 
> > > > On Thu, Aug 04, 2022 at 11:34:28AM +0800, Weijie Gao wrote:
> > > > > This patch adds basic support for MediaTek MT7986 SoC.
> > > > > This include the file that will initialize the SoC after boot
> > > > > and
> > > > > its
> > > > > device tree.
> > > > > 
> > > > > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> > > > > ---
> > > > >  arch/arm/dts/mt7986-u-boot.dtsi               |  33 ++
> > > > >  arch/arm/dts/mt7986.dtsi                      | 341
> > > > > ++++++++++++++++++
> > > > >  arch/arm/mach-mediatek/Kconfig                |  11 +
> > > > >  arch/arm/mach-mediatek/Makefile               |   1 +
> > > > >  arch/arm/mach-mediatek/mt7986/Makefile        |   4 +
> > > > >  arch/arm/mach-mediatek/mt7986/init.c          |  53 +++
> > > > >  arch/arm/mach-mediatek/mt7986/lowlevel_init.S |  30 ++
> > > > >  7 files changed, 473 insertions(+)
> > > > >  create mode 100644 arch/arm/dts/mt7986-u-boot.dtsi
> > > > >  create mode 100644 arch/arm/dts/mt7986.dtsi
> > > > >  create mode 100644 arch/arm/mach-mediatek/mt7986/Makefile
> > > > >  create mode 100644 arch/arm/mach-mediatek/mt7986/init.c
> > > > >  create mode 100644 arch/arm/mach-
> > > > > mediatek/mt7986/lowlevel_init.S
> > > > > 
> > > > > diff --git a/arch/arm/dts/mt7986-u-boot.dtsi
> > > > >  b/arch/arm/dts/mt7986-u-boot.dtsi
> > > > 
> > > > The above two lines should be a single line.
> > > > 
> > > > > new file mode 100644
> > > > > index 0000000000..95671f8afa
> > > > > --- /dev/null
> > > > > +++ b/arch/arm/dts/mt7986-u-boot.dtsi
> > > > > @@ -0,0 +1,33 @@
> > > > > +// SPDX-License-Identifier: GPL-2.0
> > > > > +/*
> > > > > + * Copyright (c) 2022 MediaTek Inc.
> > > > > + * Author: Sam Shih <sam.shih@mediatek.com>
> > > > > + */
> > > > > +
> > > > > +&topckgen {
> > > > > +	u-boot,dm-pre-reloc;
> > > > > +};
> > > > > +
> > > > > +&pericfg {
> > > > > +	u-boot,dm-pre-reloc;
> > > > > +};
> > > > > +
> > > > > +&apmixedsys {
> > > > > +	u-boot,dm-pre-reloc;
> > > > > +};
> > > > > +
> > > > > +&timer0 {
> > > > > +	u-boot,dm-pre-reloc;
> > > > > +};
> > > > > +
> > > > > +&uart0 {
> > > > > +	u-boot,dm-pre-reloc;
> > > > > +};
> > > > > +
> > > > > +&snand {
> > > > > +	u-boot,dm-pre-reloc;
> > > > > +};
> > > > > +
> > > > > +&pinctrl {
> > > > > +	u-boot,dm-pre-reloc;
> > > > > +};
> > > > > diff --git a/arch/arm/dts/mt7986.dtsi
> > > > > b/arch/arm/dts/mt7986.dtsi
> > > > > new file mode 100644
> > > > > index 0000000000..f235bd8b8c
> > > > > --- /dev/null
> > > > > +++ b/arch/arm/dts/mt7986.dtsi
> > > > > @@ -0,0 +1,341 @@
> > > > > +// SPDX-License-Identifier: GPL-2.0
> > > > > +/*
> > > > > + * Copyright (c) 2022 MediaTek Inc.
> > > > > + * Author: Sam Shih <sam.shih@mediatek.com>
> > > > > + */
> > > > > +
> > > > > +#include <dt-bindings/interrupt-controller/irq.h>
> > > > > +#include <dt-bindings/interrupt-controller/arm-gic.h>
> > > > > +#include <dt-bindings/phy/phy.h>
> > > > > +#include <dt-bindings/clock/mt7986-clk.h>
> > > > > +#include <dt-bindings/reset/mt7629-reset.h>
> > > > > +#include <dt-bindings/pinctrl/mt65xx.h>
> > > > > +
> > > > > +/ {
> > > > > +	compatible = "mediatek,mt7986";
> > > > > +	interrupt-parent = <&gic>;
> > > > > +	#address-cells = <1>;
> > > > > +	#size-cells = <1>;
> > > > > +
> > > > > +	config {
> > > > > +		u-boot,mmc-env-partition = "u-boot-env";
> > > > > +	};
> > > > > +
> > > > > +	cpus {
> > > > > +		#address-cells = <1>;
> > > > > +		#size-cells = <0>;
> > > > > +		cpu0: cpu@0 {
> > > > > +			device_type = "cpu";
> > > > > +			compatible = "arm,cortex-a53";
> > > > > +			reg = <0x0>;
> > > > > +		};
> > > > > +		cpu1: cpu@1 {
> > > > > +			device_type = "cpu";
> > > > > +			compatible = "arm,cortex-a53";
> > > > > +			reg = <0x1>;
> > > > > +		};
> > > > > +		cpu2: cpu@2 {
> > > > > +			device_type = "cpu";
> > > > > +			compatible = "arm,cortex-a53";
> > > > > +			reg = <0x1>;
> > > > > +		};
> > > > > +		cpu3: cpu@3 {
> > > > > +			device_type = "cpu";
> > > > > +			compatible = "arm,cortex-a53";
> > > > > +			reg = <0x1>;
> > > > > +		};
> > > > > +	};
> > > > > +
> > > > > +	dummy_clk: dummy12m {
> > > > > +		compatible = "fixed-clock";
> > > > > +		clock-frequency = <12000000>;
> > > > > +		#clock-cells = <0>;
> > > > > +		/* must need this line, or uart uanable to
> > > > > get
> > > > > dummy_clk */
> > > > > +		u-boot,dm-pre-reloc;
> > > > > +	};
> > > > > +
> > > > > +	timer {
> > > > > +		compatible = "arm,armv8-timer";
> > > > > +		interrupt-parent = <&gic>;
> > > > > +		clock-frequency = <13000000>;
> > > > > +		interrupts = <GIC_PPI 13
> > > > > IRQ_TYPE_LEVEL_LOW>,
> > > > > +			     <GIC_PPI 14
> > > > > IRQ_TYPE_LEVEL_LOW>,
> > > > > +			     <GIC_PPI 11
> > > > > IRQ_TYPE_LEVEL_LOW>,
> > > > > +			     <GIC_PPI 10
> > > > > IRQ_TYPE_LEVEL_LOW>;
> > > > > +		arm,cpu-registers-not-fw-configured;
> > > > > +	};
> > > > > +
> > > > > +	timer0: timer@10008000 {
> > > > > +		compatible = "mediatek,mt7986-timer";
> > > > > +		reg = <0x10008000 0x1000>;
> > > > > +		interrupts = <GIC_SPI 130
> > > > > IRQ_TYPE_LEVEL_HIGH>;
> > > > > +		clocks = <&infracfg CK_INFRA_CK_F26M>;
> > > > > +		clock-names = "gpt-clk";
> > > > > +		u-boot,dm-pre-reloc;
> > > > > +	};
> > > > > +
> > > > > +	watchdog: watchdog@1001c000 {
> > > > > +		compatible = "mediatek,mt7986-wdt";
> > > > > +		reg = <0x1001c000 0x1000>;
> > > > > +		interrupts = <GIC_SPI 110
> > > > > IRQ_TYPE_LEVEL_HIGH>;
> > > > > +		#reset-cells = <1>;
> > > > > +		status = "disabled";
> > > > > +	};
> > > > > +
> > > > > +	gic: interrupt-controller@c000000 {
> > > > > +		compatible = "arm,gic-v3";
> > > > > +		#interrupt-cells = <3>;
> > > > > +		interrupt-parent = <&gic>;
> > > > > +		interrupt-controller;
> > > > > +		reg = <0x0c000000 0x40000>,  /* GICD */
> > > > > +		      <0x0c080000 0x200000>; /* GICR */
> > > > > +
> > > > > +		interrupts = <GIC_PPI 9
> > > > > IRQ_TYPE_LEVEL_HIGH>;
> > > > > +	};
> > > > > +
> > > > > +	fixed_plls: apmixedsys@1001E000 {
> > > > > +		compatible = "mediatek,mt7986-fixed-plls";
> > > > > +		reg = <0x1001E000 0x1000>;
> > > > > +		#clock-cells = <1>;
> > > > > +	};
> > > > > +
> > > > > +	topckgen: topckgen@1001B000 {
> > > > > +		compatible = "mediatek,mt7986-topckgen";
> > > > > +		reg = <0x1001B000 0x1000>;
> > > > > +		clock-parent = <&fixed_plls>;
> > > > > +		#clock-cells = <1>;
> > > > > +	};
> > > > > +
> > > > > +	infracfg_ao: infracfg_ao@10001000 {
> > > > > +		compatible = "mediatek,mt7986-infracfg_ao";
> > > > > +		reg = <0x10001000 0x68>;
> > > > > +		clock-parent = <&infracfg>;
> > > > > +		#clock-cells = <1>;
> > > > > +	};
> > > > > +
> > > > > +	infracfg: infracfg@10001040 {
> > > > > +		compatible = "mediatek,mt7986-infracfg";
> > > > > +		reg = <0x10001000 0x1000>;
> > > > > +		clock-parent = <&topckgen>;
> > > > > +		#clock-cells = <1>;
> > > > > +	};
> > > > > +
> > > > > +	pinctrl: pinctrl@1001f000 {
> > > > > +		compatible = "mediatek,mt7986-pinctrl";
> > > > > +		reg = <0x1001f000 0x1000>,
> > > > > +		      <0x11c30000 0x1000>,
> > > > > +		      <0x11c40000 0x1000>,
> > > > > +		      <0x11e20000 0x1000>,
> > > > > +		      <0x11e30000 0x1000>,
> > > > > +		      <0x11f00000 0x1000>,
> > > > > +		      <0x11f10000 0x1000>,
> > > > > +		      <0x1000b000 0x1000>;
> > > > > +		reg-names = "gpio_base", "iocfg_rt_base",
> > > > > "iocfg_rb_base",
> > > > > +			    "iocfg_lt_base",
> > > > > "iocfg_lb_base",
> > > > > "iocfg_tr_base",
> > > > > +			    "iocfg_tl_base", "eint";
> > > > > +		gpio: gpio-controller {
> > > > > +			gpio-controller;
> > > > > +			#gpio-cells = <2>;
> > > > > +		};
> > > > > +	};
> > > > > +
> > > > > +	pwm: pwm@10048000 {
> > > > > +		compatible = "mediatek,mt7986-pwm";
> > > > > +		reg = <0x10048000 0x1000>;
> > > > > +		#clock-cells = <1>;
> > > > > +		#pwm-cells = <2>;
> > > > > +		interrupts = <GIC_SPI 137
> > > > > IRQ_TYPE_LEVEL_HIGH>;
> > > > > +		clocks = <&infracfg CK_INFRA_PWM>,
> > > > > +			 <&infracfg_ao CK_INFRA_PWM_BSEL>,
> > > > > +			 <&infracfg_ao CK_INFRA_PWM1_CK>,
> > > > > +			 <&infracfg_ao CK_INFRA_PWM2_CK>;
> > > > > +		assigned-clocks = <&topckgen
> > > > > CK_TOP_PWM_SEL>,
> > > > > +				  <&infracfg
> > > > > CK_INFRA_PWM_BSEL>,
> > > > > +				  <&infracfg
> > > > > CK_INFRA_PWM1_SEL>,
> > > > > +				  <&infracfg
> > > > > CK_INFRA_PWM2_SEL>;
> > > > > +		assigned-clock-parents = <&topckgen
> > > > > CK_TOP_CB_M_D4>,
> > > > > +					 <&infracfg
> > > > > CK_INFRA_PWM>,
> > > > > +					 <&infracfg
> > > > > CK_INFRA_PWM>,
> > > > > +					 <&infracfg
> > > > > CK_INFRA_PWM>;
> > > > > +		clock-names = "top", "main", "pwm1", "pwm2";
> > > > > +		status = "disabled";
> > > > > +		u-boot,dm-pre-reloc;
> > > > > +	};
> > > > > +
> > > > > +	uart0: serial@11002000 {
> > > > > +		compatible = "mediatek,hsuart";
> > > > > +		reg = <0x11002000 0x400>;
> > > > > +		interrupts = <GIC_SPI 123
> > > > > IRQ_TYPE_LEVEL_HIGH>;
> > > > > +		clocks = <&infracfg_ao CK_INFRA_UART0_CK>;
> > > > > +		assigned-clocks = <&topckgen
> > > > > CK_TOP_UART_SEL>,
> > > > > +				  <&infracfg_ao
> > > > > CK_INFRA_UART0_SEL>;
> > > > > +		assigned-clock-parents = <&topckgen
> > > > > CK_TOP_CB_CKSQ_40M>,
> > > > > +					 <&infracfg
> > > > > CK_INFRA_UART>;
> > > > > +		mediatek,force-highspeed;
> > > > > +		status = "disabled";
> > > > > +		u-boot,dm-pre-reloc;
> > > > > +	};
> > > > > +
> > > > > +	uart1: serial@11003000 {
> > > > > +		compatible = "mediatek,hsuart";
> > > > > +		reg = <0x11003000 0x400>;
> > > > > +		interrupts = <GIC_SPI 124
> > > > > IRQ_TYPE_LEVEL_HIGH>;
> > > > > +		clocks = <&infracfg_ao CK_INFRA_UART1_CK>;
> > > > > +		assigned-clocks = <&infracfg
> > > > > CK_INFRA_UART1_SEL>;
> > > > > +		assigned-clock-parents = <&infracfg
> > > > > CK_INFRA_CK_F26M>;
> > > > > +		mediatek,force-highspeed;
> > > > > +		status = "disabled";
> > > > > +	};
> > > > > +
> > > > > +	uart2: serial@11004000 {
> > > > > +		compatible = "mediatek,hsuart";
> > > > > +		reg = <0x11004000 0x400>;
> > > > > +		interrupts = <GIC_SPI 124
> > > > > IRQ_TYPE_LEVEL_HIGH>;
> > > > > +		clocks = <&infracfg_ao CK_INFRA_UART2_CK>;
> > > > > +		assigned-clocks = <&infracfg
> > > > > CK_INFRA_UART2_SEL>;
> > > > > +		assigned-clock-parents = <&infracfg
> > > > > CK_INFRA_CK_F26M>;
> > > > > +		mediatek,force-highspeed;
> > > > > +		status = "disabled";
> > > > > +	};
> > > > > +
> > > > > +	snand: snand@11005000 {
> > > > > +		compatible = "mediatek,mt7986-snand";
> > > > > +		reg = <0x11005000 0x1000>,
> > > > > +		      <0x11006000 0x1000>;
> > > > > +		reg-names = "nfi", "ecc";
> > > > > +		clocks = <&infracfg_ao CK_INFRA_SPINFI1_CK>,
> > > > > +			 <&infracfg_ao CK_INFRA_NFI1_CK>,
> > > > > +			 <&infracfg_ao CK_INFRA_NFI_HCK_CK>;
> > > > > +		clock-names = "pad_clk", "nfi_clk",
> > > > > "nfi_hclk";
> > > > > +		assigned-clocks = <&topckgen
> > > > > CK_TOP_SPINFI_SEL>,
> > > > > +				  <&topckgen
> > > > > CK_TOP_NFI1X_SEL>;
> > > > > +		assigned-clock-parents = <&topckgen
> > > > > CK_TOP_CB_M_D8>,
> > > > > +					 <&topckgen
> > > > > CK_TOP_CB_M_D8>;
> > > > > +		status = "disabled";
> > > > > +	};
> > > > > +
> > > > > +	ethsys: syscon@15000000 {
> > > > > +		compatible = "mediatek,mt7986-ethsys",
> > > > > "syscon";
> > > > > +		reg = <0x15000000 0x1000>;
> > > > > +		clock-parent = <&topckgen>;
> > > > > +		#clock-cells = <1>;
> > > > > +		#reset-cells = <1>;
> > > > > +	};
> > > > > +
> > > > > +	eth: ethernet@15100000 {
> > > > > +		compatible = "mediatek,mt7986-eth",
> > > > > "syscon";
> > > > > +		reg = <0x15100000 0x20000>;
> > > > > +		resets = <&ethsys ETHSYS_FE_RST>;
> > > > > +		reset-names = "fe";
> > > > > +		mediatek,ethsys = <&ethsys>;
> > > > > +		mediatek,sgmiisys = <&sgmiisys0>;
> > > > > +		#address-cells = <1>;
> > > > > +		#size-cells = <0>;
> > > > > +		status = "disabled";
> > > > > +	};
> > > > > +
> > > > > +	sgmiisys0: syscon@10060000 {
> > > > > +		compatible = "mediatek,mt7986-sgmiisys",
> > > > > "syscon";
> > > > > +		reg = <0x10060000 0x1000>;
> > > > > +		#clock-cells = <1>;
> > > > > +	};
> > > > > +
> > > > > +	sgmiisys1: syscon@10070000 {
> > > > > +		compatible = "mediatek,mt7986-sgmiisys",
> > > > > "syscon";
> > > > > +		reg = <0x10070000 0x1000>;
> > > > > +		#clock-cells = <1>;
> > > > > +	};
> > > > > +
> > > > > +	spi0: spi@1100a000 {
> > > > > +		compatible = "mediatek,ipm-spi";
> > > > > +		reg = <0x1100a000 0x100>;
> > > > > +		clocks = <&infracfg_ao CK_INFRA_SPI0_CK>,
> > > > > +			 <&topckgen CK_TOP_SPI_SEL>;
> > > > > +		assigned-clocks = <&topckgen
> > > > > CK_TOP_SPI_SEL>,
> > > > > +				  <&infracfg
> > > > > CK_INFRA_SPI0_SEL>;
> > > > > +		assigned-clock-parents = <&topckgen
> > > > > CK_TOP_CB_M_D2>,
> > > > > +					 <&topckgen
> > > > > CK_INFRA_ISPI0>;
> > > > > +		clock-names = "sel-clk", "spi-clk";
> > > > > +		interrupts = <GIC_SPI 140
> > > > > IRQ_TYPE_LEVEL_HIGH>;
> > > > > +		status = "disabled";
> > > > > +	};
> > > > > +
> > > > > +	spi1: spi@1100b000 {
> > > > > +		compatible = "mediatek,ipm-spi";
> > > > > +		reg = <0x1100b000 0x100>;
> > > > > +		interrupts = <GIC_SPI 141
> > > > > IRQ_TYPE_LEVEL_HIGH>;
> > > > > +		status = "disabled";
> > > > > +	};
> > > > > +
> > > > > +	mmc0: mmc@11230000 {
> > > > > +		compatible = "mediatek,mt7986-mmc";
> > > > > +		reg = <0x11230000 0x1000>,
> > > > > +		      <0x11C20000 0x1000>;
> > > > > +		interrupts = <GIC_SPI 143
> > > > > IRQ_TYPE_LEVEL_HIGH>;
> > > > > +		clocks = <&topckgen CK_TOP_EMMC_416M>,
> > > > > +			<&topckgen CK_TOP_EMMC_250M>,
> > > > > +			<&infracfg_ao CK_INFRA_MSDC_CK>;
> > > > > +		assigned-clocks = <&topckgen
> > > > > CK_TOP_EMMC_416M_SEL>,
> > > > > +				  <&topckgen
> > > > > CK_TOP_EMMC_250M_SEL>;
> > > > > +		assigned-clock-parents = <&topckgen
> > > > > CK_TOP_CB_M_416M>,
> > > > > +					 <&topckgen
> > > > > CK_TOP_NET1_D5_D2>;
> > > > > +		clock-names = "source", "hclk", "source_cg";
> > > > > +		status = "disabled";
> > > > > +	};
> > > > > +
> > > > > +	xhci: xhci@11200000 {
> > > > > +		compatible = "mediatek,mt7986-xhci",
> > > > > +			     "mediatek,mtk-xhci";
> > > > > +		reg = <0x11200000 0x2e00>,
> > > > > +		      <0x11203e00 0x0100>;
> > > > > +		reg-names = "mac", "ippc";
> > > > > +		interrupts = <GIC_SPI 173
> > > > > IRQ_TYPE_LEVEL_HIGH>;
> > > > > +		phys = <&u2port0 PHY_TYPE_USB2>,
> > > > > +		       <&u3port0 PHY_TYPE_USB3>,
> > > > > +		       <&u2port1 PHY_TYPE_USB2>;
> > > > > +		clocks = <&dummy_clk>,
> > > > > +			 <&dummy_clk>,
> > > > > +			 <&dummy_clk>,
> > > > > +			 <&dummy_clk>,
> > > > > +			 <&dummy_clk>;
> > > > > +		clock-names = "sys_ck",
> > > > > +			      "xhci_ck",
> > > > > +			      "ref_ck",
> > > > > +			      "mcu_ck",
> > > > > +			      "dma_ck";
> > > > > +		tpl-support;
> > > > > +		status = "okay";
> > > > > +	};
> > > > > +
> > > > > +	usbtphy: usb-phy@11e10000 {
> > > > > +		compatible = "mediatek,mt7986",
> > > > > +			     "mediatek,generic-tphy-v2";
> > > > > +		#address-cells = <1>;
> > > > > +		#size-cells = <1>;
> > > > > +		status = "okay";
> > > > > +
> > > > > +		u2port0: usb-phy@11e10000 {
> > > > > +			reg = <0x11e10000 0x700>;
> > > > > +			clocks = <&dummy_clk>;
> > > > > +			clock-names = "ref";
> > > > > +			#phy-cells = <1>;
> > > > > +			status = "okay";
> > > > > +		};
> > > > > +
> > > > > +		u3port0: usb-phy@11e10700 {
> > > > > +			reg = <0x11e10700 0x900>;
> > > > > +			clocks = <&dummy_clk>;
> > > > > +			clock-names = "ref";
> > > > > +			#phy-cells = <1>;
> > > > > +			status = "okay";
> > > > > +		};
> > > > > +
> > > > > +		u2port1: usb-phy@11e11000 {
> > > > > +			reg = <0x11e11000 0x700>;
> > > > > +			clocks = <&dummy_clk>;
> > > > > +			clock-names = "ref";
> > > > > +			#phy-cells = <1>;
> > > > > +			status = "okay";
> > > > > +		};
> > > > > +	};
> > > > > +};
> > > > > diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-
> > > > > mediatek/Kconfig
> > > > > index f79a5c62cd..e059a013db 100644
> > > > > --- a/arch/arm/mach-mediatek/Kconfig
> > > > > +++ b/arch/arm/mach-mediatek/Kconfig
> > > > > @@ -40,6 +40,14 @@ config TARGET_MT7629
> > > > >  	  including DDR3, crypto engine, 3x3 11n/ac Wi-Fi,
> > > > > Gigabit
> > > > > Ethernet,
> > > > >  	  switch, USB3.0, PCIe, UART, SPI, I2C and PWM.
> > > > >  
> > > > > +config TARGET_MT7986
> > > > > +	bool "MediaTek MT7986 SoC"
> > > > > +	select ARM64
> > > > > +	help
> > > > > +	  The MediaTek MT7986 is a ARM64-based SoC with a
> > > > > quad-
> > > > > core Cortex-A53.
> > > > > +	  including UART, SPI, SPI flash, USB3.0, MMC, NAND,
> > > > > SNFI,
> > > > > PWM, PCIe,
> > > > > +	  Gigabit Ethernet, I2C, built-in 4x4 Wi-Fi, and
> > > > > PCIe.
> > > > > +
> > > > >  config TARGET_MT8183
> > > > >  	bool "MediaTek MT8183 SoC"
> > > > >  	select ARM64
> > > > > @@ -84,6 +92,7 @@ config SYS_BOARD
> > > > >  	default "mt7622" if TARGET_MT7622
> > > > >  	default "mt7623" if TARGET_MT7623
> > > > >  	default "mt7629" if TARGET_MT7629
> > > > > +	default "mt7986" if TARGET_MT7986
> > > > >  	default "mt8183" if TARGET_MT8183
> > > > >  	default "mt8512" if TARGET_MT8512
> > > > >  	default "mt8516" if TARGET_MT8516
> > > > > @@ -99,6 +108,7 @@ config SYS_CONFIG_NAME
> > > > >  	default "mt7622" if TARGET_MT7622
> > > > >  	default "mt7623" if TARGET_MT7623
> > > > >  	default "mt7629" if TARGET_MT7629
> > > > > +	default "mt7986" if TARGET_MT7986
> > > > >  	default "mt8183" if TARGET_MT8183
> > > > >  	default "mt8512" if TARGET_MT8512
> > > > >  	default "mt8516" if TARGET_MT8516
> > > > > @@ -113,6 +123,7 @@ config MTK_BROM_HEADER_INFO
> > > > >  	string
> > > > >  	default "media=nor" if TARGET_MT8518 ||
> > > > > TARGET_MT8512 ||
> > > > > TARGET_MT7629 ||
> > > > >  TARGET_MT7622
> > > > 
> > > > Same here.
> > > > 
> > > > >  	default "media=emmc" if TARGET_MT8516 ||
> > > > > TARGET_MT8365
> > > > > > > 
> > > > > 
> > > > > TARGET_MT8183
> > > > > +	default "media=snand;nandinfo=2k+64" if
> > > > > TARGET_MT7986
> > > > >  	default "lk=1" if TARGET_MT7623
> > > > >  
> > > > >  endif
> > > > > diff --git a/arch/arm/mach-mediatek/Makefile
> > > > >  b/arch/arm/mach-mediatek/Makefile
> > > > 
> > > > And here.
> > > > 
> > > > > index 0f5b0c16d2..fe5c3a837c 100644
> > > > > --- a/arch/arm/mach-mediatek/Makefile
> > > > > +++ b/arch/arm/mach-mediatek/Makefile
> > > > > @@ -7,6 +7,7 @@ obj-$(CONFIG_MT8512) += mt8512/
> > > > >  obj-$(CONFIG_TARGET_MT7622) += mt7622/
> > > > >  obj-$(CONFIG_TARGET_MT7623) += mt7623/
> > > > >  obj-$(CONFIG_TARGET_MT7629) += mt7629/
> > > > > +obj-$(CONFIG_TARGET_MT7986) += mt7986/
> > > > >  obj-$(CONFIG_TARGET_MT8183) += mt8183/
> > > > >  obj-$(CONFIG_TARGET_MT8516) += mt8516/
> > > > >  obj-$(CONFIG_TARGET_MT8518) += mt8518/
> > > > > diff --git a/arch/arm/mach-mediatek/mt7986/Makefile
> > > > >  b/arch/arm/mach-mediatek/mt7986/Makefile
> > > > 
> > > > And here.
> > > > 
> > > > > new file mode 100644
> > > > > index 0000000000..007eb4a367
> > > > > --- /dev/null
> > > > > +++ b/arch/arm/mach-mediatek/mt7986/Makefile
> > > > > @@ -0,0 +1,4 @@
> > > > > +# SPDX-License-Identifier:	GPL-2.0
> > > > > +
> > > > > +obj-y += init.o
> > > > > +obj-y += lowlevel_init.o
> > > > > diff --git a/arch/arm/mach-mediatek/mt7986/init.c
> > > > >  b/arch/arm/mach-mediatek/mt7986/init.c
> > > > 
> > > > And here again.
> > > > 
> > > > > new file mode 100644
> > > > > index 0000000000..4884cbdc67
> > > > > --- /dev/null
> > > > > +++ b/arch/arm/mach-mediatek/mt7986/init.c
> > > > > @@ -0,0 +1,53 @@
> > > > > +// SPDX-License-Identifier: GPL-2.0
> > > > > +/*
> > > > > + * Copyright (C) 2022 MediaTek Inc.
> > > > > + * Author: Sam Shih <sam.shih@mediatek.com>
> > > > > + */
> > > > > +
> > > > > +#include <fdtdec.h>
> > > > > +#include <asm/armv8/mmu.h>
> > > > > +#include <init.h>
> > > > > +#include <asm/system.h>
> > > > > +#include <asm/global_data.h>
> > > > > +#include <linux/sizes.h>
> > > > > +
> > > > > +DECLARE_GLOBAL_DATA_PTR;
> > > > > +
> > > > > +int print_cpuinfo(void)
> > > > > +{
> > > > > +	printf("CPU:   MediaTek MT7986\n");
> > > > > +	return 0;
> > > > > +}
> > > > > +
> > > > > +int dram_init(void)
> > > > > +{
> > > > > +	gd->ram_size = get_ram_size((void
> > > > > *)CONFIG_SYS_SDRAM_BASE,
> > > > > SZ_2G);
> > > > > +
> > > > > +	return 0;
> > > > > +}
> > > > > +
> > > > > +void reset_cpu(ulong addr)
> > > > > +{
> > > > > +	psci_system_reset();
> > > > > +}
> > > > > +
> > > > > +static struct mm_region mt7986_mem_map[] = {
> > > > > +	{
> > > > > +		/* DDR */
> > > > > +		.virt = 0x40000000UL,
> > > > > +		.phys = 0x40000000UL,
> > > > > +		.size = 0x80000000UL,
> > > > > +		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
> > > > > PTE_BLOCK_OUTER_SHARE,
> > > > > +	}, {
> > > > > +		.virt = 0x00000000UL,
> > > > > +		.phys = 0x00000000UL,
> > > > > +		.size = 0x40000000UL,
> > > > > +		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE)
> > > > > |
> > > > > +			 PTE_BLOCK_NON_SHARE |
> > > > > +			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
> > > > > +	}, {
> > > > > +		0,
> > > > > +	}
> > > > > +};
> > > > > +
> > > > > +struct mm_region *mem_map = mt7986_mem_map;
> > > > > diff --git a/arch/arm/mach-mediatek/mt7986/lowlevel_init.S
> > > > >  b/arch/arm/mach-mediatek/mt7986/lowlevel_init.S
> > > > 
> > > > And here.
> > > > 
> > > > > new file mode 100644
> > > > > index 0000000000..244d2c1385
> > > > > --- /dev/null
> > > > > +++ b/arch/arm/mach-mediatek/mt7986/lowlevel_init.S
> > > > > @@ -0,0 +1,30 @@
> > > > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > > > +/*
> > > > > + * Copyright (C) 2022 MediaTek Inc.
> > > > > + * Author: Sam Shih <sam.shih@mediatek.com>
> > > > > + */
> > > > > +
> > > > > +/*
> > > > > + * Switch from AArch64 EL2 to AArch32 EL2
> > > > > + * @param inputs:
> > > > > + * x0: argument, zero
> > > > > + * x1: machine nr
> > > > > + * x2: fdt address
> > > > > + * x3: input argument
> > > > > + * x4: kernel entry point
> > > > > + * @param outputs for secure firmware:
> > > > > + * x0: function id
> > > > > + * x1: kernel entry point
> > > > > + * x2: machine nr
> > > > > + * x3: fdt address
> > > > > +*/
> > > > > +
> > > > > +.global armv8_el2_to_aarch32
> > > > > +armv8_el2_to_aarch32:
> > > > > +	mov     x3, x2
> > > > > +	mov     x2, x1
> > > > > +	mov     x1, x4
> > > > > +	mov	x4, #0
> > > > > +	ldr x0, =0x82000200
> > > > > +	SMC #0
> > > > > +	ret
> > > > > -- 
> > > > > 2.17.1
> > > > > 

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 02/31] arm: mediatek: add support for MediaTek MT7981 SoC
  2022-08-04 13:57   ` Simon Glass
@ 2022-08-08  2:17     ` Weijie Gao
  2022-08-08 19:26       ` Simon Glass
  0 siblings, 1 reply; 100+ messages in thread
From: Weijie Gao @ 2022-08-08  2:17 UTC (permalink / raw)
  To: Simon Glass; +Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream

On Thu, 2022-08-04 at 07:57 -0600, Simon Glass wrote:
> Hi Weijie,
> 
> On Wed, 3 Aug 2022 at 21:35, Weijie Gao <weijie.gao@mediatek.com>
> wrote:
> > 
> > This patch adds basic support for MediaTek MT7981 SoC.
> > This include the file that will initialize the SoC after boot and
> > its
> > device tree.
> > 
> > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> > ---
> >  arch/arm/dts/mt7981.dtsi                      | 288
> > ++++++++++++++++++
> >  arch/arm/mach-mediatek/Kconfig                |  12 +-
> >  arch/arm/mach-mediatek/Makefile               |   1 +
> >  arch/arm/mach-mediatek/mt7981/Makefile        |   4 +
> >  arch/arm/mach-mediatek/mt7981/init.c          |  52 ++++
> >  arch/arm/mach-mediatek/mt7981/lowlevel_init.S |  30 ++
> >  6 files changed, 386 insertions(+), 1 deletion(-)
> >  create mode 100644 arch/arm/dts/mt7981.dtsi
> >  create mode 100644 arch/arm/mach-mediatek/mt7981/Makefile
> >  create mode 100644 arch/arm/mach-mediatek/mt7981/init.c
> >  create mode 100644 arch/arm/mach-mediatek/mt7981/lowlevel_init.S
> > 
> 
> 
> [..]
> 
> > diff --git a/arch/arm/mach-mediatek/mt7981/init.c
> >  b/arch/arm/mach-mediatek/mt7981/init.c
> > new file mode 100644
> > index 0000000000..f503bb804b
> > --- /dev/null
> > +++ b/arch/arm/mach-mediatek/mt7981/init.c
> > @@ -0,0 +1,52 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2022 MediaTek Inc.
> > + * Author: Sam Shih <sam.shih@mediatek.com>
> > + */
> > +
> > +#include <fdtdec.h>
> 
> Do you need that?

This was used during testing, and should be remove now.

> 
> > +#include <asm/armv8/mmu.h>
> > +#include <init.h>
> 
> Move up one

ok.

> 
> > +#include <asm/system.h>
> > +#include <asm/global_data.h>
> > +
> > +DECLARE_GLOBAL_DATA_PTR;
> > +
> > +int print_cpuinfo(void)
> 
> Can you use the CPU uclass and DISPLAY_CPUINFO instead/

Basically there's nothing to do for print_cpuinfo other than printing a
fixed CPU model string. Not sure if it's worth using a CPU uclass.

Besides, Using a cpu uclass involves modifying other chips, and some
of them cann't be tested by me.

> 
> > +{
> > +       printf("CPU:   MediaTek MT7981\n");
> > +       return 0;
> > +}
> > +
> 
> [..]
> 
> > diff --git a/arch/arm/mach-mediatek/mt7981/lowlevel_init.S
> >  b/arch/arm/mach-mediatek/mt7981/lowlevel_init.S
> > new file mode 100644
> > index 0000000000..244d2c1385
> > --- /dev/null
> > +++ b/arch/arm/mach-mediatek/mt7981/lowlevel_init.S
> > @@ -0,0 +1,30 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Copyright (C) 2022 MediaTek Inc.
> > + * Author: Sam Shih <sam.shih@mediatek.com>
> > + */
> > +
> > +/*
> > + * Switch from AArch64 EL2 to AArch32 EL2
> > + * @param inputs:
> > + * x0: argument, zero
> > + * x1: machine nr
> > + * x2: fdt address
> > + * x3: input argument
> > + * x4: kernel entry point
> > + * @param outputs for secure firmware:
> > + * x0: function id
> > + * x1: kernel entry point
> > + * x2: machine nr
> > + * x3: fdt address
> > +*/
> > +
> > +.global armv8_el2_to_aarch32
> > +armv8_el2_to_aarch32:
> > +       mov     x3, x2
> > +       mov     x2, x1
> > +       mov     x1, x4
> > +       mov     x4, #0
> > +       ldr x0, =0x82000200
> 
> Please comment or add a symbol for this

I can add the following link as a comment:
https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/plat/m
ediatek/common/mtk_sip_svc.c#n73

> 
> > +       SMC #0
> > +       ret
> > --
> > 2.17.1
> > 
> 
> Regards,
> Simon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 05/31] mmc: mediatek: add support for MediaTek MT7891/MT7986 SoCs
  2022-08-04 13:57   ` Simon Glass
@ 2022-08-08  2:22     ` Weijie Gao
  0 siblings, 0 replies; 100+ messages in thread
From: Weijie Gao @ 2022-08-08  2:22 UTC (permalink / raw)
  To: Simon Glass
  Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream, Peng Fan, Jaehoon Chung

On Thu, 2022-08-04 at 07:57 -0600, Simon Glass wrote:
> Hi Weijie,
> 
> On Wed, 3 Aug 2022 at 21:35, Weijie Gao <weijie.gao@mediatek.com>
> wrote:
> > 
> > This patch adds eMMC and SDXC support for MediaTek MT7981/MT7986
> > SoCs
> 
> Add eMMC and SDXC support for MediaTek MT7981/MT7986 SoCs.
> 
> (describe your changes in imperative mood)

I'll change it in v2

> 
> > 
> > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> > ---
> >  drivers/mmc/mtk-sd.c | 68 ++++++++++++++++++++++++++++++++++----
> > ------
> >  1 file changed, 53 insertions(+), 15 deletions(-)
> > 
> 
> Reviewed-by: Simon Glass <sjg@chromium.org>
> 
> Regards,
> Simon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 06/31] net: mediatek: use a struct to cover variations of all SoCs
  2022-08-04 13:56   ` Simon Glass
@ 2022-08-08  2:28     ` Weijie Gao
  0 siblings, 0 replies; 100+ messages in thread
From: Weijie Gao @ 2022-08-08  2:28 UTC (permalink / raw)
  To: Simon Glass
  Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream, Joe Hershberger,
	Ramon Fried

On Thu, 2022-08-04 at 07:56 -0600, Simon Glass wrote:
> Hi Weijie,
> 
> On Wed, 3 Aug 2022 at 21:36, Weijie Gao <weijie.gao@mediatek.com>
> wrote:
> > 
> > Using a single soc id to control different initialization and TX/RX
> > flow
> > for all SoCs is not extensible if more hardware variations are
> > added in
> > the future.
> > 
> > This patch introduces a struct to replace the original mtk_soc to
> > allow
> > the driver be able handle newer hardwares.
> > 
> > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> > ---
> >  drivers/net/mtk_eth.c | 50 +++++++++++++++++++++++++++++--------
> > ------
> >  drivers/net/mtk_eth.h | 25 +++++++++++++++++++++-
> >  2 files changed, 58 insertions(+), 17 deletions(-)
> 
> Reviewed-by: Simon Glass <sjg@chromium.org>
> 
> > 
> > diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c
> > index 4fe7ee0d36..92d2ea4f2a 100644
> > --- a/drivers/net/mtk_eth.c
> > +++ b/drivers/net/mtk_eth.c
> > @@ -142,11 +142,9 @@ enum mtk_switch {
> >         SW_MT7531
> >  };
> > 
> > -enum mtk_soc {
> > -       SOC_MT7623,
> > -       SOC_MT7629,
> > -       SOC_MT7622,
> > -       SOC_MT7621
> > +struct mtk_soc_data {
> > +       u32 caps;
> > +       u32 ana_rgc3;
> 
> please comment these
> [..]

OK.

> 
> Regards,
> Simon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 07/31] net: mediatek: stop using bitfileds for DMA descriptors
  2022-08-06 17:50   ` Ramon Fried
@ 2022-08-08  2:29     ` Weijie Gao
  0 siblings, 0 replies; 100+ messages in thread
From: Weijie Gao @ 2022-08-08  2:29 UTC (permalink / raw)
  To: Ramon Fried; +Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream, Joe Hershberger

On Sat, 2022-08-06 at 20:50 +0300, Ramon Fried wrote:
> On Thu, Aug 4, 2022 at 6:35 AM Weijie Gao <weijie.gao@mediatek.com>
> wrote:
> > 
> > This patch is a preparation for adding a new version of PDMA of
> > which the
> > DMA descriptor fields has changed. Using bitfields will result in a
> > complex
> > modification. Convert bitfields to u32 units can solve this problem
> > easily.
> > 
> > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> > ---
> >  drivers/net/mtk_eth.c | 144 ++++++++++++++----------------------
> > ------
> >  drivers/net/mtk_eth.h |  32 ++++++++++
> >  2 files changed, 80 insertions(+), 96 deletions(-)
> > 
> > diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c
> > index 92d2ea4f2a..bfa049cf79 100644
> > --- a/drivers/net/mtk_eth.c
> > +++ b/drivers/net/mtk_eth.c
> > @@ -65,77 +65,6 @@
> >         (DP_DISCARD << MC_DP_S) | \
> >         (DP_DISCARD << UN_DP_S))
> > 
> > -struct pdma_rxd_info1 {
> > -       u32 PDP0;
> > -};
> > -
> > -struct pdma_rxd_info2 {
> > -       u32 PLEN1 : 14;
> > -       u32 LS1 : 1;
> > -       u32 UN_USED : 1;
> > -       u32 PLEN0 : 14;
> > -       u32 LS0 : 1;
> > -       u32 DDONE : 1;
> > -};
> > -
> > -struct pdma_rxd_info3 {
> > -       u32 PDP1;
> > -};
> > -
> > -struct pdma_rxd_info4 {
> > -       u32 FOE_ENTRY : 14;
> > -       u32 CRSN : 5;
> > -       u32 SP : 3;
> > -       u32 L4F : 1;
> > -       u32 L4VLD : 1;
> > -       u32 TACK : 1;
> > -       u32 IP4F : 1;
> > -       u32 IP4 : 1;
> > -       u32 IP6 : 1;
> > -       u32 UN_USED : 4;
> > -};
> > -
> > -struct pdma_rxdesc {
> > -       struct pdma_rxd_info1 rxd_info1;
> > -       struct pdma_rxd_info2 rxd_info2;
> > -       struct pdma_rxd_info3 rxd_info3;
> > -       struct pdma_rxd_info4 rxd_info4;
> > -};
> > -
> > -struct pdma_txd_info1 {
> > -       u32 SDP0;
> > -};
> > -
> > -struct pdma_txd_info2 {
> > -       u32 SDL1 : 14;
> > -       u32 LS1 : 1;
> > -       u32 BURST : 1;
> > -       u32 SDL0 : 14;
> > -       u32 LS0 : 1;
> > -       u32 DDONE : 1;
> > -};
> > -
> > -struct pdma_txd_info3 {
> > -       u32 SDP1;
> > -};
> > -
> > -struct pdma_txd_info4 {
> > -       u32 VLAN_TAG : 16;
> > -       u32 INS : 1;
> > -       u32 RESV : 2;
> > -       u32 UDF : 6;
> > -       u32 FPORT : 3;
> > -       u32 TSO : 1;
> > -       u32 TUI_CO : 3;
> > -};
> > -
> > -struct pdma_txdesc {
> > -       struct pdma_txd_info1 txd_info1;
> > -       struct pdma_txd_info2 txd_info2;
> > -       struct pdma_txd_info3 txd_info3;
> > -       struct pdma_txd_info4 txd_info4;
> > -};
> > -
> >  enum mtk_switch {
> >         SW_NONE,
> >         SW_MT7530,
> > @@ -145,13 +74,15 @@ enum mtk_switch {
> >  struct mtk_soc_data {
> >         u32 caps;
> >         u32 ana_rgc3;
> > +       u32 txd_size;
> > +       u32 rxd_size;
> >  };
> > 
> >  struct mtk_eth_priv {
> >         char pkt_pool[TOTAL_PKT_BUF_SIZE]
> > __aligned(ARCH_DMA_MINALIGN);
> > 
> > -       struct pdma_txdesc *tx_ring_noc;
> > -       struct pdma_rxdesc *rx_ring_noc;
> > +       void *tx_ring_noc;
> > +       void *rx_ring_noc;
> > 
> >         int rx_dma_owner_idx0;
> >         int tx_cpu_owner_idx0;
> > @@ -1196,14 +1127,16 @@ static void mtk_mac_init(struct
> > mtk_eth_priv *priv)
> >  static void mtk_eth_fifo_init(struct mtk_eth_priv *priv)
> >  {
> >         char *pkt_base = priv->pkt_pool;
> > +       struct mtk_tx_dma *txd;
> > +       struct mtk_rx_dma *rxd;
> >         int i;
> > 
> >         mtk_pdma_rmw(priv, PDMA_GLO_CFG_REG, 0xffff0000, 0);
> >         udelay(500);
> > 
> > -       memset(priv->tx_ring_noc, 0, NUM_TX_DESC * sizeof(struct
> > pdma_txdesc));
> > -       memset(priv->rx_ring_noc, 0, NUM_RX_DESC * sizeof(struct
> > pdma_rxdesc));
> > -       memset(priv->pkt_pool, 0, TOTAL_PKT_BUF_SIZE);
> > +       memset(priv->tx_ring_noc, 0, NUM_TX_DESC * priv->soc-
> > >txd_size);
> > +       memset(priv->rx_ring_noc, 0, NUM_RX_DESC * priv->soc-
> > >rxd_size);
> > +       memset(priv->pkt_pool, 0xff, TOTAL_PKT_BUF_SIZE);
> > 
> >         flush_dcache_range((ulong)pkt_base,
> >                            (ulong)(pkt_base + TOTAL_PKT_BUF_SIZE));
> > @@ -1212,17 +1145,21 @@ static void mtk_eth_fifo_init(struct
> > mtk_eth_priv
> >  *priv)
> >         priv->tx_cpu_owner_idx0 = 0;
> > 
> >         for (i = 0; i < NUM_TX_DESC; i++) {
> > -               priv->tx_ring_noc[i].txd_info2.LS0 = 1;
> > -               priv->tx_ring_noc[i].txd_info2.DDONE = 1;
> > -               priv->tx_ring_noc[i].txd_info4.FPORT = priv-
> > >gmac_id + 1;
> > +               txd = priv->tx_ring_noc + i * priv->soc->txd_size;
> > +
> > +               txd->txd1 = virt_to_phys(pkt_base);
> > +               txd->txd2 = PDMA_TXD2_DDONE | PDMA_TXD2_LS0;
> > +               txd->txd4 = PDMA_TXD4_FPORT_SET(priv->gmac_id + 1);
> > 
> > -               priv->tx_ring_noc[i].txd_info1.SDP0 =
> > virt_to_phys(pkt_base);
> >                 pkt_base += PKTSIZE_ALIGN;
> >         }
> > 
> >         for (i = 0; i < NUM_RX_DESC; i++) {
> > -               priv->rx_ring_noc[i].rxd_info2.PLEN0 =
> > PKTSIZE_ALIGN;
> > -               priv->rx_ring_noc[i].rxd_info1.PDP0 =
> > virt_to_phys(pkt_base);
> > +               rxd = priv->rx_ring_noc + i * priv->soc->rxd_size;
> > +
> > +               rxd->rxd1 = virt_to_phys(pkt_base);
> > +               rxd->rxd2 = PDMA_RXD2_PLEN0_SET(PKTSIZE_ALIGN);
> > +
> >                 pkt_base += PKTSIZE_ALIGN;
> >         }
> > 
> > @@ -1309,20 +1246,22 @@ static int mtk_eth_send(struct udevice
> > *dev, void
> >  *packet, int length)
> >  {
> >         struct mtk_eth_priv *priv = dev_get_priv(dev);
> >         u32 idx = priv->tx_cpu_owner_idx0;
> > +       struct mtk_tx_dma *txd;
> >         void *pkt_base;
> > 
> > -       if (!priv->tx_ring_noc[idx].txd_info2.DDONE) {
> > +       txd = priv->tx_ring_noc + idx * priv->soc->txd_size;
> > +
> > +       if (!(txd->txd2 & PDMA_TXD2_DDONE)) {
> >                 debug("mtk-eth: TX DMA descriptor ring is full\n");
> >                 return -EPERM;
> >         }
> > 
> > -       pkt_base = (void *)phys_to_virt(priv-
> > >tx_ring_noc[idx].txd_info1.SDP0);
> > +       pkt_base = (void *)phys_to_virt(txd->txd1);
> >         memcpy(pkt_base, packet, length);
> >         flush_dcache_range((ulong)pkt_base, (ulong)pkt_base +
> >                            roundup(length, ARCH_DMA_MINALIGN));
> > 
> > -       priv->tx_ring_noc[idx].txd_info2.SDL0 = length;
> > -       priv->tx_ring_noc[idx].txd_info2.DDONE = 0;
> > +       txd->txd2 = PDMA_TXD2_LS0 | PDMA_TXD2_SDL0_SET(length);
> > 
> >         priv->tx_cpu_owner_idx0 = (priv->tx_cpu_owner_idx0 + 1) %
> > NUM_TX_DESC;
> >         mtk_pdma_write(priv, TX_CTX_IDX_REG(0), priv-
> > >tx_cpu_owner_idx0);
> > @@ -1334,16 +1273,20 @@ static int mtk_eth_recv(struct udevice
> > *dev, int
> >  flags, uchar **packetp)
> >  {
> >         struct mtk_eth_priv *priv = dev_get_priv(dev);
> >         u32 idx = priv->rx_dma_owner_idx0;
> > +       struct mtk_rx_dma *rxd;
> >         uchar *pkt_base;
> >         u32 length;
> > 
> > -       if (!priv->rx_ring_noc[idx].rxd_info2.DDONE) {
> > +       rxd = priv->rx_ring_noc + idx * priv->soc->rxd_size;
> > +
> > +       if (!(rxd->rxd2 & PDMA_RXD2_DDONE)) {
> >                 debug("mtk-eth: RX DMA descriptor ring is
> > empty\n");
> >                 return -EAGAIN;
> >         }
> > 
> > -       length = priv->rx_ring_noc[idx].rxd_info2.PLEN0;
> > -       pkt_base = (void *)phys_to_virt(priv-
> > >rx_ring_noc[idx].rxd_info1.PDP0);
> > +       length = PDMA_RXD2_PLEN0_GET(rxd->rxd2);
> > +
> > +       pkt_base = (void *)phys_to_virt(rxd->rxd1);
> >         invalidate_dcache_range((ulong)pkt_base, (ulong)pkt_base +
> >                                 roundup(length,
> > ARCH_DMA_MINALIGN));
> > 
> > @@ -1357,10 +1300,11 @@ static int mtk_eth_free_pkt(struct udevice
> > *dev,
> >  uchar *packet, int length)
> >  {
> >         struct mtk_eth_priv *priv = dev_get_priv(dev);
> >         u32 idx = priv->rx_dma_owner_idx0;
> > +       struct mtk_rx_dma *rxd;
> > +
> > +       rxd = priv->rx_ring_noc + idx * priv->soc->rxd_size;
> > 
> > -       priv->rx_ring_noc[idx].rxd_info2.DDONE = 0;
> > -       priv->rx_ring_noc[idx].rxd_info2.LS0 = 0;
> > -       priv->rx_ring_noc[idx].rxd_info2.PLEN0 = PKTSIZE_ALIGN;
> > +       rxd->rxd2 = PDMA_RXD2_PLEN0_SET(PKTSIZE_ALIGN);
> > 
> >         mtk_pdma_write(priv, RX_CRX_IDX_REG(0), idx);
> >         priv->rx_dma_owner_idx0 = (priv->rx_dma_owner_idx0 + 1) %
> > NUM_RX_DESC;
> > @@ -1387,11 +1331,11 @@ static int mtk_eth_probe(struct udevice
> > *dev)
> >                 return ret;
> > 
> >         /* Prepare for tx/rx rings */
> > -       priv->tx_ring_noc = (struct pdma_txdesc *)
> > -               noncached_alloc(sizeof(struct pdma_txdesc) *
> > NUM_TX_DESC,
> > +       priv->tx_ring_noc = (void *)
> > +               noncached_alloc(priv->soc->txd_size * NUM_TX_DESC,
> >                                 ARCH_DMA_MINALIGN);
> > -       priv->rx_ring_noc = (struct pdma_rxdesc *)
> > -               noncached_alloc(sizeof(struct pdma_rxdesc) *
> > NUM_RX_DESC,
> > +       priv->rx_ring_noc = (void *)
> > +               noncached_alloc(priv->soc->rxd_size * NUM_RX_DESC,
> >                                 ARCH_DMA_MINALIGN);
> > 
> >         /* Set MAC mode */
> > @@ -1548,18 +1492,26 @@ static int mtk_eth_of_to_plat(struct
> > udevice *dev)
> > 
> >  static const struct mtk_soc_data mt7629_data = {
> >         .ana_rgc3 = 0x128,
> > +       .txd_size = sizeof(struct mtk_tx_dma),
> > +       .rxd_size = sizeof(struct mtk_rx_dma),
> >  };
> > 
> >  static const struct mtk_soc_data mt7623_data = {
> >         .caps = MT7623_CAPS,
> > +       .txd_size = sizeof(struct mtk_tx_dma),
> > +       .rxd_size = sizeof(struct mtk_rx_dma),
> >  };
> > 
> >  static const struct mtk_soc_data mt7622_data = {
> >         .ana_rgc3 = 0x2028,
> > +       .txd_size = sizeof(struct mtk_tx_dma),
> > +       .rxd_size = sizeof(struct mtk_rx_dma),
> >  };
> > 
> >  static const struct mtk_soc_data mt7621_data = {
> >         .caps = MT7621_CAPS,
> > +       .txd_size = sizeof(struct mtk_tx_dma),
> > +       .rxd_size = sizeof(struct mtk_rx_dma),
> >  };
> > 
> >  static const struct udevice_id mtk_eth_ids[] = {
> > diff --git a/drivers/net/mtk_eth.h b/drivers/net/mtk_eth.h
> > index 15c2030617..65bc9fcc04 100644
> > --- a/drivers/net/mtk_eth.h
> > +++ b/drivers/net/mtk_eth.h
> > @@ -10,6 +10,7 @@
> >  #define _MTK_ETH_H_
> > 
> >  #include <linux/bitops.h>
> > +#include <linux/bitfield.h>
> > 
> >  enum mkt_eth_capabilities {
> >         MTK_TRGMII_BIT,
> > @@ -435,4 +436,35 @@ enum mkt_eth_capabilities {
> >  #define PHY_POWER_SAVING_M             0x300
> >  #define PHY_POWER_SAVING_TX            0x0
> > 
> > +/* PDMA descriptors */
> > +struct mtk_rx_dma {
> > +       unsigned int rxd1;
> > +       unsigned int rxd2;
> > +       unsigned int rxd3;
> > +       unsigned int rxd4;
> > +} __packed __aligned(4);
> > +
> > +struct mtk_tx_dma {
> > +       unsigned int txd1;
> > +       unsigned int txd2;
> > +       unsigned int txd3;
> > +       unsigned int txd4;
> > +} __packed __aligned(4);
> > +
> > +/* PDMA TXD fields */
> > +#define PDMA_TXD2_DDONE                        BIT(31)
> > +#define PDMA_TXD2_LS0                  BIT(30)
> > +#define PDMA_TXD2_SDL0_M               GENMASK(29, 16)
> > +#define PDMA_TXD2_SDL0_SET(_v) FIELD_PREP(PDMA_TXD2_SDL0_M, (_v))
> > +
> > +#define PDMA_TXD4_FPORT_M              GENMASK(27, 25)
> > +#define
> > PDMA_TXD4_FPORT_SET(_v)        FIELD_PREP(PDMA_TXD4_FPORT_M, (_v))
> > +
> > +/* PDMA RXD fields */
> > +#define PDMA_RXD2_DDONE                        BIT(31)
> > +#define PDMA_RXD2_LS0                  BIT(30)
> > +#define PDMA_RXD2_PLEN0_M              GENMASK(29, 16)
> > +#define
> > PDMA_RXD2_PLEN0_GET(_v)        FIELD_GET(PDMA_RXD2_PLEN0_M, (_v))
> > +#define
> > PDMA_RXD2_PLEN0_SET(_v)        FIELD_PREP(PDMA_RXD2_PLEN0_M, (_v))
> > +
> >  #endif /* _MTK_ETH_H_ */
> > --
> > 2.17.1
> > 
> 
> Commit topic has typo in fields

That's a mistake. I'll fix it in v2.

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 10/31] serial: mtk: add support for using dynamic baud clock souce
  2022-08-04 13:56   ` Simon Glass
@ 2022-08-08  2:36     ` Weijie Gao
  2022-08-08 19:26       ` Simon Glass
  0 siblings, 1 reply; 100+ messages in thread
From: Weijie Gao @ 2022-08-08  2:36 UTC (permalink / raw)
  To: Simon Glass; +Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream, Pali Rohár

On Thu, 2022-08-04 at 07:56 -0600, Simon Glass wrote:
> Hi Weijie,
> 
> On Wed, 3 Aug 2022 at 21:36, Weijie Gao <weijie.gao@mediatek.com>
> wrote:
> > 
> > The baud clock on some platform may change due to assigned-clock-
> > parent
> > set in DT. In current flow the baud clock is only retrieved during
> > probe
> > stage. If the parent of the source clock changes after probe stage,
> > the
> > setbrg will set wrong baudrate.
> > 
> > To get the right clock rate, this patch records the baud clk struct
> > to the
> > driver's priv, and changes the driver's flow to get the clock rate
> > before
> > calling _mtk_serial_setbrg().
> > 
> > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> > ---
> >  drivers/serial/serial_mtk.c | 72 ++++++++++++++++++++-------------
> > ----
> >  1 file changed, 39 insertions(+), 33 deletions(-)
> 
> Reviewed-by: Simon Glass <sjg@chromium.org>
> 
> please see below
> 
> > 
> > diff --git a/drivers/serial/serial_mtk.c
> > b/drivers/serial/serial_mtk.c
> > index a84f39b3fa..99cf62b8d9 100644
> > --- a/drivers/serial/serial_mtk.c
> > +++ b/drivers/serial/serial_mtk.c
> > @@ -10,6 +10,7 @@
> >  #include <common.h>
> >  #include <div64.h>
> >  #include <dm.h>
> > +#include <dm/device_compat.h>
> >  #include <errno.h>
> >  #include <log.h>
> >  #include <serial.h>
> > @@ -72,25 +73,27 @@ struct mtk_serial_regs {
> > 
> >  struct mtk_serial_priv {
> 
> please add a full comment for this struct

OK.

> 
> >         struct mtk_serial_regs __iomem *regs;
> > -       u32 clock;
> > +       struct clk clk;
> > +       u32 fixed_clk_rate;
> >         bool force_highspeed;
> >  };
> > 
> > -static void _mtk_serial_setbrg(struct mtk_serial_priv *priv, int
> > baud)
> > +static void _mtk_serial_setbrg(struct mtk_serial_priv *priv, int
> > baud,
> > +                              u32 clk_rate)
> 
> Why u32? Can you use uint? Generally it is better for parameters to
> use natural types unless there is a good reason.

In fact u32 is identical to uint.

<asm-generic/int-ll64.h>: typedef __u32 u32;
<asm-generic/int-ll64.h>: typedef unsigned int __u32;

<linux/types.h>: typedef unsigned int uint;

> 
> [..]
> 
> Regards,
> Simon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 17/31] i2c: add support for MediaTek I2C interface
  2022-08-04 13:57   ` Simon Glass
@ 2022-08-08  3:00     ` Weijie Gao
  0 siblings, 0 replies; 100+ messages in thread
From: Weijie Gao @ 2022-08-08  3:00 UTC (permalink / raw)
  To: Simon Glass; +Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream, Heiko Schocher

On Thu, 2022-08-04 at 07:57 -0600, Simon Glass wrote:
> Hi Weijie,
> 
> On Wed, 3 Aug 2022 at 21:38, Weijie Gao <weijie.gao@mediatek.com>
> wrote:
> > 
> > This patch adds support for MediaTek I2C interface
> > 
> > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> > ---
> >  drivers/i2c/Kconfig   |   9 +
> >  drivers/i2c/Makefile  |   1 +
> >  drivers/i2c/mtk_i2c.c | 822
> > ++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 832 insertions(+)
> >  create mode 100644 drivers/i2c/mtk_i2c.c
> > 
> 
> Reviewed-by: Simon Glass <sjg@chromium.org>
> 
> [..]
> 
> > diff --git a/drivers/i2c/mtk_i2c.c b/drivers/i2c/mtk_i2c.c
> > new file mode 100644
> > index 0000000000..1d4a93f8c9
> > --- /dev/null
> > +++ b/drivers/i2c/mtk_i2c.c
> > @@ -0,0 +1,822 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * Copyright (C) 2022 MediaTek Inc. All Rights Reserved.
> > + *
> > + * Author: Mingming Lee <Mingming.Lee@mediatek.com>
> > + *
> > + * MediaTek I2C Interface driver
> > + */
> > +
> > +#include <clk.h>
> > +#include <cpu_func.h>
> > +#include <dm.h>
> > +#include <i2c.h>
> > +#include <log.h>
> > +#include <asm/cache.h>
> > +#include <asm/io.h>
> > +#include <linux/delay.h>
> > +#include <linux/errno.h>
> > +
> 
> [..]
> 
> > +
> > +U_BOOT_DRIVER(mtk_i2c) = {
> > +       .name           = "mtk_i2c",
> > +       .id             = UCLASS_I2C,
> > +       .of_match       = mtk_i2c_ids,
> > +       .of_to_plat     = mtk_i2c_ofdata_to_platdata,
> 
> mtk_i2c_of_to_plat (for consistency)

OK.

> 
> > +       .probe          = mtk_i2c_probe,
> > +       .priv_auto      = sizeof(struct mtk_i2c_priv),
> > +       .ops            = &mtk_i2c_ops,
> > +};
> > --
> > 2.17.1
> > 
> 
> Regards,
> Simon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 22/31] clk: mediatek: add CLK_BYPASS_XTAL flag to allow bypassing searching clock parent of xtal clock
  2022-08-04 13:57   ` Simon Glass
@ 2022-08-08  3:01     ` Weijie Gao
  0 siblings, 0 replies; 100+ messages in thread
From: Weijie Gao @ 2022-08-08  3:01 UTC (permalink / raw)
  To: Simon Glass
  Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream, Lukasz Majewski,
	Sean Anderson

On Thu, 2022-08-04 at 07:57 -0600, Simon Glass wrote:
> Hi Weijie,
> 
> On Wed, 3 Aug 2022 at 21:39, Weijie Gao <weijie.gao@mediatek.com>
> wrote:
> > 
> > The mtk clock framework in u-boot uses array index for searching
> > clock
> > parent (kernel uses strings for search), so we need to specify a
> > special
> > clock with ID=0 for CLK_XTAL in u-boot.
> > 
> > In the mt7622/mt7629 clock tree, the clocks with ID=0 never call
> > mtk_topckgen_get_mux_rate, adn return xtal clock directly. This
> > what we
> > expected.
> > 
> > However for newer chips, they may have some clocks with ID=0 not
> > representing the xtal clock and still needs
> > mtk_topckgen_get_mux_rate be
> > called. Current logic will make entire clock driver not working.
> > 
> > This patch adds a flag to indicate that whether a clock driver
> > needs clocks
> > with ID=0 to call mtk_topckgen_get_mux_rate.
> > 
> > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> > ---
> >  drivers/clk/mediatek/clk-mtk.c | 5 ++++-
> >  drivers/clk/mediatek/clk-mtk.h | 3 +++
> >  2 files changed, 7 insertions(+), 1 deletion(-)
> 
> Reviewed-by: Simon Glass <sjg@chromium.org>
> 
> > 
> > diff --git a/drivers/clk/mediatek/clk-mtk.c
> > b/drivers/clk/mediatek/clk-mtk.c
> > index d43b8a0648..d99ea55df0 100644
> > --- a/drivers/clk/mediatek/clk-mtk.c
> > +++ b/drivers/clk/mediatek/clk-mtk.c
> > @@ -314,12 +314,15 @@ static ulong mtk_topckgen_get_mux_rate(struct
> > clk
> >  *clk, u32 off)
> >         struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
> >         const struct mtk_composite *mux = &priv->tree->muxes[off];
> >         u32 index;
> > +       u32 flag = 0;
> > 
> >         index = readl(priv->base + mux->mux_reg);
> >         index &= mux->mux_mask << mux->mux_shift;
> >         index = index >> mux->mux_shift;
> > 
> > -       if (mux->parent[index])
> > +       if (mux->parent[index] == CLK_XTAL && priv->tree->flags &
> > CLK_BYPASS_XTAL)
> > +               flag = 1;
> > +       if (mux->parent[index] > 0 || flag == 1)
> >                 return mtk_clk_find_parent_rate(clk, mux-
> > >parent[index],
> >                                                 NULL);
> > 
> > diff --git a/drivers/clk/mediatek/clk-mtk.h
> > b/drivers/clk/mediatek/clk-mtk.h
> > index 95a23d14a8..0ab6912bf0 100644
> > --- a/drivers/clk/mediatek/clk-mtk.h
> > +++ b/drivers/clk/mediatek/clk-mtk.h
> > @@ -11,6 +11,8 @@
> >  #define CLK_XTAL                       0
> >  #define MHZ                            (1000 * 1000)
> > 
> > +#define CLK_BYPASS_XTAL                        BIT(0)
> > +
> >  #define HAVE_RST_BAR                   BIT(0)
> >  #define CLK_DOMAIN_SCPSYS              BIT(0)
> >  #define CLK_MUX_SETCLR_UPD             BIT(1)
> > @@ -197,6 +199,7 @@ struct mtk_clk_tree {
> >         const struct mtk_fixed_clk *fclks;
> >         const struct mtk_fixed_factor *fdivs;
> >         const struct mtk_composite *muxes;
> > +       u32 flags;
> 
> This needs a comment as to what the flags mean

OK.

> 
> >  };
> > 
> >  struct mtk_clk_priv {
> > --
> > 2.17.1
> > 
> 
> Regards,
> Simon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 25/31] clk: mediatek: add CLK_XTAL support for clock driver
  2022-08-04 13:57   ` Simon Glass
@ 2022-08-08  3:10     ` Weijie Gao
  0 siblings, 0 replies; 100+ messages in thread
From: Weijie Gao @ 2022-08-08  3:10 UTC (permalink / raw)
  To: Simon Glass
  Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream, Lukasz Majewski,
	Sean Anderson

On Thu, 2022-08-04 at 07:57 -0600, Simon Glass wrote:
> Hi Weijie,
> 
> On Wed, 3 Aug 2022 at 21:40, Weijie Gao <weijie.gao@mediatek.com>
> wrote:
> > 
> > This add CLK_XTAL macro and flag to mediatek clock driver common
> > part,
> > to make thi SoC that has clock directlly connect to XTAL working.
> > 
> > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> > ---
> >  drivers/clk/mediatek/clk-mtk.c | 3 +++
> >  drivers/clk/mediatek/clk-mtk.h | 3 ++-
> >  2 files changed, 5 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/clk/mediatek/clk-mtk.c
> > b/drivers/clk/mediatek/clk-mtk.c
> > index be3846c85b..5a4650d137 100644
> > --- a/drivers/clk/mediatek/clk-mtk.c
> > +++ b/drivers/clk/mediatek/clk-mtk.c
> > @@ -296,6 +296,7 @@ static ulong
> > mtk_topckgen_get_factor_rate(struct clk
> >  *clk, u32 off)
> >                 rate = mtk_clk_find_parent_rate(clk, fdiv->parent,
> > NULL);
> >                 break;
> > 
> > +       case CLK_PARENT_XTAL:
> >         default:
> >                 rate = priv->tree->xtal_rate;
> >         }
> > @@ -314,6 +315,8 @@ static ulong
> > mtk_infrasys_get_factor_rate(struct clk
> >  *clk, u32 off)
> >                 rate = mtk_clk_find_parent_rate(clk, fdiv->parent,
> >                                                 priv->parent);
> >                 break;
> > +       case CLK_PARENT_XTAL:
> > +               rate = priv->tree->xtal_rate;
> 
> Please document the fall-through here, if it is not a bug.

This is indeed a bug. I'll fix it.

> 
> >         default:
> >                 rate = mtk_clk_find_parent_rate(clk, fdiv->parent,
> > NULL);
> >         }
> > diff --git a/drivers/clk/mediatek/clk-mtk.h
> > b/drivers/clk/mediatek/clk-mtk.h
> > index 8536275671..211356697b 100644
> > --- a/drivers/clk/mediatek/clk-mtk.h
> > +++ b/drivers/clk/mediatek/clk-mtk.h
> > @@ -26,7 +26,8 @@
> >  #define CLK_PARENT_APMIXED             BIT(4)
> >  #define CLK_PARENT_TOPCKGEN            BIT(5)
> >  #define CLK_PARENT_INFRASYS            BIT(6)
> > -#define CLK_PARENT_MASK                        GENMASK(6, 4)
> > +#define CLK_PARENT_XTAL                        BIT(7)
> > +#define CLK_PARENT_MASK                        GENMASK(7, 4)
> > 
> >  #define ETHSYS_HIFSYS_RST_CTRL_OFS     0x34
> > 
> > --
> > 2.17.1
> > 
> 
> REgards,
> Simon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 26/31] clk: mediatek: add clock driver support for MediaTek MT7986 SoC
  2022-08-04 13:57   ` Simon Glass
@ 2022-08-08  3:13     ` Weijie Gao
  0 siblings, 0 replies; 100+ messages in thread
From: Weijie Gao @ 2022-08-08  3:13 UTC (permalink / raw)
  To: Simon Glass
  Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream, Lukasz Majewski,
	Sean Anderson

On Thu, 2022-08-04 at 07:57 -0600, Simon Glass wrote:
> Hi Weijie,
> 
> On Wed, 3 Aug 2022 at 21:40, Weijie Gao <weijie.gao@mediatek.com>
> wrote:
> > 
> > This patch adds clock driver support for MediaTek MT7986 SoC
> > 
> > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> > ---
> >  drivers/clk/mediatek/Makefile          |   1 +
> >  drivers/clk/mediatek/clk-mt7986.c      | 671
> > +++++++++++++++++++++++++
> >  include/dt-bindings/clock/mt7986-clk.h | 249 +++++++++
> >  3 files changed, 921 insertions(+)
> >  create mode 100644 drivers/clk/mediatek/clk-mt7986.c
> >  create mode 100644 include/dt-bindings/clock/mt7986-clk.h
> > 
> 
> Reviewed-by: Simon Glass <sjg@chromium.org>
> 
> [..]
> 
> > new file mode 100644
> > index 0000000000..11c489cd50
> > --- /dev/null
> > +++ b/drivers/clk/mediatek/clk-mt7986.c
> > @@ -0,0 +1,671 @@
> 
> 
> [..]
> 
> > +static int mt7986_topckgen_probe(struct udevice *dev)
> > +{
> > +       struct mtk_clk_priv *priv = dev_get_priv(dev);
> > +
> > +       priv->base = dev_read_addr_ptr(dev);
> > +       writel(MT7986_CLK_PDN_EN_WRITE, priv->base +
> > MT7986_CLK_PDN);
> 
> blank line here

OK.

> 
> > +       return mtk_common_clk_init(dev, &mt7986_topckgen_clk_tree);
> > +}
> > +
> > +U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
> > +       .name = "mt7986-clock-fixed-pll",
> > +       .id = UCLASS_CLK,
> > +       .of_match = mt7986_fixed_pll_compat,
> > +       .probe = mt7986_fixed_pll_probe,
> > +       .priv_auto = sizeof(struct mtk_clk_priv),
> > +       .ops = &mtk_clk_topckgen_ops,
> > +       .flags = DM_FLAG_PRE_RELOC,
> > +};
> > +
> > +U_BOOT_DRIVER(mtk_clk_topckgen) = {
> > +       .name = "mt7986-clock-topckgen",
> > +       .id = UCLASS_CLK,
> > +       .of_match = mt7986_topckgen_compat,
> > +       .probe = mt7986_topckgen_probe,
> > +       .priv_auto = sizeof(struct mtk_clk_priv),
> > +       .ops = &mtk_clk_topckgen_ops,
> > +       .flags = DM_FLAG_PRE_RELOC,
> > +};
> > +
> > +static const struct udevice_id mt7986_infracfg_compat[] = {
> > +       { .compatible = "mediatek,mt7986-infracfg" },
> > +       {}
> > +};
> > +
> > +static const struct udevice_id mt7986_infracfg_ao_compat[] = {
> > +       { .compatible = "mediatek,mt7986-infracfg_ao" },
> > +       {}
> > +};
> > +
> > +static int mt7986_infracfg_probe(struct udevice *dev)
> > +{
> > +       return mtk_common_clk_init(dev, &mt7986_infracfg_clk_tree);
> > +}
> > +
> > +static int mt7986_infracfg_ao_probe(struct udevice *dev)
> > +{
> > +       return mtk_common_clk_gate_init(dev,
> > &mt7986_infracfg_clk_tree,
> > +                                       infracfg_ao_gates);
> > +}
> > +
> > +U_BOOT_DRIVER(mtk_clk_infracfg) = {
> > +       .name = "mt7986-clock-infracfg",
> > +       .id = UCLASS_CLK,
> > +       .of_match = mt7986_infracfg_compat,
> > +       .probe = mt7986_infracfg_probe,
> > +       .priv_auto = sizeof(struct mtk_clk_priv),
> > +       .ops = &mtk_clk_infrasys_ops,
> > +       .flags = DM_FLAG_PRE_RELOC,
> > +};
> > +
> > +U_BOOT_DRIVER(mtk_clk_infracfg_ao) = {
> > +       .name = "mt7986-clock-infracfg-ao",
> > +       .id = UCLASS_CLK,
> > +       .of_match = mt7986_infracfg_ao_compat,
> > +       .probe = mt7986_infracfg_ao_probe,
> > +       .priv_auto = sizeof(struct mtk_cg_priv),
> > +       .ops = &mtk_clk_gate_ops,
> > +       .flags = DM_FLAG_PRE_RELOC,
> > +};
> > +
> > +/* ethsys */
> > +static const struct mtk_gate_regs eth_cg_regs = {
> > +       .sta_ofs = 0x30,
> > +};
> > +
> > +#define GATE_ETH(_id, _name, _parent, _shift)
> >     \
> > +       {                                                          
> >             \
> > +               .id = _id, .parent = _parent, .regs =
> > &eth_cg_regs,            \
> > +               .shift =
> > _shift,                                               \
> > +               .flags = CLK_GATE_NO_SETCLR_INV |
> > CLK_PARENT_TOPCKGEN,         \
> > +       }
> > +
> > +static const struct mtk_gate eth_cgs[] = {
> > +       GATE_ETH(CK_ETH_FE_EN, "eth_fe_en", CK_TOP_NETSYS_2X, 7),
> > +       GATE_ETH(CK_ETH_GP2_EN, "eth_gp2_en", CK_TOP_SGM_325M, 8),
> > +       GATE_ETH(CK_ETH_GP1_EN, "eth_gp1_en", CK_TOP_SGM_325M, 8),
> > +       GATE_ETH(CK_ETH_WOCPU1_EN, "eth_wocpu1_en",
> > CK_TOP_NETSYS_WED_MCU, 14),
> > +       GATE_ETH(CK_ETH_WOCPU0_EN, "eth_wocpu0_en",
> > CK_TOP_NETSYS_WED_MCU, 15),
> > +};
> > +
> > +static int mt7986_ethsys_probe(struct udevice *dev)
> > +{
> > +       return mtk_common_clk_gate_init(dev,
> > &mt7986_topckgen_clk_tree,
> > +                                       eth_cgs);
> > +}
> > +
> > +static int mt7986_ethsys_bind(struct udevice *dev)
> > +{
> > +       int ret = 0;
> > +
> > +#if CONFIG_IS_ENABLED(RESET_MEDIATEK)
> 
> if (CONFIG_IS_ENABLED()...

OK.

> 
> > +       ret = mediatek_reset_bind(dev, ETHSYS_HIFSYS_RST_CTRL_OFS,
> > 1);
> > +       if (ret)
> > +               debug("Warning: failed to bind reset
> > controller\n");
> > +#endif
> > +
> > +       return ret;
> > +}
> > +
> > +static const struct udevice_id mt7986_ethsys_compat[] = {
> > +       { .compatible = "mediatek,mt7986-ethsys" },
> > +       { }
> > +};
> > +
> > +U_BOOT_DRIVER(mtk_clk_ethsys) = {
> > +       .name = "mt7986-clock-ethsys",
> > +       .id = UCLASS_CLK,
> > +       .of_match = mt7986_ethsys_compat,
> > +       .probe = mt7986_ethsys_probe,
> > +       .bind = mt7986_ethsys_bind,
> > +       .priv_auto = sizeof(struct mtk_cg_priv),
> > +       .ops = &mtk_clk_gate_ops,
> > +};
> 
> Regards,
> Simon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 27/31] clk: mediatek: add clock driver support for MediaTek MT7981 SoC
  2022-08-04 13:57   ` Simon Glass
@ 2022-08-08  3:18     ` Weijie Gao
  0 siblings, 0 replies; 100+ messages in thread
From: Weijie Gao @ 2022-08-08  3:18 UTC (permalink / raw)
  To: Simon Glass
  Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream, Lukasz Majewski,
	Sean Anderson

On Thu, 2022-08-04 at 07:57 -0600, Simon Glass wrote:
> Hi Weijie,
> 
> On Wed, 3 Aug 2022 at 21:40, Weijie Gao <weijie.gao@mediatek.com>
> wrote:
> > 
> > This patch adds clock driver support for MediaTek MT7981 SoC
> > 
> > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> > ---
> >  drivers/clk/mediatek/Makefile          |   1 +
> >  drivers/clk/mediatek/clk-mt7981.c      | 682
> > +++++++++++++++++++++++++
> >  include/dt-bindings/clock/mt7981-clk.h | 267 ++++++++++
> >  3 files changed, 950 insertions(+)
> >  create mode 100644 drivers/clk/mediatek/clk-mt7981.c
> >  create mode 100644 include/dt-bindings/clock/mt7981-clk.h
> 
> Reviewed-by: Simon Glass <sjg@chromium.org>
> 
> use if CONFIG_IS_ENABLED(RESET_MEDIATEK)

OK.

> 
> Regards,
> Simon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 29/31] tools: mtk_image: split the code of generating NAND header into a new file
  2022-08-04 13:57   ` Simon Glass
@ 2022-08-08  3:23     ` Weijie Gao
  0 siblings, 0 replies; 100+ messages in thread
From: Weijie Gao @ 2022-08-08  3:23 UTC (permalink / raw)
  To: Simon Glass
  Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream, AKASHI Takahiro,
	Pali Rohár, Stefan Roese, Andre Przywara, Samuel Holland

On Thu, 2022-08-04 at 07:57 -0600, Simon Glass wrote:
> Hi Weijie,
> 
> On Wed, 3 Aug 2022 at 21:37, Weijie Gao <weijie.gao@mediatek.com>
> wrote:
> > 
> > The predefined NAND headers take too much spaces in the
> > mtk_image.c.
> > Moving them into a new file can significantly improve the
> > readability of
> > both mtk_image.c and the new mtk_nand_headers.c.
> > 
> > This is a preparation for adding more NAND headers.
> > 
> > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> > ---
> >  tools/Makefile           |   1 +
> >  tools/mtk_image.c        | 304 ++++++-----------------------------
> > ----
> >  tools/mtk_image.h        |  25 ----
> >  tools/mtk_nand_headers.c | 286
> > ++++++++++++++++++++++++++++++++++++
> >  tools/mtk_nand_headers.h |  52 +++++++
> >  5 files changed, 379 insertions(+), 289 deletions(-)
> >  create mode 100644 tools/mtk_nand_headers.c
> >  create mode 100644 tools/mtk_nand_headers.h
> 
> Reviewed-by: Simon Glass <sjg@chromium.org>
> 
> [..]
> 
> > new file mode 100644
> > index 0000000000..691db85005
> > --- /dev/null
> > +++ b/tools/mtk_nand_headers.h
> > @@ -0,0 +1,52 @@
> > +/* SPDX-License-Identifier: GPL-2.0+ */
> > +/*
> > + * MediaTek BootROM NAND header definitions
> > + *
> > + * Copyright (C) 2022 MediaTek Inc.
> > + * Author: Weijie Gao <weijie.gao@mediatek.com>
> > + */
> > +
> > +#ifndef _MTK_NAND_HEADERS_H
> > +#define _MTK_NAND_HEADERS_H
> > +
> > +#include <stdint.h>
> > +#include <stdbool.h>
> > +
> > +struct nand_header_info {
> > +       uint32_t page_size;
> > +       uint32_t spare_size;
> > +       uint32_t gfh_offset;
> > +};
> > +
> > +/* AP BROM Header for NAND */
> 
> Where is this documented?

This wasn't documented. The bootrom doesn't know the configuration
of the nand device. It has to read the first page to retrive necessary
information from this header.

> 
> > +union nand_boot_header {
> > +       struct {
> > +               char name[12];
> > +               char version[4];
> > +               char id[8];
> > +               uint16_t ioif;
> > +               uint16_t pagesize;
> > +               uint16_t addrcycles;
> > +               uint16_t oobsize;
> > +               uint16_t pages_of_block;
> > +               uint16_t numblocks;
> > +               uint16_t writesize_shift;
> > +               uint16_t erasesize_shift;
> > +               uint8_t dummy[60];
> > +               uint8_t ecc_parity[28];
> > +       };
> > +
> > +       uint8_t data[0x80];
> > +};
> > +
> > +#define NAND_BOOT_NAME         "BOOTLOADER!"
> > +#define NAND_BOOT_VERSION      "V006"
> > +#define NAND_BOOT_ID           "NFIINFO"
> > +
> > +const union nand_boot_header *mtk_nand_header_find(const char
> > *name);
> > +uint32_t mtk_nand_header_size(const union nand_boot_header
> > *hdr_nand);
> > +int mtk_nand_header_info(const void *ptr, struct nand_header_info
> > *info);
> > +bool is_mtk_nand_header(const void *ptr);
> > +uint32_t mtk_nand_header_put(const union nand_boot_header
> > *hdr_nand, void
> >  *ptr);
> 
> Please comment each of these.

OK.

> 
> > +
> > +#endif /* _MTK_NAND_HEADERS_H */
> > --
> > 2.17.1
> > 
> 
> Regards,
> SImon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 29/31] tools: mtk_image: split the code of generating NAND header into a new file
  2022-08-05 18:26   ` Daniel Golle
@ 2022-08-08  3:26     ` Weijie Gao
  0 siblings, 0 replies; 100+ messages in thread
From: Weijie Gao @ 2022-08-08  3:26 UTC (permalink / raw)
  To: Daniel Golle
  Cc: u-boot, GSS_MTK_Uboot_upstream, Simon Glass, AKASHI Takahiro,
	Pali Rohár, Stefan Roese, Andre Przywara, Samuel Holland

On Fri, 2022-08-05 at 20:26 +0200, Daniel Golle wrote:
> Hi Weijie,
> 
> please see one comment in-line below:
> 
> On Thu, Aug 04, 2022 at 11:36:50AM +0800, Weijie Gao wrote:
> > The predefined NAND headers take too much spaces in the
> > mtk_image.c.
> > Moving them into a new file can significantly improve the
> > readability of
> > both mtk_image.c and the new mtk_nand_headers.c.
> > 
> > This is a preparation for adding more NAND headers.
> > 
> > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> > ---
> >  tools/Makefile           |   1 +
> >  tools/mtk_image.c        | 304 ++++++-----------------------------
> > ----
> >  tools/mtk_image.h        |  25 ----
> >  tools/mtk_nand_headers.c | 286
> > ++++++++++++++++++++++++++++++++++++
> >  tools/mtk_nand_headers.h |  52 +++++++
> >  5 files changed, 379 insertions(+), 289 deletions(-)
> >  create mode 100644 tools/mtk_nand_headers.c
> >  create mode 100644 tools/mtk_nand_headers.h
> > 
> > diff --git a/tools/Makefile b/tools/Makefile
> > index 9f2339666a..4f27ed1ab1 100644
> > --- a/tools/Makefile
> > +++ b/tools/Makefile
> > @@ -147,6 +147,7 @@ dumpimage-mkimage-objs := aisimage.o \
> >  			gpimage.o \
> >  			gpimage-common.o \
> >  			mtk_image.o \
> > +			mtk_nand_headers.o \
> >  			$(ECDSA_OBJS-y) \
> >  			$(RSA_OBJS-y) \
> >  			$(AES_OBJS-y)
> > diff --git a/tools/mtk_image.c b/tools/mtk_image.c
> > index dcd6525f32..3701d1564a 100644
> > --- a/tools/mtk_image.c
> > +++ b/tools/mtk_image.c
> > @@ -12,216 +12,7 @@
> >  #include <u-boot/sha256.h>
> >  #include "imagetool.h"
> >  #include "mtk_image.h"
> > -
> > -/* NAND header for SPI-NAND with 2KB page + 64B spare */
> > -static const union nand_boot_header snand_hdr_2k_64_data = {
> > -	.data = {
> > -		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> > -		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> > -		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> > -		0x00, 0x00, 0x00, 0x08, 0x03, 0x00, 0x40, 0x00,
> > -		0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x7B, 0xC4, 0x17, 0x9D,
> > -		0xCA, 0x42, 0x90, 0xD0, 0x98, 0xD0, 0xE0, 0xF7,
> > -		0xDB, 0xCD, 0x16, 0xF6, 0x03, 0x73, 0xD2, 0xB8,
> > -		0x93, 0xB2, 0x56, 0x5A, 0x84, 0x6E, 0x00, 0x00
> > -	}
> > -};
> > -
> > -/* NAND header for SPI-NAND with 2KB page + 120B/128B spare */
> > -static const union nand_boot_header snand_hdr_2k_128_data = {
> > -	.data = {
> > -		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> > -		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> > -		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> > -		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
> > -		0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x90, 0x28, 0xED, 0x13,
> > -		0x7F, 0x12, 0x22, 0xCD, 0x3D, 0x06, 0xF1, 0xB3,
> > -		0x6F, 0x2E, 0xD9, 0xA0, 0x9D, 0x7A, 0xBD, 0xD7,
> > -		0xB3, 0x28, 0x3C, 0x13, 0xDB, 0x4E, 0x00, 0x00
> > -	}
> > -};
> > -
> > -/* NAND header for SPI-NAND with 4KB page + 256B spare */
> > -static const union nand_boot_header snand_hdr_4k_256_data = {
> > -	.data = {
> > -		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> > -		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> > -		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> > -		0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0xE0, 0x00,
> > -		0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x47, 0xED, 0x0E, 0xC3,
> > -		0x83, 0xBF, 0x41, 0xD2, 0x85, 0x21, 0x97, 0x57,
> > -		0xC4, 0x2E, 0x6B, 0x7A, 0x40, 0xE0, 0xCF, 0x8F,
> > -		0x37, 0xBD, 0x17, 0xB6, 0xC7, 0xFE, 0x00, 0x00
> > -	}
> > -};
> > -
> > -/* NAND header for Parallel NAND 1Gb with 2KB page + 64B spare */
> > -static const union nand_boot_header nand_hdr_1gb_2k_64_data = {
> > -	.data = {
> > -		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> > -		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> > -		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> > -		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
> > -		0x40, 0x00, 0x00, 0x04, 0x0B, 0x00, 0x11, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x1C, 0x12,
> > -		0x8F, 0xFD, 0xF8, 0x32, 0x6F, 0x6D, 0xCF, 0x6C,
> > -		0xDA, 0x21, 0x70, 0x8C, 0xDA, 0x0A, 0x22, 0x82,
> > -		0xAA, 0x59, 0xFA, 0x7C, 0x42, 0x2D, 0x00, 0x00
> > -	}
> > -};
> > -
> > -/* NAND header for Parallel NAND 2Gb with 2KB page + 64B spare */
> > -static const union nand_boot_header nand_hdr_2gb_2k_64_data = {
> > -	.data = {
> > -		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> > -		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> > -		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> > -		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
> > -		0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x20, 0x9C, 0x3D, 0x2D,
> > -		0x7B, 0x68, 0x63, 0x52, 0x2E, 0x04, 0x63, 0xF1,
> > -		0x35, 0x4E, 0x44, 0x3E, 0xF8, 0xAC, 0x9B, 0x95,
> > -		0xAB, 0xFE, 0xE4, 0xE1, 0xD5, 0xF9, 0x00, 0x00
> > -	}
> > -};
> > -
> > -/* NAND header for Parallel NAND 4Gb with 2KB page + 64B spare */
> > -static const union nand_boot_header nand_hdr_4gb_2k_64_data = {
> > -	.data = {
> > -		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> > -		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> > -		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> > -		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
> > -		0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0xE3, 0x0F, 0x86, 0x32,
> > -		0x68, 0x05, 0xD9, 0xC8, 0x13, 0xDF, 0xC5, 0x0B,
> > -		0x35, 0x3A, 0x68, 0xA5, 0x3C, 0x0C, 0x73, 0x87,
> > -		0x63, 0xB0, 0xBE, 0xCC, 0x84, 0x47, 0x00, 0x00
> > -	}
> > -};
> > -
> > -/* NAND header for Parallel NAND 2Gb with 2KB page + 128B spare */
> > -static const union nand_boot_header nand_hdr_2gb_2k_128_data = {
> > -	.data = {
> > -		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> > -		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> > -		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> > -		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
> > -		0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x01, 0xA5, 0xE9, 0x5A,
> > -		0xDF, 0x58, 0x62, 0x41, 0xD6, 0x26, 0x77, 0xBC,
> > -		0x76, 0x1F, 0x27, 0x4E, 0x4F, 0x6C, 0xC3, 0xF0,
> > -		0x36, 0xDE, 0xD9, 0xB3, 0xFF, 0x93, 0x00, 0x00
> > -	}
> > -};
> > -
> > -/* NAND header for Parallel NAND 4Gb with 2KB page + 128B spare */
> > -static const union nand_boot_header nand_hdr_4gb_2k_128_data = {
> > -	.data = {
> > -		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> > -		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> > -		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> > -		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
> > -		0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -		0x00, 0x00, 0x00, 0x00, 0xC2, 0x36, 0x52, 0x45,
> > -		0xCC, 0x35, 0xD8, 0xDB, 0xEB, 0xFD, 0xD1, 0x46,
> > -		0x76, 0x6B, 0x0B, 0xD5, 0x8B, 0xCC, 0x2B, 0xE2,
> > -		0xFE, 0x90, 0x83, 0x9E, 0xAE, 0x2D, 0x00, 0x00
> > -	}
> > -};
> > -
> > -static const struct nand_header_type {
> > -	const char *name;
> > -	const union nand_boot_header *data;
> > -} nand_headers[] = {
> > -	{
> > -		.name = "2k+64",
> > -		.data = &snand_hdr_2k_64_data
> > -	}, {
> > -		.name = "2k+120",
> > -		.data = &snand_hdr_2k_128_data
> > -	}, {
> > -		.name = "2k+128",
> > -		.data = &snand_hdr_2k_128_data
> > -	}, {
> > -		.name = "4k+256",
> > -		.data = &snand_hdr_4k_256_data
> > -	}, {
> > -		.name = "1g:2k+64",
> > -		.data = &nand_hdr_1gb_2k_64_data
> > -	}, {
> > -		.name = "2g:2k+64",
> > -		.data = &nand_hdr_2gb_2k_64_data
> > -	}, {
> > -		.name = "4g:2k+64",
> > -		.data = &nand_hdr_4gb_2k_64_data
> > -	}, {
> > -		.name = "2g:2k+128",
> > -		.data = &nand_hdr_2gb_2k_128_data
> > -	}, {
> > -		.name = "4g:2k+128",
> > -		.data = &nand_hdr_4gb_2k_128_data
> > -	}
> > -};
> > +#include "mtk_nand_headers.h"
> >  
> >  static const struct brom_img_type {
> >  	const char *name;
> > @@ -264,6 +55,7 @@ static uint32_t crc32tbl[256];
> >  
> >  /* NAND header selected by user */
> >  static const union nand_boot_header *hdr_nand;
> > +static uint32_t hdr_nand_size;
> >  
> >  /* GFH header + 2 * 4KB pages of NAND */
> >  static char hdr_tmp[sizeof(struct gfh_header) + 0x2000];
> > @@ -402,12 +194,7 @@ static int mtk_brom_parse_imagename(const char
> >  *imagename)
> >  	}
> >  
> >  	/* parse nand header type */
> > -	for (i = 0; i < ARRAY_SIZE(nand_headers); i++) {
> > -		if (!strcmp(nand_headers[i].name, nandinfo)) {
> > -			hdr_nand = nand_headers[i].data;
> > -			break;
> > -		}
> > -	}
> > +	hdr_nand = mtk_nand_header_find(nandinfo);
> >  
> >  	/* parse device header offset */
> >  	if (hdr_offs && hdr_offs[0])
> > @@ -432,6 +219,8 @@ static int mtk_brom_parse_imagename(const char
> >  *imagename)
> >  		return -EINVAL;
> >  	}
> >  
> > +	hdr_nand_size = mtk_nand_header_size(hdr_nand);
> 
> This call has to be guarded and only happen in case of NAND or SNAND,
> otherwise we get segfault because of NULL pointer here in case of
> non-NAND boot media.

I'll fix this.

> 
> > +
> >  	return 0;
> >  }
> >  
> > @@ -468,7 +257,7 @@ static int mtk_image_vrec_header(struct
> >  image_tool_params *params,
> >  	}
> >  
> >  	if (hdr_media == BRLYT_TYPE_NAND || hdr_media ==
> > BRLYT_TYPE_SNAND)
> > -		tparams->header_size = 2 * le16_to_cpu(hdr_nand-
> > >pagesize);
> > +		tparams->header_size = hdr_nand_size;
> >  	else
> >  		tparams->header_size = sizeof(struct
> > gen_device_header);
> >  
> > @@ -566,16 +355,17 @@ static int mtk_image_verify_gen_header(const
> > uint8_t
> >  *ptr, int print)
> >  
> >  static int mtk_image_verify_nand_header(const uint8_t *ptr, int
> > print)
> >  {
> > -	union nand_boot_header *nh = (union nand_boot_header
> > *)ptr;
> >  	struct brom_layout_header *bh;
> > +	struct nand_header_info info;
> >  	struct gfh_header *gfh;
> >  	const char *bootmedia;
> > +	int ret;
> >  
> > -	if (strncmp(nh->version, NAND_BOOT_VERSION, sizeof(nh-
> > >version)) ||
> > -	    strcmp(nh->id, NAND_BOOT_ID))
> > -		return -1;
> > +	ret = mtk_nand_header_info(ptr, &info);
> > +	if (ret < 0)
> > +		return ret;
> >  
> > -	bh = (struct brom_layout_header *)(ptr + le16_to_cpu(nh-
> > >pagesize));
> > +	bh = (struct brom_layout_header *)(ptr + info.page_size);
> >  
> >  	if (strcmp(bh->name, BRLYT_NAME))
> >  		return -1;
> > @@ -586,34 +376,23 @@ static int mtk_image_verify_nand_header(const
> > uint8_t
> >  *ptr, int print)
> >  		if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND)
> >  			bootmedia = "Parallel NAND";
> >  		else if (le32_to_cpu(bh->type) ==
> > BRLYT_TYPE_SNAND)
> > -			bootmedia = "Serial NAND";
> > +			bootmedia = "Serial NAND (SNFI/AP)";
> >  		else
> >  			return -1;
> >  	}
> >  
> >  	if (print) {
> > -		printf("Boot Media: %s\n", bootmedia);
> > -
> > -		if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND) {
> > -			uint64_t capacity =
> > -				(uint64_t)le16_to_cpu(nh-
> > >numblocks) *
> > -				(uint64_t)le16_to_cpu(nh-
> > >pages_of_block) *
> > -				(uint64_t)le16_to_cpu(nh-
> > >pagesize) * 8;
> > -			printf("Capacity:     %dGb\n",
> > -			       (uint32_t)(capacity >> 30));
> > -		}
> > +		printf("Boot Media:   %s\n", bootmedia);
> >  
> > -		if (le16_to_cpu(nh->pagesize) >= 1024)
> > -			printf("Page Size:    %dKB\n",
> > -			       le16_to_cpu(nh->pagesize) >> 10);
> > +		if (info.page_size >= 1024)
> > +			printf("Page Size:    %dKB\n",
> > info.page_size >> 10);
> >  		else
> > -			printf("Page Size:    %dB\n",
> > -			       le16_to_cpu(nh->pagesize));
> > +			printf("Page Size:    %dB\n",
> > info.page_size);
> >  
> > -		printf("Spare Size:   %dB\n", le16_to_cpu(nh-
> > >oobsize));
> > +		printf("Spare Size:   %dB\n", info.spare_size);
> >  	}
> >  
> > -	gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(nh-
> > >pagesize));
> > +	gfh = (struct gfh_header *)(ptr + info.gfh_offset);
> >  
> >  	return mtk_image_verify_gfh(gfh, GFH_FLASH_TYPE_NAND,
> > print);
> >  }
> > @@ -713,7 +492,7 @@ static int mtk_image_verify_header(unsigned
> > char *ptr,
> >  int image_size,
> >  	if (image_get_magic(hdr) == IH_MAGIC)
> >  		return mtk_image_verify_mt7621_header(ptr, 0);
> >  
> > -	if (!strcmp((char *)ptr, NAND_BOOT_NAME))
> > +	if (is_mtk_nand_header(ptr))
> >  		return mtk_image_verify_nand_header(ptr, 0);
> >  	else
> >  		return mtk_image_verify_gen_header(ptr, 0);
> > @@ -739,7 +518,7 @@ static void mtk_image_print_header(const void
> > *ptr)
> >  		return;
> >  	}
> >  
> > -	if (!strcmp((char *)ptr, NAND_BOOT_NAME))
> > +	if (is_mtk_nand_header(ptr))
> >  		mtk_image_verify_nand_header(ptr, 1);
> >  	else
> >  		mtk_image_verify_gen_header(ptr, 1);
> > @@ -870,36 +649,33 @@ static void mtk_image_set_gen_header(void
> > *ptr, off_t
> >  filesize,
> >  static void mtk_image_set_nand_header(void *ptr, off_t filesize,
> >  				      uint32_t loadaddr)
> >  {
> > -	union nand_boot_header *nh = (union nand_boot_header
> > *)ptr;
> >  	struct brom_layout_header *brlyt;
> >  	struct gfh_header *gfh;
> > -	uint32_t payload_pages;
> > -	int i;
> > +	uint32_t payload_pages, nand_page_size;
> >  
> > -	/* NAND device header, repeat 4 times */
> > -	for (i = 0; i < 4; i++)
> > -		memcpy(nh + i, hdr_nand, sizeof(union
> > nand_boot_header));
> > +	/* NAND header */
> > +	nand_page_size = mtk_nand_header_put(hdr_nand, ptr);
> >  
> > -	/* BRLYT header */
> > -	payload_pages = (filesize + le16_to_cpu(hdr_nand-
> > >pagesize) - 1) /
> > -			le16_to_cpu(hdr_nand->pagesize);
> > -	brlyt = (struct brom_layout_header *)
> > -		(ptr + le16_to_cpu(hdr_nand->pagesize));
> > -	put_brom_layout_header(brlyt, hdr_media);
> > -	brlyt->header_size = cpu_to_le32(2);
> > -	brlyt->total_size = cpu_to_le32(payload_pages);
> > -	brlyt->header_size_2 = brlyt->header_size;
> > -	brlyt->total_size_2 = brlyt->total_size;
> > -	brlyt->unused = cpu_to_le32(1);
> > +	if (nand_page_size) {
> > +		/* BRLYT header */
> > +		payload_pages = (filesize + nand_page_size - 1) /
> > +				nand_page_size;
> > +		brlyt = (struct brom_layout_header *)(ptr +
> > nand_page_size);
> > +		put_brom_layout_header(brlyt, hdr_media);
> > +		brlyt->header_size = cpu_to_le32(2);
> > +		brlyt->total_size = cpu_to_le32(payload_pages);
> > +		brlyt->header_size_2 = brlyt->header_size;
> > +		brlyt->total_size_2 = brlyt->total_size;
> > +		brlyt->unused = cpu_to_le32(1);
> > +	}
> >  
> >  	/* GFH header */
> > -	gfh = (struct gfh_header *)(ptr + 2 *
> > le16_to_cpu(hdr_nand->pagesize));
> > -	put_ghf_header(gfh, filesize, 2 * le16_to_cpu(hdr_nand-
> > >pagesize),
> > -		       loadaddr, GFH_FLASH_TYPE_NAND);
> > +	gfh = (struct gfh_header *)(ptr + hdr_nand_size);
> > +	put_ghf_header(gfh, filesize, hdr_nand_size, loadaddr,
> > +		       GFH_FLASH_TYPE_NAND);
> >  
> >  	/* Generate SHA256 hash */
> > -	put_hash((uint8_t *)gfh,
> > -		 filesize - 2 * le16_to_cpu(hdr_nand->pagesize) -
> > SHA256_SUM_LEN);
> > +	put_hash((uint8_t *)gfh, filesize - hdr_nand_size -
> > SHA256_SUM_LEN);
> >  }
> >  
> >  static void mtk_image_set_mt7621_header(void *ptr, off_t filesize,
> > diff --git a/tools/mtk_image.h b/tools/mtk_image.h
> > index d868545a33..fad9372100 100644
> > --- a/tools/mtk_image.h
> > +++ b/tools/mtk_image.h
> > @@ -26,31 +26,6 @@ union gen_boot_header {
> >  #define SF_BOOT_NAME		"SF_BOOT"
> >  #define SDMMC_BOOT_NAME		"SDMMC_BOOT"
> >  
> > -/* Header for NAND */
> > -union nand_boot_header {
> > -	struct {
> > -		char name[12];
> > -		char version[4];
> > -		char id[8];
> > -		uint16_t ioif;
> > -		uint16_t pagesize;
> > -		uint16_t addrcycles;
> > -		uint16_t oobsize;
> > -		uint16_t pages_of_block;
> > -		uint16_t numblocks;
> > -		uint16_t writesize_shift;
> > -		uint16_t erasesize_shift;
> > -		uint8_t dummy[60];
> > -		uint8_t ecc_parity[28];
> > -	};
> > -
> > -	uint8_t data[0x80];
> > -};
> > -
> > -#define NAND_BOOT_NAME		"BOOTLOADER!"
> > -#define NAND_BOOT_VERSION	"V006"
> > -#define NAND_BOOT_ID		"NFIINFO"
> > -
> >  /* BootROM layout header */
> >  struct brom_layout_header {
> >  	char name[8];
> > diff --git a/tools/mtk_nand_headers.c b/tools/mtk_nand_headers.c
> > new file mode 100644
> > index 0000000000..12f827c39f
> > --- /dev/null
> > +++ b/tools/mtk_nand_headers.c
> > @@ -0,0 +1,286 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * MediaTek BootROM NAND header definitions
> > + *
> > + * Copyright (C) 2022 MediaTek Inc.
> > + * Author: Weijie Gao <weijie.gao@mediatek.com>
> > + */
> > +
> > +#include <stdint.h>
> > +#include <string.h>
> > +#include "imagetool.h"
> > +#include "mtk_image.h"
> > +#include "mtk_nand_headers.h"
> > +
> > +/* NAND header for SPI-NAND with 2KB page + 64B spare */
> > +static const union nand_boot_header snand_hdr_2k_64_data = {
> > +	.data = {
> > +		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> > +		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> > +		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> > +		0x00, 0x00, 0x00, 0x08, 0x03, 0x00, 0x40, 0x00,
> > +		0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x7B, 0xC4, 0x17, 0x9D,
> > +		0xCA, 0x42, 0x90, 0xD0, 0x98, 0xD0, 0xE0, 0xF7,
> > +		0xDB, 0xCD, 0x16, 0xF6, 0x03, 0x73, 0xD2, 0xB8,
> > +		0x93, 0xB2, 0x56, 0x5A, 0x84, 0x6E, 0x00, 0x00
> > +	}
> > +};
> > +
> > +/* NAND header for SPI-NAND with 2KB page + 120B/128B spare */
> > +static const union nand_boot_header snand_hdr_2k_128_data = {
> > +	.data = {
> > +		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> > +		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> > +		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> > +		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
> > +		0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x90, 0x28, 0xED, 0x13,
> > +		0x7F, 0x12, 0x22, 0xCD, 0x3D, 0x06, 0xF1, 0xB3,
> > +		0x6F, 0x2E, 0xD9, 0xA0, 0x9D, 0x7A, 0xBD, 0xD7,
> > +		0xB3, 0x28, 0x3C, 0x13, 0xDB, 0x4E, 0x00, 0x00
> > +	}
> > +};
> > +
> > +/* NAND header for SPI-NAND with 4KB page + 256B spare */
> > +static const union nand_boot_header snand_hdr_4k_256_data = {
> > +	.data = {
> > +		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> > +		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> > +		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> > +		0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0xE0, 0x00,
> > +		0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x47, 0xED, 0x0E, 0xC3,
> > +		0x83, 0xBF, 0x41, 0xD2, 0x85, 0x21, 0x97, 0x57,
> > +		0xC4, 0x2E, 0x6B, 0x7A, 0x40, 0xE0, 0xCF, 0x8F,
> > +		0x37, 0xBD, 0x17, 0xB6, 0xC7, 0xFE, 0x00, 0x00
> > +	}
> > +};
> > +
> > +/* NAND header for Parallel NAND 1Gb with 2KB page + 64B spare */
> > +static const union nand_boot_header nand_hdr_1gb_2k_64_data = {
> > +	.data = {
> > +		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> > +		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> > +		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> > +		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
> > +		0x40, 0x00, 0x00, 0x04, 0x0B, 0x00, 0x11, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x1C, 0x12,
> > +		0x8F, 0xFD, 0xF8, 0x32, 0x6F, 0x6D, 0xCF, 0x6C,
> > +		0xDA, 0x21, 0x70, 0x8C, 0xDA, 0x0A, 0x22, 0x82,
> > +		0xAA, 0x59, 0xFA, 0x7C, 0x42, 0x2D, 0x00, 0x00
> > +	}
> > +};
> > +
> > +/* NAND header for Parallel NAND 2Gb with 2KB page + 64B spare */
> > +static const union nand_boot_header nand_hdr_2gb_2k_64_data = {
> > +	.data = {
> > +		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> > +		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> > +		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> > +		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
> > +		0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x20, 0x9C, 0x3D, 0x2D,
> > +		0x7B, 0x68, 0x63, 0x52, 0x2E, 0x04, 0x63, 0xF1,
> > +		0x35, 0x4E, 0x44, 0x3E, 0xF8, 0xAC, 0x9B, 0x95,
> > +		0xAB, 0xFE, 0xE4, 0xE1, 0xD5, 0xF9, 0x00, 0x00
> > +	}
> > +};
> > +
> > +/* NAND header for Parallel NAND 4Gb with 2KB page + 64B spare */
> > +static const union nand_boot_header nand_hdr_4gb_2k_64_data = {
> > +	.data = {
> > +		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> > +		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> > +		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> > +		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
> > +		0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0xE3, 0x0F, 0x86, 0x32,
> > +		0x68, 0x05, 0xD9, 0xC8, 0x13, 0xDF, 0xC5, 0x0B,
> > +		0x35, 0x3A, 0x68, 0xA5, 0x3C, 0x0C, 0x73, 0x87,
> > +		0x63, 0xB0, 0xBE, 0xCC, 0x84, 0x47, 0x00, 0x00
> > +	}
> > +};
> > +
> > +/* NAND header for Parallel NAND 2Gb with 2KB page + 128B spare */
> > +static const union nand_boot_header nand_hdr_2gb_2k_128_data = {
> > +	.data = {
> > +		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> > +		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> > +		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> > +		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
> > +		0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x01, 0xA5, 0xE9, 0x5A,
> > +		0xDF, 0x58, 0x62, 0x41, 0xD6, 0x26, 0x77, 0xBC,
> > +		0x76, 0x1F, 0x27, 0x4E, 0x4F, 0x6C, 0xC3, 0xF0,
> > +		0x36, 0xDE, 0xD9, 0xB3, 0xFF, 0x93, 0x00, 0x00
> > +	}
> > +};
> > +
> > +/* NAND header for Parallel NAND 4Gb with 2KB page + 128B spare */
> > +static const union nand_boot_header nand_hdr_4gb_2k_128_data = {
> > +	.data = {
> > +		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
> > +		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
> > +		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
> > +		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
> > +		0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +		0x00, 0x00, 0x00, 0x00, 0xC2, 0x36, 0x52, 0x45,
> > +		0xCC, 0x35, 0xD8, 0xDB, 0xEB, 0xFD, 0xD1, 0x46,
> > +		0x76, 0x6B, 0x0B, 0xD5, 0x8B, 0xCC, 0x2B, 0xE2,
> > +		0xFE, 0x90, 0x83, 0x9E, 0xAE, 0x2D, 0x00, 0x00
> > +	}
> > +};
> > +
> > +static const struct nand_header_type {
> > +	const char *name;
> > +	const union nand_boot_header *data;
> > +} nand_headers[] = {
> > +	{
> > +		.name = "2k+64",
> > +		.data = &snand_hdr_2k_64_data
> > +	}, {
> > +		.name = "2k+120",
> > +		.data = &snand_hdr_2k_128_data
> > +	}, {
> > +		.name = "2k+128",
> > +		.data = &snand_hdr_2k_128_data
> > +	}, {
> > +		.name = "4k+256",
> > +		.data = &snand_hdr_4k_256_data
> > +	}, {
> > +		.name = "1g:2k+64",
> > +		.data = &nand_hdr_1gb_2k_64_data
> > +	}, {
> > +		.name = "2g:2k+64",
> > +		.data = &nand_hdr_2gb_2k_64_data
> > +	}, {
> > +		.name = "4g:2k+64",
> > +		.data = &nand_hdr_4gb_2k_64_data
> > +	}, {
> > +		.name = "2g:2k+128",
> > +		.data = &nand_hdr_2gb_2k_128_data
> > +	}, {
> > +		.name = "4g:2k+128",
> > +		.data = &nand_hdr_4gb_2k_128_data
> > +	}
> > +};
> > +
> > +const union nand_boot_header *mtk_nand_header_find(const char
> > *name)
> > +{
> > +	uint32_t i;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(nand_headers); i++) {
> > +		if (!strcmp(nand_headers[i].name, name))
> > +			return nand_headers[i].data;
> > +	}
> > +
> > +	return NULL;
> > +}
> > +
> > +uint32_t mtk_nand_header_size(const union nand_boot_header
> > *hdr_nand)
> > +{
> > +	return 2 * le16_to_cpu(hdr_nand->pagesize);
> > +}
> > +
> > +static int mtk_nand_header_ap_info(const void *ptr,
> > +				   struct nand_header_info *info)
> > +{
> > +	union nand_boot_header *nh = (union nand_boot_header
> > *)ptr;
> > +
> > +	if (strncmp(nh->version, NAND_BOOT_VERSION, sizeof(nh-
> > >version)) ||
> > +	    strcmp(nh->id, NAND_BOOT_ID))
> > +		return -1;
> > +
> > +	info->page_size = le16_to_cpu(nh->pagesize);
> > +	info->spare_size = le16_to_cpu(nh->oobsize);
> > +	info->gfh_offset = 2 * info->page_size;
> > +
> > +	return 0;
> > +}
> > +
> > +int mtk_nand_header_info(const void *ptr, struct nand_header_info
> > *info)
> > +{
> > +	if (!strcmp((char *)ptr, NAND_BOOT_NAME))
> > +		return mtk_nand_header_ap_info(ptr, info);
> > +
> > +	return -1;
> > +}
> > +
> > +bool is_mtk_nand_header(const void *ptr)
> > +{
> > +	struct nand_header_info info;
> > +
> > +	if (mtk_nand_header_info(ptr, &info) >= 0)
> > +		return true;
> > +
> > +	return false;
> > +}
> > +
> > +uint32_t mtk_nand_header_put(const union nand_boot_header
> > *hdr_nand, void
> >  *ptr)
> > +{
> > +	union nand_boot_header *nh = (union nand_boot_header
> > *)ptr;
> > +	int i;
> > +
> > +	/* NAND device header, repeat 4 times */
> > +	for (i = 0; i < 4; i++)
> > +		memcpy(nh + i, hdr_nand, sizeof(union
> > nand_boot_header));
> > +
> > +	return le16_to_cpu(hdr_nand->pagesize);
> > +}
> > diff --git a/tools/mtk_nand_headers.h b/tools/mtk_nand_headers.h
> > new file mode 100644
> > index 0000000000..691db85005
> > --- /dev/null
> > +++ b/tools/mtk_nand_headers.h
> > @@ -0,0 +1,52 @@
> > +/* SPDX-License-Identifier: GPL-2.0+ */
> > +/*
> > + * MediaTek BootROM NAND header definitions
> > + *
> > + * Copyright (C) 2022 MediaTek Inc.
> > + * Author: Weijie Gao <weijie.gao@mediatek.com>
> > + */
> > +
> > +#ifndef _MTK_NAND_HEADERS_H
> > +#define _MTK_NAND_HEADERS_H
> > +
> > +#include <stdint.h>
> > +#include <stdbool.h>
> > +
> > +struct nand_header_info {
> > +	uint32_t page_size;
> > +	uint32_t spare_size;
> > +	uint32_t gfh_offset;
> > +};
> > +
> > +/* AP BROM Header for NAND */
> > +union nand_boot_header {
> > +	struct {
> > +		char name[12];
> > +		char version[4];
> > +		char id[8];
> > +		uint16_t ioif;
> > +		uint16_t pagesize;
> > +		uint16_t addrcycles;
> > +		uint16_t oobsize;
> > +		uint16_t pages_of_block;
> > +		uint16_t numblocks;
> > +		uint16_t writesize_shift;
> > +		uint16_t erasesize_shift;
> > +		uint8_t dummy[60];
> > +		uint8_t ecc_parity[28];
> > +	};
> > +
> > +	uint8_t data[0x80];
> > +};
> > +
> > +#define NAND_BOOT_NAME		"BOOTLOADER!"
> > +#define NAND_BOOT_VERSION	"V006"
> > +#define NAND_BOOT_ID		"NFIINFO"
> > +
> > +const union nand_boot_header *mtk_nand_header_find(const char
> > *name);
> > +uint32_t mtk_nand_header_size(const union nand_boot_header
> > *hdr_nand);
> > +int mtk_nand_header_info(const void *ptr, struct nand_header_info
> > *info);
> > +bool is_mtk_nand_header(const void *ptr);
> > +uint32_t mtk_nand_header_put(const union nand_boot_header
> > *hdr_nand, void
> >  *ptr);
> > +
> > +#endif /* _MTK_NAND_HEADERS_H */
> > -- 
> > 2.17.1
> > 

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 30/31] tools: mtk_image: add support for nand headers used by newer chips
  2022-08-04 13:57   ` Simon Glass
@ 2022-08-08  3:31     ` Weijie Gao
  0 siblings, 0 replies; 100+ messages in thread
From: Weijie Gao @ 2022-08-08  3:31 UTC (permalink / raw)
  To: Simon Glass; +Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream

On Thu, 2022-08-04 at 07:57 -0600, Simon Glass wrote:
> Hi Weijie,
> 
> On Wed, 3 Aug 2022 at 21:41, Weijie Gao <weijie.gao@mediatek.com>
> wrote:
> > 
> > This patch adds more nand headers in two new types:
> > 1. HSM header, used for spi-nand thru SNFI interface
> > 2. SPIM header, used for spi-nand thru spi-mem interface
> > 
> > The original nand header is renamed to AP header.
> > 
> > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> > ---
> >  tools/mtk_image.c        |  23 ++-
> >  tools/mtk_nand_headers.c | 422
> > +++++++++++++++++++++++++++++++++++++--
> >  tools/mtk_nand_headers.h | 110 +++++++++-
> >  3 files changed, 525 insertions(+), 30 deletions(-)
> 
> Reviewed-by: Simon Glass <sjg@chromium.org>
> 
> [..]
> 
> > diff --git a/tools/mtk_nand_headers.h b/tools/mtk_nand_headers.h
> > index 691db85005..ce4a824e29 100644
> > --- a/tools/mtk_nand_headers.h
> > +++ b/tools/mtk_nand_headers.h
> > @@ -16,6 +16,7 @@ struct nand_header_info {
> >         uint32_t page_size;
> >         uint32_t spare_size;
> >         uint32_t gfh_offset;
> > +       bool snfi;
> >  };
> > 
> >  /* AP BROM Header for NAND */
> > @@ -39,14 +40,117 @@ union nand_boot_header {
> >         uint8_t data[0x80];
> >  };
> > 
> > +/* HSM BROM Header for NAND */
> > +union hsm_nand_boot_header {
> > +       struct {
> > +               char id[8];
> > +               uint32_t version;
> > +               uint32_t config;
> > +               uint32_t sector_size;
> > +               uint32_t fdm_size;
> > +               uint32_t fdm_ecc_size;
> > +               uint32_t lbs;
> > +               uint32_t page_size;
> > +               uint32_t spare_size;
> > +               uint32_t page_per_block;
> > +               uint32_t blocks;
> > +               uint32_t plane_sel_position;
> > +               uint32_t pll;
> > +               uint32_t acccon;
> > +               uint32_t strobe_sel;
> > +               uint32_t acccon1;
> > +               uint32_t dqs_mux;
> > +               uint32_t dqs_ctrl;
> > +               uint32_t delay_ctrl;
> > +               uint32_t latch_lat;
> > +               uint32_t sample_delay;
> > +               uint32_t driving;
> > +               uint32_t bl_start;
> > +               uint32_t bl_end;
> > +               uint8_t ecc_parity[42];
> > +       };
> > +
> > +       uint8_t data[0x8E];
> > +};
> > +
> > +/* HSM2.0 BROM Header for NAND */
> > +union hsm20_nand_boot_header {
> > +       struct {
> > +               char id[8];
> > +               uint32_t version;
> > +               uint32_t config;
> > +               uint32_t sector_size;
> > +               uint32_t fdm_size;
> > +               uint32_t fdm_ecc_size;
> > +               uint32_t lbs;
> > +               uint32_t page_size;
> > +               uint32_t spare_size;
> > +               uint32_t page_per_block;
> > +               uint32_t blocks;
> > +               uint32_t plane_sel_position;
> > +               uint32_t pll;
> > +               uint32_t acccon;
> > +               uint32_t strobe_sel;
> > +               uint32_t acccon1;
> > +               uint32_t dqs_mux;
> > +               uint32_t dqs_ctrl;
> > +               uint32_t delay_ctrl;
> > +               uint32_t latch_lat;
> > +               uint32_t sample_delay;
> > +               uint32_t driving;
> > +               uint32_t reserved;
> > +               uint32_t bl0_start;
> > +               uint32_t bl0_end;
> > +               uint32_t bl0_type;
> > +               uint8_t bl_reserve[84];
> > +               uint8_t ecc_parity[42];
> > +       };
> > +
> > +       uint8_t data[0xEA];
> > +};
> > +
> > +/* SPIM BROM Header for NAND */
> > +union spim_nand_boot_header {
> > +       struct {
> > +               char id[8];
> > +               uint32_t version;
> > +               uint32_t config;
> > +               uint32_t page_size;
> > +               uint32_t spare_size;
> > +               uint16_t page_per_block;
> > +               uint16_t plane_sel_position;
> > +               uint16_t reserve_reg;
> > +               uint16_t reserve_val;
> > +               uint16_t ecc_error;
> > +               uint16_t ecc_mask;
> > +               uint32_t bl_start;
> > +               uint32_t bl_end;
> > +               uint8_t ecc_parity[32];
> > +               uint32_t integrity_crc;
> > +       };
> > +
> > +       uint8_t data[0x50];
> > +};
> > +
> > +enum nand_boot_header_type {
> > +       NAND_BOOT_AP_HEADER,
> > +       NAND_BOOT_HSM_HEADER,
> > +       NAND_BOOT_HSM20_HEADER,
> > +       NAND_BOOT_SPIM_HEADER
> > +};
> > +
> >  #define NAND_BOOT_NAME         "BOOTLOADER!"
> >  #define NAND_BOOT_VERSION      "V006"
> >  #define NAND_BOOT_ID           "NFIINFO"
> > 
> > -const union nand_boot_header *mtk_nand_header_find(const char
> > *name);
> > -uint32_t mtk_nand_header_size(const union nand_boot_header
> > *hdr_nand);
> > +#define HSM_NAND_BOOT_NAME     "NANDCFG!"
> > +#define SPIM_NAND_BOOT_NAME    "SPINAND!"
> > +
> > +const struct nand_header_type *mtk_nand_header_find(const char
> > *name);
> > +uint32_t mtk_nand_header_size(const struct nand_header_type
> > *hdr_nand);
> >  int mtk_nand_header_info(const void *ptr, struct nand_header_info
> > *info);
> >  bool is_mtk_nand_header(const void *ptr);
> > -uint32_t mtk_nand_header_put(const union nand_boot_header
> > *hdr_nand, void
> >  *ptr);
> > +uint32_t mtk_nand_header_put(const struct nand_header_type
> > *hdr_nand,
> > +                            void *ptr);
> 
> functions and structs need documentation

OK. BTW most fields in nand headers are not used at all.

> 
> > 
> >  #endif /* _MTK_NAND_HEADERS_H */
> > --
> > 2.17.1
> > 
> 
> Regards,
> Simon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 02/31] arm: mediatek: add support for MediaTek MT7981 SoC
  2022-08-08  2:17     ` Weijie Gao
@ 2022-08-08 19:26       ` Simon Glass
  0 siblings, 0 replies; 100+ messages in thread
From: Simon Glass @ 2022-08-08 19:26 UTC (permalink / raw)
  To: Weijie Gao; +Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream

Hi Weijie,

On Sun, 7 Aug 2022 at 20:17, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> On Thu, 2022-08-04 at 07:57 -0600, Simon Glass wrote:
> > Hi Weijie,
> >
> > On Wed, 3 Aug 2022 at 21:35, Weijie Gao <weijie.gao@mediatek.com>
> > wrote:
> > >
> > > This patch adds basic support for MediaTek MT7981 SoC.
> > > This include the file that will initialize the SoC after boot and
> > > its
> > > device tree.
> > >
> > > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> > > ---
> > >  arch/arm/dts/mt7981.dtsi                      | 288
> > > ++++++++++++++++++
> > >  arch/arm/mach-mediatek/Kconfig                |  12 +-
> > >  arch/arm/mach-mediatek/Makefile               |   1 +
> > >  arch/arm/mach-mediatek/mt7981/Makefile        |   4 +
> > >  arch/arm/mach-mediatek/mt7981/init.c          |  52 ++++
> > >  arch/arm/mach-mediatek/mt7981/lowlevel_init.S |  30 ++
> > >  6 files changed, 386 insertions(+), 1 deletion(-)
> > >  create mode 100644 arch/arm/dts/mt7981.dtsi
> > >  create mode 100644 arch/arm/mach-mediatek/mt7981/Makefile
> > >  create mode 100644 arch/arm/mach-mediatek/mt7981/init.c
> > >  create mode 100644 arch/arm/mach-mediatek/mt7981/lowlevel_init.S
> > >
> >
> >
> > [..]
> >
> > > diff --git a/arch/arm/mach-mediatek/mt7981/init.c
> > >  b/arch/arm/mach-mediatek/mt7981/init.c
> > > new file mode 100644
> > > index 0000000000..f503bb804b
> > > --- /dev/null
> > > +++ b/arch/arm/mach-mediatek/mt7981/init.c
> > > @@ -0,0 +1,52 @@
> > > +// SPDX-License-Identifier: GPL-2.0
> > > +/*
> > > + * Copyright (C) 2022 MediaTek Inc.
> > > + * Author: Sam Shih <sam.shih@mediatek.com>
> > > + */
> > > +
> > > +#include <fdtdec.h>
> >
> > Do you need that?
>
> This was used during testing, and should be remove now.
>
> >
> > > +#include <asm/armv8/mmu.h>
> > > +#include <init.h>
> >
> > Move up one
>
> ok.
>
> >
> > > +#include <asm/system.h>
> > > +#include <asm/global_data.h>
> > > +
> > > +DECLARE_GLOBAL_DATA_PTR;
> > > +
> > > +int print_cpuinfo(void)
> >
> > Can you use the CPU uclass and DISPLAY_CPUINFO instead/
>
> Basically there's nothing to do for print_cpuinfo other than printing a
> fixed CPU model string. Not sure if it's worth using a CPU uclass.
>
> Besides, Using a cpu uclass involves modifying other chips, and some
> of them cann't be tested by me.

Something to consider for the future as it is nice to list the CPUs
and their status. You can enable CONFIG_CPU for one Soc and not
another.

Regards,
Simon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 10/31] serial: mtk: add support for using dynamic baud clock souce
  2022-08-08  2:36     ` Weijie Gao
@ 2022-08-08 19:26       ` Simon Glass
  0 siblings, 0 replies; 100+ messages in thread
From: Simon Glass @ 2022-08-08 19:26 UTC (permalink / raw)
  To: Weijie Gao; +Cc: U-Boot Mailing List, GSS_MTK_Uboot_upstream, Pali Rohár

Hi Weijie,

On Sun, 7 Aug 2022 at 20:36, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> On Thu, 2022-08-04 at 07:56 -0600, Simon Glass wrote:
> > Hi Weijie,
> >
> > On Wed, 3 Aug 2022 at 21:36, Weijie Gao <weijie.gao@mediatek.com>
> > wrote:
> > >
> > > The baud clock on some platform may change due to assigned-clock-
> > > parent
> > > set in DT. In current flow the baud clock is only retrieved during
> > > probe
> > > stage. If the parent of the source clock changes after probe stage,
> > > the
> > > setbrg will set wrong baudrate.
> > >
> > > To get the right clock rate, this patch records the baud clk struct
> > > to the
> > > driver's priv, and changes the driver's flow to get the clock rate
> > > before
> > > calling _mtk_serial_setbrg().
> > >
> > > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> > > ---
> > >  drivers/serial/serial_mtk.c | 72 ++++++++++++++++++++-------------
> > > ----
> > >  1 file changed, 39 insertions(+), 33 deletions(-)
> >
> > Reviewed-by: Simon Glass <sjg@chromium.org>
> >
> > please see below
> >
> > >
> > > diff --git a/drivers/serial/serial_mtk.c
> > > b/drivers/serial/serial_mtk.c
> > > index a84f39b3fa..99cf62b8d9 100644
> > > --- a/drivers/serial/serial_mtk.c
> > > +++ b/drivers/serial/serial_mtk.c
> > > @@ -10,6 +10,7 @@
> > >  #include <common.h>
> > >  #include <div64.h>
> > >  #include <dm.h>
> > > +#include <dm/device_compat.h>
> > >  #include <errno.h>
> > >  #include <log.h>
> > >  #include <serial.h>
> > > @@ -72,25 +73,27 @@ struct mtk_serial_regs {
> > >
> > >  struct mtk_serial_priv {
> >
> > please add a full comment for this struct
>
> OK.
>
> >
> > >         struct mtk_serial_regs __iomem *regs;
> > > -       u32 clock;
> > > +       struct clk clk;
> > > +       u32 fixed_clk_rate;
> > >         bool force_highspeed;
> > >  };
> > >
> > > -static void _mtk_serial_setbrg(struct mtk_serial_priv *priv, int
> > > baud)
> > > +static void _mtk_serial_setbrg(struct mtk_serial_priv *priv, int
> > > baud,
> > > +                              u32 clk_rate)
> >
> > Why u32? Can you use uint? Generally it is better for parameters to
> > use natural types unless there is a good reason.
>
> In fact u32 is identical to uint.
>
> <asm-generic/int-ll64.h>: typedef __u32 u32;
> <asm-generic/int-ll64.h>: typedef unsigned int __u32;
>
> <linux/types.h>: typedef unsigned int uint;

It's not about the eventual type...if u32 is the same as uint, why not
just use uint? It is simpler and does the right thing on 64-bit, where
u32 is different. The clock interface uses long.  In some cases the
compiler must mask the values so it adds to code size.

Regards,
SImon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 03/31] board: mediatek: add MT7986 reference boards
  2022-08-04  3:35 ` [PATCH 03/31] board: mediatek: add MT7986 reference boards Weijie Gao
  2022-08-04 13:57   ` Simon Glass
@ 2022-08-09  9:10   ` Daniel Golle
  2022-08-12 11:02     ` Weijie Gao
  1 sibling, 1 reply; 100+ messages in thread
From: Daniel Golle @ 2022-08-09  9:10 UTC (permalink / raw)
  To: Weijie Gao
  Cc: u-boot, GSS_MTK_Uboot_upstream, Simon Glass, Marcel Ziswiler,
	Andre Przywara, Fabio Estevam, Samuel Holland, Marek Vasut,
	Ying-Chun Liu (PaulLiu),
	Christian Hewitt

Hi Weijie,

On Thu, Aug 04, 2022 at 11:35:03AM +0800, Weijie Gao wrote:
> This patch adds general board files based on MT7986 SoCs.
> 
> The SD/eMMC controller on MT7986A and MT7986B have different pin
> configurations so that four different reference board configs has to be
> added.
> 
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
> [...]
> diff --git a/include/configs/mt7986.h b/include/configs/mt7986.h
> new file mode 100644
> index 0000000000..b28fc0f613
> --- /dev/null
> +++ b/include/configs/mt7986.h
> @@ -0,0 +1,26 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Configuration for MediaTek MT7986 SoC
> + *
> + * Copyright (C) 2022 MediaTek Inc.
> + * Author: Sam Shih <sam.shih@mediatek.com>
> + */
> +
> +#ifndef __MT7986_H
> +#define __MT7986_H
> +
> +#include <linux/sizes.h>
> +

In the SDK sources I found also
#define CONFIG_SYS_BOOTM_LEN           SZ_128M
here which is actually needed to boot any image with uncompressed
kernel larger than 8MiB. As for ARM64 this size is easily exceeded and
we got plenty of RAM, I suggest to also include a more generous
CONFIG_SYS_BOOTM_LEN in your submission to upstream U-Boot.



> +#define CONFIG_SYS_NONCACHED_MEMORY	SZ_1M
> +#define CONFIG_SYS_MMC_ENV_DEV		0
> +
> +/* Uboot definition */
> +#define CONFIG_SYS_UBOOT_BASE		CONFIG_SYS_TEXT_BASE
> +
> +/* SPL -> Uboot */
> +#define CONFIG_SYS_UBOOT_START		CONFIG_SYS_TEXT_BASE
> +
> +/* DRAM */
> +#define CONFIG_SYS_SDRAM_BASE		0x40000000
> +
> +#endif
> -- 
> 2.17.1
> 

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 17/31] i2c: add support for MediaTek I2C interface
  2022-08-04  3:36 ` [PATCH 17/31] i2c: add support for MediaTek I2C interface Weijie Gao
  2022-08-04 13:57   ` Simon Glass
@ 2022-08-10 11:12   ` Heiko Schocher
  2022-08-10 11:24   ` Michael Nazzareno Trimarchi
  2 siblings, 0 replies; 100+ messages in thread
From: Heiko Schocher @ 2022-08-10 11:12 UTC (permalink / raw)
  To: Weijie Gao, u-boot; +Cc: GSS_MTK_Uboot_upstream

Hello Weijie Gao,

On 04.08.22 05:36, Weijie Gao wrote:
> This patch adds support for MediaTek I2C interface
> 
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  drivers/i2c/Kconfig   |   9 +
>  drivers/i2c/Makefile  |   1 +
>  drivers/i2c/mtk_i2c.c | 822 ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 832 insertions(+)
>  create mode 100644 drivers/i2c/mtk_i2c.c

beside comment from Simon

Reviewed-by: Heiko Schocher <hs@denx.de>

Thanks!

bye,
Heiko

-- 
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-52   Fax: +49-8142-66989-80   Email: hs@denx.de

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 17/31] i2c: add support for MediaTek I2C interface
  2022-08-04  3:36 ` [PATCH 17/31] i2c: add support for MediaTek I2C interface Weijie Gao
  2022-08-04 13:57   ` Simon Glass
  2022-08-10 11:12   ` Heiko Schocher
@ 2022-08-10 11:24   ` Michael Nazzareno Trimarchi
  2022-08-12  9:46     ` Weijie Gao
  2 siblings, 1 reply; 100+ messages in thread
From: Michael Nazzareno Trimarchi @ 2022-08-10 11:24 UTC (permalink / raw)
  To: Weijie Gao; +Cc: u-boot, GSS_MTK_Uboot_upstream, Heiko Schocher

Hi

On Thu, Aug 4, 2022 at 5:38 AM Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> This patch adds support for MediaTek I2C interface
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  drivers/i2c/Kconfig   |   9 +
>  drivers/i2c/Makefile  |   1 +
>  drivers/i2c/mtk_i2c.c | 822 ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 832 insertions(+)
>  create mode 100644 drivers/i2c/mtk_i2c.c
>
> diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
> index be4724bf8e..08b6c7bdcc 100644
> --- a/drivers/i2c/Kconfig
> +++ b/drivers/i2c/Kconfig
> @@ -261,6 +261,15 @@ config SYS_I2C_MESON
>           internal buffer holding up to 8 bytes for transfers and supports
>           both 7-bit and 10-bit addresses.
>
> +config SYS_I2C_MTK
> +       bool "MediaTek I2C driver"
> +       help
> +         This selects the MediaTek Integrated Inter Circuit bus driver.
> +         The I2C bus adapter is the base for some other I2C client,
> +         eg: touch, sensors.
> +         If you want to use MediaTek I2C interface, say Y here.
> +         If unsure, say N.
> +
>  config SYS_I2C_MICROCHIP
>         bool "Microchip I2C driver"
>         help
> diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
> index 7e046f809a..920aafb91c 100644
> --- a/drivers/i2c/Makefile
> +++ b/drivers/i2c/Makefile
> @@ -32,6 +32,7 @@ obj-$(CONFIG_SYS_I2C_MICROCHIP) += i2c-microchip.o
>  obj-$(CONFIG_SYS_I2C_MV) += mv_i2c.o
>  obj-$(CONFIG_SYS_I2C_MVTWSI) += mvtwsi.o
>  obj-$(CONFIG_SYS_I2C_MXC) += mxc_i2c.o
> +obj-$(CONFIG_SYS_I2C_MTK) += mtk_i2c.o
>  obj-$(CONFIG_SYS_I2C_NEXELL) += nx_i2c.o
>  obj-$(CONFIG_SYS_I2C_NPCM) += npcm_i2c.o
>  obj-$(CONFIG_SYS_I2C_OCORES) += ocores_i2c.o
> diff --git a/drivers/i2c/mtk_i2c.c b/drivers/i2c/mtk_i2c.c
> new file mode 100644
> index 0000000000..1d4a93f8c9
> --- /dev/null
> +++ b/drivers/i2c/mtk_i2c.c
> @@ -0,0 +1,822 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2022 MediaTek Inc. All Rights Reserved.
> + *
> + * Author: Mingming Lee <Mingming.Lee@mediatek.com>
> + *
> + * MediaTek I2C Interface driver
> + */
> +
> +#include <clk.h>
> +#include <cpu_func.h>
> +#include <dm.h>
> +#include <i2c.h>
> +#include <log.h>
> +#include <asm/cache.h>
> +#include <asm/io.h>
> +#include <linux/delay.h>
> +#include <linux/errno.h>
> +
> +#define I2C_RS_TRANSFER                        BIT(4)
> +#define I2C_HS_NACKERR                 BIT(2)
> +#define I2C_ACKERR                     BIT(1)
> +#define I2C_TRANSAC_COMP               BIT(0)
> +#define I2C_TRANSAC_START              BIT(0)
> +#define I2C_RS_MUL_CNFG                        BIT(15)
> +#define I2C_RS_MUL_TRIG                        BIT(14)
> +#define I2C_DCM_DISABLE                        0x0000
> +#define I2C_IO_CONFIG_OPEN_DRAIN       0x0003
> +#define I2C_IO_CONFIG_PUSH_PULL                0x0000
> +#define I2C_SOFT_RST                   0x0001
> +#define I2C_FIFO_ADDR_CLR              0x0001
> +#define I2C_DELAY_LEN                  0x0002
> +#define I2C_ST_START_CON               0x8001
> +#define I2C_FS_START_CON               0x1800
> +#define I2C_TIME_CLR_VALUE             0x0000
> +#define I2C_TIME_DEFAULT_VALUE         0x0003
> +#define I2C_WRRD_TRANAC_VALUE          0x0002
> +#define I2C_RD_TRANAC_VALUE            0x0001
> +
> +#define I2C_DMA_CON_TX                 0x0000
> +#define I2C_DMA_CON_RX                 0x0001
> +#define I2C_DMA_START_EN               0x0001
> +#define I2C_DMA_INT_FLAG_NONE          0x0000
> +#define I2C_DMA_CLR_FLAG               0x0000
> +#define I2C_DMA_TX_RX                  0x0000
> +#define I2C_DMA_HARD_RST               0x0002
> +
> +#define MAX_ST_MODE_SPEED              100000
> +#define MAX_FS_MODE_SPEED              400000
> +#define MAX_HS_MODE_SPEED              3400000
> +#define MAX_SAMPLE_CNT_DIV             8
> +#define MAX_STEP_CNT_DIV               64
> +#define MAX_HS_STEP_CNT_DIV            8
> +#define I2C_DEFAULT_CLK_DIV            4
> +
> +#define MAX_I2C_ADDR                   0x7f
> +#define MAX_I2C_LEN                    0xff
> +#define TRANS_ADDR_ONLY                        BIT(8)
> +#define TRANSFER_TIMEOUT               50000  /* us */
> +#define I2C_FIFO_STAT1_MASK            0x001f
> +#define TIMING_SAMPLE_OFFSET           8
> +#define HS_SAMPLE_OFFSET               12
> +#define HS_STEP_OFFSET                 8
> +
> +#define I2C_CONTROL_WRAPPER            BIT(0)
> +#define I2C_CONTROL_RS                 BIT(1)
> +#define I2C_CONTROL_DMA_EN             BIT(2)
> +#define I2C_CONTROL_CLK_EXT_EN         BIT(3)
> +#define I2C_CONTROL_DIR_CHANGE         BIT(4)
> +#define I2C_CONTROL_ACKERR_DET_EN      BIT(5)
> +#define I2C_CONTROL_TRANSFER_LEN_CHANGE BIT(6)
> +#define I2C_CONTROL_DMAACK             BIT(8)
> +#define I2C_CONTROL_ASYNC              BIT(9)
> +
> +enum I2C_REGS_OFFSET {
> +       REG_PORT,
> +       REG_SLAVE_ADDR,
> +       REG_INTR_MASK,
> +       REG_INTR_STAT,
> +       REG_CONTROL,
> +       REG_TRANSFER_LEN,
> +       REG_TRANSAC_LEN,
> +       REG_DELAY_LEN,
> +       REG_TIMING,
> +       REG_START,
> +       REG_EXT_CONF,
> +       REG_FIFO_STAT1,
> +       REG_LTIMING,
> +       REG_FIFO_STAT,
> +       REG_FIFO_THRESH,
> +       REG_FIFO_ADDR_CLR,
> +       REG_IO_CONFIG,
> +       REG_RSV_DEBUG,
> +       REG_HS,
> +       REG_SOFTRESET,
> +       REG_DCM_EN,
> +       REG_PATH_DIR,
> +       REG_DEBUGSTAT,
> +       REG_DEBUGCTRL,
> +       REG_TRANSFER_LEN_AUX,
> +       REG_CLOCK_DIV,
> +       REG_SCL_HL_RATIO,
> +       REG_SCL_HS_HL_RATIO,
> +       REG_SCL_MIS_COMP_POINT,
> +       REG_STA_STOP_AC_TIME,
> +       REG_HS_STA_STOP_AC_TIME,
> +       REG_DATA_TIME,
> +};
> +
> +enum DMA_REGS_OFFSET {
> +       REG_INT_FLAG = 0x0,
> +       REG_INT_EN = 0x04,
> +       REG_EN = 0x08,
> +       REG_RST = 0x0c,
> +       REG_CON = 0x18,
> +       REG_TX_MEM_ADDR = 0x1c,
> +       REG_RX_MEM_ADDR = 0x20,
> +       REG_TX_LEN = 0x24,
> +       REG_RX_LEN = 0x28,
> +};
> +
> +static const uint mt_i2c_regs_v1[] = {
> +       [REG_PORT] = 0x0,
> +       [REG_SLAVE_ADDR] = 0x4,
> +       [REG_INTR_MASK] = 0x8,
> +       [REG_INTR_STAT] = 0xc,
> +       [REG_CONTROL] = 0x10,
> +       [REG_TRANSFER_LEN] = 0x14,
> +       [REG_TRANSAC_LEN] = 0x18,
> +       [REG_DELAY_LEN] = 0x1c,
> +       [REG_TIMING] = 0x20,
> +       [REG_START] = 0x24,
> +       [REG_EXT_CONF] = 0x28,
> +       [REG_FIFO_STAT1] = 0x2c,
> +       [REG_FIFO_STAT] = 0x30,
> +       [REG_FIFO_THRESH] = 0x34,
> +       [REG_FIFO_ADDR_CLR] = 0x38,
> +       [REG_IO_CONFIG] = 0x40,
> +       [REG_RSV_DEBUG] = 0x44,
> +       [REG_HS] = 0x48,
> +       [REG_SOFTRESET] = 0x50,
> +       [REG_SOFTRESET] = 0x50,
> +       [REG_DCM_EN] = 0x54,
> +       [REG_DEBUGSTAT] = 0x64,
> +       [REG_DEBUGCTRL] = 0x68,
> +       [REG_TRANSFER_LEN_AUX] = 0x6c,
> +       [REG_CLOCK_DIV] = 0x70,
> +       [REG_SCL_HL_RATIO] = 0x74,
> +       [REG_SCL_HS_HL_RATIO] = 0x78,
> +       [REG_SCL_MIS_COMP_POINT] = 0x7c,
> +       [REG_STA_STOP_AC_TIME] = 0x80,
> +       [REG_HS_STA_STOP_AC_TIME] = 0x84,
> +       [REG_DATA_TIME] = 0x88,
> +};
> +
> +static const uint mt_i2c_regs_v2[] = {
> +       [REG_PORT] = 0x0,
> +       [REG_SLAVE_ADDR] = 0x4,
> +       [REG_INTR_MASK] = 0x8,
> +       [REG_INTR_STAT] = 0xc,
> +       [REG_CONTROL] = 0x10,
> +       [REG_TRANSFER_LEN] = 0x14,
> +       [REG_TRANSAC_LEN] = 0x18,
> +       [REG_DELAY_LEN] = 0x1c,
> +       [REG_TIMING] = 0x20,
> +       [REG_START] = 0x24,
> +       [REG_EXT_CONF] = 0x28,
> +       [REG_LTIMING] = 0x2c,
> +       [REG_HS] = 0x30,
> +       [REG_IO_CONFIG] = 0x34,
> +       [REG_FIFO_ADDR_CLR] = 0x38,
> +       [REG_TRANSFER_LEN_AUX] = 0x44,
> +       [REG_CLOCK_DIV] = 0x48,
> +       [REG_SOFTRESET] = 0x50,
> +       [REG_DEBUGSTAT] = 0xe0,
> +       [REG_DEBUGCTRL] = 0xe8,
> +       [REG_FIFO_STAT] = 0xf4,
> +       [REG_FIFO_THRESH] = 0xf8,
> +       [REG_DCM_EN] = 0xf88,
> +};
> +
> +enum mtk_trans_op {
> +       I2C_MASTER_WR = 1,
> +       I2C_MASTER_RD,
> +       I2C_MASTER_WRRD,
> +};
> +
> +struct mtk_i2c_soc_data {
> +       const uint *regs;
> +       uint dma_sync: 1;
> +};
> +
> +struct mtk_i2c_priv {
> +       /* set in i2c probe */
> +       void __iomem *base;             /* i2c base addr */
> +       void __iomem *pdmabase;         /* dma base address*/
> +       struct clk clk_main;            /* main clock for i2c bus */
> +       struct clk clk_dma;             /* DMA clock for i2c via DMA */
> +       const struct mtk_i2c_soc_data *soc_data; /* Compatible data for different
>  IC */
> +       enum mtk_trans_op op;           /* operation mode */
> +       bool zero_len;                  /* Only transfer slave address, no data */
> +       bool pushpull;                  /* push pull mode or open drain mode */
> +       bool filter_msg;                /* filter msg error log */
> +       bool auto_restart;              /* restart mode */
> +       bool ignore_restart_irq;        /* ignore restart IRQ */
> +       uint speed;                     /* i2c speed, unit: hz */
> +};
> +
> +static inline void i2c_writel(struct mtk_i2c_priv *priv, uint reg, uint
>  value)
> +{
> +       u32 offset = priv->soc_data->regs[reg];
> +
> +       writel(value, priv->base + offset);
> +}
> +
> +static inline uint i2c_readl(struct mtk_i2c_priv *priv, uint offset)
> +{
> +       return readl(priv->base + priv->soc_data->regs[offset]);
> +}
> +
> +static int mtk_i2c_clk_enable(struct mtk_i2c_priv *priv)
> +{
> +       int ret;
> +
> +       ret = clk_enable(&priv->clk_main);
> +       if (ret)
> +               return log_msg_ret("enable clk_main", ret);
> +
> +       ret = clk_enable(&priv->clk_dma);
> +       if (ret)
> +               return log_msg_ret("enable clk_dma", ret);
> +
> +       return 0;
> +}
> +
> +static int mtk_i2c_clk_disable(struct mtk_i2c_priv *priv)
> +{
> +       int ret;
> +
> +       ret = clk_disable(&priv->clk_dma);
> +       if (ret)
> +               return log_msg_ret("disable clk_dma", ret);
> +
> +       ret = clk_disable(&priv->clk_main);
> +       if (ret)
> +               return log_msg_ret("disable clk_main", ret);
> +
> +       return 0;
> +}
> +
> +static void mtk_i2c_init_hw(struct mtk_i2c_priv *priv)
> +{
> +       uint control_reg;
> +
> +       writel(I2C_DMA_HARD_RST, priv->pdmabase + REG_RST);
> +       writel(I2C_DMA_CLR_FLAG, priv->pdmabase + REG_RST);
> +       i2c_writel(priv, REG_SOFTRESET, I2C_SOFT_RST);
> +       /* set ioconfig */
> +       if (priv->pushpull)
> +               i2c_writel(priv, REG_IO_CONFIG, I2C_IO_CONFIG_PUSH_PULL);
> +       else
> +               i2c_writel(priv, REG_IO_CONFIG, I2C_IO_CONFIG_OPEN_DRAIN);
> +
> +       i2c_writel(priv, REG_DCM_EN, I2C_DCM_DISABLE);
> +       control_reg = I2C_CONTROL_ACKERR_DET_EN | I2C_CONTROL_CLK_EXT_EN;
> +       if (priv->soc_data->dma_sync)
> +               control_reg |= I2C_CONTROL_DMAACK | I2C_CONTROL_ASYNC;
> +       i2c_writel(priv, REG_CONTROL, control_reg);
> +       i2c_writel(priv, REG_DELAY_LEN, I2C_DELAY_LEN);
> +}
> +
> +/*
> + * Calculate i2c port speed
> + *
> + * Hardware design:
> + * i2c_bus_freq = parent_clk / (clock_div * 2 * sample_cnt * step_cnt)
> + * clock_div: fixed in hardware, but may be various in different SoCs
> + *
> + * The calculation want to pick the highest bus frequency that is still
> + * less than or equal to target_speed. The calculation try to get
> + * sample_cnt and step_cn
> + * @param[in]
> + *     clk_src: i2c clock source
> + * @param[out]
> + *     timing_step_cnt: step cnt calculate result
> + * @param[out]
> + *     timing_sample_cnt: sample cnt calculate result
> + * @return
> + *     0, set speed successfully.
> + *     -EINVAL, Unsupported speed.
> + */
> +static int mtk_i2c_calculate_speed(uint clk_src,
> +                                  uint target_speed,
> +                                  uint *timing_step_cnt,
> +                                  uint *timing_sample_cnt)
> +{
> +       uint base_sample_cnt = MAX_SAMPLE_CNT_DIV;
> +       uint base_step_cnt;
> +       uint max_step_cnt;
> +       uint sample_cnt;
> +       uint step_cnt;
> +       uint opt_div;
> +       uint best_mul;
> +       uint cnt_mul;
> +
> +       if (target_speed > MAX_HS_MODE_SPEED)
> +               target_speed = MAX_HS_MODE_SPEED;
> +
> +       if (target_speed > MAX_FS_MODE_SPEED)
> +               max_step_cnt = MAX_HS_STEP_CNT_DIV;
> +       else
> +               max_step_cnt = MAX_STEP_CNT_DIV;
> +
> +       base_step_cnt = max_step_cnt;
> +       /* Find the best combination */
> +       opt_div = DIV_ROUND_UP(clk_src >> 1, target_speed);
> +       best_mul = MAX_SAMPLE_CNT_DIV * max_step_cnt;
> +
> +       /*
> +        * Search for the best pair (sample_cnt, step_cnt) with
> +        * 0 < sample_cnt < MAX_SAMPLE_CNT_DIV
> +        * 0 < step_cnt < max_step_cnt
> +        * sample_cnt * step_cnt >= opt_div
> +        * optimizing for sample_cnt * step_cnt being minimal
> +        */
> +       for (sample_cnt = 1; sample_cnt <= MAX_SAMPLE_CNT_DIV; sample_cnt++) {
> +               step_cnt = DIV_ROUND_UP(opt_div, sample_cnt);
> +               cnt_mul = step_cnt * sample_cnt;
> +               if (step_cnt > max_step_cnt)
> +                       continue;
> +
> +               if (cnt_mul < best_mul) {
> +                       best_mul = cnt_mul;
> +                       base_sample_cnt = sample_cnt;
> +                       base_step_cnt = step_cnt;
> +                       if (best_mul == opt_div)
> +                               break;
> +               }
> +       }
> +
> +       sample_cnt = base_sample_cnt;
> +       step_cnt = base_step_cnt;
> +
> +       if ((clk_src / (2 * sample_cnt * step_cnt)) > target_speed) {
> +               /*
> +                * In this case, hardware can't support such
> +                * low i2c_bus_freq
> +                */
> +               debug("Unsupported speed(%uhz)\n", target_speed);
> +               return log_msg_ret("calculate speed", -EINVAL);
> +       }
> +
> +       *timing_step_cnt = step_cnt - 1;
> +       *timing_sample_cnt = sample_cnt - 1;
> +
> +       return 0;
> +}
> +
> +/*
> + * mtk_i2c_set_speed
> + *
> + * @par Description
> + *     Calculate i2c speed and write sample_cnt, step_cnt to TIMING
>  register.
> + * @param[in]
> + *     dev: udevice pointer, struct udevice contains i2c source clock,
> + *     clock divide and speed.
> + * @return
> + *     0, set speed successfully.\n
> + *     error code from mtk_i2c_calculate_speed().
> + */
> +static int mtk_i2c_set_speed(struct udevice *dev, uint speed)
> +{
> +       struct mtk_i2c_priv *priv = dev_get_priv(dev);
> +       uint high_speed_reg;
> +       uint sample_cnt;
> +       uint timing_reg;
> +       uint step_cnt;
> +       uint clk_src;
> +       int ret = 0;
> +
> +       priv->speed = speed;
> +       if (mtk_i2c_clk_enable(priv))
> +               return log_msg_ret("set_speed enable clk", -1);
> +
> +       clk_src = clk_get_rate(&priv->clk_main) / I2C_DEFAULT_CLK_DIV;
> +       i2c_writel(priv, REG_CLOCK_DIV, (I2C_DEFAULT_CLK_DIV - 1));
> +       if (priv->speed > MAX_FS_MODE_SPEED) {
> +               /* Set master code speed register */
> +               ret = mtk_i2c_calculate_speed(clk_src, MAX_FS_MODE_SPEED,
> +                                             &step_cnt, &sample_cnt);
> +               if (ret < 0)
> +                       goto exit;
> +
> +               timing_reg = (sample_cnt << TIMING_SAMPLE_OFFSET) | step_cnt;
> +               i2c_writel(priv, REG_TIMING, timing_reg);
> +               /* Set the high speed mode register */
> +               ret = mtk_i2c_calculate_speed(clk_src, priv->speed,
> +                                             &step_cnt, &sample_cnt);
> +               if (ret < 0)
> +                       goto exit;
> +
> +               high_speed_reg = I2C_TIME_DEFAULT_VALUE |
> +                               (sample_cnt << HS_SAMPLE_OFFSET) |
> +                               (step_cnt << HS_STEP_OFFSET);
> +               i2c_writel(priv, REG_HS, high_speed_reg);
> +       } else {
> +               ret = mtk_i2c_calculate_speed(clk_src, priv->speed,
> +                                             &step_cnt, &sample_cnt);
> +               if (ret < 0)
> +                       goto exit;
> +
> +               timing_reg = (sample_cnt << TIMING_SAMPLE_OFFSET) | step_cnt;
> +               /* Disable the high speed transaction */
> +               high_speed_reg = I2C_TIME_CLR_VALUE;
> +               i2c_writel(priv, REG_TIMING, timing_reg);
> +               i2c_writel(priv, REG_HS, high_speed_reg);
> +       }
> +exit:
> +       if (mtk_i2c_clk_disable(priv))
> +               return log_msg_ret("set_speed disable clk", -1);
> +
> +       return ret;
> +}
> +
> +/*
> + * mtk_i2c_do_transfer
> + *
> + * @par Description
> + *     Configure i2c register and trigger transfer.
> + * @param[in]
> + *     priv: mtk_i2cmtk_i2c_priv pointer, struct mtk_i2c_priv contains
>  register base\n
> + *     address, operation mode, interrupt status and i2c driver data.
> + * @param[in]
> + *     msgs: i2c_msg pointer, struct i2c_msg contains slave\n
> + *     address, operation mode, msg length and data buffer.
> + * @param[in]
> + *     num: i2c_msg number.
> + * @param[in]
> + *     left_num: left i2c_msg number.
> + * @return
> + *     0, i2c transfer successfully.\n
> + *     -ETIMEDOUT, i2c transfer timeout.\n
> + *     -EREMOTEIO, i2c transfer ack error.
> + */
> +static int mtk_i2c_do_transfer(struct mtk_i2c_priv *priv,
> +                              struct i2c_msg *msgs,
> +                              int num, int left_num)
> +{
> +       uint restart_flag = 0;
> +       uint trans_error = 0;
> +       uint irq_stat = 0;
> +       uint tmo_poll = 0;
> +       uint control_reg;
> +       bool tmo = false;
> +       uint start_reg;
> +       uint addr_reg;
> +       int ret = 0;
> +
> +       if (priv->auto_restart)
> +               restart_flag = I2C_RS_TRANSFER;
> +
> +       control_reg = i2c_readl(priv, REG_CONTROL) &
> +               ~(I2C_CONTROL_DIR_CHANGE | I2C_CONTROL_RS);
> +
> +       if (priv->speed > MAX_FS_MODE_SPEED || num > 1)
> +               control_reg |= I2C_CONTROL_RS;
> +
> +       if (priv->op == I2C_MASTER_WRRD)
> +               control_reg |= I2C_CONTROL_DIR_CHANGE | I2C_CONTROL_RS;
> +
> +       control_reg |= I2C_CONTROL_DMA_EN;
> +       i2c_writel(priv, REG_CONTROL, control_reg);
> +
> +       /* set start condition */
> +       if (priv->speed <= MAX_ST_MODE_SPEED)
> +               i2c_writel(priv, REG_EXT_CONF, I2C_ST_START_CON);
> +       else
> +               i2c_writel(priv, REG_EXT_CONF, I2C_FS_START_CON);
> +
> +       addr_reg = msgs->addr << 1;
> +       if (priv->op == I2C_MASTER_RD)
> +               addr_reg |= I2C_M_RD;
> +       if (priv->zero_len)
> +               i2c_writel(priv, REG_SLAVE_ADDR, addr_reg | TRANS_ADDR_ONLY);
> +       else
> +               i2c_writel(priv, REG_SLAVE_ADDR, addr_reg);
> +
> +       /* clear interrupt status */
> +       i2c_writel(priv, REG_INTR_STAT, restart_flag | I2C_HS_NACKERR |
> +                  I2C_ACKERR | I2C_TRANSAC_COMP);
> +       i2c_writel(priv, REG_FIFO_ADDR_CLR, I2C_FIFO_ADDR_CLR);
> +
> +       /* enable interrupt */
> +       i2c_writel(priv, REG_INTR_MASK, restart_flag | I2C_HS_NACKERR |
> +                  I2C_ACKERR | I2C_TRANSAC_COMP);
> +
> +       /* set transfer and transaction len */
> +       if (priv->op == I2C_MASTER_WRRD) {
> +               i2c_writel(priv, REG_TRANSFER_LEN, msgs->len);
> +               i2c_writel(priv, REG_TRANSFER_LEN_AUX, (msgs + 1)->len);
> +               i2c_writel(priv, REG_TRANSAC_LEN, I2C_WRRD_TRANAC_VALUE);
> +       } else {
> +               i2c_writel(priv, REG_TRANSFER_LEN, msgs->len);
> +               i2c_writel(priv, REG_TRANSAC_LEN, num);
> +       }
> +
> +       /*
> +        * prepare buffer data to start transfer
> +        * three cases here: read, write, write then read
> +        */
> +       if (priv->op == I2C_MASTER_RD) {
> +               /* Clear DMA interrupt flag*/
> +               writel(I2C_DMA_INT_FLAG_NONE, priv->pdmabase + REG_INT_FLAG);
> +               /* Set DMA direction RX*/
> +               writel(I2C_DMA_CON_RX, priv->pdmabase + REG_CON);
> +               flush_cache((ulong)msgs->buf, msgs->len);
> +               /* Write the rx buffer address to dma register*/
> +               writel((ulong)msgs->buf, priv->pdmabase + REG_RX_MEM_ADDR);
> +               /* Write the rx length to dma register*/
> +               writel(msgs->len, priv->pdmabase + REG_RX_LEN);
> +       } else if (priv->op == I2C_MASTER_WR) {
> +               /* Clear DMA interrupt flag*/
> +               writel(I2C_DMA_INT_FLAG_NONE, priv->pdmabase + REG_INT_FLAG);
> +               /* Set DMA direction TX*/
> +               writel(I2C_DMA_CON_TX, priv->pdmabase + REG_CON);
> +               flush_cache((ulong)msgs->buf, msgs->len);
> +               /* Write the tx buffer address to dma register*/
> +               writel((ulong)msgs->buf, priv->pdmabase + REG_TX_MEM_ADDR);
> +               /* Write the tx length to dma register*/
> +               writel(msgs->len, priv->pdmabase + REG_TX_LEN);
> +       } else {
> +               /* Clear DMA interrupt flag*/
> +               writel(I2C_DMA_INT_FLAG_NONE, priv->pdmabase + REG_INT_FLAG);

I think you can use a switch. Clear can be moved out. You can use a
bit more smarter direction flag
in order to flush dcache when needed etc. Your code will be less
duplicate and will be much clean

Michael

> +               /* Set DMA direction TX and RX*/
> +               writel(I2C_DMA_TX_RX, priv->pdmabase + REG_CON);
> +               flush_cache((ulong)msgs->buf, msgs->len);
> +               flush_cache((ulong)(msgs + 1)->buf, (msgs + 1)->len);
> +               /* Write the tx buffer address to dma register*/
> +               writel((ulong)msgs->buf, priv->pdmabase + REG_TX_MEM_ADDR);
> +               /* Write the tx buffer address to dma register*/
> +               writel((ulong)(msgs + 1)->buf, priv->pdmabase + REG_RX_MEM_ADDR);
> +               /* Write the tx length to dma register*/
> +               writel(msgs->len, priv->pdmabase + REG_TX_LEN);
> +               /* Write the rx length to dma register*/
> +               writel((msgs + 1)->len, priv->pdmabase + REG_RX_LEN);
> +       }
> +
> +       writel(I2C_DMA_START_EN, priv->pdmabase + REG_EN);
> +
> +       if (!priv->auto_restart) {
> +               start_reg = I2C_TRANSAC_START;
> +       } else {
> +               start_reg = I2C_TRANSAC_START | I2C_RS_MUL_TRIG;
> +               if (left_num >= 1)
> +                       start_reg |= I2C_RS_MUL_CNFG;
> +       }
> +       i2c_writel(priv, REG_START, start_reg);
> +
> +       for (;;) {
> +               irq_stat = i2c_readl(priv, REG_INTR_STAT);
> +
> +               /* ignore the first restart irq after the master code */
> +               if (priv->ignore_restart_irq && (irq_stat | restart_flag)) {
> +                       priv->ignore_restart_irq = false;
> +                       irq_stat = 0;
> +                       writel(I2C_RS_MUL_CNFG | I2C_RS_MUL_TRIG |
> +                              I2C_TRANSAC_START, priv->base + REG_START);
> +               }
> +
> +               if (irq_stat & (I2C_TRANSAC_COMP | restart_flag)) {
> +                       tmo = false;
> +                       if (irq_stat & (I2C_HS_NACKERR | I2C_ACKERR))
> +                               trans_error = 1;
> +
> +                       break;
> +               }
> +               udelay(1);
> +               if (tmo_poll++ >= TRANSFER_TIMEOUT) {
> +                       tmo = true;
> +                       break;
> +               }

I think we have already better function to wait a condition in uboot

> +       }
> +
> +       /* clear interrupt mask */
> +       i2c_writel(priv, REG_INTR_MASK, ~(restart_flag | I2C_HS_NACKERR |
> +                 I2C_ACKERR | I2C_TRANSAC_COMP));
> +
> +       if (!tmo && trans_error != 0) {
> +               if (tmo) {
> +                       ret = -ETIMEDOUT;
> +                       if (!priv->filter_msg)
> +                               debug("I2C timeout! addr: 0x%x,\n", msgs->addr);
> +               } else {
> +                       ret = -EREMOTEIO;
> +                       if (!priv->filter_msg)
> +                               debug("I2C ACKERR! addr: 0x%x,IRQ:0x%x\n",
> +                                     msgs->addr, irq_stat);
> +               }
> +               mtk_i2c_init_hw(priv);
> +       }
> +
> +       return ret;
> +}
> +
> +/*
> + * mtk_i2c_transfer
> + *
> + * @par Description
> + *     Common i2c transfer API. Set i2c transfer mode according to
>  i2c_msg\n
> + *     information, then call mtk_i2c_do_transfer() to configure i2c
>  register\n
> + *     and trigger transfer.
> + * @param[in]
> + *     dev: udevice pointer, struct udevice contains struct mtk_i2c_priv,
>  \n
> + *        struct mtk_i2c_priv contains register base\n
> + *     address, operation mode, interrupt status and i2c driver data.
> + * @param[in]
> + *     msgs: i2c_msg pointer, struct i2c_msg contains slave\n
> + *     address, operation mode, msg length and data buffer.
> + * @param[in]
> + *     num: i2c_msg number.
> + * @return
> + *     i2c_msg number, i2c transfer successfully.\n
> + *     -EINVAL, msg length is more than 16\n
> + *     use DMA MODE or slave address more than 0x7f.\n
> + *     error code from mtk_i2c_init_base().\n
> + *     error code from mtk_i2c_set_speed().\n
> + *     error code from mtk_i2c_do_transfer().
> + */
> +static int mtk_i2c_transfer(struct udevice *dev, struct i2c_msg *msg,
> +                           int nmsgs)
> +{
> +       struct mtk_i2c_priv *priv = dev_get_priv(dev);
> +       int left_num;
> +       uint num_cnt;
> +       int ret;
> +
> +       priv->auto_restart = true;
> +       left_num = nmsgs;
> +       if (mtk_i2c_clk_enable(priv))
> +               return log_msg_ret("transfer enable clk", -1);
> +
> +       for (num_cnt = 0; num_cnt < nmsgs; num_cnt++) {
> +               if (((msg + num_cnt)->addr) > MAX_I2C_ADDR) {
> +                       ret = -EINVAL;
> +                       goto err_exit;
> +               }
> +               if ((msg + num_cnt)->len > MAX_I2C_LEN) {
> +                       ret = -EINVAL;
> +                       goto err_exit;
> +               }
> +       }
> +
> +       /* check if we can skip restart and optimize using WRRD mode */
> +       if (priv->auto_restart && nmsgs == 2) {
> +               if (!(msg[0].flags & I2C_M_RD) && (msg[1].flags & I2C_M_RD) &&
> +                   msg[0].addr == msg[1].addr) {
> +                       priv->auto_restart = false;
> +               }
> +       }
> +
> +       if (priv->auto_restart && nmsgs >= 2 && priv->speed > MAX_FS_MODE_SPEED)
> +               /* ignore the first restart irq after the master code,
> +                * otherwise the first transfer will be discarded.
> +                */
> +               priv->ignore_restart_irq = true;
> +       else
> +               priv->ignore_restart_irq = false;
> +
> +       while (left_num--) {
> +               /* transfer slave address only to support devices detect */
> +               if (!msg->buf)
> +                       priv->zero_len = true;
> +               else
> +                       priv->zero_len = false;
> +
> +               if (msg->flags & I2C_M_RD)
> +                       priv->op = I2C_MASTER_RD;
> +               else
> +                       priv->op = I2C_MASTER_WR;
> +
> +               if (!priv->auto_restart) {
> +                       if (nmsgs > 1) {
> +                               /* combined two messages into one transaction */
> +                               priv->op = I2C_MASTER_WRRD;
> +                               left_num--;
> +                       }
> +               }
> +               ret = mtk_i2c_do_transfer(priv, msg, nmsgs, left_num);
> +               if (ret < 0)
> +                       goto err_exit;
> +               msg++;
> +       }
> +       ret = 0;
> +
> +err_exit:
> +       if (mtk_i2c_clk_disable(priv))
> +               return log_msg_ret("transfer disable clk", -1);
> +
> +       return ret;
> +}
> +
> +static int mtk_i2c_ofdata_to_platdata(struct udevice *dev)
> +{
> +       struct mtk_i2c_priv *priv = dev_get_priv(dev);
> +       int ret;
> +
> +       priv->base = dev_remap_addr_index(dev, 0);
> +       priv->pdmabase = dev_remap_addr_index(dev, 1);
> +       ret = clk_get_by_index(dev, 0, &priv->clk_main);
> +       if (ret)
> +               return log_msg_ret("clk_get_by_index 0", ret);
> +
> +       ret = clk_get_by_index(dev, 1, &priv->clk_dma);
> +
> +       return ret;
> +}
> +
> +static int mtk_i2c_probe(struct udevice *dev)
> +{
> +       struct mtk_i2c_priv *priv = dev_get_priv(dev);
> +
> +       priv->soc_data = (struct mtk_i2c_soc_data *)dev_get_driver_data(dev);
> +
> +       if (mtk_i2c_clk_enable(priv))
> +               return log_msg_ret("probe enable clk", -1);
> +
> +       mtk_i2c_init_hw(priv);
> +
> +       if (mtk_i2c_clk_disable(priv))
> +               return log_msg_ret("probe disable clk", -1);
> +
> +       return 0;
> +}
> +
> +static int mtk_i2c_deblock(struct udevice *dev)
> +{
> +       struct mtk_i2c_priv *priv = dev_get_priv(dev);
> +
> +       if (mtk_i2c_clk_enable(priv))
> +               return log_msg_ret("deblock enable clk", -1);
> +
> +       mtk_i2c_init_hw(priv);
> +
> +       if (mtk_i2c_clk_disable(priv))
> +               return log_msg_ret("deblock disable clk", -1);
> +
> +       return 0;
> +}
> +
> +static const struct mtk_i2c_soc_data mt76xx_soc_data = {
> +       .regs = mt_i2c_regs_v1,
> +       .dma_sync = 0,
> +};
> +
> +static const struct mtk_i2c_soc_data mt7981_soc_data = {
> +       .regs = mt_i2c_regs_v1,
> +       .dma_sync = 1,
> +};
> +
> +static const struct mtk_i2c_soc_data mt7986_soc_data = {
> +       .regs = mt_i2c_regs_v1,
> +       .dma_sync = 1,
> +};
> +
> +static const struct mtk_i2c_soc_data mt8183_soc_data = {
> +       .regs = mt_i2c_regs_v2,
> +       .dma_sync = 1,
> +};
> +
> +static const struct mtk_i2c_soc_data mt8518_soc_data = {
> +       .regs = mt_i2c_regs_v1,
> +       .dma_sync = 0,
> +};
> +
> +static const struct mtk_i2c_soc_data mt8512_soc_data = {
> +       .regs = mt_i2c_regs_v1,
> +       .dma_sync = 1,
> +};
> +
> +static const struct dm_i2c_ops mtk_i2c_ops = {
> +       .xfer           = mtk_i2c_transfer,
> +       .set_bus_speed  = mtk_i2c_set_speed,
> +       .deblock        = mtk_i2c_deblock,
> +};
> +
> +static const struct udevice_id mtk_i2c_ids[] = {
> +       {
> +               .compatible = "mediatek,mt7622-i2c",
> +               .data = (ulong)&mt76xx_soc_data,
> +       }, {
> +               .compatible = "mediatek,mt7623-i2c",
> +               .data = (ulong)&mt76xx_soc_data,
> +       }, {
> +               .compatible = "mediatek,mt7629-i2c",
> +               .data = (ulong)&mt76xx_soc_data,
> +       }, {
> +               .compatible = "mediatek,mt7981-i2c",
> +               .data = (ulong)&mt7981_soc_data,
> +       }, {
> +               .compatible = "mediatek,mt7986-i2c",
> +               .data = (ulong)&mt7986_soc_data,
> +       }, {
> +               .compatible = "mediatek,mt8183-i2c",
> +               .data = (ulong)&mt8183_soc_data,
> +       }, {
> +               .compatible = "mediatek,mt8512-i2c",
> +               .data = (ulong)&mt8512_soc_data,
> +       }, {
> +               .compatible = "mediatek,mt8518-i2c",
> +               .data = (ulong)&mt8518_soc_data,
> +       }
> +};
> +
> +U_BOOT_DRIVER(mtk_i2c) = {
> +       .name           = "mtk_i2c",
> +       .id             = UCLASS_I2C,
> +       .of_match       = mtk_i2c_ids,
> +       .of_to_plat     = mtk_i2c_ofdata_to_platdata,
> +       .probe          = mtk_i2c_probe,
> +       .priv_auto      = sizeof(struct mtk_i2c_priv),
> +       .ops            = &mtk_i2c_ops,
> +};
> --
> 2.17.1
>


-- 
Michael Nazzareno Trimarchi
Co-Founder & Chief Executive Officer
M. +39 347 913 2170
michael@amarulasolutions.com
__________________________________

Amarula Solutions BV
Joop Geesinkweg 125, 1114 AB, Amsterdam, NL
T. +31 (0)85 111 9172
info@amarulasolutions.com
www.amarulasolutions.com

^ permalink raw reply	[flat|nested] 100+ messages in thread

* RE: [PATCH 05/31] mmc: mediatek: add support for MediaTek MT7891/MT7986 SoCs
  2022-08-04  3:35 ` [PATCH 05/31] mmc: mediatek: add support for MediaTek MT7891/MT7986 SoCs Weijie Gao
  2022-08-04 13:57   ` Simon Glass
@ 2022-08-11  5:50   ` jh80.chung
  1 sibling, 0 replies; 100+ messages in thread
From: jh80.chung @ 2022-08-11  5:50 UTC (permalink / raw)
  To: 'Weijie Gao', u-boot
  Cc: 'GSS_MTK_Uboot_upstream', 'Peng Fan'



> -----Original Message-----
> From: Weijie Gao [mailto:weijie.gao@mediatek.com]
> Sent: Thursday, August 4, 2022 12:35 PM
> To: u-boot@lists.denx.de
> Cc: GSS_MTK_Uboot_upstream; Peng Fan; Jaehoon Chung; Weijie Gao
> Subject: [PATCH 05/31] mmc: mediatek: add support for MediaTek MT7891/MT7986 SoCs
>
> This patch adds eMMC and SDXC support for MediaTek MT7981/MT7986 SoCs
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>

Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>

Best Regards,
Jaehoon Chung

> ---
>  drivers/mmc/mtk-sd.c | 68 ++++++++++++++++++++++++++++++++++----------
>  1 file changed, 53 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/mmc/mtk-sd.c b/drivers/mmc/mtk-sd.c
> index e61e8cf4b9..b206b0a085 100644
> --- a/drivers/mmc/mtk-sd.c
> +++ b/drivers/mmc/mtk-sd.c
> @@ -1496,7 +1496,12 @@ static void msdc_init_hw(struct msdc_host *host)
>  	/* Enable data & cmd interrupts */
>  	writel(DATA_INTS_MASK | CMD_INTS_MASK, &host->base->msdc_inten);
>
> -	writel(0, tune_reg);
> +	if (host->top_base) {
> +		writel(0, &host->top_base->emmc_top_control);
> +		writel(0, &host->top_base->emmc_top_cmd);
> +	} else {
> +		writel(0, tune_reg);
> +	}
>  	writel(0, &host->base->msdc_iocon);
>
>  	if (host->r_smpl)
> @@ -1507,9 +1512,14 @@ static void msdc_init_hw(struct msdc_host *host)
>  	writel(0x403c0046, &host->base->patch_bit0);
>  	writel(0xffff4089, &host->base->patch_bit1);
>
> -	if (host->dev_comp->stop_clk_fix)
> +	if (host->dev_comp->stop_clk_fix) {
>  		clrsetbits_le32(&host->base->patch_bit1, MSDC_PB1_STOP_DLY_M,
>  				3 << MSDC_PB1_STOP_DLY_S);
> +		clrbits_le32(&host->base->sdc_fifo_cfg,
> +			     SDC_FIFO_CFG_WRVALIDSEL);
> +		clrbits_le32(&host->base->sdc_fifo_cfg,
> +			     SDC_FIFO_CFG_RDVALIDSEL);
> +	}
>
>  	if (host->dev_comp->busy_check)
>  		clrbits_le32(&host->base->patch_bit1, (1 << 7));
> @@ -1544,15 +1554,28 @@ static void msdc_init_hw(struct msdc_host *host)
>  	}
>
>  	if (host->dev_comp->data_tune) {
> -		setbits_le32(tune_reg,
> -			     MSDC_PAD_TUNE_RD_SEL | MSDC_PAD_TUNE_CMD_SEL);
> -		clrsetbits_le32(&host->base->patch_bit0,
> -				MSDC_INT_DAT_LATCH_CK_SEL_M,
> -				host->latch_ck <<
> -				MSDC_INT_DAT_LATCH_CK_SEL_S);
> +		if (host->top_base) {
> +			setbits_le32(&host->top_base->emmc_top_control,
> +				     PAD_DAT_RD_RXDLY_SEL);
> +			clrbits_le32(&host->top_base->emmc_top_control,
> +				     DATA_K_VALUE_SEL);
> +			setbits_le32(&host->top_base->emmc_top_cmd,
> +				     PAD_CMD_RD_RXDLY_SEL);
> +		} else {
> +			setbits_le32(tune_reg,
> +				     MSDC_PAD_TUNE_RD_SEL | MSDC_PAD_TUNE_CMD_SEL);
> +			clrsetbits_le32(&host->base->patch_bit0,
> +					MSDC_INT_DAT_LATCH_CK_SEL_M,
> +					host->latch_ck <<
> +					MSDC_INT_DAT_LATCH_CK_SEL_S);
> +		}
>  	} else {
>  		/* choose clock tune */
> -		setbits_le32(tune_reg, MSDC_PAD_TUNE_RXDLYSEL);
> +		if (host->top_base)
> +			setbits_le32(&host->top_base->emmc_top_control,
> +				     PAD_RXDLY_SEL);
> +		else
> +			setbits_le32(tune_reg, MSDC_PAD_TUNE_RXDLYSEL);
>  	}
>
>  	if (host->dev_comp->builtin_pad_ctrl) {
> @@ -1604,12 +1627,6 @@ static void msdc_init_hw(struct msdc_host *host)
>  	clrsetbits_le32(&host->base->sdc_cfg, SDC_CFG_DTOC_M,
>  			3 << SDC_CFG_DTOC_S);
>
> -	if (host->dev_comp->stop_clk_fix) {
> -		clrbits_le32(&host->base->sdc_fifo_cfg,
> -			     SDC_FIFO_CFG_WRVALIDSEL);
> -		clrbits_le32(&host->base->sdc_fifo_cfg,
> -			     SDC_FIFO_CFG_RDVALIDSEL);
> -	}
>
>  	host->def_tune_para.iocon = readl(&host->base->msdc_iocon);
>  	host->def_tune_para.pad_tune = readl(&host->base->pad_tune);
> @@ -1792,6 +1809,25 @@ static const struct msdc_compatible mt7623_compat = {
>  	.enhance_rx = false
>  };
>
> +static const struct msdc_compatible mt7986_compat = {
> +	.clk_div_bits = 12,
> +	.pad_tune0 = true,
> +	.async_fifo = true,
> +	.data_tune = true,
> +	.busy_check = true,
> +	.stop_clk_fix = true,
> +	.enhance_rx = true,
> +};
> +
> +static const struct msdc_compatible mt7981_compat = {
> +	.clk_div_bits = 12,
> +	.pad_tune0 = true,
> +	.async_fifo = true,
> +	.data_tune = true,
> +	.busy_check = true,
> +	.stop_clk_fix = true,
> +};
> +
>  static const struct msdc_compatible mt8512_compat = {
>  	.clk_div_bits = 12,
>  	.pad_tune0 = true,
> @@ -1824,6 +1860,8 @@ static const struct udevice_id msdc_ids[] = {
>  	{ .compatible = "mediatek,mt7621-mmc", .data = (ulong)&mt7621_compat },
>  	{ .compatible = "mediatek,mt7622-mmc", .data = (ulong)&mt7622_compat },
>  	{ .compatible = "mediatek,mt7623-mmc", .data = (ulong)&mt7623_compat },
> +	{ .compatible = "mediatek,mt7986-mmc", .data = (ulong)&mt7986_compat },
> +	{ .compatible = "mediatek,mt7981-mmc", .data = (ulong)&mt7981_compat },
>  	{ .compatible = "mediatek,mt8512-mmc", .data = (ulong)&mt8512_compat },
>  	{ .compatible = "mediatek,mt8516-mmc", .data = (ulong)&mt8516_compat },
>  	{ .compatible = "mediatek,mt8183-mmc", .data = (ulong)&mt8183_compat },
> --
> 2.17.1




^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 17/31] i2c: add support for MediaTek I2C interface
  2022-08-10 11:24   ` Michael Nazzareno Trimarchi
@ 2022-08-12  9:46     ` Weijie Gao
  0 siblings, 0 replies; 100+ messages in thread
From: Weijie Gao @ 2022-08-12  9:46 UTC (permalink / raw)
  To: Michael Nazzareno Trimarchi
  Cc: u-boot, GSS_MTK_Uboot_upstream, Heiko Schocher

On Wed, 2022-08-10 at 13:24 +0200, Michael Nazzareno Trimarchi wrote:
> Hi
> 
> On Thu, Aug 4, 2022 at 5:38 AM Weijie Gao <weijie.gao@mediatek.com>
> wrote:
> > 
> > This patch adds support for MediaTek I2C interface
> > 
> > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> > ---
> >  drivers/i2c/Kconfig   |   9 +
> >  drivers/i2c/Makefile  |   1 +
> >  drivers/i2c/mtk_i2c.c | 822
> > ++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 832 insertions(+)
> >  create mode 100644 drivers/i2c/mtk_i2c.c
> > 
> > diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
> > index be4724bf8e..08b6c7bdcc 100644
> > --- a/drivers/i2c/Kconfig
> > +++ b/drivers/i2c/Kconfig
> > @@ -261,6 +261,15 @@ config SYS_I2C_MESON
> >           internal buffer holding up to 8 bytes for transfers and
> > supports
> >           both 7-bit and 10-bit addresses.
> > 
> > +config SYS_I2C_MTK
> > +       bool "MediaTek I2C driver"
> > +       help
> > +         This selects the MediaTek Integrated Inter Circuit bus
> > driver.
> > +         The I2C bus adapter is the base for some other I2C
> > client,
> > +         eg: touch, sensors.
> > +         If you want to use MediaTek I2C interface, say Y here.
> > +         If unsure, say N.
> > +
> >  config SYS_I2C_MICROCHIP
> >         bool "Microchip I2C driver"
> >         help
> > diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
> > index 7e046f809a..920aafb91c 100644
> > --- a/drivers/i2c/Makefile
> > +++ b/drivers/i2c/Makefile
> > @@ -32,6 +32,7 @@ obj-$(CONFIG_SYS_I2C_MICROCHIP) += i2c-
> > microchip.o
> >  obj-$(CONFIG_SYS_I2C_MV) += mv_i2c.o
> >  obj-$(CONFIG_SYS_I2C_MVTWSI) += mvtwsi.o
> >  obj-$(CONFIG_SYS_I2C_MXC) += mxc_i2c.o
> > +obj-$(CONFIG_SYS_I2C_MTK) += mtk_i2c.o
> >  obj-$(CONFIG_SYS_I2C_NEXELL) += nx_i2c.o
> >  obj-$(CONFIG_SYS_I2C_NPCM) += npcm_i2c.o
> >  obj-$(CONFIG_SYS_I2C_OCORES) += ocores_i2c.o
> > diff --git a/drivers/i2c/mtk_i2c.c b/drivers/i2c/mtk_i2c.c
> > new file mode 100644
> > index 0000000000..1d4a93f8c9
> > --- /dev/null
> > +++ b/drivers/i2c/mtk_i2c.c
> > @@ -0,0 +1,822 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * Copyright (C) 2022 MediaTek Inc. All Rights Reserved.
> > + *
> > + * Author: Mingming Lee <Mingming.Lee@mediatek.com>
> > + *
> > + * MediaTek I2C Interface driver
> > + */
> > +
> > +#include <clk.h>
> > +#include <cpu_func.h>
> > +#include <dm.h>
> > +#include <i2c.h>
> > +#include <log.h>
> > +#include <asm/cache.h>
> > +#include <asm/io.h>
> > +#include <linux/delay.h>
> > +#include <linux/errno.h>
> > +
> > +#define I2C_RS_TRANSFER                        BIT(4)
> > +#define I2C_HS_NACKERR                 BIT(2)
> > +#define I2C_ACKERR                     BIT(1)
> > +#define I2C_TRANSAC_COMP               BIT(0)
> > +#define I2C_TRANSAC_START              BIT(0)
> > +#define I2C_RS_MUL_CNFG                        BIT(15)
> > +#define I2C_RS_MUL_TRIG                        BIT(14)
> > +#define I2C_DCM_DISABLE                        0x0000
> > +#define I2C_IO_CONFIG_OPEN_DRAIN       0x0003
> > +#define I2C_IO_CONFIG_PUSH_PULL                0x0000
> > +#define I2C_SOFT_RST                   0x0001
> > +#define I2C_FIFO_ADDR_CLR              0x0001
> > +#define I2C_DELAY_LEN                  0x0002
> > +#define I2C_ST_START_CON               0x8001
> > +#define I2C_FS_START_CON               0x1800
> > +#define I2C_TIME_CLR_VALUE             0x0000
> > +#define I2C_TIME_DEFAULT_VALUE         0x0003
> > +#define I2C_WRRD_TRANAC_VALUE          0x0002
> > +#define I2C_RD_TRANAC_VALUE            0x0001
> > +
> > +#define I2C_DMA_CON_TX                 0x0000
> > +#define I2C_DMA_CON_RX                 0x0001
> > +#define I2C_DMA_START_EN               0x0001
> > +#define I2C_DMA_INT_FLAG_NONE          0x0000
> > +#define I2C_DMA_CLR_FLAG               0x0000
> > +#define I2C_DMA_TX_RX                  0x0000
> > +#define I2C_DMA_HARD_RST               0x0002
> > +
> > +#define MAX_ST_MODE_SPEED              100000
> > +#define MAX_FS_MODE_SPEED              400000
> > +#define MAX_HS_MODE_SPEED              3400000
> > +#define MAX_SAMPLE_CNT_DIV             8
> > +#define MAX_STEP_CNT_DIV               64
> > +#define MAX_HS_STEP_CNT_DIV            8
> > +#define I2C_DEFAULT_CLK_DIV            4
> > +
> > +#define MAX_I2C_ADDR                   0x7f
> > +#define MAX_I2C_LEN                    0xff
> > +#define TRANS_ADDR_ONLY                        BIT(8)
> > +#define TRANSFER_TIMEOUT               50000  /* us */
> > +#define I2C_FIFO_STAT1_MASK            0x001f
> > +#define TIMING_SAMPLE_OFFSET           8
> > +#define HS_SAMPLE_OFFSET               12
> > +#define HS_STEP_OFFSET                 8
> > +
> > +#define I2C_CONTROL_WRAPPER            BIT(0)
> > +#define I2C_CONTROL_RS                 BIT(1)
> > +#define I2C_CONTROL_DMA_EN             BIT(2)
> > +#define I2C_CONTROL_CLK_EXT_EN         BIT(3)
> > +#define I2C_CONTROL_DIR_CHANGE         BIT(4)
> > +#define I2C_CONTROL_ACKERR_DET_EN      BIT(5)
> > +#define I2C_CONTROL_TRANSFER_LEN_CHANGE BIT(6)
> > +#define I2C_CONTROL_DMAACK             BIT(8)
> > +#define I2C_CONTROL_ASYNC              BIT(9)
> > +
> > +enum I2C_REGS_OFFSET {
> > +       REG_PORT,
> > +       REG_SLAVE_ADDR,
> > +       REG_INTR_MASK,
> > +       REG_INTR_STAT,
> > +       REG_CONTROL,
> > +       REG_TRANSFER_LEN,
> > +       REG_TRANSAC_LEN,
> > +       REG_DELAY_LEN,
> > +       REG_TIMING,
> > +       REG_START,
> > +       REG_EXT_CONF,
> > +       REG_FIFO_STAT1,
> > +       REG_LTIMING,
> > +       REG_FIFO_STAT,
> > +       REG_FIFO_THRESH,
> > +       REG_FIFO_ADDR_CLR,
> > +       REG_IO_CONFIG,
> > +       REG_RSV_DEBUG,
> > +       REG_HS,
> > +       REG_SOFTRESET,
> > +       REG_DCM_EN,
> > +       REG_PATH_DIR,
> > +       REG_DEBUGSTAT,
> > +       REG_DEBUGCTRL,
> > +       REG_TRANSFER_LEN_AUX,
> > +       REG_CLOCK_DIV,
> > +       REG_SCL_HL_RATIO,
> > +       REG_SCL_HS_HL_RATIO,
> > +       REG_SCL_MIS_COMP_POINT,
> > +       REG_STA_STOP_AC_TIME,
> > +       REG_HS_STA_STOP_AC_TIME,
> > +       REG_DATA_TIME,
> > +};
> > +
> > +enum DMA_REGS_OFFSET {
> > +       REG_INT_FLAG = 0x0,
> > +       REG_INT_EN = 0x04,
> > +       REG_EN = 0x08,
> > +       REG_RST = 0x0c,
> > +       REG_CON = 0x18,
> > +       REG_TX_MEM_ADDR = 0x1c,
> > +       REG_RX_MEM_ADDR = 0x20,
> > +       REG_TX_LEN = 0x24,
> > +       REG_RX_LEN = 0x28,
> > +};
> > +
> > +static const uint mt_i2c_regs_v1[] = {
> > +       [REG_PORT] = 0x0,
> > +       [REG_SLAVE_ADDR] = 0x4,
> > +       [REG_INTR_MASK] = 0x8,
> > +       [REG_INTR_STAT] = 0xc,
> > +       [REG_CONTROL] = 0x10,
> > +       [REG_TRANSFER_LEN] = 0x14,
> > +       [REG_TRANSAC_LEN] = 0x18,
> > +       [REG_DELAY_LEN] = 0x1c,
> > +       [REG_TIMING] = 0x20,
> > +       [REG_START] = 0x24,
> > +       [REG_EXT_CONF] = 0x28,
> > +       [REG_FIFO_STAT1] = 0x2c,
> > +       [REG_FIFO_STAT] = 0x30,
> > +       [REG_FIFO_THRESH] = 0x34,
> > +       [REG_FIFO_ADDR_CLR] = 0x38,
> > +       [REG_IO_CONFIG] = 0x40,
> > +       [REG_RSV_DEBUG] = 0x44,
> > +       [REG_HS] = 0x48,
> > +       [REG_SOFTRESET] = 0x50,
> > +       [REG_SOFTRESET] = 0x50,
> > +       [REG_DCM_EN] = 0x54,
> > +       [REG_DEBUGSTAT] = 0x64,
> > +       [REG_DEBUGCTRL] = 0x68,
> > +       [REG_TRANSFER_LEN_AUX] = 0x6c,
> > +       [REG_CLOCK_DIV] = 0x70,
> > +       [REG_SCL_HL_RATIO] = 0x74,
> > +       [REG_SCL_HS_HL_RATIO] = 0x78,
> > +       [REG_SCL_MIS_COMP_POINT] = 0x7c,
> > +       [REG_STA_STOP_AC_TIME] = 0x80,
> > +       [REG_HS_STA_STOP_AC_TIME] = 0x84,
> > +       [REG_DATA_TIME] = 0x88,
> > +};
> > +
> > +static const uint mt_i2c_regs_v2[] = {
> > +       [REG_PORT] = 0x0,
> > +       [REG_SLAVE_ADDR] = 0x4,
> > +       [REG_INTR_MASK] = 0x8,
> > +       [REG_INTR_STAT] = 0xc,
> > +       [REG_CONTROL] = 0x10,
> > +       [REG_TRANSFER_LEN] = 0x14,
> > +       [REG_TRANSAC_LEN] = 0x18,
> > +       [REG_DELAY_LEN] = 0x1c,
> > +       [REG_TIMING] = 0x20,
> > +       [REG_START] = 0x24,
> > +       [REG_EXT_CONF] = 0x28,
> > +       [REG_LTIMING] = 0x2c,
> > +       [REG_HS] = 0x30,
> > +       [REG_IO_CONFIG] = 0x34,
> > +       [REG_FIFO_ADDR_CLR] = 0x38,
> > +       [REG_TRANSFER_LEN_AUX] = 0x44,
> > +       [REG_CLOCK_DIV] = 0x48,
> > +       [REG_SOFTRESET] = 0x50,
> > +       [REG_DEBUGSTAT] = 0xe0,
> > +       [REG_DEBUGCTRL] = 0xe8,
> > +       [REG_FIFO_STAT] = 0xf4,
> > +       [REG_FIFO_THRESH] = 0xf8,
> > +       [REG_DCM_EN] = 0xf88,
> > +};
> > +
> > +enum mtk_trans_op {
> > +       I2C_MASTER_WR = 1,
> > +       I2C_MASTER_RD,
> > +       I2C_MASTER_WRRD,
> > +};
> > +
> > +struct mtk_i2c_soc_data {
> > +       const uint *regs;
> > +       uint dma_sync: 1;
> > +};
> > +
> > +struct mtk_i2c_priv {
> > +       /* set in i2c probe */
> > +       void __iomem *base;             /* i2c base addr */
> > +       void __iomem *pdmabase;         /* dma base address*/
> > +       struct clk clk_main;            /* main clock for i2c bus
> > */
> > +       struct clk clk_dma;             /* DMA clock for i2c via
> > DMA */
> > +       const struct mtk_i2c_soc_data *soc_data; /* Compatible data
> > for different
> >  IC */
> > +       enum mtk_trans_op op;           /* operation mode */
> > +       bool zero_len;                  /* Only transfer slave
> > address, no data */
> > +       bool pushpull;                  /* push pull mode or open
> > drain mode */
> > +       bool filter_msg;                /* filter msg error log */
> > +       bool auto_restart;              /* restart mode */
> > +       bool ignore_restart_irq;        /* ignore restart IRQ */
> > +       uint speed;                     /* i2c speed, unit: hz */
> > +};
> > +
> > +static inline void i2c_writel(struct mtk_i2c_priv *priv, uint reg,
> > uint
> >  value)
> > +{
> > +       u32 offset = priv->soc_data->regs[reg];
> > +
> > +       writel(value, priv->base + offset);
> > +}
> > +
> > +static inline uint i2c_readl(struct mtk_i2c_priv *priv, uint
> > offset)
> > +{
> > +       return readl(priv->base + priv->soc_data->regs[offset]);
> > +}
> > +
> > +static int mtk_i2c_clk_enable(struct mtk_i2c_priv *priv)
> > +{
> > +       int ret;
> > +
> > +       ret = clk_enable(&priv->clk_main);
> > +       if (ret)
> > +               return log_msg_ret("enable clk_main", ret);
> > +
> > +       ret = clk_enable(&priv->clk_dma);
> > +       if (ret)
> > +               return log_msg_ret("enable clk_dma", ret);
> > +
> > +       return 0;
> > +}
> > +
> > +static int mtk_i2c_clk_disable(struct mtk_i2c_priv *priv)
> > +{
> > +       int ret;
> > +
> > +       ret = clk_disable(&priv->clk_dma);
> > +       if (ret)
> > +               return log_msg_ret("disable clk_dma", ret);
> > +
> > +       ret = clk_disable(&priv->clk_main);
> > +       if (ret)
> > +               return log_msg_ret("disable clk_main", ret);
> > +
> > +       return 0;
> > +}
> > +
> > +static void mtk_i2c_init_hw(struct mtk_i2c_priv *priv)
> > +{
> > +       uint control_reg;
> > +
> > +       writel(I2C_DMA_HARD_RST, priv->pdmabase + REG_RST);
> > +       writel(I2C_DMA_CLR_FLAG, priv->pdmabase + REG_RST);
> > +       i2c_writel(priv, REG_SOFTRESET, I2C_SOFT_RST);
> > +       /* set ioconfig */
> > +       if (priv->pushpull)
> > +               i2c_writel(priv, REG_IO_CONFIG,
> > I2C_IO_CONFIG_PUSH_PULL);
> > +       else
> > +               i2c_writel(priv, REG_IO_CONFIG,
> > I2C_IO_CONFIG_OPEN_DRAIN);
> > +
> > +       i2c_writel(priv, REG_DCM_EN, I2C_DCM_DISABLE);
> > +       control_reg = I2C_CONTROL_ACKERR_DET_EN |
> > I2C_CONTROL_CLK_EXT_EN;
> > +       if (priv->soc_data->dma_sync)
> > +               control_reg |= I2C_CONTROL_DMAACK |
> > I2C_CONTROL_ASYNC;
> > +       i2c_writel(priv, REG_CONTROL, control_reg);
> > +       i2c_writel(priv, REG_DELAY_LEN, I2C_DELAY_LEN);
> > +}
> > +
> > +/*
> > + * Calculate i2c port speed
> > + *
> > + * Hardware design:
> > + * i2c_bus_freq = parent_clk / (clock_div * 2 * sample_cnt *
> > step_cnt)
> > + * clock_div: fixed in hardware, but may be various in different
> > SoCs
> > + *
> > + * The calculation want to pick the highest bus frequency that is
> > still
> > + * less than or equal to target_speed. The calculation try to get
> > + * sample_cnt and step_cn
> > + * @param[in]
> > + *     clk_src: i2c clock source
> > + * @param[out]
> > + *     timing_step_cnt: step cnt calculate result
> > + * @param[out]
> > + *     timing_sample_cnt: sample cnt calculate result
> > + * @return
> > + *     0, set speed successfully.
> > + *     -EINVAL, Unsupported speed.
> > + */
> > +static int mtk_i2c_calculate_speed(uint clk_src,
> > +                                  uint target_speed,
> > +                                  uint *timing_step_cnt,
> > +                                  uint *timing_sample_cnt)
> > +{
> > +       uint base_sample_cnt = MAX_SAMPLE_CNT_DIV;
> > +       uint base_step_cnt;
> > +       uint max_step_cnt;
> > +       uint sample_cnt;
> > +       uint step_cnt;
> > +       uint opt_div;
> > +       uint best_mul;
> > +       uint cnt_mul;
> > +
> > +       if (target_speed > MAX_HS_MODE_SPEED)
> > +               target_speed = MAX_HS_MODE_SPEED;
> > +
> > +       if (target_speed > MAX_FS_MODE_SPEED)
> > +               max_step_cnt = MAX_HS_STEP_CNT_DIV;
> > +       else
> > +               max_step_cnt = MAX_STEP_CNT_DIV;
> > +
> > +       base_step_cnt = max_step_cnt;
> > +       /* Find the best combination */
> > +       opt_div = DIV_ROUND_UP(clk_src >> 1, target_speed);
> > +       best_mul = MAX_SAMPLE_CNT_DIV * max_step_cnt;
> > +
> > +       /*
> > +        * Search for the best pair (sample_cnt, step_cnt) with
> > +        * 0 < sample_cnt < MAX_SAMPLE_CNT_DIV
> > +        * 0 < step_cnt < max_step_cnt
> > +        * sample_cnt * step_cnt >= opt_div
> > +        * optimizing for sample_cnt * step_cnt being minimal
> > +        */
> > +       for (sample_cnt = 1; sample_cnt <= MAX_SAMPLE_CNT_DIV;
> > sample_cnt++) {
> > +               step_cnt = DIV_ROUND_UP(opt_div, sample_cnt);
> > +               cnt_mul = step_cnt * sample_cnt;
> > +               if (step_cnt > max_step_cnt)
> > +                       continue;
> > +
> > +               if (cnt_mul < best_mul) {
> > +                       best_mul = cnt_mul;
> > +                       base_sample_cnt = sample_cnt;
> > +                       base_step_cnt = step_cnt;
> > +                       if (best_mul == opt_div)
> > +                               break;
> > +               }
> > +       }
> > +
> > +       sample_cnt = base_sample_cnt;
> > +       step_cnt = base_step_cnt;
> > +
> > +       if ((clk_src / (2 * sample_cnt * step_cnt)) > target_speed)
> > {
> > +               /*
> > +                * In this case, hardware can't support such
> > +                * low i2c_bus_freq
> > +                */
> > +               debug("Unsupported speed(%uhz)\n", target_speed);
> > +               return log_msg_ret("calculate speed", -EINVAL);
> > +       }
> > +
> > +       *timing_step_cnt = step_cnt - 1;
> > +       *timing_sample_cnt = sample_cnt - 1;
> > +
> > +       return 0;
> > +}
> > +
> > +/*
> > + * mtk_i2c_set_speed
> > + *
> > + * @par Description
> > + *     Calculate i2c speed and write sample_cnt, step_cnt to
> > TIMING
> >  register.
> > + * @param[in]
> > + *     dev: udevice pointer, struct udevice contains i2c source
> > clock,
> > + *     clock divide and speed.
> > + * @return
> > + *     0, set speed successfully.\n
> > + *     error code from mtk_i2c_calculate_speed().
> > + */
> > +static int mtk_i2c_set_speed(struct udevice *dev, uint speed)
> > +{
> > +       struct mtk_i2c_priv *priv = dev_get_priv(dev);
> > +       uint high_speed_reg;
> > +       uint sample_cnt;
> > +       uint timing_reg;
> > +       uint step_cnt;
> > +       uint clk_src;
> > +       int ret = 0;
> > +
> > +       priv->speed = speed;
> > +       if (mtk_i2c_clk_enable(priv))
> > +               return log_msg_ret("set_speed enable clk", -1);
> > +
> > +       clk_src = clk_get_rate(&priv->clk_main) /
> > I2C_DEFAULT_CLK_DIV;
> > +       i2c_writel(priv, REG_CLOCK_DIV, (I2C_DEFAULT_CLK_DIV - 1));
> > +       if (priv->speed > MAX_FS_MODE_SPEED) {
> > +               /* Set master code speed register */
> > +               ret = mtk_i2c_calculate_speed(clk_src,
> > MAX_FS_MODE_SPEED,
> > +                                             &step_cnt,
> > &sample_cnt);
> > +               if (ret < 0)
> > +                       goto exit;
> > +
> > +               timing_reg = (sample_cnt << TIMING_SAMPLE_OFFSET) |
> > step_cnt;
> > +               i2c_writel(priv, REG_TIMING, timing_reg);
> > +               /* Set the high speed mode register */
> > +               ret = mtk_i2c_calculate_speed(clk_src, priv->speed,
> > +                                             &step_cnt,
> > &sample_cnt);
> > +               if (ret < 0)
> > +                       goto exit;
> > +
> > +               high_speed_reg = I2C_TIME_DEFAULT_VALUE |
> > +                               (sample_cnt << HS_SAMPLE_OFFSET) |
> > +                               (step_cnt << HS_STEP_OFFSET);
> > +               i2c_writel(priv, REG_HS, high_speed_reg);
> > +       } else {
> > +               ret = mtk_i2c_calculate_speed(clk_src, priv->speed,
> > +                                             &step_cnt,
> > &sample_cnt);
> > +               if (ret < 0)
> > +                       goto exit;
> > +
> > +               timing_reg = (sample_cnt << TIMING_SAMPLE_OFFSET) |
> > step_cnt;
> > +               /* Disable the high speed transaction */
> > +               high_speed_reg = I2C_TIME_CLR_VALUE;
> > +               i2c_writel(priv, REG_TIMING, timing_reg);
> > +               i2c_writel(priv, REG_HS, high_speed_reg);
> > +       }
> > +exit:
> > +       if (mtk_i2c_clk_disable(priv))
> > +               return log_msg_ret("set_speed disable clk", -1);
> > +
> > +       return ret;
> > +}
> > +
> > +/*
> > + * mtk_i2c_do_transfer
> > + *
> > + * @par Description
> > + *     Configure i2c register and trigger transfer.
> > + * @param[in]
> > + *     priv: mtk_i2cmtk_i2c_priv pointer, struct mtk_i2c_priv
> > contains
> >  register base\n
> > + *     address, operation mode, interrupt status and i2c driver
> > data.
> > + * @param[in]
> > + *     msgs: i2c_msg pointer, struct i2c_msg contains slave\n
> > + *     address, operation mode, msg length and data buffer.
> > + * @param[in]
> > + *     num: i2c_msg number.
> > + * @param[in]
> > + *     left_num: left i2c_msg number.
> > + * @return
> > + *     0, i2c transfer successfully.\n
> > + *     -ETIMEDOUT, i2c transfer timeout.\n
> > + *     -EREMOTEIO, i2c transfer ack error.
> > + */
> > +static int mtk_i2c_do_transfer(struct mtk_i2c_priv *priv,
> > +                              struct i2c_msg *msgs,
> > +                              int num, int left_num)
> > +{
> > +       uint restart_flag = 0;
> > +       uint trans_error = 0;
> > +       uint irq_stat = 0;
> > +       uint tmo_poll = 0;
> > +       uint control_reg;
> > +       bool tmo = false;
> > +       uint start_reg;
> > +       uint addr_reg;
> > +       int ret = 0;
> > +
> > +       if (priv->auto_restart)
> > +               restart_flag = I2C_RS_TRANSFER;
> > +
> > +       control_reg = i2c_readl(priv, REG_CONTROL) &
> > +               ~(I2C_CONTROL_DIR_CHANGE | I2C_CONTROL_RS);
> > +
> > +       if (priv->speed > MAX_FS_MODE_SPEED || num > 1)
> > +               control_reg |= I2C_CONTROL_RS;
> > +
> > +       if (priv->op == I2C_MASTER_WRRD)
> > +               control_reg |= I2C_CONTROL_DIR_CHANGE |
> > I2C_CONTROL_RS;
> > +
> > +       control_reg |= I2C_CONTROL_DMA_EN;
> > +       i2c_writel(priv, REG_CONTROL, control_reg);
> > +
> > +       /* set start condition */
> > +       if (priv->speed <= MAX_ST_MODE_SPEED)
> > +               i2c_writel(priv, REG_EXT_CONF, I2C_ST_START_CON);
> > +       else
> > +               i2c_writel(priv, REG_EXT_CONF, I2C_FS_START_CON);
> > +
> > +       addr_reg = msgs->addr << 1;
> > +       if (priv->op == I2C_MASTER_RD)
> > +               addr_reg |= I2C_M_RD;
> > +       if (priv->zero_len)
> > +               i2c_writel(priv, REG_SLAVE_ADDR, addr_reg |
> > TRANS_ADDR_ONLY);
> > +       else
> > +               i2c_writel(priv, REG_SLAVE_ADDR, addr_reg);
> > +
> > +       /* clear interrupt status */
> > +       i2c_writel(priv, REG_INTR_STAT, restart_flag |
> > I2C_HS_NACKERR |
> > +                  I2C_ACKERR | I2C_TRANSAC_COMP);
> > +       i2c_writel(priv, REG_FIFO_ADDR_CLR, I2C_FIFO_ADDR_CLR);
> > +
> > +       /* enable interrupt */
> > +       i2c_writel(priv, REG_INTR_MASK, restart_flag |
> > I2C_HS_NACKERR |
> > +                  I2C_ACKERR | I2C_TRANSAC_COMP);
> > +
> > +       /* set transfer and transaction len */
> > +       if (priv->op == I2C_MASTER_WRRD) {
> > +               i2c_writel(priv, REG_TRANSFER_LEN, msgs->len);
> > +               i2c_writel(priv, REG_TRANSFER_LEN_AUX, (msgs + 1)-
> > >len);
> > +               i2c_writel(priv, REG_TRANSAC_LEN,
> > I2C_WRRD_TRANAC_VALUE);
> > +       } else {
> > +               i2c_writel(priv, REG_TRANSFER_LEN, msgs->len);
> > +               i2c_writel(priv, REG_TRANSAC_LEN, num);
> > +       }
> > +
> > +       /*
> > +        * prepare buffer data to start transfer
> > +        * three cases here: read, write, write then read
> > +        */
> > +       if (priv->op == I2C_MASTER_RD) {
> > +               /* Clear DMA interrupt flag*/
> > +               writel(I2C_DMA_INT_FLAG_NONE, priv->pdmabase +
> > REG_INT_FLAG);
> > +               /* Set DMA direction RX*/
> > +               writel(I2C_DMA_CON_RX, priv->pdmabase + REG_CON);
> > +               flush_cache((ulong)msgs->buf, msgs->len);
> > +               /* Write the rx buffer address to dma register*/
> > +               writel((ulong)msgs->buf, priv->pdmabase +
> > REG_RX_MEM_ADDR);
> > +               /* Write the rx length to dma register*/
> > +               writel(msgs->len, priv->pdmabase + REG_RX_LEN);
> > +       } else if (priv->op == I2C_MASTER_WR) {
> > +               /* Clear DMA interrupt flag*/
> > +               writel(I2C_DMA_INT_FLAG_NONE, priv->pdmabase +
> > REG_INT_FLAG);
> > +               /* Set DMA direction TX*/
> > +               writel(I2C_DMA_CON_TX, priv->pdmabase + REG_CON);
> > +               flush_cache((ulong)msgs->buf, msgs->len);
> > +               /* Write the tx buffer address to dma register*/
> > +               writel((ulong)msgs->buf, priv->pdmabase +
> > REG_TX_MEM_ADDR);
> > +               /* Write the tx length to dma register*/
> > +               writel(msgs->len, priv->pdmabase + REG_TX_LEN);
> > +       } else {
> > +               /* Clear DMA interrupt flag*/
> > +               writel(I2C_DMA_INT_FLAG_NONE, priv->pdmabase +
> > REG_INT_FLAG);
> 
> I think you can use a switch. Clear can be moved out. You can use a
> bit more smarter direction flag
> in order to flush dcache when needed etc. Your code will be less
> duplicate and will be much clean
> 
> Michael

OK. I'll reorganize this part.

> 
> > +               /* Set DMA direction TX and RX*/
> > +               writel(I2C_DMA_TX_RX, priv->pdmabase + REG_CON);
> > +               flush_cache((ulong)msgs->buf, msgs->len);
> > +               flush_cache((ulong)(msgs + 1)->buf, (msgs + 1)-
> > >len);
> > +               /* Write the tx buffer address to dma register*/
> > +               writel((ulong)msgs->buf, priv->pdmabase +
> > REG_TX_MEM_ADDR);
> > +               /* Write the tx buffer address to dma register*/
> > +               writel((ulong)(msgs + 1)->buf, priv->pdmabase +
> > REG_RX_MEM_ADDR);
> > +               /* Write the tx length to dma register*/
> > +               writel(msgs->len, priv->pdmabase + REG_TX_LEN);
> > +               /* Write the rx length to dma register*/
> > +               writel((msgs + 1)->len, priv->pdmabase +
> > REG_RX_LEN);
> > +       }
> > +
> > +       writel(I2C_DMA_START_EN, priv->pdmabase + REG_EN);
> > +
> > +       if (!priv->auto_restart) {
> > +               start_reg = I2C_TRANSAC_START;
> > +       } else {
> > +               start_reg = I2C_TRANSAC_START | I2C_RS_MUL_TRIG;
> > +               if (left_num >= 1)
> > +                       start_reg |= I2C_RS_MUL_CNFG;
> > +       }
> > +       i2c_writel(priv, REG_START, start_reg);
> > +
> > +       for (;;) {
> > +               irq_stat = i2c_readl(priv, REG_INTR_STAT);
> > +
> > +               /* ignore the first restart irq after the master
> > code */
> > +               if (priv->ignore_restart_irq && (irq_stat |
> > restart_flag)) {
> > +                       priv->ignore_restart_irq = false;
> > +                       irq_stat = 0;
> > +                       writel(I2C_RS_MUL_CNFG | I2C_RS_MUL_TRIG |
> > +                              I2C_TRANSAC_START, priv->base +
> > REG_START);
> > +               }
> > +
> > +               if (irq_stat & (I2C_TRANSAC_COMP | restart_flag)) {
> > +                       tmo = false;
> > +                       if (irq_stat & (I2C_HS_NACKERR |
> > I2C_ACKERR))
> > +                               trans_error = 1;
> > +
> > +                       break;
> > +               }
> > +               udelay(1);
> > +               if (tmo_poll++ >= TRANSFER_TIMEOUT) {
> > +                       tmo = true;
> > +                       break;
> > +               }
> 
> I think we have already better function to wait a condition in uboot

I didn't find such a function that can handle this complex condition.
wait_for_bit_xx can only wait for bits set unconditionally.

> 
> > +       }
> > +
> > +       /* clear interrupt mask */
> > +       i2c_writel(priv, REG_INTR_MASK, ~(restart_flag |
> > I2C_HS_NACKERR |
> > +                 I2C_ACKERR | I2C_TRANSAC_COMP));
> > +
> > +       if (!tmo && trans_error != 0) {
> > +               if (tmo) {
> > +                       ret = -ETIMEDOUT;
> > +                       if (!priv->filter_msg)
> > +                               debug("I2C timeout! addr: 0x%x,\n",
> > msgs->addr);
> > +               } else {
> > +                       ret = -EREMOTEIO;
> > +                       if (!priv->filter_msg)
> > +                               debug("I2C ACKERR! addr:
> > 0x%x,IRQ:0x%x\n",
> > +                                     msgs->addr, irq_stat);
> > +               }
> > +               mtk_i2c_init_hw(priv);
> > +       }
> > +
> > +       return ret;
> > +}
> > +
> > +/*
> > + * mtk_i2c_transfer
> > + *
> > + * @par Description
> > + *     Common i2c transfer API. Set i2c transfer mode according to
> >  i2c_msg\n
> > + *     information, then call mtk_i2c_do_transfer() to configure
> > i2c
> >  register\n
> > + *     and trigger transfer.
> > + * @param[in]
> > + *     dev: udevice pointer, struct udevice contains struct
> > mtk_i2c_priv,
> >  \n
> > + *        struct mtk_i2c_priv contains register base\n
> > + *     address, operation mode, interrupt status and i2c driver
> > data.
> > + * @param[in]
> > + *     msgs: i2c_msg pointer, struct i2c_msg contains slave\n
> > + *     address, operation mode, msg length and data buffer.
> > + * @param[in]
> > + *     num: i2c_msg number.
> > + * @return
> > + *     i2c_msg number, i2c transfer successfully.\n
> > + *     -EINVAL, msg length is more than 16\n
> > + *     use DMA MODE or slave address more than 0x7f.\n
> > + *     error code from mtk_i2c_init_base().\n
> > + *     error code from mtk_i2c_set_speed().\n
> > + *     error code from mtk_i2c_do_transfer().
> > + */
> > +static int mtk_i2c_transfer(struct udevice *dev, struct i2c_msg
> > *msg,
> > +                           int nmsgs)
> > +{
> > +       struct mtk_i2c_priv *priv = dev_get_priv(dev);
> > +       int left_num;
> > +       uint num_cnt;
> > +       int ret;
> > +
> > +       priv->auto_restart = true;
> > +       left_num = nmsgs;
> > +       if (mtk_i2c_clk_enable(priv))
> > +               return log_msg_ret("transfer enable clk", -1);
> > +
> > +       for (num_cnt = 0; num_cnt < nmsgs; num_cnt++) {
> > +               if (((msg + num_cnt)->addr) > MAX_I2C_ADDR) {
> > +                       ret = -EINVAL;
> > +                       goto err_exit;
> > +               }
> > +               if ((msg + num_cnt)->len > MAX_I2C_LEN) {
> > +                       ret = -EINVAL;
> > +                       goto err_exit;
> > +               }
> > +       }
> > +
> > +       /* check if we can skip restart and optimize using WRRD
> > mode */
> > +       if (priv->auto_restart && nmsgs == 2) {
> > +               if (!(msg[0].flags & I2C_M_RD) && (msg[1].flags &
> > I2C_M_RD) &&
> > +                   msg[0].addr == msg[1].addr) {
> > +                       priv->auto_restart = false;
> > +               }
> > +       }
> > +
> > +       if (priv->auto_restart && nmsgs >= 2 && priv->speed >
> > MAX_FS_MODE_SPEED)
> > +               /* ignore the first restart irq after the master
> > code,
> > +                * otherwise the first transfer will be discarded.
> > +                */
> > +               priv->ignore_restart_irq = true;
> > +       else
> > +               priv->ignore_restart_irq = false;
> > +
> > +       while (left_num--) {
> > +               /* transfer slave address only to support devices
> > detect */
> > +               if (!msg->buf)
> > +                       priv->zero_len = true;
> > +               else
> > +                       priv->zero_len = false;
> > +
> > +               if (msg->flags & I2C_M_RD)
> > +                       priv->op = I2C_MASTER_RD;
> > +               else
> > +                       priv->op = I2C_MASTER_WR;
> > +
> > +               if (!priv->auto_restart) {
> > +                       if (nmsgs > 1) {
> > +                               /* combined two messages into one
> > transaction */
> > +                               priv->op = I2C_MASTER_WRRD;
> > +                               left_num--;
> > +                       }
> > +               }
> > +               ret = mtk_i2c_do_transfer(priv, msg, nmsgs,
> > left_num);
> > +               if (ret < 0)
> > +                       goto err_exit;
> > +               msg++;
> > +       }
> > +       ret = 0;
> > +
> > +err_exit:
> > +       if (mtk_i2c_clk_disable(priv))
> > +               return log_msg_ret("transfer disable clk", -1);
> > +
> > +       return ret;
> > +}
> > +
> > +static int mtk_i2c_ofdata_to_platdata(struct udevice *dev)
> > +{
> > +       struct mtk_i2c_priv *priv = dev_get_priv(dev);
> > +       int ret;
> > +
> > +       priv->base = dev_remap_addr_index(dev, 0);
> > +       priv->pdmabase = dev_remap_addr_index(dev, 1);
> > +       ret = clk_get_by_index(dev, 0, &priv->clk_main);
> > +       if (ret)
> > +               return log_msg_ret("clk_get_by_index 0", ret);
> > +
> > +       ret = clk_get_by_index(dev, 1, &priv->clk_dma);
> > +
> > +       return ret;
> > +}
> > +
> > +static int mtk_i2c_probe(struct udevice *dev)
> > +{
> > +       struct mtk_i2c_priv *priv = dev_get_priv(dev);
> > +
> > +       priv->soc_data = (struct mtk_i2c_soc_data
> > *)dev_get_driver_data(dev);
> > +
> > +       if (mtk_i2c_clk_enable(priv))
> > +               return log_msg_ret("probe enable clk", -1);
> > +
> > +       mtk_i2c_init_hw(priv);
> > +
> > +       if (mtk_i2c_clk_disable(priv))
> > +               return log_msg_ret("probe disable clk", -1);
> > +
> > +       return 0;
> > +}
> > +
> > +static int mtk_i2c_deblock(struct udevice *dev)
> > +{
> > +       struct mtk_i2c_priv *priv = dev_get_priv(dev);
> > +
> > +       if (mtk_i2c_clk_enable(priv))
> > +               return log_msg_ret("deblock enable clk", -1);
> > +
> > +       mtk_i2c_init_hw(priv);
> > +
> > +       if (mtk_i2c_clk_disable(priv))
> > +               return log_msg_ret("deblock disable clk", -1);
> > +
> > +       return 0;
> > +}
> > +
> > +static const struct mtk_i2c_soc_data mt76xx_soc_data = {
> > +       .regs = mt_i2c_regs_v1,
> > +       .dma_sync = 0,
> > +};
> > +
> > +static const struct mtk_i2c_soc_data mt7981_soc_data = {
> > +       .regs = mt_i2c_regs_v1,
> > +       .dma_sync = 1,
> > +};
> > +
> > +static const struct mtk_i2c_soc_data mt7986_soc_data = {
> > +       .regs = mt_i2c_regs_v1,
> > +       .dma_sync = 1,
> > +};
> > +
> > +static const struct mtk_i2c_soc_data mt8183_soc_data = {
> > +       .regs = mt_i2c_regs_v2,
> > +       .dma_sync = 1,
> > +};
> > +
> > +static const struct mtk_i2c_soc_data mt8518_soc_data = {
> > +       .regs = mt_i2c_regs_v1,
> > +       .dma_sync = 0,
> > +};
> > +
> > +static const struct mtk_i2c_soc_data mt8512_soc_data = {
> > +       .regs = mt_i2c_regs_v1,
> > +       .dma_sync = 1,
> > +};
> > +
> > +static const struct dm_i2c_ops mtk_i2c_ops = {
> > +       .xfer           = mtk_i2c_transfer,
> > +       .set_bus_speed  = mtk_i2c_set_speed,
> > +       .deblock        = mtk_i2c_deblock,
> > +};
> > +
> > +static const struct udevice_id mtk_i2c_ids[] = {
> > +       {
> > +               .compatible = "mediatek,mt7622-i2c",
> > +               .data = (ulong)&mt76xx_soc_data,
> > +       }, {
> > +               .compatible = "mediatek,mt7623-i2c",
> > +               .data = (ulong)&mt76xx_soc_data,
> > +       }, {
> > +               .compatible = "mediatek,mt7629-i2c",
> > +               .data = (ulong)&mt76xx_soc_data,
> > +       }, {
> > +               .compatible = "mediatek,mt7981-i2c",
> > +               .data = (ulong)&mt7981_soc_data,
> > +       }, {
> > +               .compatible = "mediatek,mt7986-i2c",
> > +               .data = (ulong)&mt7986_soc_data,
> > +       }, {
> > +               .compatible = "mediatek,mt8183-i2c",
> > +               .data = (ulong)&mt8183_soc_data,
> > +       }, {
> > +               .compatible = "mediatek,mt8512-i2c",
> > +               .data = (ulong)&mt8512_soc_data,
> > +       }, {
> > +               .compatible = "mediatek,mt8518-i2c",
> > +               .data = (ulong)&mt8518_soc_data,
> > +       }
> > +};
> > +
> > +U_BOOT_DRIVER(mtk_i2c) = {
> > +       .name           = "mtk_i2c",
> > +       .id             = UCLASS_I2C,
> > +       .of_match       = mtk_i2c_ids,
> > +       .of_to_plat     = mtk_i2c_ofdata_to_platdata,
> > +       .probe          = mtk_i2c_probe,
> > +       .priv_auto      = sizeof(struct mtk_i2c_priv),
> > +       .ops            = &mtk_i2c_ops,
> > +};
> > --
> > 2.17.1
> > 
> 
> 

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 03/31] board: mediatek: add MT7986 reference boards
  2022-08-09  9:10   ` Daniel Golle
@ 2022-08-12 11:02     ` Weijie Gao
  2022-08-12 11:29       ` Daniel Golle
  0 siblings, 1 reply; 100+ messages in thread
From: Weijie Gao @ 2022-08-12 11:02 UTC (permalink / raw)
  To: Daniel Golle
  Cc: u-boot, GSS_MTK_Uboot_upstream, Simon Glass, Marcel Ziswiler,
	Andre Przywara, Fabio Estevam, Samuel Holland, Marek Vasut,
	Ying-Chun Liu (PaulLiu),
	Christian Hewitt

On Tue, 2022-08-09 at 11:10 +0200, Daniel Golle wrote:
> Hi Weijie,
> 
> On Thu, Aug 04, 2022 at 11:35:03AM +0800, Weijie Gao wrote:
> > This patch adds general board files based on MT7986 SoCs.
> > 
> > The SD/eMMC controller on MT7986A and MT7986B have different pin
> > configurations so that four different reference board configs has
> > to be
> > added.
> > 
> > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> > ---
> > [...]
> > diff --git a/include/configs/mt7986.h b/include/configs/mt7986.h
> > new file mode 100644
> > index 0000000000..b28fc0f613
> > --- /dev/null
> > +++ b/include/configs/mt7986.h
> > @@ -0,0 +1,26 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Configuration for MediaTek MT7986 SoC
> > + *
> > + * Copyright (C) 2022 MediaTek Inc.
> > + * Author: Sam Shih <sam.shih@mediatek.com>
> > + */
> > +
> > +#ifndef __MT7986_H
> > +#define __MT7986_H
> > +
> > +#include <linux/sizes.h>
> > +
> 
> In the SDK sources I found also
> #define CONFIG_SYS_BOOTM_LEN           SZ_128M
> here which is actually needed to boot any image with uncompressed
> kernel larger than 8MiB. As for ARM64 this size is easily exceeded
> and
> we got plenty of RAM, I suggest to also include a more generous
> CONFIG_SYS_BOOTM_LEN in your submission to upstream U-Boot.

CONFIG_SYS_BOOTM_LEN is now a Kconfig symbol. It will no be defined in
this header.
Instead, the default value of this symbol is 0x4000000 (64M) for ARM64
which is enough for an ARM64 kernel.

> 
> 
> > +#define CONFIG_SYS_NONCACHED_MEMORY	SZ_1M
> > +#define CONFIG_SYS_MMC_ENV_DEV		0
> > +
> > +/* Uboot definition */
> > +#define CONFIG_SYS_UBOOT_BASE		CONFIG_SYS_TEXT_BASE
> > +
> > +/* SPL -> Uboot */
> > +#define CONFIG_SYS_UBOOT_START		CONFIG_SYS_TEXT_BASE
> > +
> > +/* DRAM */
> > +#define CONFIG_SYS_SDRAM_BASE		0x40000000
> > +
> > +#endif
> > -- 
> > 2.17.1
> > 

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 03/31] board: mediatek: add MT7986 reference boards
  2022-08-12 11:02     ` Weijie Gao
@ 2022-08-12 11:29       ` Daniel Golle
  0 siblings, 0 replies; 100+ messages in thread
From: Daniel Golle @ 2022-08-12 11:29 UTC (permalink / raw)
  To: Weijie Gao
  Cc: u-boot, GSS_MTK_Uboot_upstream, Simon Glass, Marcel Ziswiler,
	Andre Przywara, Fabio Estevam, Samuel Holland, Marek Vasut,
	Ying-Chun Liu (PaulLiu),
	Christian Hewitt

On Fri, Aug 12, 2022 at 07:02:17PM +0800, Weijie Gao wrote:
> On Tue, 2022-08-09 at 11:10 +0200, Daniel Golle wrote:
> > Hi Weijie,
> > 
> > On Thu, Aug 04, 2022 at 11:35:03AM +0800, Weijie Gao wrote:
> > > This patch adds general board files based on MT7986 SoCs.
> > > 
> > > The SD/eMMC controller on MT7986A and MT7986B have different pin
> > > configurations so that four different reference board configs has
> > > to be
> > > added.
> > > 
> > > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> > > ---
> > > [...]
> > > diff --git a/include/configs/mt7986.h b/include/configs/mt7986.h
> > > new file mode 100644
> > > index 0000000000..b28fc0f613
> > > --- /dev/null
> > > +++ b/include/configs/mt7986.h
> > > @@ -0,0 +1,26 @@
> > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > +/*
> > > + * Configuration for MediaTek MT7986 SoC
> > > + *
> > > + * Copyright (C) 2022 MediaTek Inc.
> > > + * Author: Sam Shih <sam.shih@mediatek.com>
> > > + */
> > > +
> > > +#ifndef __MT7986_H
> > > +#define __MT7986_H
> > > +
> > > +#include <linux/sizes.h>
> > > +
> > 
> > In the SDK sources I found also
> > #define CONFIG_SYS_BOOTM_LEN           SZ_128M
> > here which is actually needed to boot any image with uncompressed
> > kernel larger than 8MiB. As for ARM64 this size is easily exceeded
> > and
> > we got plenty of RAM, I suggest to also include a more generous
> > CONFIG_SYS_BOOTM_LEN in your submission to upstream U-Boot.
> 
> CONFIG_SYS_BOOTM_LEN is now a Kconfig symbol. It will no be defined in
> this header.
> Instead, the default value of this symbol is 0x4000000 (64M) for ARM64
> which is enough for an ARM64 kernel.

Sorry, I missed c45568cc4e ("Convert CONFIG_SYS_BOOTM_LEN to Kconfig")
and was trying the series on top of U-Boot 2022.07 (for inclusion in
OpenWrt) locally.

I've tested the whole series with Bananapi BPi-R3 (MT7986A) board.

U-Boot itself works great with all 4 boot media options.
The only remaining problem is BootROM header generation using
mkimage/mtk_image for SPI-NOR:
TF-A and U-Boot ithemselves both work well with SPI-NOR when using
'bromutil' to generate the image. When using 'mkimage -T mtk_image'
instead of 'bromutil' the resulting bl2.img doesn't work:
F0: 102B 0000
FA: 0000 0000
V0: 7027 6006 [0001]
00: 1017 0000
FA: 5100 0000
01: 102A 0001
02: 5100 0000
BP: 2000 00C0 [0001]
EC: 0000 0000 [0000]
T0: 0000 0213 [010F]
System halt!


Cheers


Daniel


^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 23/31] clk: mediatek: add support to configure clock driver parent
  2022-08-04  3:36 ` [PATCH 23/31] clk: mediatek: add support to configure clock driver parent Weijie Gao
  2022-08-04 13:57   ` Simon Glass
@ 2022-08-13  4:18   ` Sean Anderson
  2022-08-23 10:43     ` Weijie Gao
  1 sibling, 1 reply; 100+ messages in thread
From: Sean Anderson @ 2022-08-13  4:18 UTC (permalink / raw)
  To: Weijie Gao, u-boot; +Cc: GSS_MTK_Uboot_upstream, Lukasz Majewski

On 8/3/22 11:36 PM, Weijie Gao wrote:
> This patch adds support for a clock node to configure its parent clock
> where possible.
> 
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>   drivers/clk/mediatek/clk-mtk.c | 79 ++++++++++++++++++++--------------
>   drivers/clk/mediatek/clk-mtk.h |  2 +
>   2 files changed, 48 insertions(+), 33 deletions(-)
> 
> diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
> index d99ea55df0..908ed2b4ba 100644
> --- a/drivers/clk/mediatek/clk-mtk.c
> +++ b/drivers/clk/mediatek/clk-mtk.c
> @@ -42,20 +42,14 @@
>    * the accurate frequency.
>    */
>   static ulong mtk_clk_find_parent_rate(struct clk *clk, int id,
> -				      const struct driver *drv)
> +				      struct udevice *pdev)
>   {
>   	struct clk parent = { .id = id, };
>   
> -	if (drv) {
> -		struct udevice *dev;
> -
> -		if (uclass_get_device_by_driver(UCLASS_CLK, drv, &dev))
> -			return -ENODEV;
> -
> -		parent.dev = dev;
> -	} else {
> +	if (pdev)
> +		parent.dev = pdev;
> +	else
>   		parent.dev = clk->dev;
> -	}
>   
>   	return clk_get_rate(&parent);

You must call clk_request(parent) before calling clk_get_rate.

>   }
> @@ -296,7 +290,7 @@ static ulong mtk_topckgen_get_factor_rate(struct clk
>   *clk, u32 off)
>   	switch (fdiv->flags & CLK_PARENT_MASK) {
>   	case CLK_PARENT_APMIXED:
>   		rate = mtk_clk_find_parent_rate(clk, fdiv->parent,
> -				DM_DRIVER_GET(mtk_clk_apmixedsys));
> +						priv->parent);
>   		break;
>   	case CLK_PARENT_TOPCKGEN:
>   		rate = mtk_clk_find_parent_rate(clk, fdiv->parent, NULL);
> @@ -322,9 +316,18 @@ static ulong mtk_topckgen_get_mux_rate(struct clk *clk,
>   u32 off)
>   
>   	if (mux->parent[index] == CLK_XTAL && priv->tree->flags & CLK_BYPASS_XTAL)
>   		flag = 1;
> -	if (mux->parent[index] > 0 || flag == 1)
> -		return mtk_clk_find_parent_rate(clk, mux->parent[index],
> -						NULL);
> +	if (mux->parent[index] > 0 || flag == 1) {
> +		switch (mux->flags & CLK_PARENT_MASK) {
> +		case CLK_PARENT_APMIXED:
> +			return mtk_clk_find_parent_rate(clk, mux->parent[index],
> +							priv->parent);
> +			break;
> +		default:
> +			return mtk_clk_find_parent_rate(clk, mux->parent[index],
> +							NULL);
> +			break;
> +		}
> +	}
>   
>   	return priv->tree->xtal_rate;
>   }
> @@ -343,7 +346,7 @@ static ulong mtk_topckgen_get_rate(struct clk *clk)
>   						 priv->tree->muxes_offs);
>   }
>   
> -static int mtk_topckgen_enable(struct clk *clk)
> +static int mtk_clk_mux_enable(struct clk *clk)
>   {
>   	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
>   	const struct mtk_composite *mux;
> @@ -376,7 +379,7 @@ static int mtk_topckgen_enable(struct clk *clk)
>   	return 0;
>   }
>   
> -static int mtk_topckgen_disable(struct clk *clk)
> +static int mtk_clk_mux_disable(struct clk *clk)
>   {
>   	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
>   	const struct mtk_composite *mux;
> @@ -402,7 +405,7 @@ static int mtk_topckgen_disable(struct clk *clk)
>   	return 0;
>   }
>   
> -static int mtk_topckgen_set_parent(struct clk *clk, struct clk *parent)
> +static int mtk_common_clk_set_parent(struct clk *clk, struct clk *parent)
>   {
>   	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
>   
> @@ -474,19 +477,7 @@ static ulong mtk_clk_gate_get_rate(struct clk *clk)
>   	struct mtk_cg_priv *priv = dev_get_priv(clk->dev);
>   	const struct mtk_gate *gate = &priv->gates[clk->id];
>   
> -	switch (gate->flags & CLK_PARENT_MASK) {
> -	case CLK_PARENT_APMIXED:
> -		return mtk_clk_find_parent_rate(clk, gate->parent,
> -				DM_DRIVER_GET(mtk_clk_apmixedsys));
> -		break;
> -	case CLK_PARENT_TOPCKGEN:
> -		return mtk_clk_find_parent_rate(clk, gate->parent,
> -				DM_DRIVER_GET(mtk_clk_topckgen));
> -		break;
> -
> -	default:
> -		return priv->tree->xtal_rate;
> -	}
> +	return mtk_clk_find_parent_rate(clk, gate->parent, priv->parent);
>   }
>   
>   const struct clk_ops mtk_clk_apmixedsys_ops = {
> @@ -497,10 +488,10 @@ const struct clk_ops mtk_clk_apmixedsys_ops = {
>   };
>   
>   const struct clk_ops mtk_clk_topckgen_ops = {
> -	.enable = mtk_topckgen_enable,
> -	.disable = mtk_topckgen_disable,
> +	.enable = mtk_clk_mux_enable,
> +	.disable = mtk_clk_mux_disable,
>   	.get_rate = mtk_topckgen_get_rate,
> -	.set_parent = mtk_topckgen_set_parent,
> +	.set_parent = mtk_common_clk_set_parent,
>   };
>   
>   const struct clk_ops mtk_clk_gate_ops = {
> @@ -513,11 +504,22 @@ int mtk_common_clk_init(struct udevice *dev,
>   			const struct mtk_clk_tree *tree)
>   {
>   	struct mtk_clk_priv *priv = dev_get_priv(dev);
> +	struct udevice *parent;
> +	int ret;
>   
>   	priv->base = dev_read_addr_ptr(dev);
>   	if (!priv->base)
>   		return -ENOENT;
>   
> +	ret = uclass_get_device_by_phandle(UCLASS_CLK, dev, "clock-parent",
>   &parent);
> +	if (ret || !parent) {
> +		ret = uclass_get_device_by_driver(UCLASS_CLK,
> +				DM_DRIVER_GET(mtk_clk_apmixedsys), &parent);
> +		if (ret || !parent)
> +			return -ENOENT;
> +	}
> +
> +	priv->parent = parent;
>   	priv->tree = tree;
>   
>   	return 0;
> @@ -528,11 +530,22 @@ int mtk_common_clk_gate_init(struct udevice *dev,
>   			     const struct mtk_gate *gates)
>   {
>   	struct mtk_cg_priv *priv = dev_get_priv(dev);
> +	struct udevice *parent;
> +	int ret;
>   
>   	priv->base = dev_read_addr_ptr(dev);
>   	if (!priv->base)
>   		return -ENOENT;
>   
> +	ret = uclass_get_device_by_phandle(UCLASS_CLK, dev, "clock-parent",
>   &parent);

Why not just use clk_get?

> +	if (ret || !parent) {
> +		ret = uclass_get_device_by_driver(UCLASS_CLK,
> +				DM_DRIVER_GET(mtk_clk_topckgen), &parent);
> +		if (ret || !parent)
> +			return -ENOENT;
> +	}
> +
> +	priv->parent = parent;
>   	priv->tree = tree;
>   	priv->gates = gates;
>   
> diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
> index 0ab6912bf0..7955d469db 100644
> --- a/drivers/clk/mediatek/clk-mtk.h
> +++ b/drivers/clk/mediatek/clk-mtk.h
> @@ -203,11 +203,13 @@ struct mtk_clk_tree {
>   };
>   
>   struct mtk_clk_priv {
> +	struct udevice *parent;
>   	void __iomem *base;
>   	const struct mtk_clk_tree *tree;
>   };
>   
>   struct mtk_cg_priv {
> +	struct udevice *parent;
>   	void __iomem *base;
>   	const struct mtk_clk_tree *tree;
>   	const struct mtk_gate *gates;
> 

--Sean

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 24/31] clk: mediatek: add infrasys clock mux support
  2022-08-04  3:36 ` [PATCH 24/31] clk: mediatek: add infrasys clock mux support Weijie Gao
  2022-08-04 13:57   ` Simon Glass
@ 2022-08-13  4:21   ` Sean Anderson
  2022-08-17  8:00     ` Weijie Gao
  1 sibling, 1 reply; 100+ messages in thread
From: Sean Anderson @ 2022-08-13  4:21 UTC (permalink / raw)
  To: Weijie Gao, u-boot; +Cc: GSS_MTK_Uboot_upstream, Lukasz Majewski

On 8/3/22 11:36 PM, Weijie Gao wrote:
> This patch adds infrasys clock mux support for mediatek clock drivers.
> 
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>   drivers/clk/mediatek/clk-mtk.c | 72 ++++++++++++++++++++++++++++++++++
>   drivers/clk/mediatek/clk-mtk.h |  4 +-
>   2 files changed, 75 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
> index 908ed2b4ba..be3846c85b 100644
> --- a/drivers/clk/mediatek/clk-mtk.c
> +++ b/drivers/clk/mediatek/clk-mtk.c
> @@ -303,6 +303,24 @@ static ulong mtk_topckgen_get_factor_rate(struct clk
>   *clk, u32 off)
>   	return mtk_factor_recalc_rate(fdiv, rate);
>   }
>   
> +static ulong mtk_infrasys_get_factor_rate(struct clk *clk, u32 off)
> +{
> +	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
> +	const struct mtk_fixed_factor *fdiv = &priv->tree->fdivs[off];
> +	ulong rate;
> +
> +	switch (fdiv->flags & CLK_PARENT_MASK) {
> +	case CLK_PARENT_TOPCKGEN:
> +		rate = mtk_clk_find_parent_rate(clk, fdiv->parent,
> +						priv->parent);
> +		break;
> +	default:
> +		rate = mtk_clk_find_parent_rate(clk, fdiv->parent, NULL);
> +	}
> +
> +	return mtk_factor_recalc_rate(fdiv, rate);
> +}
> +
>   static ulong mtk_topckgen_get_mux_rate(struct clk *clk, u32 off)
>   {
>   	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
> @@ -332,6 +350,34 @@ static ulong mtk_topckgen_get_mux_rate(struct clk *clk,
>   u32 off)
>   	return priv->tree->xtal_rate;
>   }
>   
> +static ulong mtk_infrasys_get_mux_rate(struct clk *clk, u32 off)
> +{
> +	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
> +	const struct mtk_composite *mux = &priv->tree->muxes[off];
> +	u32 index;
> +	u32 flag;
> +
> +	index = readl(priv->base + mux->mux_reg);
> +	index &= mux->mux_mask << mux->mux_shift;
> +	index = index >> mux->mux_shift;
> +
> +	if (mux->parent[index] == CLK_XTAL && priv->tree->flags & CLK_BYPASS_XTAL)
> +		flag = 1;
> +	if (mux->parent[index] > 0 || flag == 1) {

Please just use the condition directly

> +		switch (mux->flags & CLK_PARENT_MASK) {
> +		case CLK_PARENT_TOPCKGEN:
> +			return mtk_clk_find_parent_rate(clk, mux->parent[index],
> +							priv->parent);
> +			break;
> +		default:
> +			return mtk_clk_find_parent_rate(clk, mux->parent[index],
> +							NULL);
> +			break;
> +		}
> +	}
> +	return 0;
> +}
> +
>   static ulong mtk_topckgen_get_rate(struct clk *clk)
>   {
>   	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
> @@ -346,6 +392,25 @@ static ulong mtk_topckgen_get_rate(struct clk *clk)
>   						 priv->tree->muxes_offs);
>   }
>   
> +static ulong mtk_infrasys_get_rate(struct clk *clk)
> +{
> +	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
> +
> +	ulong rate;
> +
> +	if (clk->id < priv->tree->fdivs_offs) {
> +		rate = priv->tree->fclks[clk->id].rate;
> +	} else if (clk->id < priv->tree->muxes_offs) {
> +		rate = mtk_infrasys_get_factor_rate(clk, clk->id -
> +						    priv->tree->fdivs_offs);
> +	} else {
> +		rate = mtk_infrasys_get_mux_rate(clk, clk->id -
> +						 priv->tree->muxes_offs);
> +	}
> +
> +	return rate;
> +}
> +
>   static int mtk_clk_mux_enable(struct clk *clk)
>   {
>   	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
> @@ -494,6 +559,13 @@ const struct clk_ops mtk_clk_topckgen_ops = {
>   	.set_parent = mtk_common_clk_set_parent,
>   };
>   
> +const struct clk_ops mtk_clk_infrasys_ops = {
> +	.enable = mtk_clk_mux_enable,
> +	.disable = mtk_clk_mux_disable,
> +	.get_rate = mtk_infrasys_get_rate,
> +	.set_parent = mtk_common_clk_set_parent,
> +};
> +
>   const struct clk_ops mtk_clk_gate_ops = {
>   	.enable = mtk_clk_gate_enable,
>   	.disable = mtk_clk_gate_disable,
> diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
> index 7955d469db..8536275671 100644
> --- a/drivers/clk/mediatek/clk-mtk.h
> +++ b/drivers/clk/mediatek/clk-mtk.h
> @@ -25,7 +25,8 @@
>   
>   #define CLK_PARENT_APMIXED		BIT(4)
>   #define CLK_PARENT_TOPCKGEN		BIT(5)
> -#define CLK_PARENT_MASK			GENMASK(5, 4)
> +#define CLK_PARENT_INFRASYS		BIT(6)
> +#define CLK_PARENT_MASK			GENMASK(6, 4)
>   
>   #define ETHSYS_HIFSYS_RST_CTRL_OFS	0x34
>   
> @@ -217,6 +218,7 @@ struct mtk_cg_priv {
>   
>   extern const struct clk_ops mtk_clk_apmixedsys_ops;
>   extern const struct clk_ops mtk_clk_topckgen_ops;
> +extern const struct clk_ops mtk_clk_infrasys_ops;
>   extern const struct clk_ops mtk_clk_gate_ops;
>   
>   int mtk_common_clk_init(struct udevice *dev,
> 


^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 25/31] clk: mediatek: add CLK_XTAL support for clock driver
  2022-08-04  3:36 ` [PATCH 25/31] clk: mediatek: add CLK_XTAL support for clock driver Weijie Gao
  2022-08-04 13:57   ` Simon Glass
@ 2022-08-13  4:25   ` Sean Anderson
  2022-08-17  8:08     ` Weijie Gao
  1 sibling, 1 reply; 100+ messages in thread
From: Sean Anderson @ 2022-08-13  4:25 UTC (permalink / raw)
  To: Weijie Gao, u-boot; +Cc: GSS_MTK_Uboot_upstream, Lukasz Majewski

On 8/3/22 11:36 PM, Weijie Gao wrote:
> This add CLK_XTAL macro and flag to mediatek clock driver common part,
> to make thi SoC that has clock directlly connect to XTAL working.

nit: this.. directly

But I'm having trouble reading your commit message. Perhaps something like

> This adds the CLK_XTAL macro/flag to allow modeling clocks which are
> directly connected to a fixed-rate clock.
> 
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>   drivers/clk/mediatek/clk-mtk.c | 3 +++
>   drivers/clk/mediatek/clk-mtk.h | 3 ++-
>   2 files changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
> index be3846c85b..5a4650d137 100644
> --- a/drivers/clk/mediatek/clk-mtk.c
> +++ b/drivers/clk/mediatek/clk-mtk.c
> @@ -296,6 +296,7 @@ static ulong mtk_topckgen_get_factor_rate(struct clk
>   *clk, u32 off)
>   		rate = mtk_clk_find_parent_rate(clk, fdiv->parent, NULL);
>   		break;
>   
> +	case CLK_PARENT_XTAL:
>   	default:
>   		rate = priv->tree->xtal_rate;
>   	}
> @@ -314,6 +315,8 @@ static ulong mtk_infrasys_get_factor_rate(struct clk
>   *clk, u32 off)
>   		rate = mtk_clk_find_parent_rate(clk, fdiv->parent,
>   						priv->parent);
>   		break;
> +	case CLK_PARENT_XTAL:
> +		rate = priv->tree->xtal_rate;
>   	default:
>   		rate = mtk_clk_find_parent_rate(clk, fdiv->parent, NULL);
>   	}
> diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
> index 8536275671..211356697b 100644
> --- a/drivers/clk/mediatek/clk-mtk.h
> +++ b/drivers/clk/mediatek/clk-mtk.h
> @@ -26,7 +26,8 @@
>   #define CLK_PARENT_APMIXED		BIT(4)
>   #define CLK_PARENT_TOPCKGEN		BIT(5)
>   #define CLK_PARENT_INFRASYS		BIT(6)
> -#define CLK_PARENT_MASK			GENMASK(6, 4)
> +#define CLK_PARENT_XTAL			BIT(7)
> +#define CLK_PARENT_MASK			GENMASK(7, 4)
>   
>   #define ETHSYS_HIFSYS_RST_CTRL_OFS	0x34
>   
> 


^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 27/31] clk: mediatek: add clock driver support for MediaTek MT7981 SoC
  2022-08-04  3:36 ` [PATCH 27/31] clk: mediatek: add clock driver support for MediaTek MT7981 SoC Weijie Gao
  2022-08-04 13:57   ` Simon Glass
@ 2022-08-13  4:31   ` Sean Anderson
  2022-08-17  8:16     ` Weijie Gao
  1 sibling, 1 reply; 100+ messages in thread
From: Sean Anderson @ 2022-08-13  4:31 UTC (permalink / raw)
  To: Weijie Gao, u-boot; +Cc: GSS_MTK_Uboot_upstream, Lukasz Majewski

On 8/3/22 11:36 PM, Weijie Gao wrote:
> This patch adds clock driver support for MediaTek MT7981 SoC
> 
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>   drivers/clk/mediatek/Makefile          |   1 +
>   drivers/clk/mediatek/clk-mt7981.c      | 682 +++++++++++++++++++++++++
>   include/dt-bindings/clock/mt7981-clk.h | 267 ++++++++++
>   3 files changed, 950 insertions(+)
>   create mode 100644 drivers/clk/mediatek/clk-mt7981.c
>   create mode 100644 include/dt-bindings/clock/mt7981-clk.h
> 
> diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
> index 1aa38215bf..1decf31a77 100644
> --- a/drivers/clk/mediatek/Makefile
> +++ b/drivers/clk/mediatek/Makefile
> @@ -8,6 +8,7 @@ obj-$(CONFIG_TARGET_MT7623) += clk-mt7623.o
>   obj-$(CONFIG_TARGET_MT7622) += clk-mt7622.o
>   obj-$(CONFIG_TARGET_MT7629) += clk-mt7629.o
>   obj-$(CONFIG_TARGET_MT7986) += clk-mt7986.o
> +obj-$(CONFIG_TARGET_MT7981) += clk-mt7981.o
>   obj-$(CONFIG_TARGET_MT8183) += clk-mt8183.o
>   obj-$(CONFIG_TARGET_MT8516) += clk-mt8516.o
>   obj-$(CONFIG_TARGET_MT8518) += clk-mt8518.o
> diff --git a/drivers/clk/mediatek/clk-mt7981.c
>   b/drivers/clk/mediatek/clk-mt7981.c
> new file mode 100644
> index 0000000000..53d09250e6
> --- /dev/null
> +++ b/drivers/clk/mediatek/clk-mt7981.c
> @@ -0,0 +1,682 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * MediaTek clock driver for MT7981 SoC
> + *
> + * Copyright (C) 2022 MediaTek Inc.
> + * Author: Sam Shih <sam.shih@mediatek.com>
> + */
> +
> +#include <dm.h>
> +#include <log.h>
> +#include <asm/arch-mediatek/reset.h>
> +#include <asm/io.h>
> +#include <dt-bindings/clock/mt7981-clk.h>
> +#include <linux/bitops.h>
> +
> +#include "clk-mtk.h"
> +
> +#define MT7981_CLK_PDN 0x250
> +#define MT7981_CLK_PDN_EN_WRITE BIT(31)
> +
> +#define PLL_FACTOR(_id, _name, _parent, _mult, _div)
>      \
> +	FACTOR(_id, _parent, _mult, _div, CLK_PARENT_APMIXED)
> +
> +#define TOP_FACTOR(_id, _name, _parent, _mult, _div)
>      \
> +	FACTOR(_id, _parent, _mult, _div, CLK_PARENT_TOPCKGEN)
> +
> +#define INFRA_FACTOR(_id, _name, _parent, _mult, _div)
>      \
> +	FACTOR(_id, _parent, _mult, _div, CLK_PARENT_INFRASYS)
> +
> +/* FIXED PLLS */
> +static const struct mtk_fixed_clk fixed_pll_clks[] = {
> +	FIXED_CLK(CK_APMIXED_ARMPLL, CLK_XTAL, 1300000000),
> +	FIXED_CLK(CK_APMIXED_NET2PLL, CLK_XTAL, 800000000),
> +	FIXED_CLK(CK_APMIXED_MMPLL, CLK_XTAL, 720000000),
> +	FIXED_CLK(CK_APMIXED_SGMPLL, CLK_XTAL, 325000000),
> +	FIXED_CLK(CK_APMIXED_WEDMCUPLL, CLK_XTAL, 208000000),
> +	FIXED_CLK(CK_APMIXED_NET1PLL, CLK_XTAL, 2500000000),
> +	FIXED_CLK(CK_APMIXED_MPLL, CLK_XTAL, 416000000),
> +	FIXED_CLK(CK_APMIXED_APLL2, CLK_XTAL, 196608000),
> +};
> +
> +/* TOPCKGEN FIXED CLK */
> +static const struct mtk_fixed_clk top_fixed_clks[] = {
> +	FIXED_CLK(CK_TOP_CB_CKSQ_40M, CLK_XTAL, 40000000),
> +};
> +
> +/* TOPCKGEN FIXED DIV */
> +static const struct mtk_fixed_factor top_fixed_divs[] = {
> +	PLL_FACTOR(CK_TOP_CB_M_416M, "cb_m_416m", CK_APMIXED_MPLL, 1, 1),
> +	PLL_FACTOR(CK_TOP_CB_M_D2, "cb_m_d2", CK_APMIXED_MPLL, 1, 2),
> +	PLL_FACTOR(CK_TOP_CB_M_D3, "cb_m_d3", CK_APMIXED_MPLL, 1, 3),
> +	PLL_FACTOR(CK_TOP_M_D3_D2, "m_d3_d2", CK_APMIXED_MPLL, 1, 2),
> +	PLL_FACTOR(CK_TOP_CB_M_D4, "cb_m_d4", CK_APMIXED_MPLL, 1, 4),
> +	PLL_FACTOR(CK_TOP_CB_M_D8, "cb_m_d8", CK_APMIXED_MPLL, 1, 8),
> +	PLL_FACTOR(CK_TOP_M_D8_D2, "m_d8_d2", CK_APMIXED_MPLL, 1, 16),
> +	PLL_FACTOR(CK_TOP_CB_MM_720M, "cb_mm_720m", CK_APMIXED_MMPLL, 1, 1),
> +	PLL_FACTOR(CK_TOP_CB_MM_D2, "cb_mm_d2", CK_APMIXED_MMPLL, 1, 2),
> +	PLL_FACTOR(CK_TOP_CB_MM_D3, "cb_mm_d3", CK_APMIXED_MMPLL, 1, 3),
> +	PLL_FACTOR(CK_TOP_CB_MM_D3_D5, "cb_mm_d3_d5", CK_APMIXED_MMPLL, 1, 15),
> +	PLL_FACTOR(CK_TOP_CB_MM_D4, "cb_mm_d4", CK_APMIXED_MMPLL, 1, 4),
> +	PLL_FACTOR(CK_TOP_CB_MM_D6, "cb_mm_d6", CK_APMIXED_MMPLL, 1, 6),
> +	PLL_FACTOR(CK_TOP_MM_D6_D2, "mm_d6_d2", CK_APMIXED_MMPLL, 1, 12),
> +	PLL_FACTOR(CK_TOP_CB_MM_D8, "cb_mm_d8", CK_APMIXED_MMPLL, 1, 8),
> +	PLL_FACTOR(CK_TOP_CB_APLL2_196M, "cb_apll2_196m", CK_APMIXED_APLL2, 1,
> +		   1),
> +	PLL_FACTOR(CK_TOP_APLL2_D2, "apll2_d2", CK_APMIXED_APLL2, 1, 2),
> +	PLL_FACTOR(CK_TOP_APLL2_D4, "apll2_d4", CK_APMIXED_APLL2, 1, 4),
> +	PLL_FACTOR(CK_TOP_NET1_2500M, "net1_2500m", CK_APMIXED_NET1PLL, 1, 1),
> +	PLL_FACTOR(CK_TOP_CB_NET1_D4, "cb_net1_d4", CK_APMIXED_NET1PLL, 1, 4),
> +	PLL_FACTOR(CK_TOP_CB_NET1_D5, "cb_net1_d5", CK_APMIXED_NET1PLL, 1, 5),
> +	PLL_FACTOR(CK_TOP_NET1_D5_D2, "net1_d5_d2", CK_APMIXED_NET1PLL, 1, 10),
> +	PLL_FACTOR(CK_TOP_NET1_D5_D4, "net1_d5_d4", CK_APMIXED_NET1PLL, 1, 20),
> +	PLL_FACTOR(CK_TOP_CB_NET1_D8, "cb_net1_d8", CK_APMIXED_NET1PLL, 1, 8),
> +	PLL_FACTOR(CK_TOP_NET1_D8_D2, "net1_d8_d2", CK_APMIXED_NET1PLL, 1, 16),
> +	PLL_FACTOR(CK_TOP_NET1_D8_D4, "net1_d8_d4", CK_APMIXED_NET1PLL, 1, 32),
> +	PLL_FACTOR(CK_TOP_CB_NET2_800M, "cb_net2_800m", CK_APMIXED_NET2PLL, 1,
> +		   1),
> +	PLL_FACTOR(CK_TOP_CB_NET2_D2, "cb_net2_d2", CK_APMIXED_NET2PLL, 1, 2),
> +	PLL_FACTOR(CK_TOP_CB_NET2_D4, "cb_net2_d4", CK_APMIXED_NET2PLL, 1, 4),
> +	PLL_FACTOR(CK_TOP_NET2_D4_D2, "net2_d4_d2", CK_APMIXED_NET2PLL, 1, 8),
> +	PLL_FACTOR(CK_TOP_NET2_D4_D4, "net2_d4_d4", CK_APMIXED_NET2PLL, 1, 16),
> +	PLL_FACTOR(CK_TOP_CB_NET2_D6, "cb_net2_d6", CK_APMIXED_NET2PLL, 1, 6),
> +	PLL_FACTOR(CK_TOP_CB_WEDMCU_208M, "cb_wedmcu_208m",
> +		   CK_APMIXED_WEDMCUPLL, 1, 1),
> +	PLL_FACTOR(CK_TOP_CB_SGM_325M, "cb_sgm_325m", CK_APMIXED_SGMPLL, 1, 1),
> +	TOP_FACTOR(CK_TOP_CKSQ_40M_D2, "cksq_40m_d2", CK_TOP_CB_CKSQ_40M, 1, 2),
> +	TOP_FACTOR(CK_TOP_CB_RTC_32K, "cb_rtc_32k", CK_TOP_CB_CKSQ_40M, 1,
> +		   1250),
> +	TOP_FACTOR(CK_TOP_CB_RTC_32P7K, "cb_rtc_32p7k", CK_TOP_CB_CKSQ_40M, 1,
> +		   1220),
> +	TOP_FACTOR(CK_TOP_USB_TX250M, "usb_tx250m", CK_TOP_CB_CKSQ_40M, 1, 1),
> +	TOP_FACTOR(CK_TOP_FAUD, "faud", CK_TOP_CB_CKSQ_40M, 1, 1),
> +	TOP_FACTOR(CK_TOP_NFI1X, "nfi1x", CK_TOP_NFI1X_SEL, 1, 1),
> +	TOP_FACTOR(CK_TOP_USB_EQ_RX250M, "usb_eq_rx250m", CK_TOP_CB_CKSQ_40M, 1,
> +		   1),
> +	TOP_FACTOR(CK_TOP_USB_CDR_CK, "usb_cdr", CK_TOP_CB_CKSQ_40M, 1, 1),
> +	TOP_FACTOR(CK_TOP_USB_LN0_CK, "usb_ln0", CK_TOP_CB_CKSQ_40M, 1, 1),
> +	TOP_FACTOR(CK_TOP_SPINFI_BCK, "spinfi_bck", CK_TOP_SPINFI_SEL, 1, 1),
> +	TOP_FACTOR(CK_TOP_SPI, "spi", CK_TOP_SPI_SEL, 1, 1),
> +	TOP_FACTOR(CK_TOP_SPIM_MST, "spim_mst", CK_TOP_SPIM_MST_SEL, 1, 1),
> +	TOP_FACTOR(CK_TOP_UART_BCK, "uart_bck", CK_TOP_UART_SEL, 1, 1),
> +	TOP_FACTOR(CK_TOP_PWM_BCK, "pwm_bck", CK_TOP_PWM_SEL, 1, 1),
> +	TOP_FACTOR(CK_TOP_I2C_BCK, "i2c_bck", CK_TOP_I2C_SEL, 1, 1),
> +	TOP_FACTOR(CK_TOP_PEXTP_TL, "pextp_tl", CK_TOP_PEXTP_TL_SEL, 1, 1),
> +	TOP_FACTOR(CK_TOP_EMMC_208M, "emmc_208m", CK_TOP_EMMC_208M_SEL, 1, 1),
> +	TOP_FACTOR(CK_TOP_EMMC_400M, "emmc_400m", CK_TOP_EMMC_400M_SEL, 1, 1),
> +	TOP_FACTOR(CK_TOP_DRAMC_REF, "dramc_ref", CK_TOP_DRAMC_SEL, 1, 1),
> +	TOP_FACTOR(CK_TOP_DRAMC_MD32, "dramc_md32", CK_TOP_DRAMC_MD32_SEL, 1,
> +		   1),
> +	TOP_FACTOR(CK_TOP_SYSAXI, "sysaxi", CK_TOP_SYSAXI_SEL, 1, 1),
> +	TOP_FACTOR(CK_TOP_SYSAPB, "sysapb", CK_TOP_SYSAPB_SEL, 1, 1),
> +	TOP_FACTOR(CK_TOP_ARM_DB_MAIN, "arm_db_main", CK_TOP_ARM_DB_MAIN_SEL, 1,
> +		   1),
> +	TOP_FACTOR(CK_TOP_AP2CNN_HOST, "ap2cnn_host", CK_TOP_AP2CNN_HOST_SEL, 1,
> +		   1),
> +	TOP_FACTOR(CK_TOP_NETSYS, "netsys", CK_TOP_NETSYS_SEL, 1, 1),
> +	TOP_FACTOR(CK_TOP_NETSYS_500M, "netsys_500m", CK_TOP_NETSYS_500M_SEL, 1,
> +		   1),
> +	TOP_FACTOR(CK_TOP_NETSYS_WED_MCU, "netsys_wed_mcu",
> +		   CK_TOP_NETSYS_MCU_SEL, 1, 1),
> +	TOP_FACTOR(CK_TOP_NETSYS_2X, "netsys_2x", CK_TOP_NETSYS_2X_SEL, 1, 1),
> +	TOP_FACTOR(CK_TOP_SGM_325M, "sgm_325m", CK_TOP_SGM_325M_SEL, 1, 1),
> +	TOP_FACTOR(CK_TOP_SGM_REG, "sgm_reg", CK_TOP_SGM_REG_SEL, 1, 1),
> +	TOP_FACTOR(CK_TOP_F26M, "csw_f26m", CK_TOP_F26M_SEL, 1, 1),
> +	TOP_FACTOR(CK_TOP_EIP97B, "eip97b", CK_TOP_EIP97B_SEL, 1, 1),
> +	TOP_FACTOR(CK_TOP_USB3_PHY, "usb3_phy", CK_TOP_USB3_PHY_SEL, 1, 1),
> +	TOP_FACTOR(CK_TOP_AUD, "aud", CK_TOP_FAUD, 1, 1),
> +	TOP_FACTOR(CK_TOP_A1SYS, "a1sys", CK_TOP_A1SYS_SEL, 1, 1),
> +	TOP_FACTOR(CK_TOP_AUD_L, "aud_l", CK_TOP_AUD_L_SEL, 1, 1),
> +	TOP_FACTOR(CK_TOP_A_TUNER, "a_tuner", CK_TOP_A_TUNER_SEL, 1, 1),
> +	TOP_FACTOR(CK_TOP_U2U3_REF, "u2u3_ref", CK_TOP_U2U3_SEL, 1, 1),
> +	TOP_FACTOR(CK_TOP_U2U3_SYS, "u2u3_sys", CK_TOP_U2U3_SYS_SEL, 1, 1),
> +	TOP_FACTOR(CK_TOP_U2U3_XHCI, "u2u3_xhci", CK_TOP_U2U3_XHCI_SEL, 1, 1),
> +	TOP_FACTOR(CK_TOP_USB_FRMCNT, "usb_frmcnt", CK_TOP_USB_FRMCNT_SEL, 1,
> +		   1),
> +};
> +
> +/* TOPCKGEN MUX PARENTS */
> +static const int nfi1x_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_MM_D4,
> +				     CK_TOP_NET1_D8_D2,  CK_TOP_CB_NET2_D6,
> +				     CK_TOP_CB_M_D4,     CK_TOP_CB_MM_D8,
> +				     CK_TOP_NET1_D8_D4,  CK_TOP_CB_M_D8 };
> +
> +static const int spinfi_parents[] = { CK_TOP_CKSQ_40M_D2,
>   CK_TOP_CB_CKSQ_40M,
> +				      CK_TOP_NET1_D5_D4,  CK_TOP_CB_M_D4,
> +				      CK_TOP_CB_MM_D8,    CK_TOP_NET1_D8_D4,
> +				      CK_TOP_MM_D6_D2,    CK_TOP_CB_M_D8 };
> +
> +static const int spi_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D2,
> +				   CK_TOP_CB_MM_D4,    CK_TOP_NET1_D8_D2,
> +				   CK_TOP_CB_NET2_D6,  CK_TOP_NET1_D5_D4,
> +				   CK_TOP_CB_M_D4,     CK_TOP_NET1_D8_D4 };
> +
> +static const int uart_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D8,
> +				    CK_TOP_M_D8_D2 };
> +
> +static const int pwm_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D8_D2,
> +				   CK_TOP_NET1_D5_D4,  CK_TOP_CB_M_D4,
> +				   CK_TOP_M_D8_D2,     CK_TOP_CB_RTC_32K };
> +
> +static const int i2c_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D5_D4,
> +				   CK_TOP_CB_M_D4, CK_TOP_NET1_D8_D4 };
> +
> +static const int pextp_tl_ck_parents[] = { CK_TOP_CB_CKSQ_40M,
> +					   CK_TOP_NET1_D5_D4, CK_TOP_CB_M_D4,
> +					   CK_TOP_CB_RTC_32K };
> +
> +static const int emmc_208m_parents[] = {
> +	CK_TOP_CB_CKSQ_40M,   CK_TOP_CB_M_D2,  CK_TOP_CB_NET2_D4,
> +	CK_TOP_CB_APLL2_196M, CK_TOP_CB_MM_D4, CK_TOP_NET1_D8_D2,
> +	CK_TOP_CB_MM_D6
> +};
> +
> +static const int emmc_400m_parents[] = { CK_TOP_CB_CKSQ_40M,
>   CK_TOP_CB_NET2_D2,
> +					 CK_TOP_CB_MM_D2, CK_TOP_CB_NET2_D2 };
> +
> +static const int csw_f26m_parents[] = { CK_TOP_CKSQ_40M_D2, CK_TOP_M_D8_D2
>   };
> +
> +static const int dramc_md32_parents[] = { CK_TOP_CB_CKSQ_40M,
>   CK_TOP_CB_M_D2,
> +					  CK_TOP_CB_WEDMCU_208M };
> +
> +static const int sysaxi_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D8_D2
>   };
> +
> +static const int sysapb_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_M_D3_D2 };
> +
> +static const int arm_db_main_parents[] = { CK_TOP_CB_CKSQ_40M,
> +					   CK_TOP_CB_NET2_D6 };
> +
> +static const int ap2cnn_host_parents[] = { CK_TOP_CB_CKSQ_40M,
> +					   CK_TOP_NET1_D8_D4 };
> +
> +static const int netsys_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_MM_D2
>   };
> +
> +static const int netsys_500m_parents[] = { CK_TOP_CB_CKSQ_40M,
> +					   CK_TOP_CB_NET1_D5 };
> +
> +static const int netsys_mcu_parents[] = { CK_TOP_CB_CKSQ_40M,
>   CK_TOP_CB_MM_720M,
> +					  CK_TOP_CB_NET1_D4, CK_TOP_CB_NET1_D5,
> +					  CK_TOP_CB_M_416M };
> +
> +static const int netsys_2x_parents[] = { CK_TOP_CB_CKSQ_40M,
> +					 CK_TOP_CB_NET2_800M,
> +					 CK_TOP_CB_MM_720M };
> +
> +static const int sgm_325m_parents[] = { CK_TOP_CB_CKSQ_40M,
> +					CK_TOP_CB_SGM_325M };
> +
> +static const int sgm_reg_parents[] = { CK_TOP_CB_CKSQ_40M,
>   CK_TOP_CB_NET2_D4 };
> +
> +static const int eip97b_parents[] = { CK_TOP_CB_CKSQ_40M,
>   CK_TOP_CB_NET1_D5,
> +				      CK_TOP_CB_M_416M, CK_TOP_CB_MM_D2,
> +				      CK_TOP_NET1_D5_D2 };
> +
> +static const int aud_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_APLL2_196M
>   };
> +
> +static const int a1sys_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_APLL2_D4 };
> +
> +static const int aud_l_parents[] = { CK_TOP_CB_CKSQ_40M,
>   CK_TOP_CB_APLL2_196M,
> +				     CK_TOP_M_D8_D2 };
> +
> +static const int a_tuner_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_APLL2_D4,
> +				       CK_TOP_M_D8_D2 };
> +
> +static const int u2u3_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_M_D8_D2 };
> +
> +static const int u2u3_sys_parents[] = { CK_TOP_CB_CKSQ_40M,
>   CK_TOP_NET1_D5_D4 };
> +
> +static const int usb_frmcnt_parents[] = { CK_TOP_CB_CKSQ_40M,
> +					  CK_TOP_CB_MM_D3_D5 };
> +
> +#define TOP_MUX(_id, _name, _parents, _mux_ofs, _mux_set_ofs, _mux_clr_ofs,
>      \
> +		_shift, _width, _gate, _upd_ofs, _upd)                         \
> +	{                                                                      \
> +		.id = _id, .mux_reg = _mux_ofs, .mux_set_reg = _mux_set_ofs,   \
> +		.mux_clr_reg = _mux_clr_ofs, .upd_reg = _upd_ofs,              \
> +		.upd_shift = _upd, .mux_shift = _shift,                        \
> +		.mux_mask = BIT(_width) - 1, .gate_reg = _mux_ofs,             \
> +		.gate_shift = _gate, .parent = _parents,                       \
> +		.num_parents = ARRAY_SIZE(_parents),                           \
> +		.flags = CLK_MUX_SETCLR_UPD,                                   \
> +	}
> +
> +/* TOPCKGEN MUX_GATE */
> +static const struct mtk_composite top_muxes[] = {
> +	TOP_MUX(CK_TOP_NFI1X_SEL, "nfi1x_sel", nfi1x_parents, 0x0, 0x4, 0x8, 0,
> +		3, 7, 0x1c0, 0),
> +	TOP_MUX(CK_TOP_SPINFI_SEL, "spinfi_sel", spinfi_parents, 0x0, 0x4, 0x8,
> +		8, 3, 15, 0x1c0, 1),
> +	TOP_MUX(CK_TOP_SPI_SEL, "spi_sel", spi_parents, 0x0, 0x4, 0x8, 16, 3,
> +		23, 0x1c0, 2),
> +	TOP_MUX(CK_TOP_SPIM_MST_SEL, "spim_mst_sel", spi_parents, 0x0, 0x4, 0x8,
> +		24, 3, 31, 0x1c0, 3),
> +	TOP_MUX(CK_TOP_UART_SEL, "uart_sel", uart_parents, 0x10, 0x14, 0x18, 0,
> +		2, 7, 0x1c0, 4),
> +	TOP_MUX(CK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x10, 0x14, 0x18, 8, 3,
> +		15, 0x1c0, 5),
> +	TOP_MUX(CK_TOP_I2C_SEL, "i2c_sel", i2c_parents, 0x10, 0x14, 0x18, 16, 2,
> +		23, 0x1c0, 6),
> +	TOP_MUX(CK_TOP_PEXTP_TL_SEL, "pextp_tl_ck_sel", pextp_tl_ck_parents,
> +		0x10, 0x14, 0x18, 24, 2, 31, 0x1c0, 7),
> +	TOP_MUX(CK_TOP_EMMC_208M_SEL, "emmc_208m_sel", emmc_208m_parents, 0x20,
> +		0x24, 0x28, 0, 3, 7, 0x1c0, 8),
> +	TOP_MUX(CK_TOP_EMMC_400M_SEL, "emmc_400m_sel", emmc_400m_parents, 0x20,
> +		0x24, 0x28, 8, 2, 15, 0x1c0, 9),
> +	TOP_MUX(CK_TOP_F26M_SEL, "csw_f26m_sel", csw_f26m_parents, 0x20, 0x24,
> +		0x28, 16, 1, 23, 0x1c0, 10),
> +	TOP_MUX(CK_TOP_DRAMC_SEL, "dramc_sel", csw_f26m_parents, 0x20, 0x24,
> +		0x28, 24, 1, 31, 0x1c0, 11),
> +	TOP_MUX(CK_TOP_DRAMC_MD32_SEL, "dramc_md32_sel", dramc_md32_parents,
> +		0x30, 0x34, 0x38, 0, 2, 7, 0x1c0, 12),
> +	TOP_MUX(CK_TOP_SYSAXI_SEL, "sysaxi_sel", sysaxi_parents, 0x30, 0x34,
> +		0x38, 8, 1, 15, 0x1c0, 13),
> +	TOP_MUX(CK_TOP_SYSAPB_SEL, "sysapb_sel", sysapb_parents, 0x30, 0x34,
> +		0x38, 16, 1, 23, 0x1c0, 14),
> +	TOP_MUX(CK_TOP_ARM_DB_MAIN_SEL, "arm_db_main_sel", arm_db_main_parents,
> +		0x30, 0x34, 0x38, 24, 1, 31, 0x1c0, 15),
> +	TOP_MUX(CK_TOP_AP2CNN_HOST_SEL, "ap2cnn_host_sel", ap2cnn_host_parents,
> +		0x40, 0x44, 0x48, 0, 1, 7, 0x1c0, 16),
> +	TOP_MUX(CK_TOP_NETSYS_SEL, "netsys_sel", netsys_parents, 0x40, 0x44,
> +		0x48, 8, 1, 15, 0x1c0, 17),
> +	TOP_MUX(CK_TOP_NETSYS_500M_SEL, "netsys_500m_sel", netsys_500m_parents,
> +		0x40, 0x44, 0x48, 16, 1, 23, 0x1c0, 18),
> +	TOP_MUX(CK_TOP_NETSYS_MCU_SEL, "netsys_mcu_sel", netsys_mcu_parents,
> +		0x40, 0x44, 0x48, 24, 3, 31, 0x1c0, 19),
> +	TOP_MUX(CK_TOP_NETSYS_2X_SEL, "netsys_2x_sel", netsys_2x_parents, 0x50,
> +		0x54, 0x58, 0, 2, 7, 0x1c0, 20),
> +	TOP_MUX(CK_TOP_SGM_325M_SEL, "sgm_325m_sel", sgm_325m_parents, 0x50,
> +		0x54, 0x58, 8, 1, 15, 0x1c0, 21),
> +	TOP_MUX(CK_TOP_SGM_REG_SEL, "sgm_reg_sel", sgm_reg_parents, 0x50, 0x54,
> +		0x58, 16, 1, 23, 0x1c0, 22),
> +	TOP_MUX(CK_TOP_EIP97B_SEL, "eip97b_sel", eip97b_parents, 0x50, 0x54,
> +		0x58, 24, 3, 31, 0x1c0, 23),
> +	TOP_MUX(CK_TOP_USB3_PHY_SEL, "usb3_phy_sel", csw_f26m_parents, 0x60,
> +		0x64, 0x68, 0, 1, 7, 0x1c0, 24),
> +	TOP_MUX(CK_TOP_AUD_SEL, "aud_sel", aud_parents, 0x60, 0x64, 0x68, 8, 1,
> +		15, 0x1c0, 25),
> +	TOP_MUX(CK_TOP_A1SYS_SEL, "a1sys_sel", a1sys_parents, 0x60, 0x64, 0x68,
> +		16, 1, 23, 0x1c0, 26),
> +	TOP_MUX(CK_TOP_AUD_L_SEL, "aud_l_sel", aud_l_parents, 0x60, 0x64, 0x68,
> +		24, 2, 31, 0x1c0, 27),
> +	TOP_MUX(CK_TOP_A_TUNER_SEL, "a_tuner_sel", a_tuner_parents, 0x70, 0x74,
> +		0x78, 0, 2, 7, 0x1c0, 28),
> +	TOP_MUX(CK_TOP_U2U3_SEL, "u2u3_sel", u2u3_parents, 0x70, 0x74, 0x78, 8,
> +		1, 15, 0x1c0, 29),
> +	TOP_MUX(CK_TOP_U2U3_SYS_SEL, "u2u3_sys_sel", u2u3_sys_parents, 0x70,
> +		0x74, 0x78, 16, 1, 23, 0x1c0, 30),
> +	TOP_MUX(CK_TOP_U2U3_XHCI_SEL, "u2u3_xhci_sel", u2u3_sys_parents, 0x70,
> +		0x74, 0x78, 24, 1, 31, 0x1c4, 0),
> +	TOP_MUX(CK_TOP_USB_FRMCNT_SEL, "usb_frmcnt_sel", usb_frmcnt_parents,
> +		0x80, 0x84, 0x88, 0, 1, 7, 0x1c4, 1),
> +};
> +
> +/* INFRA FIXED DIV */
> +static const struct mtk_fixed_factor infra_fixed_divs[] = {
> +	TOP_FACTOR(CK_INFRA_CK_F26M, "infra_ck_f26m", CK_TOP_F26M_SEL, 1, 1),
> +	TOP_FACTOR(CK_INFRA_UART, "infra_uart", CK_TOP_UART_SEL, 1, 1),
> +	TOP_FACTOR(CK_INFRA_ISPI0, "infra_ispi0", CK_TOP_SPI_SEL, 1, 1),
> +	TOP_FACTOR(CK_INFRA_I2C, "infra_i2c", CK_TOP_I2C_SEL, 1, 1),
> +	TOP_FACTOR(CK_INFRA_ISPI1, "infra_ispi1", CK_TOP_SPIM_MST_SEL, 1, 1),
> +	TOP_FACTOR(CK_INFRA_PWM, "infra_pwm", CK_TOP_PWM_SEL, 1, 1),
> +	TOP_FACTOR(CK_INFRA_66M_MCK, "infra_66m_mck", CK_TOP_SYSAXI_SEL, 1, 2),
> +	TOP_FACTOR(CK_INFRA_CK_F32K, "infra_ck_f32k", CK_TOP_CB_RTC_32P7K, 1,
> +		   1),
> +	TOP_FACTOR(CK_INFRA_PCIE_CK, "infra_pcie", CK_TOP_PEXTP_TL_SEL, 1, 1),
> +	INFRA_FACTOR(CK_INFRA_PWM_BCK, "infra_pwm_bck", CK_INFRA_PWM_BSEL, 1,
> +		     1),
> +	INFRA_FACTOR(CK_INFRA_PWM_CK1, "infra_pwm_ck1", CK_INFRA_PWM1_SEL, 1,
> +		     1),
> +	INFRA_FACTOR(CK_INFRA_PWM_CK2, "infra_pwm_ck2", CK_INFRA_PWM2_SEL, 1,
> +		     1),
> +	TOP_FACTOR(CK_INFRA_133M_HCK, "infra_133m_hck", CK_TOP_SYSAXI, 1, 1),
> +	INFRA_FACTOR(CK_INFRA_66M_PHCK, "infra_66m_phck", CK_INFRA_133M_HCK, 1,
> +		     1),
> +	TOP_FACTOR(CK_INFRA_FAUD_L_CK, "infra_faud_l", CK_TOP_AUD_L, 1, 1),
> +	TOP_FACTOR(CK_INFRA_FAUD_AUD_CK, "infra_faud_aud", CK_TOP_A1SYS, 1, 1),
> +	TOP_FACTOR(CK_INFRA_FAUD_EG2_CK, "infra_faud_eg2", CK_TOP_A_TUNER, 1,
> +		   1),
> +	TOP_FACTOR(CK_INFRA_I2CS_CK, "infra_i2cs", CK_TOP_I2C_BCK, 1, 1),
> +	INFRA_FACTOR(CK_INFRA_MUX_UART0, "infra_mux_uart0", CK_INFRA_UART0_SEL,
> +		     1, 1),
> +	INFRA_FACTOR(CK_INFRA_MUX_UART1, "infra_mux_uart1", CK_INFRA_UART1_SEL,
> +		     1, 1),
> +	INFRA_FACTOR(CK_INFRA_MUX_UART2, "infra_mux_uart2", CK_INFRA_UART2_SEL,
> +		     1, 1),
> +	TOP_FACTOR(CK_INFRA_NFI_CK, "infra_nfi", CK_TOP_NFI1X, 1, 1),
> +	TOP_FACTOR(CK_INFRA_SPINFI_CK, "infra_spinfi", CK_TOP_SPINFI_BCK, 1, 1),
> +	INFRA_FACTOR(CK_INFRA_MUX_SPI0, "infra_mux_spi0", CK_INFRA_SPI0_SEL, 1,
> +		     1),
> +	INFRA_FACTOR(CK_INFRA_MUX_SPI1, "infra_mux_spi1", CK_INFRA_SPI1_SEL, 1,
> +		     1),
> +	INFRA_FACTOR(CK_INFRA_MUX_SPI2, "infra_mux_spi2", CK_INFRA_SPI2_SEL, 1,
> +		     1),
> +	TOP_FACTOR(CK_INFRA_RTC_32K, "infra_rtc_32k", CK_TOP_CB_RTC_32K, 1, 1),
> +	TOP_FACTOR(CK_INFRA_FMSDC_CK, "infra_fmsdc", CK_TOP_EMMC_400M, 1, 1),
> +	TOP_FACTOR(CK_INFRA_FMSDC_HCK_CK, "infra_fmsdc_hck", CK_TOP_EMMC_208M,
> +		   1, 1),
> +	TOP_FACTOR(CK_INFRA_PERI_133M, "infra_peri_133m", CK_TOP_SYSAXI, 1, 1),
> +	TOP_FACTOR(CK_INFRA_133M_PHCK, "infra_133m_phck", CK_TOP_SYSAXI, 1, 1),
> +	TOP_FACTOR(CK_INFRA_USB_SYS_CK, "infra_usb_sys", CK_TOP_U2U3_SYS, 1, 1),
> +	TOP_FACTOR(CK_INFRA_USB_CK, "infra_usb", CK_TOP_U2U3_REF, 1, 1),
> +	TOP_FACTOR(CK_INFRA_USB_XHCI_CK, "infra_usb_xhci", CK_TOP_U2U3_XHCI, 1,
> +		   1),
> +	TOP_FACTOR(CK_INFRA_PCIE_GFMUX_TL_O_PRE, "infra_pcie_mux",
> +		   CK_TOP_PEXTP_TL, 1, 1),
> +	TOP_FACTOR(CK_INFRA_F26M_CK0, "infra_f26m_ck0", CK_TOP_F26M, 1, 1),
> +	TOP_FACTOR(CK_INFRA_133M_MCK, "infra_133m_mck", CK_TOP_SYSAXI, 1, 1),
> +};
> +
> +/* INFRASYS MUX PARENTS */
> +static const int infra_uart0_parents[] = { CK_INFRA_CK_F26M, CK_INFRA_UART
>   };
> +
> +static const int infra_spi0_parents[] = { CK_INFRA_I2C, CK_INFRA_ISPI0 };
> +
> +static const int infra_spi1_parents[] = { CK_INFRA_I2C, CK_INFRA_ISPI1 };
> +
> +static const int infra_pwm1_parents[] = { -1, -1, -1, CK_INFRA_PWM };
> +
> +static const int infra_pwm_bsel_parents[] = { -1, -1, -1, CK_INFRA_PWM };
> +
> +static const int infra_pcie_parents[] = { CK_INFRA_CK_F32K,
>   CK_INFRA_CK_F26M,
> +					  CK_TOP_CB_CKSQ_40M, CK_INFRA_PCIE_CK};
> +
> +#define INFRA_MUX(_id, _name, _parents, _reg, _shift, _width)
>      \
> +	{                                                                      \
> +		.id = _id, .mux_reg = (_reg) + 0x8,                            \
> +		.mux_set_reg = (_reg) + 0x0, .mux_clr_reg = (_reg) + 0x4,      \
> +		.mux_shift = _shift, .mux_mask = BIT(_width) - 1,              \
> +		.parent = _parents, .num_parents = ARRAY_SIZE(_parents),       \
> +		.flags = CLK_MUX_SETCLR_UPD | CLK_PARENT_INFRASYS,             \
> +	}
> +
> +/* INFRA MUX */
> +static const struct mtk_composite infra_muxes[] = {
> +	INFRA_MUX(CK_INFRA_UART0_SEL, "infra_uart0_sel", infra_uart0_parents,
> +		  0x10, 0, 1),
> +	INFRA_MUX(CK_INFRA_UART1_SEL, "infra_uart1_sel", infra_uart0_parents,
> +		  0x10, 1, 1),
> +	INFRA_MUX(CK_INFRA_UART2_SEL, "infra_uart2_sel", infra_uart0_parents,
> +		  0x10, 2, 1),
> +	INFRA_MUX(CK_INFRA_SPI0_SEL, "infra_spi0_sel", infra_spi0_parents, 0x10,
> +		  4, 1),
> +	INFRA_MUX(CK_INFRA_SPI1_SEL, "infra_spi1_sel", infra_spi1_parents, 0x10,
> +		  5, 1),
> +	INFRA_MUX(CK_INFRA_SPI2_SEL, "infra_spi2_sel", infra_spi0_parents, 0x10,
> +		  6, 1),
> +	INFRA_MUX(CK_INFRA_PWM1_SEL, "infra_pwm1_sel", infra_pwm1_parents, 0x10,
> +		  9, 2),
> +	INFRA_MUX(CK_INFRA_PWM2_SEL, "infra_pwm2_sel", infra_pwm1_parents, 0x10,
> +		  11, 2),
> +	INFRA_MUX(CK_INFRA_PWM_BSEL, "infra_pwm_bsel", infra_pwm_bsel_parents,
> +		  0x10, 13, 2),
> +	INFRA_MUX(CK_INFRA_PCIE_SEL, "infra_pcie_sel", infra_pcie_parents, 0x20,
> +		  0, 2),
> +};
> +
> +static const struct mtk_gate_regs infra_0_cg_regs = {
> +	.set_ofs = 0x40,
> +	.clr_ofs = 0x44,
> +	.sta_ofs = 0x48,
> +};
> +
> +static const struct mtk_gate_regs infra_1_cg_regs = {
> +	.set_ofs = 0x50,
> +	.clr_ofs = 0x54,
> +	.sta_ofs = 0x58,
> +};
> +
> +static const struct mtk_gate_regs infra_2_cg_regs = {
> +	.set_ofs = 0x60,
> +	.clr_ofs = 0x64,
> +	.sta_ofs = 0x68,
> +};
> +
> +#define GATE_INFRA0(_id, _name, _parent, _shift)
>      \
> +	{                                                                      \
> +		.id = _id, .parent = _parent, .regs = &infra_0_cg_regs,        \
> +		.shift = _shift,                                               \
> +		.flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS,                \
> +	}
> +
> +#define GATE_INFRA1(_id, _name, _parent, _shift)
>      \
> +	{                                                                      \
> +		.id = _id, .parent = _parent, .regs = &infra_1_cg_regs,        \
> +		.shift = _shift,                                               \
> +		.flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS,                \
> +	}
> +
> +#define GATE_INFRA2(_id, _name, _parent, _shift)
>      \
> +	{                                                                      \
> +		.id = _id, .parent = _parent, .regs = &infra_2_cg_regs,        \
> +		.shift = _shift,                                               \
> +		.flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS,                \
> +	}
> +
> +/* INFRA GATE */
> +static const struct mtk_gate infracfg_ao_gates[] = {
> +	GATE_INFRA0(CK_INFRA_GPT_STA, "infra_gpt_sta", CK_INFRA_66M_MCK, 0),
> +	GATE_INFRA0(CK_INFRA_PWM_HCK, "infra_pwm_hck", CK_INFRA_66M_MCK, 1),
> +	GATE_INFRA0(CK_INFRA_PWM_STA, "infra_pwm_sta", CK_INFRA_PWM_BCK, 2),
> +	GATE_INFRA0(CK_INFRA_PWM1_CK, "infra_pwm1", CK_INFRA_PWM_CK1, 3),
> +	GATE_INFRA0(CK_INFRA_PWM2_CK, "infra_pwm2", CK_INFRA_PWM_CK2, 4),
> +	GATE_INFRA0(CK_INFRA_CQ_DMA_CK, "infra_cq_dma", CK_INFRA_133M_HCK, 6),
> +	GATE_INFRA0(CK_INFRA_AUD_BUS_CK, "infra_aud_bus", CK_INFRA_66M_PHCK, 8),
> +	GATE_INFRA0(CK_INFRA_AUD_26M_CK, "infra_aud_26m", CK_INFRA_CK_F26M, 9),
> +	GATE_INFRA0(CK_INFRA_AUD_L_CK, "infra_aud_l", CK_INFRA_FAUD_L_CK, 10),
> +	GATE_INFRA0(CK_INFRA_AUD_AUD_CK, "infra_aud_aud", CK_INFRA_FAUD_AUD_CK,
> +		    11),
> +	GATE_INFRA0(CK_INFRA_AUD_EG2_CK, "infra_aud_eg2", CK_INFRA_FAUD_EG2_CK,
> +		    13),
> +	GATE_INFRA0(CK_INFRA_DRAMC_26M_CK, "infra_dramc_26m", CK_INFRA_CK_F26M,
> +		    14),
> +	GATE_INFRA0(CK_INFRA_DBG_CK, "infra_dbg", CK_INFRA_66M_MCK, 15),
> +	GATE_INFRA0(CK_INFRA_AP_DMA_CK, "infra_ap_dma", CK_INFRA_66M_MCK, 16),
> +	GATE_INFRA0(CK_INFRA_SEJ_CK, "infra_sej", CK_INFRA_66M_MCK, 24),
> +	GATE_INFRA0(CK_INFRA_SEJ_13M_CK, "infra_sej_13m", CK_INFRA_CK_F26M, 25),
> +	GATE_INFRA1(CK_INFRA_THERM_CK, "infra_therm", CK_INFRA_CK_F26M, 0),
> +	GATE_INFRA1(CK_INFRA_I2CO_CK, "infra_i2co", CK_INFRA_I2CS_CK, 1),
> +	GATE_INFRA1(CK_INFRA_UART0_CK, "infra_uart0", CK_INFRA_MUX_UART0, 2),
> +	GATE_INFRA1(CK_INFRA_UART1_CK, "infra_uart1", CK_INFRA_MUX_UART1, 3),
> +	GATE_INFRA1(CK_INFRA_UART2_CK, "infra_uart2", CK_INFRA_MUX_UART2, 4),
> +	GATE_INFRA1(CK_INFRA_SPI2_CK, "infra_spi2", CK_INFRA_MUX_SPI2, 6),
> +	GATE_INFRA1(CK_INFRA_SPI2_HCK_CK, "infra_spi2_hck", CK_INFRA_66M_MCK,
> +		    7),
> +	GATE_INFRA1(CK_INFRA_NFI1_CK, "infra_nfi1", CK_INFRA_NFI_CK, 8),
> +	GATE_INFRA1(CK_INFRA_SPINFI1_CK, "infra_spinfi1", CK_INFRA_SPINFI_CK,
> +		    9),
> +	GATE_INFRA1(CK_INFRA_NFI_HCK_CK, "infra_nfi_hck", CK_INFRA_66M_MCK, 10),
> +	GATE_INFRA1(CK_INFRA_SPI0_CK, "infra_spi0", CK_INFRA_MUX_SPI0, 11),
> +	GATE_INFRA1(CK_INFRA_SPI1_CK, "infra_spi1", CK_INFRA_MUX_SPI1, 12),
> +	GATE_INFRA1(CK_INFRA_SPI0_HCK_CK, "infra_spi0_hck", CK_INFRA_66M_MCK,
> +		    13),
> +	GATE_INFRA1(CK_INFRA_SPI1_HCK_CK, "infra_spi1_hck", CK_INFRA_66M_MCK,
> +		    14),
> +	GATE_INFRA1(CK_INFRA_FRTC_CK, "infra_frtc", CK_INFRA_RTC_32K, 15),
> +	GATE_INFRA1(CK_INFRA_MSDC_CK, "infra_msdc", CK_INFRA_FMSDC_CK, 16),
> +	GATE_INFRA1(CK_INFRA_MSDC_HCK_CK, "infra_msdc_hck",
> +		    CK_INFRA_FMSDC_HCK_CK, 17),
> +	GATE_INFRA1(CK_INFRA_MSDC_133M_CK, "infra_msdc_133m",
> +		    CK_INFRA_PERI_133M, 18),
> +	GATE_INFRA1(CK_INFRA_MSDC_66M_CK, "infra_msdc_66m", CK_INFRA_66M_PHCK,
> +		    19),
> +	GATE_INFRA1(CK_INFRA_ADC_26M_CK, "infra_adc_26m", CK_TOP_F26M, 20),
> +	GATE_INFRA1(CK_INFRA_ADC_FRC_CK, "infra_adc_frc", CK_TOP_F26M, 21),
> +	GATE_INFRA1(CK_INFRA_FBIST2FPC_CK, "infra_fbist2fpc", CK_INFRA_NFI_CK,
> +		    23),
> +	GATE_INFRA1(CK_INFRA_I2C_MCK_CK, "infra_i2c_mck", CK_INFRA_133M_MCK,
> +		    25),
> +	GATE_INFRA1(CK_INFRA_I2C_PCK_CK, "infra_i2c_pck", CK_INFRA_66M_MCK, 26),
> +	GATE_INFRA2(CK_INFRA_IUSB_133_CK, "infra_iusb_133", CK_INFRA_133M_PHCK,
> +		    0),
> +	GATE_INFRA2(CK_INFRA_IUSB_66M_CK, "infra_iusb_66m", CK_INFRA_66M_PHCK,
> +		    1),
> +	GATE_INFRA2(CK_INFRA_IUSB_SYS_CK, "infra_iusb_sys", CK_INFRA_USB_SYS_CK,
> +		    2),
> +	GATE_INFRA2(CK_INFRA_IUSB_CK, "infra_iusb", CK_INFRA_USB_CK, 3),
> +	GATE_INFRA2(CK_INFRA_IPCIE_CK, "infra_ipcie",
> +		    CK_INFRA_PCIE_GFMUX_TL_O_PRE, 12),
> +	GATE_INFRA2(CK_INFRA_IPCIER_CK, "infra_ipcier", CK_INFRA_F26M_CK0, 14),
> +	GATE_INFRA2(CK_INFRA_IPCIEB_CK, "infra_ipcieb", CK_INFRA_133M_PHCK, 15),
> +};
> +
> +static const struct mtk_clk_tree mt7981_fixed_pll_clk_tree = {
> +	.fdivs_offs = CLK_APMIXED_NR_CLK,
> +	.xtal_rate = 40 * MHZ,
> +	.fclks = fixed_pll_clks,
> +};
> +
> +static const struct mtk_clk_tree mt7981_topckgen_clk_tree = {
> +	.fdivs_offs = CK_TOP_CB_M_416M,
> +	.muxes_offs = CK_TOP_NFI1X_SEL,
> +	.fclks = top_fixed_clks,
> +	.fdivs = top_fixed_divs,
> +	.muxes = top_muxes,
> +	.flags = CLK_BYPASS_XTAL,
> +};
> +
> +static const struct mtk_clk_tree mt7981_infracfg_clk_tree = {
> +	.fdivs_offs = CK_INFRA_CK_F26M,
> +	.muxes_offs = CK_INFRA_UART0_SEL,
> +	.fdivs = infra_fixed_divs,
> +	.muxes = infra_muxes,
> +};
> +
> +static const struct udevice_id mt7981_fixed_pll_compat[] = {
> +	{ .compatible = "mediatek,mt7981-fixed-plls" },
> +	{}
> +};
> +
> +static const struct udevice_id mt7981_topckgen_compat[] = {
> +	{ .compatible = "mediatek,mt7981-topckgen" },
> +	{}
> +};
> +
> +static int mt7981_fixed_pll_probe(struct udevice *dev)
> +{
> +	return mtk_common_clk_init(dev, &mt7981_fixed_pll_clk_tree);
> +}
> +
> +static int mt7981_topckgen_probe(struct udevice *dev)
> +{
> +	struct mtk_clk_priv *priv = dev_get_priv(dev);
> +
> +	priv->base = dev_read_addr_ptr(dev);
> +	writel(MT7981_CLK_PDN_EN_WRITE, priv->base + MT7981_CLK_PDN);
> +	return mtk_common_clk_init(dev, &mt7981_topckgen_clk_tree);
> +}
> +
> +U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
> +	.name = "mt7981-clock-fixed-pll",
> +	.id = UCLASS_CLK,
> +	.of_match = mt7981_fixed_pll_compat,
> +	.probe = mt7981_fixed_pll_probe,
> +	.priv_auto = sizeof(struct mtk_clk_priv),
> +	.ops = &mtk_clk_topckgen_ops,
> +	.flags = DM_FLAG_PRE_RELOC,
> +};
> +
> +U_BOOT_DRIVER(mtk_clk_topckgen) = {
> +	.name = "mt7981-clock-topckgen",
> +	.id = UCLASS_CLK,
> +	.of_match = mt7981_topckgen_compat,
> +	.probe = mt7981_topckgen_probe,
> +	.priv_auto = sizeof(struct mtk_clk_priv),
> +	.ops = &mtk_clk_topckgen_ops,
> +	.flags = DM_FLAG_PRE_RELOC,
> +};
> +
> +static const struct udevice_id mt7981_infracfg_compat[] = {
> +	{ .compatible = "mediatek,mt7981-infracfg" },
> +	{}
> +};
> +
> +static const struct udevice_id mt7981_infracfg_ao_compat[] = {
> +	{ .compatible = "mediatek,mt7981-infracfg_ao" },
> +	{}
> +};
> +
> +static int mt7981_infracfg_probe(struct udevice *dev)
> +{
> +	return mtk_common_clk_init(dev, &mt7981_infracfg_clk_tree);
> +}
> +
> +static int mt7981_infracfg_ao_probe(struct udevice *dev)
> +{
> +	return mtk_common_clk_gate_init(dev, &mt7981_infracfg_clk_tree,
> +					infracfg_ao_gates);
> +}
> +
> +U_BOOT_DRIVER(mtk_clk_infracfg) = {
> +	.name = "mt7981-clock-infracfg",
> +	.id = UCLASS_CLK,
> +	.of_match = mt7981_infracfg_compat,
> +	.probe = mt7981_infracfg_probe,
> +	.priv_auto = sizeof(struct mtk_clk_priv),
> +	.ops = &mtk_clk_infrasys_ops,
> +	.flags = DM_FLAG_PRE_RELOC,
> +};
> +
> +U_BOOT_DRIVER(mtk_clk_infracfg_ao) = {
> +	.name = "mt7981-clock-infracfg-ao",
> +	.id = UCLASS_CLK,
> +	.of_match = mt7981_infracfg_ao_compat,
> +	.probe = mt7981_infracfg_ao_probe,
> +	.priv_auto = sizeof(struct mtk_cg_priv),
> +	.ops = &mtk_clk_gate_ops,
> +	.flags = DM_FLAG_PRE_RELOC,
> +};
> +
> +/* ethsys */
> +static const struct mtk_gate_regs eth_cg_regs = {
> +	.set_ofs = 0x30,
> +	.clr_ofs = 0x30,
> +	.sta_ofs = 0x30,
> +};
> +
> +#define GATE_ETH(_id, _name, _parent, _shift)
>      \
> +	{                                                                      \
> +		.id = _id, .parent = _parent, .regs = &eth_cg_regs,            \
> +		.shift = _shift,                                               \
> +		.flags = CLK_GATE_NO_SETCLR_INV | CLK_PARENT_TOPCKGEN,         \
> +	}
> +
> +static const struct mtk_gate eth_cgs[] = {
> +	GATE_ETH(CK_ETH_FE_EN, "eth_fe_en", CK_TOP_NETSYS_2X, 6),
> +	GATE_ETH(CK_ETH_GP2_EN, "eth_gp2_en", CK_TOP_SGM_325M, 7),
> +	GATE_ETH(CK_ETH_GP1_EN, "eth_gp1_en", CK_TOP_SGM_325M, 8),
> +	GATE_ETH(CK_ETH_WOCPU0_EN, "eth_wocpu0_en", CK_TOP_NETSYS_WED_MCU, 15),
> +};
> +
> +static int mt7981_ethsys_probe(struct udevice *dev)
> +{
> +	return mtk_common_clk_gate_init(dev, &mt7981_topckgen_clk_tree,
> +					eth_cgs);
> +}
> +
> +static int mt7981_ethsys_bind(struct udevice *dev)
> +{
> +	int ret = 0;
> +
> +#if CONFIG_IS_ENABLED(RESET_MEDIATEK)
> +	ret = mediatek_reset_bind(dev, ETHSYS_HIFSYS_RST_CTRL_OFS, 1);
> +	if (ret)
> +		debug("Warning: failed to bind reset controller\n");
> +#endif
> +
> +	return ret;
> +}
> +
> +static const struct udevice_id mt7981_ethsys_compat[] = {
> +	{ .compatible = "mediatek,mt7981-ethsys", },
> +	{}
> +};
> +
> +U_BOOT_DRIVER(mtk_clk_ethsys) = {
> +	.name = "mt7981-clock-ethsys",
> +	.id = UCLASS_CLK,
> +	.of_match = mt7981_ethsys_compat,
> +	.probe = mt7981_ethsys_probe,
> +	.bind = mt7981_ethsys_bind,
> +	.priv_auto = sizeof(struct mtk_cg_priv),
> +	.ops = &mtk_clk_gate_ops,
> +};
> diff --git a/include/dt-bindings/clock/mt7981-clk.h
>   b/include/dt-bindings/clock/mt7981-clk.h
> new file mode 100644
> index 0000000000..e24c759e49
> --- /dev/null
> +++ b/include/dt-bindings/clock/mt7981-clk.h
> @@ -0,0 +1,267 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
> + *
> + * Author: Sam Shih <sam.shih@mediatek.com>
> + */
> +
> +#ifndef _DT_BINDINGS_CLK_MT7981_H
> +#define _DT_BINDINGS_CLK_MT7981_H
> +
> +/* INFRACFG */
> +
> +#define CK_INFRA_CK_F26M		0
> +#define CK_INFRA_UART			1
> +#define CK_INFRA_ISPI0			2
> +#define CK_INFRA_I2C			3
> +#define CK_INFRA_ISPI1			4
> +#define CK_INFRA_PWM			5
> +#define CK_INFRA_66M_MCK		6
> +#define CK_INFRA_CK_F32K		7
> +#define CK_INFRA_PCIE_CK		8
> +#define CK_INFRA_PWM_BCK		9
> +#define CK_INFRA_PWM_CK1		10
> +#define CK_INFRA_PWM_CK2		11
> +#define CK_INFRA_133M_HCK		12
> +#define CK_INFRA_66M_PHCK		13
> +#define CK_INFRA_FAUD_L_CK		14
> +#define CK_INFRA_FAUD_AUD_CK		15
> +#define CK_INFRA_FAUD_EG2_CK		16
> +#define CK_INFRA_I2CS_CK		17
> +#define CK_INFRA_MUX_UART0		18
> +#define CK_INFRA_MUX_UART1		19
> +#define CK_INFRA_MUX_UART2		20
> +#define CK_INFRA_NFI_CK			21
> +#define CK_INFRA_SPINFI_CK		22
> +#define CK_INFRA_MUX_SPI0		23
> +#define CK_INFRA_MUX_SPI1		24
> +#define CK_INFRA_MUX_SPI2		25
> +#define CK_INFRA_RTC_32K		26
> +#define CK_INFRA_FMSDC_CK		27
> +#define CK_INFRA_FMSDC_HCK_CK		28
> +#define CK_INFRA_PERI_133M		29
> +#define CK_INFRA_133M_PHCK		30
> +#define CK_INFRA_USB_SYS_CK		31
> +#define CK_INFRA_USB_CK			32
> +#define CK_INFRA_USB_XHCI_CK		33
> +#define CK_INFRA_PCIE_GFMUX_TL_O_PRE	34
> +#define CK_INFRA_F26M_CK0		35
> +#define CK_INFRA_133M_MCK		36
> +#define CLK_INFRA_NR_CLK		37
> +
> +/* TOPCKGEN */
> +
> +#define CK_TOP_CB_CKSQ_40M		0
> +#define CK_TOP_CB_M_416M		1
> +#define CK_TOP_CB_M_D2			2
> +#define CK_TOP_CB_M_D3			3
> +#define CK_TOP_M_D3_D2			4
> +#define CK_TOP_CB_M_D4			5
> +#define CK_TOP_CB_M_D8			6
> +#define CK_TOP_M_D8_D2			7
> +#define CK_TOP_CB_MM_720M		8
> +#define CK_TOP_CB_MM_D2			9
> +#define CK_TOP_CB_MM_D3			10
> +#define CK_TOP_CB_MM_D3_D5		11
> +#define CK_TOP_CB_MM_D4			12
> +#define CK_TOP_CB_MM_D6			13
> +#define CK_TOP_MM_D6_D2			14
> +#define CK_TOP_CB_MM_D8			15
> +#define CK_TOP_CB_APLL2_196M		16
> +#define CK_TOP_APLL2_D2			17
> +#define CK_TOP_APLL2_D4			18
> +#define CK_TOP_NET1_2500M		19
> +#define CK_TOP_CB_NET1_D4		20
> +#define CK_TOP_CB_NET1_D5		21
> +#define CK_TOP_NET1_D5_D2		22
> +#define CK_TOP_NET1_D5_D4		23
> +#define CK_TOP_CB_NET1_D8		24
> +#define CK_TOP_NET1_D8_D2		25
> +#define CK_TOP_NET1_D8_D4		26
> +#define CK_TOP_CB_NET2_800M		27
> +#define CK_TOP_CB_NET2_D2		28
> +#define CK_TOP_CB_NET2_D4		29
> +#define CK_TOP_NET2_D4_D2		30
> +#define CK_TOP_NET2_D4_D4		31
> +#define CK_TOP_CB_NET2_D6		32
> +#define CK_TOP_CB_WEDMCU_208M		33
> +#define CK_TOP_CB_SGM_325M		34
> +#define CK_TOP_CKSQ_40M_D2		35
> +#define CK_TOP_CB_RTC_32K		36
> +#define CK_TOP_CB_RTC_32P7K		37
> +#define CK_TOP_USB_TX250M		38
> +#define CK_TOP_FAUD			39
> +#define CK_TOP_NFI1X			40
> +#define CK_TOP_USB_EQ_RX250M		41
> +#define CK_TOP_USB_CDR_CK		42
> +#define CK_TOP_USB_LN0_CK		43
> +#define CK_TOP_SPINFI_BCK		44
> +#define CK_TOP_SPI			45
> +#define CK_TOP_SPIM_MST			46
> +#define CK_TOP_UART_BCK			47
> +#define CK_TOP_PWM_BCK			48
> +#define CK_TOP_I2C_BCK			49
> +#define CK_TOP_PEXTP_TL			50
> +#define CK_TOP_EMMC_208M		51
> +#define CK_TOP_EMMC_400M		52
> +#define CK_TOP_DRAMC_REF		53
> +#define CK_TOP_DRAMC_MD32		54
> +#define CK_TOP_SYSAXI			55
> +#define CK_TOP_SYSAPB			56
> +#define CK_TOP_ARM_DB_MAIN		57
> +#define CK_TOP_AP2CNN_HOST		58
> +#define CK_TOP_NETSYS			59
> +#define CK_TOP_NETSYS_500M		60
> +#define CK_TOP_NETSYS_WED_MCU		61
> +#define CK_TOP_NETSYS_2X		62
> +#define CK_TOP_SGM_325M			63
> +#define CK_TOP_SGM_REG			64
> +#define CK_TOP_F26M			65
> +#define CK_TOP_EIP97B			66
> +#define CK_TOP_USB3_PHY			67
> +#define CK_TOP_AUD			68
> +#define CK_TOP_A1SYS			69
> +#define CK_TOP_AUD_L			70
> +#define CK_TOP_A_TUNER			71
> +#define CK_TOP_U2U3_REF			72
> +#define CK_TOP_U2U3_SYS			73
> +#define CK_TOP_U2U3_XHCI		74
> +#define CK_TOP_USB_FRMCNT		75
> +#define CK_TOP_NFI1X_SEL		76
> +#define CK_TOP_SPINFI_SEL		77
> +#define CK_TOP_SPI_SEL			78
> +#define CK_TOP_SPIM_MST_SEL		79
> +#define CK_TOP_UART_SEL			80
> +#define CK_TOP_PWM_SEL			81
> +#define CK_TOP_I2C_SEL			82
> +#define CK_TOP_PEXTP_TL_SEL		83
> +#define CK_TOP_EMMC_208M_SEL		84
> +#define CK_TOP_EMMC_400M_SEL		85
> +#define CK_TOP_F26M_SEL			86
> +#define CK_TOP_DRAMC_SEL		87
> +#define CK_TOP_DRAMC_MD32_SEL		88
> +#define CK_TOP_SYSAXI_SEL		89
> +#define CK_TOP_SYSAPB_SEL		90
> +#define CK_TOP_ARM_DB_MAIN_SEL		91
> +#define CK_TOP_AP2CNN_HOST_SEL		92
> +#define CK_TOP_NETSYS_SEL		93
> +#define CK_TOP_NETSYS_500M_SEL		94
> +#define CK_TOP_NETSYS_MCU_SEL		95
> +#define CK_TOP_NETSYS_2X_SEL		96
> +#define CK_TOP_SGM_325M_SEL		97
> +#define CK_TOP_SGM_REG_SEL		98
> +#define CK_TOP_EIP97B_SEL		99
> +#define CK_TOP_USB3_PHY_SEL		100
> +#define CK_TOP_AUD_SEL			101
> +#define CK_TOP_A1SYS_SEL		102
> +#define CK_TOP_AUD_L_SEL		103
> +#define CK_TOP_A_TUNER_SEL		104
> +#define CK_TOP_U2U3_SEL			105
> +#define CK_TOP_U2U3_SYS_SEL		106
> +#define CK_TOP_U2U3_XHCI_SEL		107
> +#define CK_TOP_USB_FRMCNT_SEL		108
> +#define CLK_TOP_NR_CLK			109
> +
> +/*
> + * INFRACFG_AO
> + * clock muxes need to be append to infracfg domain, and clock gates
> + * need to be keep in infracgh_ao domain
> + */
> +#define INFRACFG_AO_OFFSET		10
> +
> +#define CK_INFRA_UART0_SEL		(0 + CLK_INFRA_NR_CLK)
> +#define CK_INFRA_UART1_SEL		(1 + CLK_INFRA_NR_CLK)
> +#define CK_INFRA_UART2_SEL		(2 + CLK_INFRA_NR_CLK)
> +#define CK_INFRA_SPI0_SEL		(3 + CLK_INFRA_NR_CLK)
> +#define CK_INFRA_SPI1_SEL		(4 + CLK_INFRA_NR_CLK)
> +#define CK_INFRA_SPI2_SEL		(5 + CLK_INFRA_NR_CLK)
> +#define CK_INFRA_PWM1_SEL		(6 + CLK_INFRA_NR_CLK)
> +#define CK_INFRA_PWM2_SEL		(7 + CLK_INFRA_NR_CLK)
> +#define CK_INFRA_PWM_BSEL		(8 + CLK_INFRA_NR_CLK)
> +#define CK_INFRA_PCIE_SEL		(9 + CLK_INFRA_NR_CLK)
> +#define CK_INFRA_GPT_STA		(10 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_PWM_HCK		(11 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_PWM_STA		(12 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_PWM1_CK		(13 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_PWM2_CK		(14 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_CQ_DMA_CK		(15 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_AUD_BUS_CK		(16 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_AUD_26M_CK		(17 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_AUD_L_CK		(18 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_AUD_AUD_CK		(19 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_AUD_EG2_CK		(20 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_DRAMC_26M_CK		(21 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_DBG_CK			(22 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_AP_DMA_CK		(23 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_SEJ_CK			(24 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_SEJ_13M_CK		(25 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_THERM_CK		(26 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_I2CO_CK		(27 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_UART0_CK		(28 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_UART1_CK		(29 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_UART2_CK		(30 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_SPI2_CK		(31 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_SPI2_HCK_CK		(32 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_NFI1_CK		(33 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_SPINFI1_CK		(34 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_NFI_HCK_CK		(35 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_SPI0_CK		(36 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_SPI1_CK		(37 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_SPI0_HCK_CK		(38 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_SPI1_HCK_CK		(39 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_FRTC_CK		(40 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_MSDC_CK		(41 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_MSDC_HCK_CK		(42 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_MSDC_133M_CK		(43 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_MSDC_66M_CK		(44 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_ADC_26M_CK		(45 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_ADC_FRC_CK		(46 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_FBIST2FPC_CK		(47 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_I2C_MCK_CK		(48 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_I2C_PCK_CK		(49 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_IUSB_133_CK		(50 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_IUSB_66M_CK		(51 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_IUSB_SYS_CK		(52 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_IUSB_CK		(53 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_IPCIE_CK		(54 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_IPCIER_CK		(55 - INFRACFG_AO_OFFSET)
> +#define CK_INFRA_IPCIEB_CK		(56 - INFRACFG_AO_OFFSET)
> +#define CLK_INFRA_AO_NR_CLK		(57 - INFRACFG_AO_OFFSET)
> +
> +/* APMIXEDSYS */
> +
> +#define CK_APMIXED_ARMPLL		0
> +#define CK_APMIXED_NET2PLL		1
> +#define CK_APMIXED_MMPLL		2
> +#define CK_APMIXED_SGMPLL		3
> +#define CK_APMIXED_WEDMCUPLL		4
> +#define CK_APMIXED_NET1PLL		5
> +#define CK_APMIXED_MPLL			6
> +#define CK_APMIXED_APLL2		7
> +#define CLK_APMIXED_NR_CLK		8
> +
> +/* SGMIISYS_0 */
> +
> +#define CK_SGM0_TX_EN			0
> +#define CK_SGM0_RX_EN			1
> +#define CK_SGM0_CK0_EN			2
> +#define CK_SGM0_CDR_CK0_EN		3
> +#define CLK_SGMII0_NR_CLK		4
> +
> +/* SGMIISYS_1 */
> +
> +#define CK_SGM1_TX_EN			0
> +#define CK_SGM1_RX_EN			1
> +#define CK_SGM1_CK1_EN			2
> +#define CK_SGM1_CDR_CK1_EN		3
> +#define CLK_SGMII1_NR_CLK		4
> +
> +/* ETHSYS */
> +
> +#define CK_ETH_FE_EN			0
> +#define CK_ETH_GP2_EN			1
> +#define CK_ETH_GP1_EN			2
> +#define CK_ETH_WOCPU0_EN		3
> +#define CLK_ETH_NR_CLK			4
> +
> +#endif /* _DT_BINDINGS_CLK_MT7981_H */
> 

Reviewed-by: Sean Anderson <seanga2@gmail.com>

But perhaps these includes could be merged? They seem pretty similar.

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 24/31] clk: mediatek: add infrasys clock mux support
  2022-08-13  4:21   ` Sean Anderson
@ 2022-08-17  8:00     ` Weijie Gao
  0 siblings, 0 replies; 100+ messages in thread
From: Weijie Gao @ 2022-08-17  8:00 UTC (permalink / raw)
  To: Sean Anderson, u-boot; +Cc: GSS_MTK_Uboot_upstream, Lukasz Majewski

On Sat, 2022-08-13 at 00:21 -0400, Sean Anderson wrote:
> On 8/3/22 11:36 PM, Weijie Gao wrote:
> > This patch adds infrasys clock mux support for mediatek clock
> > drivers.
> > 
> > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> > ---
> >   drivers/clk/mediatek/clk-mtk.c | 72
> > ++++++++++++++++++++++++++++++++++
> >   drivers/clk/mediatek/clk-mtk.h |  4 +-
> >   2 files changed, 75 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/clk/mediatek/clk-mtk.c
> > b/drivers/clk/mediatek/clk-mtk.c
> > index 908ed2b4ba..be3846c85b 100644
> > --- a/drivers/clk/mediatek/clk-mtk.c
> > +++ b/drivers/clk/mediatek/clk-mtk.c
> > @@ -303,6 +303,24 @@ static ulong
> > mtk_topckgen_get_factor_rate(struct clk
> >   *clk, u32 off)
> >   	return mtk_factor_recalc_rate(fdiv, rate);
> >   }
> >   
> > +static ulong mtk_infrasys_get_factor_rate(struct clk *clk, u32
> > off)
> > +{
> > +	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
> > +	const struct mtk_fixed_factor *fdiv = &priv->tree-
> > >fdivs[off];
> > +	ulong rate;
> > +
> > +	switch (fdiv->flags & CLK_PARENT_MASK) {
> > +	case CLK_PARENT_TOPCKGEN:
> > +		rate = mtk_clk_find_parent_rate(clk, fdiv->parent,
> > +						priv->parent);
> > +		break;
> > +	default:
> > +		rate = mtk_clk_find_parent_rate(clk, fdiv->parent, 
> > NULL);
> > +	}
> > +
> > +	return mtk_factor_recalc_rate(fdiv, rate);
> > +}
> > +
> >   static ulong mtk_topckgen_get_mux_rate(struct clk *clk, u32 off)
> >   {
> >   	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
> > @@ -332,6 +350,34 @@ static ulong mtk_topckgen_get_mux_rate(struct
> > clk *clk,
> >   u32 off)
> >   	return priv->tree->xtal_rate;
> >   }
> >   
> > +static ulong mtk_infrasys_get_mux_rate(struct clk *clk, u32 off)
> > +{
> > +	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
> > +	const struct mtk_composite *mux = &priv->tree->muxes[off];
> > +	u32 index;
> > +	u32 flag;
> > +
> > +	index = readl(priv->base + mux->mux_reg);
> > +	index &= mux->mux_mask << mux->mux_shift;
> > +	index = index >> mux->mux_shift;
> > +
> > +	if (mux->parent[index] == CLK_XTAL && priv->tree->flags &
> > CLK_BYPASS_XTAL)
> > +		flag = 1;
> > +	if (mux->parent[index] > 0 || flag == 1) {
> 
> Please just use the condition directly

OK.

> 
> > +		switch (mux->flags & CLK_PARENT_MASK) {
> > +		case CLK_PARENT_TOPCKGEN:
> > +			return mtk_clk_find_parent_rate(clk, mux-
> > >parent[index],
> > +							priv-
> > >parent);
> > +			break;
> > +		default:
> > +			return mtk_clk_find_parent_rate(clk, mux-
> > >parent[index],
> > +							NULL);
> > +			break;
> > +		}
> > +	}
> > +	return 0;
> > +}
> > +
> >   static ulong mtk_topckgen_get_rate(struct clk *clk)
> >   {
> >   	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
> > @@ -346,6 +392,25 @@ static ulong mtk_topckgen_get_rate(struct clk
> > *clk)
> >   						 priv->tree-
> > >muxes_offs);
> >   }
> >   
> > +static ulong mtk_infrasys_get_rate(struct clk *clk)
> > +{
> > +	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
> > +
> > +	ulong rate;
> > +
> > +	if (clk->id < priv->tree->fdivs_offs) {
> > +		rate = priv->tree->fclks[clk->id].rate;
> > +	} else if (clk->id < priv->tree->muxes_offs) {
> > +		rate = mtk_infrasys_get_factor_rate(clk, clk->id -
> > +						    priv->tree-
> > >fdivs_offs);
> > +	} else {
> > +		rate = mtk_infrasys_get_mux_rate(clk, clk->id -
> > +						 priv->tree-
> > >muxes_offs);
> > +	}
> > +
> > +	return rate;
> > +}
> > +
> >   static int mtk_clk_mux_enable(struct clk *clk)
> >   {
> >   	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
> > @@ -494,6 +559,13 @@ const struct clk_ops mtk_clk_topckgen_ops = {
> >   	.set_parent = mtk_common_clk_set_parent,
> >   };
> >   
> > +const struct clk_ops mtk_clk_infrasys_ops = {
> > +	.enable = mtk_clk_mux_enable,
> > +	.disable = mtk_clk_mux_disable,
> > +	.get_rate = mtk_infrasys_get_rate,
> > +	.set_parent = mtk_common_clk_set_parent,
> > +};
> > +
> >   const struct clk_ops mtk_clk_gate_ops = {
> >   	.enable = mtk_clk_gate_enable,
> >   	.disable = mtk_clk_gate_disable,
> > diff --git a/drivers/clk/mediatek/clk-mtk.h
> > b/drivers/clk/mediatek/clk-mtk.h
> > index 7955d469db..8536275671 100644
> > --- a/drivers/clk/mediatek/clk-mtk.h
> > +++ b/drivers/clk/mediatek/clk-mtk.h
> > @@ -25,7 +25,8 @@
> >   
> >   #define CLK_PARENT_APMIXED		BIT(4)
> >   #define CLK_PARENT_TOPCKGEN		BIT(5)
> > -#define CLK_PARENT_MASK			GENMASK(5, 4)
> > +#define CLK_PARENT_INFRASYS		BIT(6)
> > +#define CLK_PARENT_MASK			GENMASK(6, 4)
> >   
> >   #define ETHSYS_HIFSYS_RST_CTRL_OFS	0x34
> >   
> > @@ -217,6 +218,7 @@ struct mtk_cg_priv {
> >   
> >   extern const struct clk_ops mtk_clk_apmixedsys_ops;
> >   extern const struct clk_ops mtk_clk_topckgen_ops;
> > +extern const struct clk_ops mtk_clk_infrasys_ops;
> >   extern const struct clk_ops mtk_clk_gate_ops;
> >   
> >   int mtk_common_clk_init(struct udevice *dev,
> > 
> 
> 

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 25/31] clk: mediatek: add CLK_XTAL support for clock driver
  2022-08-13  4:25   ` Sean Anderson
@ 2022-08-17  8:08     ` Weijie Gao
  0 siblings, 0 replies; 100+ messages in thread
From: Weijie Gao @ 2022-08-17  8:08 UTC (permalink / raw)
  To: Sean Anderson, u-boot; +Cc: GSS_MTK_Uboot_upstream, Lukasz Majewski

On Sat, 2022-08-13 at 00:25 -0400, Sean Anderson wrote:
> On 8/3/22 11:36 PM, Weijie Gao wrote:
> > This add CLK_XTAL macro and flag to mediatek clock driver common
> > part,
> > to make thi SoC that has clock directlly connect to XTAL working.
> 
> nit: this.. directly
> 
> But I'm having trouble reading your commit message. Perhaps something
> like
> 
> > This adds the CLK_XTAL macro/flag to allow modeling clocks which
> > are
> > directly connected to a fixed-rate clock.

Oh. I've put wrong commit description here.

> > 
> > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> > ---
> >   drivers/clk/mediatek/clk-mtk.c | 3 +++
> >   drivers/clk/mediatek/clk-mtk.h | 3 ++-
> >   2 files changed, 5 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/clk/mediatek/clk-mtk.c
> > b/drivers/clk/mediatek/clk-mtk.c
> > index be3846c85b..5a4650d137 100644
> > --- a/drivers/clk/mediatek/clk-mtk.c
> > +++ b/drivers/clk/mediatek/clk-mtk.c
> > @@ -296,6 +296,7 @@ static ulong
> > mtk_topckgen_get_factor_rate(struct clk
> >   *clk, u32 off)
> >   		rate = mtk_clk_find_parent_rate(clk, fdiv-
> > >parent, NULL);
> >   		break;
> >   
> > +	case CLK_PARENT_XTAL:
> >   	default:
> >   		rate = priv->tree->xtal_rate;
> >   	}
> > @@ -314,6 +315,8 @@ static ulong
> > mtk_infrasys_get_factor_rate(struct clk
> >   *clk, u32 off)
> >   		rate = mtk_clk_find_parent_rate(clk, fdiv-
> > >parent,
> >   						priv->parent);
> >   		break;
> > +	case CLK_PARENT_XTAL:
> > +		rate = priv->tree->xtal_rate;
> >   	default:
> >   		rate = mtk_clk_find_parent_rate(clk, fdiv-
> > >parent, NULL);
> >   	}
> > diff --git a/drivers/clk/mediatek/clk-mtk.h
> > b/drivers/clk/mediatek/clk-mtk.h
> > index 8536275671..211356697b 100644
> > --- a/drivers/clk/mediatek/clk-mtk.h
> > +++ b/drivers/clk/mediatek/clk-mtk.h
> > @@ -26,7 +26,8 @@
> >   #define CLK_PARENT_APMIXED		BIT(4)
> >   #define CLK_PARENT_TOPCKGEN		BIT(5)
> >   #define CLK_PARENT_INFRASYS		BIT(6)
> > -#define CLK_PARENT_MASK			GENMASK(6, 4)
> > +#define CLK_PARENT_XTAL			BIT(7)
> > +#define CLK_PARENT_MASK			GENMASK(7, 4)
> >   
> >   #define ETHSYS_HIFSYS_RST_CTRL_OFS	0x34
> >   
> > 
> 
> 

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 27/31] clk: mediatek: add clock driver support for MediaTek MT7981 SoC
  2022-08-13  4:31   ` Sean Anderson
@ 2022-08-17  8:16     ` Weijie Gao
  0 siblings, 0 replies; 100+ messages in thread
From: Weijie Gao @ 2022-08-17  8:16 UTC (permalink / raw)
  To: Sean Anderson, u-boot; +Cc: GSS_MTK_Uboot_upstream, Lukasz Majewski

On Sat, 2022-08-13 at 00:31 -0400, Sean Anderson wrote:
> On 8/3/22 11:36 PM, Weijie Gao wrote:
> > This patch adds clock driver support for MediaTek MT7981 SoC
> > 
> > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> > ---
> >   drivers/clk/mediatek/Makefile          |   1 +
> >   drivers/clk/mediatek/clk-mt7981.c      | 682
> > +++++++++++++++++++++++++
> >   include/dt-bindings/clock/mt7981-clk.h | 267 ++++++++++
> >   3 files changed, 950 insertions(+)
> >   create mode 100644 drivers/clk/mediatek/clk-mt7981.c
> >   create mode 100644 include/dt-bindings/clock/mt7981-clk.h
> > 
> > diff --git a/drivers/clk/mediatek/Makefile
> > b/drivers/clk/mediatek/Makefile
> > index 1aa38215bf..1decf31a77 100644
> > --- a/drivers/clk/mediatek/Makefile
> > +++ b/drivers/clk/mediatek/Makefile
> > @@ -8,6 +8,7 @@ obj-$(CONFIG_TARGET_MT7623) += clk-mt7623.o
> >   obj-$(CONFIG_TARGET_MT7622) += clk-mt7622.o
> >   obj-$(CONFIG_TARGET_MT7629) += clk-mt7629.o
> >   obj-$(CONFIG_TARGET_MT7986) += clk-mt7986.o
> > +obj-$(CONFIG_TARGET_MT7981) += clk-mt7981.o
> >   obj-$(CONFIG_TARGET_MT8183) += clk-mt8183.o
> >   obj-$(CONFIG_TARGET_MT8516) += clk-mt8516.o
> >   obj-$(CONFIG_TARGET_MT8518) += clk-mt8518.o
> > diff --git a/drivers/clk/mediatek/clk-mt7981.c
> >   b/drivers/clk/mediatek/clk-mt7981.c
> > new file mode 100644
> > index 0000000000..53d09250e6
> > --- /dev/null
> > +++ b/drivers/clk/mediatek/clk-mt7981.c
> > @@ -0,0 +1,682 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * MediaTek clock driver for MT7981 SoC
> > + *
> > + * Copyright (C) 2022 MediaTek Inc.
> > + * Author: Sam Shih <sam.shih@mediatek.com>
> > + */
> > +
> > +#include <dm.h>
> > +#include <log.h>
> > +#include <asm/arch-mediatek/reset.h>
> > +#include <asm/io.h>
> > +#include <dt-bindings/clock/mt7981-clk.h>
> > +#include <linux/bitops.h>
> > +
> > +#include "clk-mtk.h"
> > +
> > +#define MT7981_CLK_PDN 0x250
> > +#define MT7981_CLK_PDN_EN_WRITE BIT(31)
> > +
> > +#define PLL_FACTOR(_id, _name, _parent, _mult, _div)
> >      \
> > +	FACTOR(_id, _parent, _mult, _div, CLK_PARENT_APMIXED)
> > +
> > +#define TOP_FACTOR(_id, _name, _parent, _mult, _div)
> >      \
> > +	FACTOR(_id, _parent, _mult, _div, CLK_PARENT_TOPCKGEN)
> > +
> > +#define INFRA_FACTOR(_id, _name, _parent, _mult, _div)
> >      \
> > +	FACTOR(_id, _parent, _mult, _div, CLK_PARENT_INFRASYS)
> > +
> > +/* FIXED PLLS */
> > +static const struct mtk_fixed_clk fixed_pll_clks[] = {
> > +	FIXED_CLK(CK_APMIXED_ARMPLL, CLK_XTAL, 1300000000),
> > +	FIXED_CLK(CK_APMIXED_NET2PLL, CLK_XTAL, 800000000),
> > +	FIXED_CLK(CK_APMIXED_MMPLL, CLK_XTAL, 720000000),
> > +	FIXED_CLK(CK_APMIXED_SGMPLL, CLK_XTAL, 325000000),
> > +	FIXED_CLK(CK_APMIXED_WEDMCUPLL, CLK_XTAL, 208000000),
> > +	FIXED_CLK(CK_APMIXED_NET1PLL, CLK_XTAL, 2500000000),
> > +	FIXED_CLK(CK_APMIXED_MPLL, CLK_XTAL, 416000000),
> > +	FIXED_CLK(CK_APMIXED_APLL2, CLK_XTAL, 196608000),
> > +};
> > +
> > +/* TOPCKGEN FIXED CLK */
> > +static const struct mtk_fixed_clk top_fixed_clks[] = {
> > +	FIXED_CLK(CK_TOP_CB_CKSQ_40M, CLK_XTAL, 40000000),
> > +};
> > +
> > +/* TOPCKGEN FIXED DIV */
> > +static const struct mtk_fixed_factor top_fixed_divs[] = {
> > +	PLL_FACTOR(CK_TOP_CB_M_416M, "cb_m_416m", CK_APMIXED_MPLL,
> > 1, 1),
> > +	PLL_FACTOR(CK_TOP_CB_M_D2, "cb_m_d2", CK_APMIXED_MPLL, 1,
> > 2),
> > +	PLL_FACTOR(CK_TOP_CB_M_D3, "cb_m_d3", CK_APMIXED_MPLL, 1,
> > 3),
> > +	PLL_FACTOR(CK_TOP_M_D3_D2, "m_d3_d2", CK_APMIXED_MPLL, 1,
> > 2),
> > +	PLL_FACTOR(CK_TOP_CB_M_D4, "cb_m_d4", CK_APMIXED_MPLL, 1,
> > 4),
> > +	PLL_FACTOR(CK_TOP_CB_M_D8, "cb_m_d8", CK_APMIXED_MPLL, 1,
> > 8),
> > +	PLL_FACTOR(CK_TOP_M_D8_D2, "m_d8_d2", CK_APMIXED_MPLL, 1,
> > 16),
> > +	PLL_FACTOR(CK_TOP_CB_MM_720M, "cb_mm_720m",
> > CK_APMIXED_MMPLL, 1, 1),
> > +	PLL_FACTOR(CK_TOP_CB_MM_D2, "cb_mm_d2", CK_APMIXED_MMPLL,
> > 1, 2),
> > +	PLL_FACTOR(CK_TOP_CB_MM_D3, "cb_mm_d3", CK_APMIXED_MMPLL,
> > 1, 3),
> > +	PLL_FACTOR(CK_TOP_CB_MM_D3_D5, "cb_mm_d3_d5",
> > CK_APMIXED_MMPLL, 1, 15),
> > +	PLL_FACTOR(CK_TOP_CB_MM_D4, "cb_mm_d4", CK_APMIXED_MMPLL,
> > 1, 4),
> > +	PLL_FACTOR(CK_TOP_CB_MM_D6, "cb_mm_d6", CK_APMIXED_MMPLL,
> > 1, 6),
> > +	PLL_FACTOR(CK_TOP_MM_D6_D2, "mm_d6_d2", CK_APMIXED_MMPLL,
> > 1, 12),
> > +	PLL_FACTOR(CK_TOP_CB_MM_D8, "cb_mm_d8", CK_APMIXED_MMPLL,
> > 1, 8),
> > +	PLL_FACTOR(CK_TOP_CB_APLL2_196M, "cb_apll2_196m",
> > CK_APMIXED_APLL2, 1,
> > +		   1),
> > +	PLL_FACTOR(CK_TOP_APLL2_D2, "apll2_d2", CK_APMIXED_APLL2,
> > 1, 2),
> > +	PLL_FACTOR(CK_TOP_APLL2_D4, "apll2_d4", CK_APMIXED_APLL2,
> > 1, 4),
> > +	PLL_FACTOR(CK_TOP_NET1_2500M, "net1_2500m",
> > CK_APMIXED_NET1PLL, 1, 1),
> > +	PLL_FACTOR(CK_TOP_CB_NET1_D4, "cb_net1_d4",
> > CK_APMIXED_NET1PLL, 1, 4),
> > +	PLL_FACTOR(CK_TOP_CB_NET1_D5, "cb_net1_d5",
> > CK_APMIXED_NET1PLL, 1, 5),
> > +	PLL_FACTOR(CK_TOP_NET1_D5_D2, "net1_d5_d2",
> > CK_APMIXED_NET1PLL, 1, 10),
> > +	PLL_FACTOR(CK_TOP_NET1_D5_D4, "net1_d5_d4",
> > CK_APMIXED_NET1PLL, 1, 20),
> > +	PLL_FACTOR(CK_TOP_CB_NET1_D8, "cb_net1_d8",
> > CK_APMIXED_NET1PLL, 1, 8),
> > +	PLL_FACTOR(CK_TOP_NET1_D8_D2, "net1_d8_d2",
> > CK_APMIXED_NET1PLL, 1, 16),
> > +	PLL_FACTOR(CK_TOP_NET1_D8_D4, "net1_d8_d4",
> > CK_APMIXED_NET1PLL, 1, 32),
> > +	PLL_FACTOR(CK_TOP_CB_NET2_800M, "cb_net2_800m",
> > CK_APMIXED_NET2PLL, 1,
> > +		   1),
> > +	PLL_FACTOR(CK_TOP_CB_NET2_D2, "cb_net2_d2",
> > CK_APMIXED_NET2PLL, 1, 2),
> > +	PLL_FACTOR(CK_TOP_CB_NET2_D4, "cb_net2_d4",
> > CK_APMIXED_NET2PLL, 1, 4),
> > +	PLL_FACTOR(CK_TOP_NET2_D4_D2, "net2_d4_d2",
> > CK_APMIXED_NET2PLL, 1, 8),
> > +	PLL_FACTOR(CK_TOP_NET2_D4_D4, "net2_d4_d4",
> > CK_APMIXED_NET2PLL, 1, 16),
> > +	PLL_FACTOR(CK_TOP_CB_NET2_D6, "cb_net2_d6",
> > CK_APMIXED_NET2PLL, 1, 6),
> > +	PLL_FACTOR(CK_TOP_CB_WEDMCU_208M, "cb_wedmcu_208m",
> > +		   CK_APMIXED_WEDMCUPLL, 1, 1),
> > +	PLL_FACTOR(CK_TOP_CB_SGM_325M, "cb_sgm_325m",
> > CK_APMIXED_SGMPLL, 1, 1),
> > +	TOP_FACTOR(CK_TOP_CKSQ_40M_D2, "cksq_40m_d2",
> > CK_TOP_CB_CKSQ_40M, 1, 2),
> > +	TOP_FACTOR(CK_TOP_CB_RTC_32K, "cb_rtc_32k",
> > CK_TOP_CB_CKSQ_40M, 1,
> > +		   1250),
> > +	TOP_FACTOR(CK_TOP_CB_RTC_32P7K, "cb_rtc_32p7k",
> > CK_TOP_CB_CKSQ_40M, 1,
> > +		   1220),
> > +	TOP_FACTOR(CK_TOP_USB_TX250M, "usb_tx250m",
> > CK_TOP_CB_CKSQ_40M, 1, 1),
> > +	TOP_FACTOR(CK_TOP_FAUD, "faud", CK_TOP_CB_CKSQ_40M, 1, 1),
> > +	TOP_FACTOR(CK_TOP_NFI1X, "nfi1x", CK_TOP_NFI1X_SEL, 1, 1),
> > +	TOP_FACTOR(CK_TOP_USB_EQ_RX250M, "usb_eq_rx250m",
> > CK_TOP_CB_CKSQ_40M, 1,
> > +		   1),
> > +	TOP_FACTOR(CK_TOP_USB_CDR_CK, "usb_cdr",
> > CK_TOP_CB_CKSQ_40M, 1, 1),
> > +	TOP_FACTOR(CK_TOP_USB_LN0_CK, "usb_ln0",
> > CK_TOP_CB_CKSQ_40M, 1, 1),
> > +	TOP_FACTOR(CK_TOP_SPINFI_BCK, "spinfi_bck",
> > CK_TOP_SPINFI_SEL, 1, 1),
> > +	TOP_FACTOR(CK_TOP_SPI, "spi", CK_TOP_SPI_SEL, 1, 1),
> > +	TOP_FACTOR(CK_TOP_SPIM_MST, "spim_mst",
> > CK_TOP_SPIM_MST_SEL, 1, 1),
> > +	TOP_FACTOR(CK_TOP_UART_BCK, "uart_bck", CK_TOP_UART_SEL,
> > 1, 1),
> > +	TOP_FACTOR(CK_TOP_PWM_BCK, "pwm_bck", CK_TOP_PWM_SEL, 1,
> > 1),
> > +	TOP_FACTOR(CK_TOP_I2C_BCK, "i2c_bck", CK_TOP_I2C_SEL, 1,
> > 1),
> > +	TOP_FACTOR(CK_TOP_PEXTP_TL, "pextp_tl",
> > CK_TOP_PEXTP_TL_SEL, 1, 1),
> > +	TOP_FACTOR(CK_TOP_EMMC_208M, "emmc_208m",
> > CK_TOP_EMMC_208M_SEL, 1, 1),
> > +	TOP_FACTOR(CK_TOP_EMMC_400M, "emmc_400m",
> > CK_TOP_EMMC_400M_SEL, 1, 1),
> > +	TOP_FACTOR(CK_TOP_DRAMC_REF, "dramc_ref",
> > CK_TOP_DRAMC_SEL, 1, 1),
> > +	TOP_FACTOR(CK_TOP_DRAMC_MD32, "dramc_md32",
> > CK_TOP_DRAMC_MD32_SEL, 1,
> > +		   1),
> > +	TOP_FACTOR(CK_TOP_SYSAXI, "sysaxi", CK_TOP_SYSAXI_SEL, 1,
> > 1),
> > +	TOP_FACTOR(CK_TOP_SYSAPB, "sysapb", CK_TOP_SYSAPB_SEL, 1,
> > 1),
> > +	TOP_FACTOR(CK_TOP_ARM_DB_MAIN, "arm_db_main",
> > CK_TOP_ARM_DB_MAIN_SEL, 1,
> > +		   1),
> > +	TOP_FACTOR(CK_TOP_AP2CNN_HOST, "ap2cnn_host",
> > CK_TOP_AP2CNN_HOST_SEL, 1,
> > +		   1),
> > +	TOP_FACTOR(CK_TOP_NETSYS, "netsys", CK_TOP_NETSYS_SEL, 1,
> > 1),
> > +	TOP_FACTOR(CK_TOP_NETSYS_500M, "netsys_500m",
> > CK_TOP_NETSYS_500M_SEL, 1,
> > +		   1),
> > +	TOP_FACTOR(CK_TOP_NETSYS_WED_MCU, "netsys_wed_mcu",
> > +		   CK_TOP_NETSYS_MCU_SEL, 1, 1),
> > +	TOP_FACTOR(CK_TOP_NETSYS_2X, "netsys_2x",
> > CK_TOP_NETSYS_2X_SEL, 1, 1),
> > +	TOP_FACTOR(CK_TOP_SGM_325M, "sgm_325m",
> > CK_TOP_SGM_325M_SEL, 1, 1),
> > +	TOP_FACTOR(CK_TOP_SGM_REG, "sgm_reg", CK_TOP_SGM_REG_SEL,
> > 1, 1),
> > +	TOP_FACTOR(CK_TOP_F26M, "csw_f26m", CK_TOP_F26M_SEL, 1,
> > 1),
> > +	TOP_FACTOR(CK_TOP_EIP97B, "eip97b", CK_TOP_EIP97B_SEL, 1,
> > 1),
> > +	TOP_FACTOR(CK_TOP_USB3_PHY, "usb3_phy",
> > CK_TOP_USB3_PHY_SEL, 1, 1),
> > +	TOP_FACTOR(CK_TOP_AUD, "aud", CK_TOP_FAUD, 1, 1),
> > +	TOP_FACTOR(CK_TOP_A1SYS, "a1sys", CK_TOP_A1SYS_SEL, 1, 1),
> > +	TOP_FACTOR(CK_TOP_AUD_L, "aud_l", CK_TOP_AUD_L_SEL, 1, 1),
> > +	TOP_FACTOR(CK_TOP_A_TUNER, "a_tuner", CK_TOP_A_TUNER_SEL,
> > 1, 1),
> > +	TOP_FACTOR(CK_TOP_U2U3_REF, "u2u3_ref", CK_TOP_U2U3_SEL,
> > 1, 1),
> > +	TOP_FACTOR(CK_TOP_U2U3_SYS, "u2u3_sys",
> > CK_TOP_U2U3_SYS_SEL, 1, 1),
> > +	TOP_FACTOR(CK_TOP_U2U3_XHCI, "u2u3_xhci",
> > CK_TOP_U2U3_XHCI_SEL, 1, 1),
> > +	TOP_FACTOR(CK_TOP_USB_FRMCNT, "usb_frmcnt",
> > CK_TOP_USB_FRMCNT_SEL, 1,
> > +		   1),
> > +};
> > +
> > +/* TOPCKGEN MUX PARENTS */
> > +static const int nfi1x_parents[] = { CK_TOP_CB_CKSQ_40M,
> > CK_TOP_CB_MM_D4,
> > +				     CK_TOP_NET1_D8_D2,  CK_TOP_CB
> > _NET2_D6,
> > +				     CK_TOP_CB_M_D4,     CK_TOP_CB
> > _MM_D8,
> > +				     CK_TOP_NET1_D8_D4,  CK_TOP_CB
> > _M_D8 };
> > +
> > +static const int spinfi_parents[] = { CK_TOP_CKSQ_40M_D2,
> >   CK_TOP_CB_CKSQ_40M,
> > +				      CK_TOP_NET1_D5_D4,  CK_TOP_C
> > B_M_D4,
> > +				      CK_TOP_CB_MM_D8,    CK_TOP_N
> > ET1_D8_D4,
> > +				      CK_TOP_MM_D6_D2,    CK_TOP_C
> > B_M_D8 };
> > +
> > +static const int spi_parents[] = { CK_TOP_CB_CKSQ_40M,
> > CK_TOP_CB_M_D2,
> > +				   CK_TOP_CB_MM_D4,    CK_TOP_NET1
> > _D8_D2,
> > +				   CK_TOP_CB_NET2_D6,  CK_TOP_NET1
> > _D5_D4,
> > +				   CK_TOP_CB_M_D4,     CK_TOP_NET1
> > _D8_D4 };
> > +
> > +static const int uart_parents[] = { CK_TOP_CB_CKSQ_40M,
> > CK_TOP_CB_M_D8,
> > +				    CK_TOP_M_D8_D2 };
> > +
> > +static const int pwm_parents[] = { CK_TOP_CB_CKSQ_40M,
> > CK_TOP_NET1_D8_D2,
> > +				   CK_TOP_NET1_D5_D4,  CK_TOP_CB_M
> > _D4,
> > +				   CK_TOP_M_D8_D2,     CK_TOP_CB_R
> > TC_32K };
> > +
> > +static const int i2c_parents[] = { CK_TOP_CB_CKSQ_40M,
> > CK_TOP_NET1_D5_D4,
> > +				   CK_TOP_CB_M_D4,
> > CK_TOP_NET1_D8_D4 };
> > +
> > +static const int pextp_tl_ck_parents[] = { CK_TOP_CB_CKSQ_40M,
> > +					   CK_TOP_NET1_D5_D4,
> > CK_TOP_CB_M_D4,
> > +					   CK_TOP_CB_RTC_32K };
> > +
> > +static const int emmc_208m_parents[] = {
> > +	CK_TOP_CB_CKSQ_40M,   CK_TOP_CB_M_D2,  CK_TOP_CB_NET2_D4,
> > +	CK_TOP_CB_APLL2_196M, CK_TOP_CB_MM_D4, CK_TOP_NET1_D8_D2,
> > +	CK_TOP_CB_MM_D6
> > +};
> > +
> > +static const int emmc_400m_parents[] = { CK_TOP_CB_CKSQ_40M,
> >   CK_TOP_CB_NET2_D2,
> > +					 CK_TOP_CB_MM_D2,
> > CK_TOP_CB_NET2_D2 };
> > +
> > +static const int csw_f26m_parents[] = { CK_TOP_CKSQ_40M_D2,
> > CK_TOP_M_D8_D2
> >   };
> > +
> > +static const int dramc_md32_parents[] = { CK_TOP_CB_CKSQ_40M,
> >   CK_TOP_CB_M_D2,
> > +					  CK_TOP_CB_WEDMCU_208M };
> > +
> > +static const int sysaxi_parents[] = { CK_TOP_CB_CKSQ_40M,
> > CK_TOP_NET1_D8_D2
> >   };
> > +
> > +static const int sysapb_parents[] = { CK_TOP_CB_CKSQ_40M,
> > CK_TOP_M_D3_D2 };
> > +
> > +static const int arm_db_main_parents[] = { CK_TOP_CB_CKSQ_40M,
> > +					   CK_TOP_CB_NET2_D6 };
> > +
> > +static const int ap2cnn_host_parents[] = { CK_TOP_CB_CKSQ_40M,
> > +					   CK_TOP_NET1_D8_D4 };
> > +
> > +static const int netsys_parents[] = { CK_TOP_CB_CKSQ_40M,
> > CK_TOP_CB_MM_D2
> >   };
> > +
> > +static const int netsys_500m_parents[] = { CK_TOP_CB_CKSQ_40M,
> > +					   CK_TOP_CB_NET1_D5 };
> > +
> > +static const int netsys_mcu_parents[] = { CK_TOP_CB_CKSQ_40M,
> >   CK_TOP_CB_MM_720M,
> > +					  CK_TOP_CB_NET1_D4,
> > CK_TOP_CB_NET1_D5,
> > +					  CK_TOP_CB_M_416M };
> > +
> > +static const int netsys_2x_parents[] = { CK_TOP_CB_CKSQ_40M,
> > +					 CK_TOP_CB_NET2_800M,
> > +					 CK_TOP_CB_MM_720M };
> > +
> > +static const int sgm_325m_parents[] = { CK_TOP_CB_CKSQ_40M,
> > +					CK_TOP_CB_SGM_325M };
> > +
> > +static const int sgm_reg_parents[] = { CK_TOP_CB_CKSQ_40M,
> >   CK_TOP_CB_NET2_D4 };
> > +
> > +static const int eip97b_parents[] = { CK_TOP_CB_CKSQ_40M,
> >   CK_TOP_CB_NET1_D5,
> > +				      CK_TOP_CB_M_416M,
> > CK_TOP_CB_MM_D2,
> > +				      CK_TOP_NET1_D5_D2 };
> > +
> > +static const int aud_parents[] = { CK_TOP_CB_CKSQ_40M,
> > CK_TOP_CB_APLL2_196M
> >   };
> > +
> > +static const int a1sys_parents[] = { CK_TOP_CB_CKSQ_40M,
> > CK_TOP_APLL2_D4 };
> > +
> > +static const int aud_l_parents[] = { CK_TOP_CB_CKSQ_40M,
> >   CK_TOP_CB_APLL2_196M,
> > +				     CK_TOP_M_D8_D2 };
> > +
> > +static const int a_tuner_parents[] = { CK_TOP_CB_CKSQ_40M,
> > CK_TOP_APLL2_D4,
> > +				       CK_TOP_M_D8_D2 };
> > +
> > +static const int u2u3_parents[] = { CK_TOP_CB_CKSQ_40M,
> > CK_TOP_M_D8_D2 };
> > +
> > +static const int u2u3_sys_parents[] = { CK_TOP_CB_CKSQ_40M,
> >   CK_TOP_NET1_D5_D4 };
> > +
> > +static const int usb_frmcnt_parents[] = { CK_TOP_CB_CKSQ_40M,
> > +					  CK_TOP_CB_MM_D3_D5 };
> > +
> > +#define TOP_MUX(_id, _name, _parents, _mux_ofs, _mux_set_ofs,
> > _mux_clr_ofs,
> >      \
> > +		_shift, _width, _gate, _upd_ofs,
> > _upd)                         \
> > +	{                                                         
> >              \
> > +		.id = _id, .mux_reg = _mux_ofs, .mux_set_reg =
> > _mux_set_ofs,   \
> > +		.mux_clr_reg = _mux_clr_ofs, .upd_reg =
> > _upd_ofs,              \
> > +		.upd_shift = _upd, .mux_shift =
> > _shift,                        \
> > +		.mux_mask = BIT(_width) - 1, .gate_reg =
> > _mux_ofs,             \
> > +		.gate_shift = _gate, .parent =
> > _parents,                       \
> > +		.num_parents =
> > ARRAY_SIZE(_parents),                           \
> > +		.flags =
> > CLK_MUX_SETCLR_UPD,                                   \
> > +	}
> > +
> > +/* TOPCKGEN MUX_GATE */
> > +static const struct mtk_composite top_muxes[] = {
> > +	TOP_MUX(CK_TOP_NFI1X_SEL, "nfi1x_sel", nfi1x_parents, 0x0,
> > 0x4, 0x8, 0,
> > +		3, 7, 0x1c0, 0),
> > +	TOP_MUX(CK_TOP_SPINFI_SEL, "spinfi_sel", spinfi_parents,
> > 0x0, 0x4, 0x8,
> > +		8, 3, 15, 0x1c0, 1),
> > +	TOP_MUX(CK_TOP_SPI_SEL, "spi_sel", spi_parents, 0x0, 0x4,
> > 0x8, 16, 3,
> > +		23, 0x1c0, 2),
> > +	TOP_MUX(CK_TOP_SPIM_MST_SEL, "spim_mst_sel", spi_parents,
> > 0x0, 0x4, 0x8,
> > +		24, 3, 31, 0x1c0, 3),
> > +	TOP_MUX(CK_TOP_UART_SEL, "uart_sel", uart_parents, 0x10,
> > 0x14, 0x18, 0,
> > +		2, 7, 0x1c0, 4),
> > +	TOP_MUX(CK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x10,
> > 0x14, 0x18, 8, 3,
> > +		15, 0x1c0, 5),
> > +	TOP_MUX(CK_TOP_I2C_SEL, "i2c_sel", i2c_parents, 0x10,
> > 0x14, 0x18, 16, 2,
> > +		23, 0x1c0, 6),
> > +	TOP_MUX(CK_TOP_PEXTP_TL_SEL, "pextp_tl_ck_sel",
> > pextp_tl_ck_parents,
> > +		0x10, 0x14, 0x18, 24, 2, 31, 0x1c0, 7),
> > +	TOP_MUX(CK_TOP_EMMC_208M_SEL, "emmc_208m_sel",
> > emmc_208m_parents, 0x20,
> > +		0x24, 0x28, 0, 3, 7, 0x1c0, 8),
> > +	TOP_MUX(CK_TOP_EMMC_400M_SEL, "emmc_400m_sel",
> > emmc_400m_parents, 0x20,
> > +		0x24, 0x28, 8, 2, 15, 0x1c0, 9),
> > +	TOP_MUX(CK_TOP_F26M_SEL, "csw_f26m_sel", csw_f26m_parents,
> > 0x20, 0x24,
> > +		0x28, 16, 1, 23, 0x1c0, 10),
> > +	TOP_MUX(CK_TOP_DRAMC_SEL, "dramc_sel", csw_f26m_parents,
> > 0x20, 0x24,
> > +		0x28, 24, 1, 31, 0x1c0, 11),
> > +	TOP_MUX(CK_TOP_DRAMC_MD32_SEL, "dramc_md32_sel",
> > dramc_md32_parents,
> > +		0x30, 0x34, 0x38, 0, 2, 7, 0x1c0, 12),
> > +	TOP_MUX(CK_TOP_SYSAXI_SEL, "sysaxi_sel", sysaxi_parents,
> > 0x30, 0x34,
> > +		0x38, 8, 1, 15, 0x1c0, 13),
> > +	TOP_MUX(CK_TOP_SYSAPB_SEL, "sysapb_sel", sysapb_parents,
> > 0x30, 0x34,
> > +		0x38, 16, 1, 23, 0x1c0, 14),
> > +	TOP_MUX(CK_TOP_ARM_DB_MAIN_SEL, "arm_db_main_sel",
> > arm_db_main_parents,
> > +		0x30, 0x34, 0x38, 24, 1, 31, 0x1c0, 15),
> > +	TOP_MUX(CK_TOP_AP2CNN_HOST_SEL, "ap2cnn_host_sel",
> > ap2cnn_host_parents,
> > +		0x40, 0x44, 0x48, 0, 1, 7, 0x1c0, 16),
> > +	TOP_MUX(CK_TOP_NETSYS_SEL, "netsys_sel", netsys_parents,
> > 0x40, 0x44,
> > +		0x48, 8, 1, 15, 0x1c0, 17),
> > +	TOP_MUX(CK_TOP_NETSYS_500M_SEL, "netsys_500m_sel",
> > netsys_500m_parents,
> > +		0x40, 0x44, 0x48, 16, 1, 23, 0x1c0, 18),
> > +	TOP_MUX(CK_TOP_NETSYS_MCU_SEL, "netsys_mcu_sel",
> > netsys_mcu_parents,
> > +		0x40, 0x44, 0x48, 24, 3, 31, 0x1c0, 19),
> > +	TOP_MUX(CK_TOP_NETSYS_2X_SEL, "netsys_2x_sel",
> > netsys_2x_parents, 0x50,
> > +		0x54, 0x58, 0, 2, 7, 0x1c0, 20),
> > +	TOP_MUX(CK_TOP_SGM_325M_SEL, "sgm_325m_sel",
> > sgm_325m_parents, 0x50,
> > +		0x54, 0x58, 8, 1, 15, 0x1c0, 21),
> > +	TOP_MUX(CK_TOP_SGM_REG_SEL, "sgm_reg_sel",
> > sgm_reg_parents, 0x50, 0x54,
> > +		0x58, 16, 1, 23, 0x1c0, 22),
> > +	TOP_MUX(CK_TOP_EIP97B_SEL, "eip97b_sel", eip97b_parents,
> > 0x50, 0x54,
> > +		0x58, 24, 3, 31, 0x1c0, 23),
> > +	TOP_MUX(CK_TOP_USB3_PHY_SEL, "usb3_phy_sel",
> > csw_f26m_parents, 0x60,
> > +		0x64, 0x68, 0, 1, 7, 0x1c0, 24),
> > +	TOP_MUX(CK_TOP_AUD_SEL, "aud_sel", aud_parents, 0x60,
> > 0x64, 0x68, 8, 1,
> > +		15, 0x1c0, 25),
> > +	TOP_MUX(CK_TOP_A1SYS_SEL, "a1sys_sel", a1sys_parents,
> > 0x60, 0x64, 0x68,
> > +		16, 1, 23, 0x1c0, 26),
> > +	TOP_MUX(CK_TOP_AUD_L_SEL, "aud_l_sel", aud_l_parents,
> > 0x60, 0x64, 0x68,
> > +		24, 2, 31, 0x1c0, 27),
> > +	TOP_MUX(CK_TOP_A_TUNER_SEL, "a_tuner_sel",
> > a_tuner_parents, 0x70, 0x74,
> > +		0x78, 0, 2, 7, 0x1c0, 28),
> > +	TOP_MUX(CK_TOP_U2U3_SEL, "u2u3_sel", u2u3_parents, 0x70,
> > 0x74, 0x78, 8,
> > +		1, 15, 0x1c0, 29),
> > +	TOP_MUX(CK_TOP_U2U3_SYS_SEL, "u2u3_sys_sel",
> > u2u3_sys_parents, 0x70,
> > +		0x74, 0x78, 16, 1, 23, 0x1c0, 30),
> > +	TOP_MUX(CK_TOP_U2U3_XHCI_SEL, "u2u3_xhci_sel",
> > u2u3_sys_parents, 0x70,
> > +		0x74, 0x78, 24, 1, 31, 0x1c4, 0),
> > +	TOP_MUX(CK_TOP_USB_FRMCNT_SEL, "usb_frmcnt_sel",
> > usb_frmcnt_parents,
> > +		0x80, 0x84, 0x88, 0, 1, 7, 0x1c4, 1),
> > +};
> > +
> > +/* INFRA FIXED DIV */
> > +static const struct mtk_fixed_factor infra_fixed_divs[] = {
> > +	TOP_FACTOR(CK_INFRA_CK_F26M, "infra_ck_f26m",
> > CK_TOP_F26M_SEL, 1, 1),
> > +	TOP_FACTOR(CK_INFRA_UART, "infra_uart", CK_TOP_UART_SEL,
> > 1, 1),
> > +	TOP_FACTOR(CK_INFRA_ISPI0, "infra_ispi0", CK_TOP_SPI_SEL,
> > 1, 1),
> > +	TOP_FACTOR(CK_INFRA_I2C, "infra_i2c", CK_TOP_I2C_SEL, 1,
> > 1),
> > +	TOP_FACTOR(CK_INFRA_ISPI1, "infra_ispi1",
> > CK_TOP_SPIM_MST_SEL, 1, 1),
> > +	TOP_FACTOR(CK_INFRA_PWM, "infra_pwm", CK_TOP_PWM_SEL, 1,
> > 1),
> > +	TOP_FACTOR(CK_INFRA_66M_MCK, "infra_66m_mck",
> > CK_TOP_SYSAXI_SEL, 1, 2),
> > +	TOP_FACTOR(CK_INFRA_CK_F32K, "infra_ck_f32k",
> > CK_TOP_CB_RTC_32P7K, 1,
> > +		   1),
> > +	TOP_FACTOR(CK_INFRA_PCIE_CK, "infra_pcie",
> > CK_TOP_PEXTP_TL_SEL, 1, 1),
> > +	INFRA_FACTOR(CK_INFRA_PWM_BCK, "infra_pwm_bck",
> > CK_INFRA_PWM_BSEL, 1,
> > +		     1),
> > +	INFRA_FACTOR(CK_INFRA_PWM_CK1, "infra_pwm_ck1",
> > CK_INFRA_PWM1_SEL, 1,
> > +		     1),
> > +	INFRA_FACTOR(CK_INFRA_PWM_CK2, "infra_pwm_ck2",
> > CK_INFRA_PWM2_SEL, 1,
> > +		     1),
> > +	TOP_FACTOR(CK_INFRA_133M_HCK, "infra_133m_hck",
> > CK_TOP_SYSAXI, 1, 1),
> > +	INFRA_FACTOR(CK_INFRA_66M_PHCK, "infra_66m_phck",
> > CK_INFRA_133M_HCK, 1,
> > +		     1),
> > +	TOP_FACTOR(CK_INFRA_FAUD_L_CK, "infra_faud_l",
> > CK_TOP_AUD_L, 1, 1),
> > +	TOP_FACTOR(CK_INFRA_FAUD_AUD_CK, "infra_faud_aud",
> > CK_TOP_A1SYS, 1, 1),
> > +	TOP_FACTOR(CK_INFRA_FAUD_EG2_CK, "infra_faud_eg2",
> > CK_TOP_A_TUNER, 1,
> > +		   1),
> > +	TOP_FACTOR(CK_INFRA_I2CS_CK, "infra_i2cs", CK_TOP_I2C_BCK,
> > 1, 1),
> > +	INFRA_FACTOR(CK_INFRA_MUX_UART0, "infra_mux_uart0",
> > CK_INFRA_UART0_SEL,
> > +		     1, 1),
> > +	INFRA_FACTOR(CK_INFRA_MUX_UART1, "infra_mux_uart1",
> > CK_INFRA_UART1_SEL,
> > +		     1, 1),
> > +	INFRA_FACTOR(CK_INFRA_MUX_UART2, "infra_mux_uart2",
> > CK_INFRA_UART2_SEL,
> > +		     1, 1),
> > +	TOP_FACTOR(CK_INFRA_NFI_CK, "infra_nfi", CK_TOP_NFI1X, 1,
> > 1),
> > +	TOP_FACTOR(CK_INFRA_SPINFI_CK, "infra_spinfi",
> > CK_TOP_SPINFI_BCK, 1, 1),
> > +	INFRA_FACTOR(CK_INFRA_MUX_SPI0, "infra_mux_spi0",
> > CK_INFRA_SPI0_SEL, 1,
> > +		     1),
> > +	INFRA_FACTOR(CK_INFRA_MUX_SPI1, "infra_mux_spi1",
> > CK_INFRA_SPI1_SEL, 1,
> > +		     1),
> > +	INFRA_FACTOR(CK_INFRA_MUX_SPI2, "infra_mux_spi2",
> > CK_INFRA_SPI2_SEL, 1,
> > +		     1),
> > +	TOP_FACTOR(CK_INFRA_RTC_32K, "infra_rtc_32k",
> > CK_TOP_CB_RTC_32K, 1, 1),
> > +	TOP_FACTOR(CK_INFRA_FMSDC_CK, "infra_fmsdc",
> > CK_TOP_EMMC_400M, 1, 1),
> > +	TOP_FACTOR(CK_INFRA_FMSDC_HCK_CK, "infra_fmsdc_hck",
> > CK_TOP_EMMC_208M,
> > +		   1, 1),
> > +	TOP_FACTOR(CK_INFRA_PERI_133M, "infra_peri_133m",
> > CK_TOP_SYSAXI, 1, 1),
> > +	TOP_FACTOR(CK_INFRA_133M_PHCK, "infra_133m_phck",
> > CK_TOP_SYSAXI, 1, 1),
> > +	TOP_FACTOR(CK_INFRA_USB_SYS_CK, "infra_usb_sys",
> > CK_TOP_U2U3_SYS, 1, 1),
> > +	TOP_FACTOR(CK_INFRA_USB_CK, "infra_usb", CK_TOP_U2U3_REF,
> > 1, 1),
> > +	TOP_FACTOR(CK_INFRA_USB_XHCI_CK, "infra_usb_xhci",
> > CK_TOP_U2U3_XHCI, 1,
> > +		   1),
> > +	TOP_FACTOR(CK_INFRA_PCIE_GFMUX_TL_O_PRE, "infra_pcie_mux",
> > +		   CK_TOP_PEXTP_TL, 1, 1),
> > +	TOP_FACTOR(CK_INFRA_F26M_CK0, "infra_f26m_ck0",
> > CK_TOP_F26M, 1, 1),
> > +	TOP_FACTOR(CK_INFRA_133M_MCK, "infra_133m_mck",
> > CK_TOP_SYSAXI, 1, 1),
> > +};
> > +
> > +/* INFRASYS MUX PARENTS */
> > +static const int infra_uart0_parents[] = { CK_INFRA_CK_F26M,
> > CK_INFRA_UART
> >   };
> > +
> > +static const int infra_spi0_parents[] = { CK_INFRA_I2C,
> > CK_INFRA_ISPI0 };
> > +
> > +static const int infra_spi1_parents[] = { CK_INFRA_I2C,
> > CK_INFRA_ISPI1 };
> > +
> > +static const int infra_pwm1_parents[] = { -1, -1, -1, CK_INFRA_PWM
> > };
> > +
> > +static const int infra_pwm_bsel_parents[] = { -1, -1, -1,
> > CK_INFRA_PWM };
> > +
> > +static const int infra_pcie_parents[] = { CK_INFRA_CK_F32K,
> >   CK_INFRA_CK_F26M,
> > +					  CK_TOP_CB_CKSQ_40M,
> > CK_INFRA_PCIE_CK};
> > +
> > +#define INFRA_MUX(_id, _name, _parents, _reg, _shift, _width)
> >      \
> > +	{                                                         
> >              \
> > +		.id = _id, .mux_reg = (_reg) +
> > 0x8,                            \
> > +		.mux_set_reg = (_reg) + 0x0, .mux_clr_reg = (_reg)
> > + 0x4,      \
> > +		.mux_shift = _shift, .mux_mask = BIT(_width) -
> > 1,              \
> > +		.parent = _parents, .num_parents =
> > ARRAY_SIZE(_parents),       \
> > +		.flags = CLK_MUX_SETCLR_UPD |
> > CLK_PARENT_INFRASYS,             \
> > +	}
> > +
> > +/* INFRA MUX */
> > +static const struct mtk_composite infra_muxes[] = {
> > +	INFRA_MUX(CK_INFRA_UART0_SEL, "infra_uart0_sel",
> > infra_uart0_parents,
> > +		  0x10, 0, 1),
> > +	INFRA_MUX(CK_INFRA_UART1_SEL, "infra_uart1_sel",
> > infra_uart0_parents,
> > +		  0x10, 1, 1),
> > +	INFRA_MUX(CK_INFRA_UART2_SEL, "infra_uart2_sel",
> > infra_uart0_parents,
> > +		  0x10, 2, 1),
> > +	INFRA_MUX(CK_INFRA_SPI0_SEL, "infra_spi0_sel",
> > infra_spi0_parents, 0x10,
> > +		  4, 1),
> > +	INFRA_MUX(CK_INFRA_SPI1_SEL, "infra_spi1_sel",
> > infra_spi1_parents, 0x10,
> > +		  5, 1),
> > +	INFRA_MUX(CK_INFRA_SPI2_SEL, "infra_spi2_sel",
> > infra_spi0_parents, 0x10,
> > +		  6, 1),
> > +	INFRA_MUX(CK_INFRA_PWM1_SEL, "infra_pwm1_sel",
> > infra_pwm1_parents, 0x10,
> > +		  9, 2),
> > +	INFRA_MUX(CK_INFRA_PWM2_SEL, "infra_pwm2_sel",
> > infra_pwm1_parents, 0x10,
> > +		  11, 2),
> > +	INFRA_MUX(CK_INFRA_PWM_BSEL, "infra_pwm_bsel",
> > infra_pwm_bsel_parents,
> > +		  0x10, 13, 2),
> > +	INFRA_MUX(CK_INFRA_PCIE_SEL, "infra_pcie_sel",
> > infra_pcie_parents, 0x20,
> > +		  0, 2),
> > +};
> > +
> > +static const struct mtk_gate_regs infra_0_cg_regs = {
> > +	.set_ofs = 0x40,
> > +	.clr_ofs = 0x44,
> > +	.sta_ofs = 0x48,
> > +};
> > +
> > +static const struct mtk_gate_regs infra_1_cg_regs = {
> > +	.set_ofs = 0x50,
> > +	.clr_ofs = 0x54,
> > +	.sta_ofs = 0x58,
> > +};
> > +
> > +static const struct mtk_gate_regs infra_2_cg_regs = {
> > +	.set_ofs = 0x60,
> > +	.clr_ofs = 0x64,
> > +	.sta_ofs = 0x68,
> > +};
> > +
> > +#define GATE_INFRA0(_id, _name, _parent, _shift)
> >      \
> > +	{                                                         
> >              \
> > +		.id = _id, .parent = _parent, .regs =
> > &infra_0_cg_regs,        \
> > +		.shift =
> > _shift,                                               \
> > +		.flags = CLK_GATE_SETCLR |
> > CLK_PARENT_INFRASYS,                \
> > +	}
> > +
> > +#define GATE_INFRA1(_id, _name, _parent, _shift)
> >      \
> > +	{                                                         
> >              \
> > +		.id = _id, .parent = _parent, .regs =
> > &infra_1_cg_regs,        \
> > +		.shift =
> > _shift,                                               \
> > +		.flags = CLK_GATE_SETCLR |
> > CLK_PARENT_INFRASYS,                \
> > +	}
> > +
> > +#define GATE_INFRA2(_id, _name, _parent, _shift)
> >      \
> > +	{                                                         
> >              \
> > +		.id = _id, .parent = _parent, .regs =
> > &infra_2_cg_regs,        \
> > +		.shift =
> > _shift,                                               \
> > +		.flags = CLK_GATE_SETCLR |
> > CLK_PARENT_INFRASYS,                \
> > +	}
> > +
> > +/* INFRA GATE */
> > +static const struct mtk_gate infracfg_ao_gates[] = {
> > +	GATE_INFRA0(CK_INFRA_GPT_STA, "infra_gpt_sta",
> > CK_INFRA_66M_MCK, 0),
> > +	GATE_INFRA0(CK_INFRA_PWM_HCK, "infra_pwm_hck",
> > CK_INFRA_66M_MCK, 1),
> > +	GATE_INFRA0(CK_INFRA_PWM_STA, "infra_pwm_sta",
> > CK_INFRA_PWM_BCK, 2),
> > +	GATE_INFRA0(CK_INFRA_PWM1_CK, "infra_pwm1",
> > CK_INFRA_PWM_CK1, 3),
> > +	GATE_INFRA0(CK_INFRA_PWM2_CK, "infra_pwm2",
> > CK_INFRA_PWM_CK2, 4),
> > +	GATE_INFRA0(CK_INFRA_CQ_DMA_CK, "infra_cq_dma",
> > CK_INFRA_133M_HCK, 6),
> > +	GATE_INFRA0(CK_INFRA_AUD_BUS_CK, "infra_aud_bus",
> > CK_INFRA_66M_PHCK, 8),
> > +	GATE_INFRA0(CK_INFRA_AUD_26M_CK, "infra_aud_26m",
> > CK_INFRA_CK_F26M, 9),
> > +	GATE_INFRA0(CK_INFRA_AUD_L_CK, "infra_aud_l",
> > CK_INFRA_FAUD_L_CK, 10),
> > +	GATE_INFRA0(CK_INFRA_AUD_AUD_CK, "infra_aud_aud",
> > CK_INFRA_FAUD_AUD_CK,
> > +		    11),
> > +	GATE_INFRA0(CK_INFRA_AUD_EG2_CK, "infra_aud_eg2",
> > CK_INFRA_FAUD_EG2_CK,
> > +		    13),
> > +	GATE_INFRA0(CK_INFRA_DRAMC_26M_CK, "infra_dramc_26m",
> > CK_INFRA_CK_F26M,
> > +		    14),
> > +	GATE_INFRA0(CK_INFRA_DBG_CK, "infra_dbg",
> > CK_INFRA_66M_MCK, 15),
> > +	GATE_INFRA0(CK_INFRA_AP_DMA_CK, "infra_ap_dma",
> > CK_INFRA_66M_MCK, 16),
> > +	GATE_INFRA0(CK_INFRA_SEJ_CK, "infra_sej",
> > CK_INFRA_66M_MCK, 24),
> > +	GATE_INFRA0(CK_INFRA_SEJ_13M_CK, "infra_sej_13m",
> > CK_INFRA_CK_F26M, 25),
> > +	GATE_INFRA1(CK_INFRA_THERM_CK, "infra_therm",
> > CK_INFRA_CK_F26M, 0),
> > +	GATE_INFRA1(CK_INFRA_I2CO_CK, "infra_i2co",
> > CK_INFRA_I2CS_CK, 1),
> > +	GATE_INFRA1(CK_INFRA_UART0_CK, "infra_uart0",
> > CK_INFRA_MUX_UART0, 2),
> > +	GATE_INFRA1(CK_INFRA_UART1_CK, "infra_uart1",
> > CK_INFRA_MUX_UART1, 3),
> > +	GATE_INFRA1(CK_INFRA_UART2_CK, "infra_uart2",
> > CK_INFRA_MUX_UART2, 4),
> > +	GATE_INFRA1(CK_INFRA_SPI2_CK, "infra_spi2",
> > CK_INFRA_MUX_SPI2, 6),
> > +	GATE_INFRA1(CK_INFRA_SPI2_HCK_CK, "infra_spi2_hck",
> > CK_INFRA_66M_MCK,
> > +		    7),
> > +	GATE_INFRA1(CK_INFRA_NFI1_CK, "infra_nfi1",
> > CK_INFRA_NFI_CK, 8),
> > +	GATE_INFRA1(CK_INFRA_SPINFI1_CK, "infra_spinfi1",
> > CK_INFRA_SPINFI_CK,
> > +		    9),
> > +	GATE_INFRA1(CK_INFRA_NFI_HCK_CK, "infra_nfi_hck",
> > CK_INFRA_66M_MCK, 10),
> > +	GATE_INFRA1(CK_INFRA_SPI0_CK, "infra_spi0",
> > CK_INFRA_MUX_SPI0, 11),
> > +	GATE_INFRA1(CK_INFRA_SPI1_CK, "infra_spi1",
> > CK_INFRA_MUX_SPI1, 12),
> > +	GATE_INFRA1(CK_INFRA_SPI0_HCK_CK, "infra_spi0_hck",
> > CK_INFRA_66M_MCK,
> > +		    13),
> > +	GATE_INFRA1(CK_INFRA_SPI1_HCK_CK, "infra_spi1_hck",
> > CK_INFRA_66M_MCK,
> > +		    14),
> > +	GATE_INFRA1(CK_INFRA_FRTC_CK, "infra_frtc",
> > CK_INFRA_RTC_32K, 15),
> > +	GATE_INFRA1(CK_INFRA_MSDC_CK, "infra_msdc",
> > CK_INFRA_FMSDC_CK, 16),
> > +	GATE_INFRA1(CK_INFRA_MSDC_HCK_CK, "infra_msdc_hck",
> > +		    CK_INFRA_FMSDC_HCK_CK, 17),
> > +	GATE_INFRA1(CK_INFRA_MSDC_133M_CK, "infra_msdc_133m",
> > +		    CK_INFRA_PERI_133M, 18),
> > +	GATE_INFRA1(CK_INFRA_MSDC_66M_CK, "infra_msdc_66m",
> > CK_INFRA_66M_PHCK,
> > +		    19),
> > +	GATE_INFRA1(CK_INFRA_ADC_26M_CK, "infra_adc_26m",
> > CK_TOP_F26M, 20),
> > +	GATE_INFRA1(CK_INFRA_ADC_FRC_CK, "infra_adc_frc",
> > CK_TOP_F26M, 21),
> > +	GATE_INFRA1(CK_INFRA_FBIST2FPC_CK, "infra_fbist2fpc",
> > CK_INFRA_NFI_CK,
> > +		    23),
> > +	GATE_INFRA1(CK_INFRA_I2C_MCK_CK, "infra_i2c_mck",
> > CK_INFRA_133M_MCK,
> > +		    25),
> > +	GATE_INFRA1(CK_INFRA_I2C_PCK_CK, "infra_i2c_pck",
> > CK_INFRA_66M_MCK, 26),
> > +	GATE_INFRA2(CK_INFRA_IUSB_133_CK, "infra_iusb_133",
> > CK_INFRA_133M_PHCK,
> > +		    0),
> > +	GATE_INFRA2(CK_INFRA_IUSB_66M_CK, "infra_iusb_66m",
> > CK_INFRA_66M_PHCK,
> > +		    1),
> > +	GATE_INFRA2(CK_INFRA_IUSB_SYS_CK, "infra_iusb_sys",
> > CK_INFRA_USB_SYS_CK,
> > +		    2),
> > +	GATE_INFRA2(CK_INFRA_IUSB_CK, "infra_iusb",
> > CK_INFRA_USB_CK, 3),
> > +	GATE_INFRA2(CK_INFRA_IPCIE_CK, "infra_ipcie",
> > +		    CK_INFRA_PCIE_GFMUX_TL_O_PRE, 12),
> > +	GATE_INFRA2(CK_INFRA_IPCIER_CK, "infra_ipcier",
> > CK_INFRA_F26M_CK0, 14),
> > +	GATE_INFRA2(CK_INFRA_IPCIEB_CK, "infra_ipcieb",
> > CK_INFRA_133M_PHCK, 15),
> > +};
> > +
> > +static const struct mtk_clk_tree mt7981_fixed_pll_clk_tree = {
> > +	.fdivs_offs = CLK_APMIXED_NR_CLK,
> > +	.xtal_rate = 40 * MHZ,
> > +	.fclks = fixed_pll_clks,
> > +};
> > +
> > +static const struct mtk_clk_tree mt7981_topckgen_clk_tree = {
> > +	.fdivs_offs = CK_TOP_CB_M_416M,
> > +	.muxes_offs = CK_TOP_NFI1X_SEL,
> > +	.fclks = top_fixed_clks,
> > +	.fdivs = top_fixed_divs,
> > +	.muxes = top_muxes,
> > +	.flags = CLK_BYPASS_XTAL,
> > +};
> > +
> > +static const struct mtk_clk_tree mt7981_infracfg_clk_tree = {
> > +	.fdivs_offs = CK_INFRA_CK_F26M,
> > +	.muxes_offs = CK_INFRA_UART0_SEL,
> > +	.fdivs = infra_fixed_divs,
> > +	.muxes = infra_muxes,
> > +};
> > +
> > +static const struct udevice_id mt7981_fixed_pll_compat[] = {
> > +	{ .compatible = "mediatek,mt7981-fixed-plls" },
> > +	{}
> > +};
> > +
> > +static const struct udevice_id mt7981_topckgen_compat[] = {
> > +	{ .compatible = "mediatek,mt7981-topckgen" },
> > +	{}
> > +};
> > +
> > +static int mt7981_fixed_pll_probe(struct udevice *dev)
> > +{
> > +	return mtk_common_clk_init(dev,
> > &mt7981_fixed_pll_clk_tree);
> > +}
> > +
> > +static int mt7981_topckgen_probe(struct udevice *dev)
> > +{
> > +	struct mtk_clk_priv *priv = dev_get_priv(dev);
> > +
> > +	priv->base = dev_read_addr_ptr(dev);
> > +	writel(MT7981_CLK_PDN_EN_WRITE, priv->base +
> > MT7981_CLK_PDN);
> > +	return mtk_common_clk_init(dev,
> > &mt7981_topckgen_clk_tree);
> > +}
> > +
> > +U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
> > +	.name = "mt7981-clock-fixed-pll",
> > +	.id = UCLASS_CLK,
> > +	.of_match = mt7981_fixed_pll_compat,
> > +	.probe = mt7981_fixed_pll_probe,
> > +	.priv_auto = sizeof(struct mtk_clk_priv),
> > +	.ops = &mtk_clk_topckgen_ops,
> > +	.flags = DM_FLAG_PRE_RELOC,
> > +};
> > +
> > +U_BOOT_DRIVER(mtk_clk_topckgen) = {
> > +	.name = "mt7981-clock-topckgen",
> > +	.id = UCLASS_CLK,
> > +	.of_match = mt7981_topckgen_compat,
> > +	.probe = mt7981_topckgen_probe,
> > +	.priv_auto = sizeof(struct mtk_clk_priv),
> > +	.ops = &mtk_clk_topckgen_ops,
> > +	.flags = DM_FLAG_PRE_RELOC,
> > +};
> > +
> > +static const struct udevice_id mt7981_infracfg_compat[] = {
> > +	{ .compatible = "mediatek,mt7981-infracfg" },
> > +	{}
> > +};
> > +
> > +static const struct udevice_id mt7981_infracfg_ao_compat[] = {
> > +	{ .compatible = "mediatek,mt7981-infracfg_ao" },
> > +	{}
> > +};
> > +
> > +static int mt7981_infracfg_probe(struct udevice *dev)
> > +{
> > +	return mtk_common_clk_init(dev,
> > &mt7981_infracfg_clk_tree);
> > +}
> > +
> > +static int mt7981_infracfg_ao_probe(struct udevice *dev)
> > +{
> > +	return mtk_common_clk_gate_init(dev,
> > &mt7981_infracfg_clk_tree,
> > +					infracfg_ao_gates);
> > +}
> > +
> > +U_BOOT_DRIVER(mtk_clk_infracfg) = {
> > +	.name = "mt7981-clock-infracfg",
> > +	.id = UCLASS_CLK,
> > +	.of_match = mt7981_infracfg_compat,
> > +	.probe = mt7981_infracfg_probe,
> > +	.priv_auto = sizeof(struct mtk_clk_priv),
> > +	.ops = &mtk_clk_infrasys_ops,
> > +	.flags = DM_FLAG_PRE_RELOC,
> > +};
> > +
> > +U_BOOT_DRIVER(mtk_clk_infracfg_ao) = {
> > +	.name = "mt7981-clock-infracfg-ao",
> > +	.id = UCLASS_CLK,
> > +	.of_match = mt7981_infracfg_ao_compat,
> > +	.probe = mt7981_infracfg_ao_probe,
> > +	.priv_auto = sizeof(struct mtk_cg_priv),
> > +	.ops = &mtk_clk_gate_ops,
> > +	.flags = DM_FLAG_PRE_RELOC,
> > +};
> > +
> > +/* ethsys */
> > +static const struct mtk_gate_regs eth_cg_regs = {
> > +	.set_ofs = 0x30,
> > +	.clr_ofs = 0x30,
> > +	.sta_ofs = 0x30,
> > +};
> > +
> > +#define GATE_ETH(_id, _name, _parent, _shift)
> >      \
> > +	{                                                         
> >              \
> > +		.id = _id, .parent = _parent, .regs =
> > &eth_cg_regs,            \
> > +		.shift =
> > _shift,                                               \
> > +		.flags = CLK_GATE_NO_SETCLR_INV |
> > CLK_PARENT_TOPCKGEN,         \
> > +	}
> > +
> > +static const struct mtk_gate eth_cgs[] = {
> > +	GATE_ETH(CK_ETH_FE_EN, "eth_fe_en", CK_TOP_NETSYS_2X, 6),
> > +	GATE_ETH(CK_ETH_GP2_EN, "eth_gp2_en", CK_TOP_SGM_325M, 7),
> > +	GATE_ETH(CK_ETH_GP1_EN, "eth_gp1_en", CK_TOP_SGM_325M, 8),
> > +	GATE_ETH(CK_ETH_WOCPU0_EN, "eth_wocpu0_en",
> > CK_TOP_NETSYS_WED_MCU, 15),
> > +};
> > +
> > +static int mt7981_ethsys_probe(struct udevice *dev)
> > +{
> > +	return mtk_common_clk_gate_init(dev,
> > &mt7981_topckgen_clk_tree,
> > +					eth_cgs);
> > +}
> > +
> > +static int mt7981_ethsys_bind(struct udevice *dev)
> > +{
> > +	int ret = 0;
> > +
> > +#if CONFIG_IS_ENABLED(RESET_MEDIATEK)
> > +	ret = mediatek_reset_bind(dev, ETHSYS_HIFSYS_RST_CTRL_OFS,
> > 1);
> > +	if (ret)
> > +		debug("Warning: failed to bind reset
> > controller\n");
> > +#endif
> > +
> > +	return ret;
> > +}
> > +
> > +static const struct udevice_id mt7981_ethsys_compat[] = {
> > +	{ .compatible = "mediatek,mt7981-ethsys", },
> > +	{}
> > +};
> > +
> > +U_BOOT_DRIVER(mtk_clk_ethsys) = {
> > +	.name = "mt7981-clock-ethsys",
> > +	.id = UCLASS_CLK,
> > +	.of_match = mt7981_ethsys_compat,
> > +	.probe = mt7981_ethsys_probe,
> > +	.bind = mt7981_ethsys_bind,
> > +	.priv_auto = sizeof(struct mtk_cg_priv),
> > +	.ops = &mtk_clk_gate_ops,
> > +};
> > diff --git a/include/dt-bindings/clock/mt7981-clk.h
> >   b/include/dt-bindings/clock/mt7981-clk.h
> > new file mode 100644
> > index 0000000000..e24c759e49
> > --- /dev/null
> > +++ b/include/dt-bindings/clock/mt7981-clk.h
> > @@ -0,0 +1,267 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
> > + *
> > + * Author: Sam Shih <sam.shih@mediatek.com>
> > + */
> > +
> > +#ifndef _DT_BINDINGS_CLK_MT7981_H
> > +#define _DT_BINDINGS_CLK_MT7981_H
> > +
> > +/* INFRACFG */
> > +
> > +#define CK_INFRA_CK_F26M		0
> > +#define CK_INFRA_UART			1
> > +#define CK_INFRA_ISPI0			2
> > +#define CK_INFRA_I2C			3
> > +#define CK_INFRA_ISPI1			4
> > +#define CK_INFRA_PWM			5
> > +#define CK_INFRA_66M_MCK		6
> > +#define CK_INFRA_CK_F32K		7
> > +#define CK_INFRA_PCIE_CK		8
> > +#define CK_INFRA_PWM_BCK		9
> > +#define CK_INFRA_PWM_CK1		10
> > +#define CK_INFRA_PWM_CK2		11
> > +#define CK_INFRA_133M_HCK		12
> > +#define CK_INFRA_66M_PHCK		13
> > +#define CK_INFRA_FAUD_L_CK		14
> > +#define CK_INFRA_FAUD_AUD_CK		15
> > +#define CK_INFRA_FAUD_EG2_CK		16
> > +#define CK_INFRA_I2CS_CK		17
> > +#define CK_INFRA_MUX_UART0		18
> > +#define CK_INFRA_MUX_UART1		19
> > +#define CK_INFRA_MUX_UART2		20
> > +#define CK_INFRA_NFI_CK			21
> > +#define CK_INFRA_SPINFI_CK		22
> > +#define CK_INFRA_MUX_SPI0		23
> > +#define CK_INFRA_MUX_SPI1		24
> > +#define CK_INFRA_MUX_SPI2		25
> > +#define CK_INFRA_RTC_32K		26
> > +#define CK_INFRA_FMSDC_CK		27
> > +#define CK_INFRA_FMSDC_HCK_CK		28
> > +#define CK_INFRA_PERI_133M		29
> > +#define CK_INFRA_133M_PHCK		30
> > +#define CK_INFRA_USB_SYS_CK		31
> > +#define CK_INFRA_USB_CK			32
> > +#define CK_INFRA_USB_XHCI_CK		33
> > +#define CK_INFRA_PCIE_GFMUX_TL_O_PRE	34
> > +#define CK_INFRA_F26M_CK0		35
> > +#define CK_INFRA_133M_MCK		36
> > +#define CLK_INFRA_NR_CLK		37
> > +
> > +/* TOPCKGEN */
> > +
> > +#define CK_TOP_CB_CKSQ_40M		0
> > +#define CK_TOP_CB_M_416M		1
> > +#define CK_TOP_CB_M_D2			2
> > +#define CK_TOP_CB_M_D3			3
> > +#define CK_TOP_M_D3_D2			4
> > +#define CK_TOP_CB_M_D4			5
> > +#define CK_TOP_CB_M_D8			6
> > +#define CK_TOP_M_D8_D2			7
> > +#define CK_TOP_CB_MM_720M		8
> > +#define CK_TOP_CB_MM_D2			9
> > +#define CK_TOP_CB_MM_D3			10
> > +#define CK_TOP_CB_MM_D3_D5		11
> > +#define CK_TOP_CB_MM_D4			12
> > +#define CK_TOP_CB_MM_D6			13
> > +#define CK_TOP_MM_D6_D2			14
> > +#define CK_TOP_CB_MM_D8			15
> > +#define CK_TOP_CB_APLL2_196M		16
> > +#define CK_TOP_APLL2_D2			17
> > +#define CK_TOP_APLL2_D4			18
> > +#define CK_TOP_NET1_2500M		19
> > +#define CK_TOP_CB_NET1_D4		20
> > +#define CK_TOP_CB_NET1_D5		21
> > +#define CK_TOP_NET1_D5_D2		22
> > +#define CK_TOP_NET1_D5_D4		23
> > +#define CK_TOP_CB_NET1_D8		24
> > +#define CK_TOP_NET1_D8_D2		25
> > +#define CK_TOP_NET1_D8_D4		26
> > +#define CK_TOP_CB_NET2_800M		27
> > +#define CK_TOP_CB_NET2_D2		28
> > +#define CK_TOP_CB_NET2_D4		29
> > +#define CK_TOP_NET2_D4_D2		30
> > +#define CK_TOP_NET2_D4_D4		31
> > +#define CK_TOP_CB_NET2_D6		32
> > +#define CK_TOP_CB_WEDMCU_208M		33
> > +#define CK_TOP_CB_SGM_325M		34
> > +#define CK_TOP_CKSQ_40M_D2		35
> > +#define CK_TOP_CB_RTC_32K		36
> > +#define CK_TOP_CB_RTC_32P7K		37
> > +#define CK_TOP_USB_TX250M		38
> > +#define CK_TOP_FAUD			39
> > +#define CK_TOP_NFI1X			40
> > +#define CK_TOP_USB_EQ_RX250M		41
> > +#define CK_TOP_USB_CDR_CK		42
> > +#define CK_TOP_USB_LN0_CK		43
> > +#define CK_TOP_SPINFI_BCK		44
> > +#define CK_TOP_SPI			45
> > +#define CK_TOP_SPIM_MST			46
> > +#define CK_TOP_UART_BCK			47
> > +#define CK_TOP_PWM_BCK			48
> > +#define CK_TOP_I2C_BCK			49
> > +#define CK_TOP_PEXTP_TL			50
> > +#define CK_TOP_EMMC_208M		51
> > +#define CK_TOP_EMMC_400M		52
> > +#define CK_TOP_DRAMC_REF		53
> > +#define CK_TOP_DRAMC_MD32		54
> > +#define CK_TOP_SYSAXI			55
> > +#define CK_TOP_SYSAPB			56
> > +#define CK_TOP_ARM_DB_MAIN		57
> > +#define CK_TOP_AP2CNN_HOST		58
> > +#define CK_TOP_NETSYS			59
> > +#define CK_TOP_NETSYS_500M		60
> > +#define CK_TOP_NETSYS_WED_MCU		61
> > +#define CK_TOP_NETSYS_2X		62
> > +#define CK_TOP_SGM_325M			63
> > +#define CK_TOP_SGM_REG			64
> > +#define CK_TOP_F26M			65
> > +#define CK_TOP_EIP97B			66
> > +#define CK_TOP_USB3_PHY			67
> > +#define CK_TOP_AUD			68
> > +#define CK_TOP_A1SYS			69
> > +#define CK_TOP_AUD_L			70
> > +#define CK_TOP_A_TUNER			71
> > +#define CK_TOP_U2U3_REF			72
> > +#define CK_TOP_U2U3_SYS			73
> > +#define CK_TOP_U2U3_XHCI		74
> > +#define CK_TOP_USB_FRMCNT		75
> > +#define CK_TOP_NFI1X_SEL		76
> > +#define CK_TOP_SPINFI_SEL		77
> > +#define CK_TOP_SPI_SEL			78
> > +#define CK_TOP_SPIM_MST_SEL		79
> > +#define CK_TOP_UART_SEL			80
> > +#define CK_TOP_PWM_SEL			81
> > +#define CK_TOP_I2C_SEL			82
> > +#define CK_TOP_PEXTP_TL_SEL		83
> > +#define CK_TOP_EMMC_208M_SEL		84
> > +#define CK_TOP_EMMC_400M_SEL		85
> > +#define CK_TOP_F26M_SEL			86
> > +#define CK_TOP_DRAMC_SEL		87
> > +#define CK_TOP_DRAMC_MD32_SEL		88
> > +#define CK_TOP_SYSAXI_SEL		89
> > +#define CK_TOP_SYSAPB_SEL		90
> > +#define CK_TOP_ARM_DB_MAIN_SEL		91
> > +#define CK_TOP_AP2CNN_HOST_SEL		92
> > +#define CK_TOP_NETSYS_SEL		93
> > +#define CK_TOP_NETSYS_500M_SEL		94
> > +#define CK_TOP_NETSYS_MCU_SEL		95
> > +#define CK_TOP_NETSYS_2X_SEL		96
> > +#define CK_TOP_SGM_325M_SEL		97
> > +#define CK_TOP_SGM_REG_SEL		98
> > +#define CK_TOP_EIP97B_SEL		99
> > +#define CK_TOP_USB3_PHY_SEL		100
> > +#define CK_TOP_AUD_SEL			101
> > +#define CK_TOP_A1SYS_SEL		102
> > +#define CK_TOP_AUD_L_SEL		103
> > +#define CK_TOP_A_TUNER_SEL		104
> > +#define CK_TOP_U2U3_SEL			105
> > +#define CK_TOP_U2U3_SYS_SEL		106
> > +#define CK_TOP_U2U3_XHCI_SEL		107
> > +#define CK_TOP_USB_FRMCNT_SEL		108
> > +#define CLK_TOP_NR_CLK			109
> > +
> > +/*
> > + * INFRACFG_AO
> > + * clock muxes need to be append to infracfg domain, and clock
> > gates
> > + * need to be keep in infracgh_ao domain
> > + */
> > +#define INFRACFG_AO_OFFSET		10
> > +
> > +#define CK_INFRA_UART0_SEL		(0 + CLK_INFRA_NR_CLK)
> > +#define CK_INFRA_UART1_SEL		(1 + CLK_INFRA_NR_CLK)
> > +#define CK_INFRA_UART2_SEL		(2 + CLK_INFRA_NR_CLK)
> > +#define CK_INFRA_SPI0_SEL		(3 + CLK_INFRA_NR_CLK)
> > +#define CK_INFRA_SPI1_SEL		(4 + CLK_INFRA_NR_CLK)
> > +#define CK_INFRA_SPI2_SEL		(5 + CLK_INFRA_NR_CLK)
> > +#define CK_INFRA_PWM1_SEL		(6 + CLK_INFRA_NR_CLK)
> > +#define CK_INFRA_PWM2_SEL		(7 + CLK_INFRA_NR_CLK)
> > +#define CK_INFRA_PWM_BSEL		(8 + CLK_INFRA_NR_CLK)
> > +#define CK_INFRA_PCIE_SEL		(9 + CLK_INFRA_NR_CLK)
> > +#define CK_INFRA_GPT_STA		(10 - INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_PWM_HCK		(11 - INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_PWM_STA		(12 - INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_PWM1_CK		(13 - INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_PWM2_CK		(14 - INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_CQ_DMA_CK		(15 -
> > INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_AUD_BUS_CK		(16 -
> > INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_AUD_26M_CK		(17 -
> > INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_AUD_L_CK		(18 - INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_AUD_AUD_CK		(19 -
> > INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_AUD_EG2_CK		(20 -
> > INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_DRAMC_26M_CK		(21 -
> > INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_DBG_CK			(22 -
> > INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_AP_DMA_CK		(23 -
> > INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_SEJ_CK			(24 -
> > INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_SEJ_13M_CK		(25 -
> > INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_THERM_CK		(26 - INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_I2CO_CK		(27 - INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_UART0_CK		(28 - INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_UART1_CK		(29 - INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_UART2_CK		(30 - INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_SPI2_CK		(31 - INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_SPI2_HCK_CK		(32 -
> > INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_NFI1_CK		(33 - INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_SPINFI1_CK		(34 -
> > INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_NFI_HCK_CK		(35 -
> > INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_SPI0_CK		(36 - INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_SPI1_CK		(37 - INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_SPI0_HCK_CK		(38 -
> > INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_SPI1_HCK_CK		(39 -
> > INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_FRTC_CK		(40 - INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_MSDC_CK		(41 - INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_MSDC_HCK_CK		(42 -
> > INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_MSDC_133M_CK		(43 -
> > INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_MSDC_66M_CK		(44 -
> > INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_ADC_26M_CK		(45 -
> > INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_ADC_FRC_CK		(46 -
> > INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_FBIST2FPC_CK		(47 -
> > INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_I2C_MCK_CK		(48 -
> > INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_I2C_PCK_CK		(49 -
> > INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_IUSB_133_CK		(50 -
> > INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_IUSB_66M_CK		(51 -
> > INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_IUSB_SYS_CK		(52 -
> > INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_IUSB_CK		(53 - INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_IPCIE_CK		(54 - INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_IPCIER_CK		(55 -
> > INFRACFG_AO_OFFSET)
> > +#define CK_INFRA_IPCIEB_CK		(56 -
> > INFRACFG_AO_OFFSET)
> > +#define CLK_INFRA_AO_NR_CLK		(57 -
> > INFRACFG_AO_OFFSET)
> > +
> > +/* APMIXEDSYS */
> > +
> > +#define CK_APMIXED_ARMPLL		0
> > +#define CK_APMIXED_NET2PLL		1
> > +#define CK_APMIXED_MMPLL		2
> > +#define CK_APMIXED_SGMPLL		3
> > +#define CK_APMIXED_WEDMCUPLL		4
> > +#define CK_APMIXED_NET1PLL		5
> > +#define CK_APMIXED_MPLL			6
> > +#define CK_APMIXED_APLL2		7
> > +#define CLK_APMIXED_NR_CLK		8
> > +
> > +/* SGMIISYS_0 */
> > +
> > +#define CK_SGM0_TX_EN			0
> > +#define CK_SGM0_RX_EN			1
> > +#define CK_SGM0_CK0_EN			2
> > +#define CK_SGM0_CDR_CK0_EN		3
> > +#define CLK_SGMII0_NR_CLK		4
> > +
> > +/* SGMIISYS_1 */
> > +
> > +#define CK_SGM1_TX_EN			0
> > +#define CK_SGM1_RX_EN			1
> > +#define CK_SGM1_CK1_EN			2
> > +#define CK_SGM1_CDR_CK1_EN		3
> > +#define CLK_SGMII1_NR_CLK		4
> > +
> > +/* ETHSYS */
> > +
> > +#define CK_ETH_FE_EN			0
> > +#define CK_ETH_GP2_EN			1
> > +#define CK_ETH_GP1_EN			2
> > +#define CK_ETH_WOCPU0_EN		3
> > +#define CLK_ETH_NR_CLK			4
> > +
> > +#endif /* _DT_BINDINGS_CLK_MT7981_H */
> > 
> 
> Reviewed-by: Sean Anderson <seanga2@gmail.com>
> 
> But perhaps these includes could be merged? They seem pretty similar.

Al though these .h seem similar, each chip has different register
definitions. They can't be merged.

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 23/31] clk: mediatek: add support to configure clock driver parent
  2022-08-13  4:18   ` Sean Anderson
@ 2022-08-23 10:43     ` Weijie Gao
  0 siblings, 0 replies; 100+ messages in thread
From: Weijie Gao @ 2022-08-23 10:43 UTC (permalink / raw)
  To: Sean Anderson, u-boot; +Cc: GSS_MTK_Uboot_upstream, Lukasz Majewski

On Sat, 2022-08-13 at 00:18 -0400, Sean Anderson wrote:
> On 8/3/22 11:36 PM, Weijie Gao wrote:
> > This patch adds support for a clock node to configure its parent
> > clock
> > where possible.
> > 
> > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> > ---
> >   drivers/clk/mediatek/clk-mtk.c | 79 ++++++++++++++++++++---------
> > -----
> >   drivers/clk/mediatek/clk-mtk.h |  2 +
> >   2 files changed, 48 insertions(+), 33 deletions(-)
> > 
> > diff --git a/drivers/clk/mediatek/clk-mtk.c
> > b/drivers/clk/mediatek/clk-mtk.c
> > index d99ea55df0..908ed2b4ba 100644
> > --- a/drivers/clk/mediatek/clk-mtk.c
> > +++ b/drivers/clk/mediatek/clk-mtk.c
> > @@ -42,20 +42,14 @@
> >    * the accurate frequency.
> >    */
> >   static ulong mtk_clk_find_parent_rate(struct clk *clk, int id,
> > -				      const struct driver *drv)
> > +				      struct udevice *pdev)
> >   {
> >   	struct clk parent = { .id = id, };
> >   
> > -	if (drv) {
> > -		struct udevice *dev;
> > -
> > -		if (uclass_get_device_by_driver(UCLASS_CLK, drv,
> > &dev))
> > -			return -ENODEV;
> > -
> > -		parent.dev = dev;
> > -	} else {
> > +	if (pdev)
> > +		parent.dev = pdev;
> > +	else
> >   		parent.dev = clk->dev;
> > -	}
> >   
> >   	return clk_get_rate(&parent);
> 
> You must call clk_request(parent) before calling clk_get_rate.

Currently the mtk clock driver doest not really register all the clock
devices. The ops->request is NULL.

The clk->id is only used by the specific soc clock driver (clk-
mtxxxx.c) as a reference to the soc's clock list.

Once clk_get_rate is called, the driver will use clk->id to search the
actual clock internally in the driver.
If a clock has its parent clock,  the driver will fill up the parent
clock's id and then call clk_get_rate again. Again clk_get_rate will go
into the driver and do the same thing until a clock has no parent.

As you can see we only use the clk->id, not the clk udevice, there's no
need to call clk_request. Only a few top-level clk udevices are
registered as the entrace to this driver (topckgen/infrasys/...).

> 
> >   }
> > @@ -296,7 +290,7 @@ static ulong
> > mtk_topckgen_get_factor_rate(struct clk
> >   *clk, u32 off)
> >   	switch (fdiv->flags & CLK_PARENT_MASK) {
> >   	case CLK_PARENT_APMIXED:
> >   		rate = mtk_clk_find_parent_rate(clk, fdiv-
> > >parent,
> > -				DM_DRIVER_GET(mtk_clk_apmixedsys))
> > ;
> > +						priv->parent);
> >   		break;
> >   	case CLK_PARENT_TOPCKGEN:
> >   		rate = mtk_clk_find_parent_rate(clk, fdiv-
> > >parent, NULL);
> > @@ -322,9 +316,18 @@ static ulong mtk_topckgen_get_mux_rate(struct
> > clk *clk,
> >   u32 off)
> >   
> >   	if (mux->parent[index] == CLK_XTAL && priv->tree->flags &
> > CLK_BYPASS_XTAL)
> >   		flag = 1;
> > -	if (mux->parent[index] > 0 || flag == 1)
> > -		return mtk_clk_find_parent_rate(clk, mux-
> > >parent[index],
> > -						NULL);
> > +	if (mux->parent[index] > 0 || flag == 1) {
> > +		switch (mux->flags & CLK_PARENT_MASK) {
> > +		case CLK_PARENT_APMIXED:
> > +			return mtk_clk_find_parent_rate(clk, mux-
> > >parent[index],
> > +							priv-
> > >parent);
> > +			break;
> > +		default:
> > +			return mtk_clk_find_parent_rate(clk, mux-
> > >parent[index],
> > +							NULL);
> > +			break;
> > +		}
> > +	}
> >   
> >   	return priv->tree->xtal_rate;
> >   }
> > @@ -343,7 +346,7 @@ static ulong mtk_topckgen_get_rate(struct clk
> > *clk)
> >   						 priv->tree-
> > >muxes_offs);
> >   }
> >   
> > -static int mtk_topckgen_enable(struct clk *clk)
> > +static int mtk_clk_mux_enable(struct clk *clk)
> >   {
> >   	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
> >   	const struct mtk_composite *mux;
> > @@ -376,7 +379,7 @@ static int mtk_topckgen_enable(struct clk *clk)
> >   	return 0;
> >   }
> >   
> > -static int mtk_topckgen_disable(struct clk *clk)
> > +static int mtk_clk_mux_disable(struct clk *clk)
> >   {
> >   	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
> >   	const struct mtk_composite *mux;
> > @@ -402,7 +405,7 @@ static int mtk_topckgen_disable(struct clk
> > *clk)
> >   	return 0;
> >   }
> >   
> > -static int mtk_topckgen_set_parent(struct clk *clk, struct clk
> > *parent)
> > +static int mtk_common_clk_set_parent(struct clk *clk, struct clk
> > *parent)
> >   {
> >   	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
> >   
> > @@ -474,19 +477,7 @@ static ulong mtk_clk_gate_get_rate(struct clk
> > *clk)
> >   	struct mtk_cg_priv *priv = dev_get_priv(clk->dev);
> >   	const struct mtk_gate *gate = &priv->gates[clk->id];
> >   
> > -	switch (gate->flags & CLK_PARENT_MASK) {
> > -	case CLK_PARENT_APMIXED:
> > -		return mtk_clk_find_parent_rate(clk, gate->parent,
> > -				DM_DRIVER_GET(mtk_clk_apmixedsys))
> > ;
> > -		break;
> > -	case CLK_PARENT_TOPCKGEN:
> > -		return mtk_clk_find_parent_rate(clk, gate->parent,
> > -				DM_DRIVER_GET(mtk_clk_topckgen));
> > -		break;
> > -
> > -	default:
> > -		return priv->tree->xtal_rate;
> > -	}
> > +	return mtk_clk_find_parent_rate(clk, gate->parent, priv-
> > >parent);
> >   }
> >   
> >   const struct clk_ops mtk_clk_apmixedsys_ops = {
> > @@ -497,10 +488,10 @@ const struct clk_ops mtk_clk_apmixedsys_ops =
> > {
> >   };
> >   
> >   const struct clk_ops mtk_clk_topckgen_ops = {
> > -	.enable = mtk_topckgen_enable,
> > -	.disable = mtk_topckgen_disable,
> > +	.enable = mtk_clk_mux_enable,
> > +	.disable = mtk_clk_mux_disable,
> >   	.get_rate = mtk_topckgen_get_rate,
> > -	.set_parent = mtk_topckgen_set_parent,
> > +	.set_parent = mtk_common_clk_set_parent,
> >   };
> >   
> >   const struct clk_ops mtk_clk_gate_ops = {
> > @@ -513,11 +504,22 @@ int mtk_common_clk_init(struct udevice *dev,
> >   			const struct mtk_clk_tree *tree)
> >   {
> >   	struct mtk_clk_priv *priv = dev_get_priv(dev);
> > +	struct udevice *parent;
> > +	int ret;
> >   
> >   	priv->base = dev_read_addr_ptr(dev);
> >   	if (!priv->base)
> >   		return -ENOENT;
> >   
> > +	ret = uclass_get_device_by_phandle(UCLASS_CLK, dev,
> > "clock-parent",
> >   &parent);
> > +	if (ret || !parent) {
> > +		ret = uclass_get_device_by_driver(UCLASS_CLK,
> > +				DM_DRIVER_GET(mtk_clk_apmixedsys),
> > &parent);
> > +		if (ret || !parent)
> > +			return -ENOENT;
> > +	}
> > +
> > +	priv->parent = parent;
> >   	priv->tree = tree;
> >   
> >   	return 0;
> > @@ -528,11 +530,22 @@ int mtk_common_clk_gate_init(struct udevice
> > *dev,
> >   			     const struct mtk_gate *gates)
> >   {
> >   	struct mtk_cg_priv *priv = dev_get_priv(dev);
> > +	struct udevice *parent;
> > +	int ret;
> >   
> >   	priv->base = dev_read_addr_ptr(dev);
> >   	if (!priv->base)
> >   		return -ENOENT;
> >   
> > +	ret = uclass_get_device_by_phandle(UCLASS_CLK, dev,
> > "clock-parent",
> >   &parent);
> 
> Why not just use clk_get?

As I mentioned before, this driver does not register clk udevices, the
clk_get_* won't work, and there's no real parent clocks. We have to
parse the fdt to get the actual top-level clk udevice specified as the
parent clock.

> 
> > +	if (ret || !parent) {
> > +		ret = uclass_get_device_by_driver(UCLASS_CLK,
> > +				DM_DRIVER_GET(mtk_clk_topckgen),
> > &parent);
> > +		if (ret || !parent)
> > +			return -ENOENT;
> > +	}
> > +
> > +	priv->parent = parent;
> >   	priv->tree = tree;
> >   	priv->gates = gates;
> >   
> > diff --git a/drivers/clk/mediatek/clk-mtk.h
> > b/drivers/clk/mediatek/clk-mtk.h
> > index 0ab6912bf0..7955d469db 100644
> > --- a/drivers/clk/mediatek/clk-mtk.h
> > +++ b/drivers/clk/mediatek/clk-mtk.h
> > @@ -203,11 +203,13 @@ struct mtk_clk_tree {
> >   };
> >   
> >   struct mtk_clk_priv {
> > +	struct udevice *parent;
> >   	void __iomem *base;
> >   	const struct mtk_clk_tree *tree;
> >   };
> >   
> >   struct mtk_cg_priv {
> > +	struct udevice *parent;
> >   	void __iomem *base;
> >   	const struct mtk_clk_tree *tree;
> >   	const struct mtk_gate *gates;
> > 
> 
> --Sean

^ permalink raw reply	[flat|nested] 100+ messages in thread

end of thread, other threads:[~2022-08-23 10:43 UTC | newest]

Thread overview: 100+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-04  3:34 [PATCH 00/31] Add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
2022-08-04  3:34 ` [PATCH 01/31] arm: mediatek: add support for MediaTek MT7986 SoC Weijie Gao
2022-08-04  8:37   ` Daniel Golle
2022-08-04  8:50     ` Weijie Gao
2022-08-05  8:43       ` Weijie Gao
2022-08-06 16:09         ` Daniel Golle
2022-08-08  1:37           ` Weijie Gao
2022-08-04  3:34 ` [PATCH 02/31] arm: mediatek: add support for MediaTek MT7981 SoC Weijie Gao
2022-08-04 13:57   ` Simon Glass
2022-08-08  2:17     ` Weijie Gao
2022-08-08 19:26       ` Simon Glass
2022-08-04  3:35 ` [PATCH 03/31] board: mediatek: add MT7986 reference boards Weijie Gao
2022-08-04 13:57   ` Simon Glass
2022-08-09  9:10   ` Daniel Golle
2022-08-12 11:02     ` Weijie Gao
2022-08-12 11:29       ` Daniel Golle
2022-08-04  3:35 ` [PATCH 04/31] board: mediatek: add MT7981 " Weijie Gao
2022-08-04 13:57   ` Simon Glass
2022-08-04  3:35 ` [PATCH 05/31] mmc: mediatek: add support for MediaTek MT7891/MT7986 SoCs Weijie Gao
2022-08-04 13:57   ` Simon Glass
2022-08-08  2:22     ` Weijie Gao
2022-08-11  5:50   ` jh80.chung
2022-08-04  3:35 ` [PATCH 06/31] net: mediatek: use a struct to cover variations of all SoCs Weijie Gao
2022-08-04 13:56   ` Simon Glass
2022-08-08  2:28     ` Weijie Gao
2022-08-04  3:35 ` [PATCH 07/31] net: mediatek: stop using bitfileds for DMA descriptors Weijie Gao
2022-08-04 13:56   ` Simon Glass
2022-08-06 17:50   ` Ramon Fried
2022-08-08  2:29     ` Weijie Gao
2022-08-04  3:35 ` [PATCH 08/31] net: mediatek: add support for PDMA v2 Weijie Gao
2022-08-04 13:56   ` Simon Glass
2022-08-06 17:49     ` Ramon Fried
2022-08-04  3:35 ` [PATCH 09/31] net: mediatek: add support for MediaTek MT7981/MT7986 Weijie Gao
2022-08-06 17:48   ` Ramon Fried
2022-08-04  3:35 ` [PATCH 10/31] serial: mtk: add support for using dynamic baud clock souce Weijie Gao
2022-08-04 13:56   ` Simon Glass
2022-08-08  2:36     ` Weijie Gao
2022-08-08 19:26       ` Simon Glass
2022-08-04  3:35 ` [PATCH 11/31] arm: dts: mt7622: force high-speed mode for uart Weijie Gao
2022-08-04 13:57   ` Simon Glass
2022-08-04  3:35 ` [PATCH 12/31] pwm: mtk: add support for MediaTek MT7986 SoC Weijie Gao
2022-08-04 13:57   ` Simon Glass
2022-08-04  3:35 ` [PATCH 13/31] pwm: mtk: add support for MediaTek MT7981 SoC Weijie Gao
2022-08-04 13:57   ` Simon Glass
2022-08-04  3:35 ` [PATCH 14/31] timer: mtk: add support for MediaTek MT7981/MT7986 SoCs Weijie Gao
2022-08-04 13:57   ` Simon Glass
2022-08-04  3:35 ` [PATCH 15/31] watchdog: mediatek: add support for MediaTek MT7986 SoC Weijie Gao
2022-08-04 13:57   ` Simon Glass
2022-08-04  3:36 ` [PATCH 16/31] spi: add support for MediaTek spi-mem controller Weijie Gao
2022-08-04 13:57   ` Simon Glass
2022-08-04  3:36 ` [PATCH 17/31] i2c: add support for MediaTek I2C interface Weijie Gao
2022-08-04 13:57   ` Simon Glass
2022-08-08  3:00     ` Weijie Gao
2022-08-10 11:12   ` Heiko Schocher
2022-08-10 11:24   ` Michael Nazzareno Trimarchi
2022-08-12  9:46     ` Weijie Gao
2022-08-04  3:36 ` [PATCH 18/31] arm: dts: mt7622: add i2c support Weijie Gao
2022-08-04 13:57   ` Simon Glass
2022-08-04  3:36 ` [PATCH 19/31] dt-bindings: pinctrl: mediatek: add a header for common pinconf parameters Weijie Gao
2022-08-04 13:57   ` Simon Glass
2022-08-04  3:36 ` [PATCH 20/31] pinctrl: mediatek: add pinctrl driver for MT7981 SoC Weijie Gao
2022-08-04 13:57   ` Simon Glass
2022-08-04  3:36 ` [PATCH 21/31] pinctrl: mediatek: add pinctrl driver for MT7986 SoC Weijie Gao
2022-08-04 13:57   ` Simon Glass
2022-08-04  3:36 ` [PATCH 22/31] clk: mediatek: add CLK_BYPASS_XTAL flag to allow bypassing searching clock parent of xtal clock Weijie Gao
2022-08-04 13:57   ` Simon Glass
2022-08-08  3:01     ` Weijie Gao
2022-08-04  3:36 ` [PATCH 23/31] clk: mediatek: add support to configure clock driver parent Weijie Gao
2022-08-04 13:57   ` Simon Glass
2022-08-13  4:18   ` Sean Anderson
2022-08-23 10:43     ` Weijie Gao
2022-08-04  3:36 ` [PATCH 24/31] clk: mediatek: add infrasys clock mux support Weijie Gao
2022-08-04 13:57   ` Simon Glass
2022-08-13  4:21   ` Sean Anderson
2022-08-17  8:00     ` Weijie Gao
2022-08-04  3:36 ` [PATCH 25/31] clk: mediatek: add CLK_XTAL support for clock driver Weijie Gao
2022-08-04 13:57   ` Simon Glass
2022-08-08  3:10     ` Weijie Gao
2022-08-13  4:25   ` Sean Anderson
2022-08-17  8:08     ` Weijie Gao
2022-08-04  3:36 ` [PATCH 26/31] clk: mediatek: add clock driver support for MediaTek MT7986 SoC Weijie Gao
2022-08-04 13:57   ` Simon Glass
2022-08-08  3:13     ` Weijie Gao
2022-08-04  3:36 ` [PATCH 27/31] clk: mediatek: add clock driver support for MediaTek MT7981 SoC Weijie Gao
2022-08-04 13:57   ` Simon Glass
2022-08-08  3:18     ` Weijie Gao
2022-08-13  4:31   ` Sean Anderson
2022-08-17  8:16     ` Weijie Gao
2022-08-04  3:36 ` [PATCH 28/31] tools: mtk_image: split gfh header verification into a new function Weijie Gao
2022-08-04 13:57   ` Simon Glass
2022-08-04  3:36 ` [PATCH 29/31] tools: mtk_image: split the code of generating NAND header into a new file Weijie Gao
2022-08-04 13:57   ` Simon Glass
2022-08-08  3:23     ` Weijie Gao
2022-08-05 18:26   ` Daniel Golle
2022-08-08  3:26     ` Weijie Gao
2022-08-04  3:36 ` [PATCH 30/31] tools: mtk_image: add support for nand headers used by newer chips Weijie Gao
2022-08-04 13:57   ` Simon Glass
2022-08-08  3:31     ` Weijie Gao
2022-08-04  3:36 ` [PATCH 31/31] MAINTAINERS: update maintainer for MediaTek ARM platform Weijie Gao
2022-08-04 13:57   ` Simon Glass

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.