[PATCH] mtd: nand: raw: mt7621-nand: allow writing ecc region in raw mode

2024-03-12 Thread Weijie Gao
Allow writing ecc parity region in raw mode. This makes sure the
nand write.raw command can write the flash data as-is.

Change-Id: Ibed3bdf13c9cf81e54041c5ac7a78192b97dcedc
Signed-off-by: Weijie Gao 
CR-Id: WCNCR00180092
---
 drivers/mtd/nand/raw/mt7621_nand.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/mt7621_nand.c 
b/drivers/mtd/nand/raw/mt7621_nand.c
index f6eddb84a9..341ef0bf2d 100644
--- a/drivers/mtd/nand/raw/mt7621_nand.c
+++ b/drivers/mtd/nand/raw/mt7621_nand.c
@@ -1003,9 +1003,9 @@ static int mt7621_nfc_write_page_raw(struct mtd_info *mtd,
mt7621_nfc_write_data(nfc, oob_fdm_ptr(nand, i),
  NFI_FDM_SIZE);
 
-   /* Write dummy ECC parity data */
-   mt7621_nfc_write_data_empty(nfc, nfc->spare_per_sector -
-   NFI_FDM_SIZE);
+   /* Write ECC parity data */
+   mt7621_nfc_write_data(nfc, oob_ecc_ptr(nfc, i),
+ nfc->spare_per_sector - NFI_FDM_SIZE);
}
 
mt7621_nfc_wait_write_completion(nfc, nand);
-- 
2.34.1



[PATCH 03/60] net: mediatek: add support for XGMII interface

2024-01-21 Thread Weijie Gao
This patch add XGMII support for connecting 2.5G PHY.

Signed-off-by: Bo-Cun Chen 
Signed-off-by: Weijie Gao 
---
 drivers/net/mtk_eth.c | 22 ++
 drivers/net/mtk_eth.h |  2 +-
 2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c
index 726aedad3f..75e7bcf83b 100644
--- a/drivers/net/mtk_eth.c
+++ b/drivers/net/mtk_eth.c
@@ -1246,7 +1246,8 @@ static int mtk_phy_start(struct mtk_eth_priv *priv)
}
 
if (!priv->force_mode) {
-   if (priv->phy_interface == PHY_INTERFACE_MODE_USXGMII)
+   if (priv->phy_interface == PHY_INTERFACE_MODE_USXGMII ||
+   priv->phy_interface == PHY_INTERFACE_MODE_XGMII)
mtk_xphy_link_adjust(priv);
else
mtk_phy_link_adjust(priv);
@@ -1516,7 +1517,7 @@ static void mtk_mac_init(struct mtk_eth_priv *priv)
 
 static void mtk_xmac_init(struct mtk_eth_priv *priv)
 {
-   u32 sts;
+   u32 force_link = 0;
 
switch (priv->phy_interface) {
case PHY_INTERFACE_MODE_USXGMII:
@@ -1531,15 +1532,19 @@ static void mtk_xmac_init(struct mtk_eth_priv *priv)
   SYSCFG0_GE_MODE_M << SYSCFG0_GE_MODE_S(priv->gmac_id),
   0);
 
-   if (priv->gmac_id == 1) {
+   if (priv->phy_interface == PHY_INTERFACE_MODE_USXGMII &&
+   priv->gmac_id == 1) {
mtk_infra_rmw(priv, TOPMISC_NETSYS_PCS_MUX,
  NETSYS_PCS_MUX_MASK, MUX_G2_USXGMII_SEL);
-   } else if (priv->gmac_id == 2) {
-   sts = mtk_gmac_read(priv, XGMAC_STS(priv->gmac_id));
-   sts |= XGMAC_FORCE_LINK;
-   mtk_gmac_write(priv, XGMAC_STS(priv->gmac_id), sts);
}
 
+   if (priv->phy_interface == PHY_INTERFACE_MODE_XGMII ||
+   priv->gmac_id == 2)
+   force_link = XGMAC_FORCE_LINK(priv->gmac_id);
+
+   mtk_gmac_rmw(priv, XGMAC_STS(priv->gmac_id),
+XGMAC_FORCE_LINK(priv->gmac_id), force_link);
+
/* Force GMAC link down */
mtk_gmac_write(priv, GMAC_PORT_MCR(priv->gmac_id), FORCE_MODE);
 }
@@ -1828,7 +1833,8 @@ static int mtk_eth_probe(struct udevice *dev)
mtk_eth_mdc_init(priv);
 
/* Set MAC mode */
-   if (priv->phy_interface == PHY_INTERFACE_MODE_USXGMII)
+   if (priv->phy_interface == PHY_INTERFACE_MODE_USXGMII ||
+   priv->phy_interface == PHY_INTERFACE_MODE_XGMII)
mtk_xmac_init(priv);
else
mtk_mac_init(priv);
diff --git a/drivers/net/mtk_eth.h b/drivers/net/mtk_eth.h
index 45229c0f9a..fd31c782c7 100644
--- a/drivers/net/mtk_eth.h
+++ b/drivers/net/mtk_eth.h
@@ -268,7 +268,7 @@ enum mkt_eth_capabilities {
 
 /* XGMAC Status Registers */
 #define XGMAC_STS(x)   (((x) == 2) ? 0x001C : 0x000C)
-#define XGMAC_FORCE_LINK   BIT(15)
+#define XGMAC_FORCE_LINK(x)(((x) == 1) ? BIT(31) : BIT(15))
 
 /* XGMAC Registers */
 #define XGMAC_PORT_MCR(x)  (0x2000 + (((x) - 1) * 0x1000))
-- 
2.34.1



[PATCH 02/60] net: mediatek: add support for adjusting MDIO clock

2024-01-21 Thread Weijie Gao
User can assign a specific MDC speed to the eth node as follow:

 {
...
phy-mode = "usxgmii";
phy-handle = <>;

mdio {
clock-frequency = <1050>;
};

phy8: eth-phy@8 {
  compatible = "ethernet-phy-id31c3.1c12";
...
};

Signed-off-by: Bo-Cun Chen 
Signed-off-by: Weijie Gao 
---
 drivers/net/mtk_eth.c | 35 +++
 drivers/net/mtk_eth.h |  7 +++
 2 files changed, 42 insertions(+)

diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c
index 3cfce05845..726aedad3f 100644
--- a/drivers/net/mtk_eth.c
+++ b/drivers/net/mtk_eth.c
@@ -137,6 +137,7 @@ struct mtk_eth_priv {
int force_mode;
int speed;
int duplex;
+   int mdc;
bool pn_swap;
 
struct phy_device *phydev;
@@ -1607,6 +1608,26 @@ static void mtk_eth_fifo_init(struct mtk_eth_priv *priv)
mtk_pdma_write(priv, PDMA_RST_IDX_REG, RST_DTX_IDX0 | RST_DRX_IDX0);
 }
 
+static void mtk_eth_mdc_init(struct mtk_eth_priv *priv)
+{
+   u32 divider;
+
+   if (priv->mdc == 0)
+   return;
+
+   divider = min_t(u32, DIV_ROUND_UP(MDC_MAX_FREQ, priv->mdc), 
MDC_MAX_DIVIDER);
+
+   /* Configure MDC turbo mode */
+   if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V3))
+   mtk_gmac_rmw(priv, GMAC_MAC_MISC_REG, 0, MISC_MDC_TURBO);
+   else
+   mtk_gmac_rmw(priv, GMAC_PPSC_REG, 0, MISC_MDC_TURBO);
+
+   /* Configure MDC divider */
+   mtk_gmac_rmw(priv, GMAC_PPSC_REG, PHY_MDC_CFG,
+FIELD_PREP(PHY_MDC_CFG, divider));
+}
+
 static int mtk_eth_start(struct udevice *dev)
 {
struct mtk_eth_priv *priv = dev_get_priv(dev);
@@ -1803,6 +1824,9 @@ static int mtk_eth_probe(struct udevice *dev)
noncached_alloc(priv->soc->rxd_size * NUM_RX_DESC,
ARCH_DMA_MINALIGN);
 
+   /* Set MDC divider */
+   mtk_eth_mdc_init(priv);
+
/* Set MAC mode */
if (priv->phy_interface == PHY_INTERFACE_MODE_USXGMII)
mtk_xmac_init(priv);
@@ -1881,6 +1905,17 @@ static int mtk_eth_of_to_plat(struct udevice *dev)
 
priv->gmac_id = dev_read_u32_default(dev, "mediatek,gmac-id", 0);
 
+   priv->mdc = 0;
+   subnode = ofnode_find_subnode(dev_ofnode(dev), "mdio");
+   if (ofnode_valid(subnode)) {
+   priv->mdc = ofnode_read_u32_default(subnode, "clock-frequency", 
250);
+   if (priv->mdc > MDC_MAX_FREQ ||
+   priv->mdc < MDC_MAX_FREQ / MDC_MAX_DIVIDER) {
+   printf("error: MDIO clock frequency out of range\n");
+   return -EINVAL;
+   }
+   }
+
/* Interface mode is required */
pdata->phy_interface = dev_read_phy_mode(dev);
priv->phy_interface = pdata->phy_interface;
diff --git a/drivers/net/mtk_eth.h b/drivers/net/mtk_eth.h
index 491cac56a8..45229c0f9a 100644
--- a/drivers/net/mtk_eth.h
+++ b/drivers/net/mtk_eth.h
@@ -180,6 +180,12 @@ enum mkt_eth_capabilities {
 
 /* GMAC Registers */
 
+#define GMAC_PPSC_REG  0x
+#define PHY_MDC_CFGGENMASK(29, 24)
+#define MDC_TURBO  BIT(20)
+#define MDC_MAX_FREQ   2500
+#define MDC_MAX_DIVIDER63
+
 #define GMAC_PIAC_REG  0x0004
 #define PHY_ACS_ST BIT(31)
 #define MDIO_REG_ADDR_S25
@@ -197,6 +203,7 @@ enum mkt_eth_capabilities {
 #define P1_XGMAC_FORCE_LINKBIT(15)
 
 #define GMAC_MAC_MISC_REG  0x0010
+#define MISC_MDC_TURBO BIT(4)
 
 #define GMAC_GSW_CFG_REG   0x0080
 #define GSWTX_IPG_M0xF
-- 
2.34.1



[PATCH 01/60] arm: dts: mt7988-sd-rfb: add SD pin driving settings

2024-01-21 Thread Weijie Gao
Set SD pin driving to 4mA

Signed-off-by: Dong Huang 
Signed-off-by: Weijie Gao 
---
 arch/arm/dts/mt7988-sd-rfb.dts | 2 ++
 arch/arm/dts/mt7988.dtsi   | 1 +
 2 files changed, 3 insertions(+)

diff --git a/arch/arm/dts/mt7988-sd-rfb.dts b/arch/arm/dts/mt7988-sd-rfb.dts
index a3df37d252..9aa198b84a 100644
--- a/arch/arm/dts/mt7988-sd-rfb.dts
+++ b/arch/arm/dts/mt7988-sd-rfb.dts
@@ -87,10 +87,12 @@
pins = "SPI2_CSB", "SPI2_MISO", "SPI2_MOSI",
   "SPI2_CLK", "SPI2_HOLD";
input-enable;
+   drive-strength = ;
};
 
conf-clk {
pins = "SPI2_WP";
+   drive-strength = ;
};
};
 };
diff --git a/arch/arm/dts/mt7988.dtsi b/arch/arm/dts/mt7988.dtsi
index ac476d5cdd..5c0c5bcfd6 100644
--- a/arch/arm/dts/mt7988.dtsi
+++ b/arch/arm/dts/mt7988.dtsi
@@ -9,6 +9,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 / {
-- 
2.34.1



[PATCH] arm: dts: medaitek: convert gmac link mode to 2500base-x for mt7986a-bpi-r3-sd

2023-08-03 Thread Weijie Gao
The mt7531 of bpi-r3 is connected to mt7986 with 2.5Gbps HSGMII, not the
regular 1Gbps SGMII.

Signed-off-by: Weijie Gao 
---
This is a supplement to commit:
aef54ea1 (arm: dts: medaitek: convert gmac link mode to 2500base-x)
---
 arch/arm/dts/mt7986a-bpi-r3-sd.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/dts/mt7986a-bpi-r3-sd.dts 
b/arch/arm/dts/mt7986a-bpi-r3-sd.dts
index 15256302b8..c156a81363 100644
--- a/arch/arm/dts/mt7986a-bpi-r3-sd.dts
+++ b/arch/arm/dts/mt7986a-bpi-r3-sd.dts
@@ -76,12 +76,12 @@
  {
status = "okay";
mediatek,gmac-id = <0>;
-   phy-mode = "sgmii";
+   phy-mode = "2500base-x";
mediatek,switch = "mt7531";
reset-gpios = < 5 GPIO_ACTIVE_HIGH>;
 
fixed-link {
-   speed = <1000>;
+   speed = <2500>;
full-duplex;
};
 };
-- 
2.17.1



[PATCH 12/29] pinctrl: mediatek: convert most definitions to const

2023-07-19 Thread Weijie Gao
There exists a situation of the mediatek pinctrl driver that may return
wrong pin function value for the pinmux driver:
- All pin function arrays are defined without const
- Some pin function arrays contain all-zero value, e.g.:
  static int mt7622_spi_funcs[] = { 0, 0, 0, 0, 0, 0, };
- These arrays will be put into .bss section during compilation
- .bss section has no "a" attribute and does not exist in the final binary
  file after objcopy.
- FDT binary blob is appended to the u-boot binary, which occupies the
  .bss section.
- During board_f stage, .bss has not been initialized, and contains the
  data of FDT, which is not full-zero data.
- pinctrl driver is initialized in board_f stage, and it will get wrong
  data if another driver is going to set default pinctrl.

Since pinmux information and soc data are only meant to be read-only, thus
should be declared as const. This will force all pinctrl data being put
into .rodata section. Since .rodata has "a" attribute, even the all-zero
data will be allocated and filled with correct value in to u-boot binary.

Signed-off-by: Weijie Gao 
---
 drivers/pinctrl/mediatek/pinctrl-mt7622.c | 474 ++---
 drivers/pinctrl/mediatek/pinctrl-mt7623.c | 650 +-
 drivers/pinctrl/mediatek/pinctrl-mt7629.c | 174 ++---
 drivers/pinctrl/mediatek/pinctrl-mt7981.c | 270 
 drivers/pinctrl/mediatek/pinctrl-mt7986.c | 145 ++--
 drivers/pinctrl/mediatek/pinctrl-mt8512.c |  24 +-
 drivers/pinctrl/mediatek/pinctrl-mt8516.c |  18 +-
 drivers/pinctrl/mediatek/pinctrl-mt8518.c |  20 +-
 drivers/pinctrl/mediatek/pinctrl-mtk-common.c |   4 +-
 drivers/pinctrl/mediatek/pinctrl-mtk-common.h |   8 +-
 10 files changed, 898 insertions(+), 889 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7622.c 
b/drivers/pinctrl/mediatek/pinctrl-mt7622.c
index bf4e9a28e9..114f2602b2 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt7622.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt7622.c
@@ -233,283 +233,285 @@ static const struct mtk_pin_desc mt7622_pins[] = {
  */
 
 /* EMMC */
-static int mt7622_emmc_pins[] = { 40, 41, 42, 43, 44, 45, 47, 48, 49, 50, };
-static int mt7622_emmc_funcs[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, };
+static const int mt7622_emmc_pins[] = {
+   40, 41, 42, 43, 44, 45, 47, 48, 49, 50, };
+static const int mt7622_emmc_funcs[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, };
 
-static int mt7622_emmc_rst_pins[] = { 37, };
-static int mt7622_emmc_rst_funcs[] = { 1, };
+static const int mt7622_emmc_rst_pins[] = { 37, };
+static const int mt7622_emmc_rst_funcs[] = { 1, };
 
 /* LED for EPHY */
-static int mt7622_ephy_leds_pins[] = { 86, 91, 92, 93, 94, };
-static int mt7622_ephy_leds_funcs[] = { 0, 0, 0, 0, 0, };
-static int mt7622_ephy0_led_pins[] = { 86, };
-static int mt7622_ephy0_led_funcs[] = { 0, };
-static int mt7622_ephy1_led_pins[] = { 91, };
-static int mt7622_ephy1_led_funcs[] = { 2, };
-static int mt7622_ephy2_led_pins[] = { 92, };
-static int mt7622_ephy2_led_funcs[] = { 2, };
-static int mt7622_ephy3_led_pins[] = { 93, };
-static int mt7622_ephy3_led_funcs[] = { 2, };
-static int mt7622_ephy4_led_pins[] = { 94, };
-static int mt7622_ephy4_led_funcs[] = { 2, };
+static const int mt7622_ephy_leds_pins[] = { 86, 91, 92, 93, 94, };
+static const int mt7622_ephy_leds_funcs[] = { 0, 0, 0, 0, 0, };
+static const int mt7622_ephy0_led_pins[] = { 86, };
+static const int mt7622_ephy0_led_funcs[] = { 0, };
+static const int mt7622_ephy1_led_pins[] = { 91, };
+static const int mt7622_ephy1_led_funcs[] = { 2, };
+static const int mt7622_ephy2_led_pins[] = { 92, };
+static const int mt7622_ephy2_led_funcs[] = { 2, };
+static const int mt7622_ephy3_led_pins[] = { 93, };
+static const int mt7622_ephy3_led_funcs[] = { 2, };
+static const int mt7622_ephy4_led_pins[] = { 94, };
+static const int mt7622_ephy4_led_funcs[] = { 2, };
 
 /* Embedded Switch */
-static int mt7622_esw_pins[] = { 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
-62, 63, 64, 65, 66, 67, 68, 69, 70, };
-static int mt7622_esw_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, };
-static int mt7622_esw_p0_p1_pins[] = { 51, 52, 53, 54, 55, 56, 57, 58, };
-static int mt7622_esw_p0_p1_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, };
-static int mt7622_esw_p2_p3_p4_pins[] = { 59, 60, 61, 62, 63, 64, 65, 66, 67,
- 68, 69, 70, };
-static int mt7622_esw_p2_p3_p4_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, };
+static const int mt7622_esw_pins[] = {
+   51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
+   69, 70, };
+static const int mt7622_esw_funcs[] = {
+   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
+static const int mt7622_esw_p0_p1_pins[] = { 51, 52, 53, 54, 55, 56, 57, 58, };
+static const int mt7622_esw_p0_p1_funcs[] = { 0,

[PATCH 29/29] board: mediatek: add MT7988 reference boards

2023-07-19 Thread Weijie Gao
This patch adds general board files based on MT7988 SoCs.

MT7988 uses one mmc controller for booting from both SD and eMMC,
and the pins of mmc controller booting from SD are also shared with
one of spi controllers.
So two configs are need for these boot types:

1. mt7988_rfb_defconfig - SPI-NOR, SPI-NAND and eMMC
2. mt7988_sd_rfb_defconfig - SPI-NAND and SD

Signed-off-by: Weijie Gao 
---
 arch/arm/dts/Makefile  |   2 +
 arch/arm/dts/mt7988-rfb.dts| 182 +
 arch/arm/dts/mt7988-sd-rfb.dts | 134 +
 board/mediatek/mt7988/MAINTAINERS  |   7 ++
 board/mediatek/mt7988/Makefile |   3 +
 board/mediatek/mt7988/mt7988_rfb.c |  10 ++
 configs/mt7988_rfb_defconfig   |  83 +
 configs/mt7988_sd_rfb_defconfig|  71 +++
 include/configs/mt7988.h   |  14 +++
 9 files changed, 506 insertions(+)
 create mode 100644 arch/arm/dts/mt7988-rfb.dts
 create mode 100644 arch/arm/dts/mt7988-sd-rfb.dts
 create mode 100644 board/mediatek/mt7988/MAINTAINERS
 create mode 100644 board/mediatek/mt7988/Makefile
 create mode 100644 board/mediatek/mt7988/mt7988_rfb.c
 create mode 100644 configs/mt7988_rfb_defconfig
 create mode 100644 configs/mt7988_sd_rfb_defconfig
 create mode 100644 include/configs/mt7988.h

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 07b26df275..92d0b377d6 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -1323,6 +1323,8 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \
mt7986b-sd-rfb.dtb \
mt7986a-emmc-rfb.dtb \
mt7986b-emmc-rfb.dtb \
+   mt7988-rfb.dtb \
+   mt7988-sd-rfb.dtb \
mt8183-pumpkin.dtb \
mt8512-bm1-emmc.dtb \
mt8516-pumpkin.dtb \
diff --git a/arch/arm/dts/mt7988-rfb.dts b/arch/arm/dts/mt7988-rfb.dts
new file mode 100644
index 00..2c11428430
--- /dev/null
+++ b/arch/arm/dts/mt7988-rfb.dts
@@ -0,0 +1,182 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Sam Shih 
+ */
+
+/dts-v1/;
+#include "mt7988.dtsi"
+#include 
+
+/ {
+   model = "mt7988-rfb";
+   compatible = "mediatek,mt7988-rfb";
+
+   chosen {
+   stdout-path = 
+   };
+
+   memory@4000 {
+   device_type = "memory";
+   reg = <0 0x4000 0 0x1000>;
+   };
+
+   reg_3p3v: regulator-3p3v {
+   compatible = "regulator-fixed";
+   regulator-name = "fixed-3.3V";
+   regulator-min-microvolt = <330>;
+   regulator-max-microvolt = <330>;
+   regulator-boot-on;
+   regulator-always-on;
+   };
+
+   reg_1p8v: regulator-1p8v {
+   compatible = "regulator-fixed";
+   regulator-name = "fixed-1.8V";
+   regulator-min-microvolt = <180>;
+   regulator-max-microvolt = <180>;
+   regulator-boot-on;
+   regulator-always-on;
+   };
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+   status = "okay";
+};
+
+ {
+   status = "okay";
+   mediatek,gmac-id = <0>;
+   phy-mode = "usxgmii";
+   mediatek,switch = "mt7988";
+
+   fixed-link {
+   speed = <1000>;
+   full-duplex;
+   pause;
+   };
+};
+
+ {
+   i2c1_pins: i2c1-pins {
+   mux {
+   function = "i2c";
+   groups = "i2c1_0";
+   };
+   };
+
+   pwm_pins: pwm-pins {
+   mux {
+   function = "pwm";
+   groups = "pwm0", "pwm1", "pwm2", "pwm3", "pwm4",
+"pwm5", "pwm6", "pwm7";
+   };
+   };
+
+   spi0_pins: spi0-pins {
+   mux {
+   function = "spi";
+   groups = "spi0", "spi0_wp_hold";
+   };
+   };
+
+   spi2_pins: spi2-pins {
+   mux {
+   function = "spi";
+   groups = "spi2", "spi2_wp_hold";
+   };
+   };
+
+   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",
+ 

[PATCH 28/29] arm: mediatek: add support for MediaTek MT7988 SoC

2023-07-19 Thread Weijie Gao
This patch adds basic support for MediaTek MT7988 SoC.
This includes files that will initialize the SoC after boot and
its device tree.

Signed-off-by: Weijie Gao 
---
 arch/arm/dts/mt7988-u-boot.dtsi   |  25 ++
 arch/arm/dts/mt7988.dtsi  | 391 ++
 arch/arm/mach-mediatek/Kconfig|  13 +-
 arch/arm/mach-mediatek/Makefile   |   1 +
 arch/arm/mach-mediatek/mt7988/Makefile|   4 +
 arch/arm/mach-mediatek/mt7988/init.c  |  63 +++
 arch/arm/mach-mediatek/mt7988/lowlevel_init.S |  30 ++
 7 files changed, 526 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/dts/mt7988-u-boot.dtsi
 create mode 100644 arch/arm/dts/mt7988.dtsi
 create mode 100644 arch/arm/mach-mediatek/mt7988/Makefile
 create mode 100644 arch/arm/mach-mediatek/mt7988/init.c
 create mode 100644 arch/arm/mach-mediatek/mt7988/lowlevel_init.S

diff --git a/arch/arm/dts/mt7988-u-boot.dtsi b/arch/arm/dts/mt7988-u-boot.dtsi
new file mode 100644
index 00..43e00a36ef
--- /dev/null
+++ b/arch/arm/dts/mt7988-u-boot.dtsi
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Sam Shih 
+ */
+
+_clk {
+   bootph-all;
+};
+
+_clk {
+   bootph-all;
+};
+
+ {
+   bootph-all;
+};
+
+ {
+   bootph-all;
+};
+
+ {
+   bootph-all;
+};
diff --git a/arch/arm/dts/mt7988.dtsi b/arch/arm/dts/mt7988.dtsi
new file mode 100644
index 00..ddd629e8c9
--- /dev/null
+++ b/arch/arm/dts/mt7988.dtsi
@@ -0,0 +1,391 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Sam Shih 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/ {
+   compatible = "mediatek,mt7988-rfb";
+   interrupt-parent = <>;
+   #address-cells = <2>;
+   #size-cells = <2>;
+
+   cpus {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   cpu0: cpu@0 {
+   device_type = "cpu";
+   compatible = "arm,cortex-a73";
+   reg = <0x0>;
+   mediatek,hwver = <>;
+   };
+
+   cpu1: cpu@1 {
+   device_type = "cpu";
+   compatible = "arm,cortex-a73";
+   reg = <0x1>;
+   mediatek,hwver = <>;
+   };
+
+   cpu2: cpu@2 {
+   device_type = "cpu";
+   compatible = "arm,cortex-a73";
+   reg = <0x2>;
+   mediatek,hwver = <>;
+   };
+
+   cpu3: cpu@3 {
+   device_type = "cpu";
+   compatible = "arm,cortex-a73";
+   reg = <0x3>;
+   mediatek,hwver = <>;
+   };
+   };
+
+   system_clk: dummy40m {
+   compatible = "fixed-clock";
+   clock-frequency = <4000>;
+   #clock-cells = <0>;
+   };
+
+   spi_clk: dummy208m {
+   compatible = "fixed-clock";
+   clock-frequency = <20800>;
+   #clock-cells = <0>;
+   };
+
+   hwver: hwver {
+   compatible = "mediatek,hwver", "syscon";
+   reg = <0 0x800 0 0x1000>;
+   };
+
+   timer {
+   compatible = "arm,armv8-timer";
+   interrupt-parent = <>;
+   clock-frequency = <1300>;
+   interrupts = ,
+,
+,
+;
+   };
+
+   watchdog: watchdog@1001c000 {
+   compatible = "mediatek,mt7622-wdt",
+"mediatek,mt6589-wdt",
+"syscon";
+   reg = <0 0x1001c000 0 0x1000>;
+   interrupts = ;
+   #reset-cells = <1>;
+   };
+
+   gic: interrupt-controller@c00 {
+   compatible = "arm,gic-v3";
+   #interrupt-cells = <3>;
+   interrupt-parent = <>;
+   interrupt-controller;
+   reg = <0 0x0c00 0 0x4>,  /* GICD */
+ <0 0x0c08 0 0x20>; /* GICR */
+   interrupts = ;
+   };
+
+   infracfg_ao_cgs: infracfg_ao_cgs@10001000 {
+   compatible = "mediatek,mt7988-infracfg_ao_cgs", "syscon";
+   reg = <0 0x10001000 0 0x1000>;
+   clock-parent = <_ao>;
+   #clock-cells = <1>;
+   };
+
+   apmixedsys: apmixedsys@1001e000 {

[PATCH 27/29] tools: mtk_image: use uint32_t for ghf header magic and version

2023-07-19 Thread Weijie Gao
This patch converts magic and version fields of ghf common header
to one field with the type of uint32_t to make this header flexible
for futher updates.

Signed-off-by: Weijie Gao 
---
 tools/mtk_image.c | 10 ++
 tools/mtk_image.h |  6 +++---
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/tools/mtk_image.c b/tools/mtk_image.c
index 30f54c8e8d..1b1aed5992 100644
--- a/tools/mtk_image.c
+++ b/tools/mtk_image.c
@@ -542,11 +542,13 @@ static void put_brom_layout_header(struct 
brom_layout_header *hdr, int type)
hdr->type = cpu_to_le32(type);
 }
 
-static void put_ghf_common_header(struct gfh_common_header *gfh, int size,
- int type, int ver)
+static void put_ghf_common_header(struct gfh_common_header *gfh, uint16_t size,
+ uint16_t type, uint8_t ver)
 {
-   memcpy(gfh->magic, GFH_HEADER_MAGIC, sizeof(gfh->magic));
-   gfh->version = ver;
+   uint32_t magic_version = GFH_HEADER_MAGIC |
+(uint32_t)ver << GFH_HEADER_VERSION_SHIFT;
+
+   gfh->magic_version = cpu_to_le32(magic_version);
gfh->size = cpu_to_le16(size);
gfh->type = cpu_to_le16(type);
 }
diff --git a/tools/mtk_image.h b/tools/mtk_image.h
index fad9372100..54a838de86 100644
--- a/tools/mtk_image.h
+++ b/tools/mtk_image.h
@@ -63,13 +63,13 @@ struct gen_device_header {
 
 /* BootROM header definitions */
 struct gfh_common_header {
-   uint8_t magic[3];
-   uint8_t version;
+   uint32_t magic_version;
uint16_t size;
uint16_t type;
 };
 
-#define GFH_HEADER_MAGIC   "MMM"
+#define GFH_HEADER_MAGIC   0x4D4D4D
+#define GFH_HEADER_VERSION_SHIFT   24
 
 #define GFH_TYPE_FILE_INFO 0
 #define GFH_TYPE_BL_INFO   1
-- 
2.17.1



[PATCH 26/29] net: mediatek: add support for MediaTek MT7988 SoC

2023-07-19 Thread Weijie Gao
This patch adds support for MediaTek MT7988.

MT7988 features MediaTek NETSYS v3, including three GMACs, and two
of them supports 10Gbps USXGMII.

MT7988 embeds a MT7531 switch (not MCM) which supports accessing
internal registers through MMIO instead of MDIO.

Signed-off-by: Weijie Gao 
---
 drivers/net/mtk_eth.c | 158 +-
 drivers/net/mtk_eth.h |  20 ++
 2 files changed, 177 insertions(+), 1 deletion(-)

diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c
index e0dc180e3c..d4111e73df 100644
--- a/drivers/net/mtk_eth.c
+++ b/drivers/net/mtk_eth.c
@@ -54,6 +54,16 @@
(DP_PDMA << MC_DP_S) | \
(DP_PDMA << UN_DP_S))
 
+#define GDMA_BRIDGE_TO_CPU \
+   (0xC000 | \
+   GDM_ICS_EN | \
+   GDM_TCS_EN | \
+   GDM_UCS_EN | \
+   (DP_PDMA << MYMAC_DP_S) | \
+   (DP_PDMA << BC_DP_S) | \
+   (DP_PDMA << MC_DP_S) | \
+   (DP_PDMA << UN_DP_S))
+
 #define GDMA_FWD_DISCARD \
(0x2000 | \
GDM_ICS_EN | \
@@ -68,7 +78,8 @@
 enum mtk_switch {
SW_NONE,
SW_MT7530,
-   SW_MT7531
+   SW_MT7531,
+   SW_MT7988,
 };
 
 /* struct mtk_soc_data -   This is the structure holding all differences
@@ -102,6 +113,7 @@ struct mtk_eth_priv {
void __iomem *fe_base;
void __iomem *gmac_base;
void __iomem *sgmii_base;
+   void __iomem *gsw_base;
 
struct regmap *ethsys_regmap;
 
@@ -171,6 +183,11 @@ static void mtk_gdma_write(struct mtk_eth_priv *priv, int 
no, u32 reg,
writel(val, priv->fe_base + gdma_base + reg);
 }
 
+static void mtk_fe_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr, u32 set)
+{
+   clrsetbits_le32(priv->fe_base + reg, clr, set);
+}
+
 static u32 mtk_gmac_read(struct mtk_eth_priv *priv, u32 reg)
 {
return readl(priv->gmac_base + reg);
@@ -208,6 +225,16 @@ static void mtk_infra_rmw(struct mtk_eth_priv *priv, u32 
reg, u32 clr,
regmap_write(priv->infra_regmap, reg, val);
 }
 
+static u32 mtk_gsw_read(struct mtk_eth_priv *priv, u32 reg)
+{
+   return readl(priv->gsw_base + reg);
+}
+
+static void mtk_gsw_write(struct mtk_eth_priv *priv, u32 reg, u32 val)
+{
+   writel(val, priv->gsw_base + reg);
+}
+
 /* Direct MDIO clause 22/45 access via SoC */
 static int mtk_mii_rw(struct mtk_eth_priv *priv, u8 phy, u8 reg, u16 data,
  u32 cmd, u32 st)
@@ -342,6 +369,11 @@ static int mt753x_reg_read(struct mtk_eth_priv *priv, u32 
reg, u32 *data)
 {
int ret, low_word, high_word;
 
+   if (priv->sw == SW_MT7988) {
+   *data = mtk_gsw_read(priv, reg);
+   return 0;
+   }
+
/* Write page address */
ret = mtk_mii_write(priv, priv->mt753x_smi_addr, 0x1f, reg >> 6);
if (ret)
@@ -367,6 +399,11 @@ static int mt753x_reg_write(struct mtk_eth_priv *priv, u32 
reg, u32 data)
 {
int ret;
 
+   if (priv->sw == SW_MT7988) {
+   mtk_gsw_write(priv, reg, data);
+   return 0;
+   }
+
/* Write page address */
ret = mtk_mii_write(priv, priv->mt753x_smi_addr, 0x1f, reg >> 6);
if (ret)
@@ -537,6 +574,7 @@ static int mtk_mdio_register(struct udevice *dev)
priv->mmd_write = mtk_mmd_ind_write;
break;
case SW_MT7531:
+   case SW_MT7988:
priv->mii_read = mt7531_mii_ind_read;
priv->mii_write = mt7531_mii_ind_write;
priv->mmd_read = mt7531_mmd_ind_read;
@@ -957,6 +995,103 @@ static int mt7531_setup(struct mtk_eth_priv *priv)
return 0;
 }
 
+static void mt7988_phy_setting(struct mtk_eth_priv *priv)
+{
+   u16 val;
+   u32 i;
+
+   for (i = 0; i < MT753X_NUM_PHYS; i++) {
+   /* Enable HW auto downshift */
+   priv->mii_write(priv, i, 0x1f, 0x1);
+   val = priv->mii_read(priv, i, PHY_EXT_REG_14);
+   val |= PHY_EN_DOWN_SHFIT;
+   priv->mii_write(priv, i, PHY_EXT_REG_14, val);
+
+   /* PHY link down power saving enable */
+   val = priv->mii_read(priv, i, PHY_EXT_REG_17);
+   val |= PHY_LINKDOWN_POWER_SAVING_EN;
+   priv->mii_write(priv, i, PHY_EXT_REG_17, val);
+   }
+}
+
+static void mt7988_mac_control(struct mtk_eth_priv *priv, bool enable)
+{
+   u32 pmcr = FORCE_MODE_LNK;
+
+   if (enable)
+   pmcr = priv->mt753x_pmcr;
+
+   mt753x_reg_write(priv, PMCR_REG(6), pmcr);
+}
+
+static int mt7988_setup(struct mtk_eth_priv *priv)
+{
+   u16 phy_addr, phy_val;
+   u32 pmcr;
+   int i;
+
+   priv->gsw_base = regmap_get_range(priv->ethsys_regmap, 0) + GSW_BASE;
+
+   priv->mt753x_phy_base = (priv->mt753x_smi_addr + 1) &
+   MT753X_SMI_ADDR_MASK;
+
+   /* Turn off PHYs */
+   for (i = 0; i

[PATCH 25/29] net: mediatek: add support for NETSYS v3

2023-07-19 Thread Weijie Gao
This patch adds support for NETSYS v3 hardware.
Comparing to NETSYS v2, NETSYS v3 has three GMACs.

Signed-off-by: Weijie Gao 
---
 drivers/net/mtk_eth.c | 49 ---
 drivers/net/mtk_eth.h |  7 +++
 2 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c
index c99ab5dbea..e0dc180e3c 100644
--- a/drivers/net/mtk_eth.c
+++ b/drivers/net/mtk_eth.c
@@ -76,6 +76,7 @@ enum mtk_switch {
  * @caps   Flags shown the extra capability for the SoC
  * @ana_rgc3:  The offset for register ANA_RGC3 related to
  * sgmiisys syscon
+ * @gdma_count:Number of GDMAs
  * @pdma_base: Register base of PDMA block
  * @txd_size:  Tx DMA descriptor size.
  * @rxd_size:  Rx DMA descriptor size.
@@ -83,6 +84,7 @@ enum mtk_switch {
 struct mtk_soc_data {
u32 caps;
u32 ana_rgc3;
+   u32 gdma_count;
u32 pdma_base;
u32 txd_size;
u32 rxd_size;
@@ -159,7 +161,9 @@ static void mtk_gdma_write(struct mtk_eth_priv *priv, int 
no, u32 reg,
 {
u32 gdma_base;
 
-   if (no == 1)
+   if (no == 2)
+   gdma_base = GDMA3_BASE;
+   else if (no == 1)
gdma_base = GDMA2_BASE;
else
gdma_base = GDMA1_BASE;
@@ -1429,7 +1433,10 @@ 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;
 
-   if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2))
+   if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V3))
+   txd->txd5 = PDMA_V2_TXD5_FPORT_SET(priv->gmac_id == 2 ?
+  15 : priv->gmac_id + 
1);
+   else 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);
@@ -1442,7 +1449,8 @@ static void mtk_eth_fifo_init(struct mtk_eth_priv *priv)
 
rxd->rxd1 = virt_to_phys(pkt_base);
 
-   if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2))
+   if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2) ||
+   MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V3))
rxd->rxd2 = PDMA_V2_RXD2_PLEN0_SET(PKTSIZE_ALIGN);
else
rxd->rxd2 = PDMA_V1_RXD2_PLEN0_SET(PKTSIZE_ALIGN);
@@ -1466,7 +1474,7 @@ static void mtk_eth_fifo_init(struct mtk_eth_priv *priv)
 static int mtk_eth_start(struct udevice *dev)
 {
struct mtk_eth_priv *priv = dev_get_priv(dev);
-   int ret;
+   int i, ret;
 
/* Reset FE */
reset_assert(>rst_fe);
@@ -1474,16 +1482,24 @@ static int mtk_eth_start(struct udevice *dev)
reset_deassert(>rst_fe);
mdelay(10);
 
-   if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2))
+   if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2) ||
+   MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V3))
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);
 
-   if (priv->gmac_id == 0)
-   mtk_gdma_write(priv, 1, GDMA_IG_CTRL_REG, GDMA_FWD_DISCARD);
-   else
-   mtk_gdma_write(priv, 0, GDMA_IG_CTRL_REG, GDMA_FWD_DISCARD);
+   for (i = 0; i < priv->soc->gdma_count; i++) {
+   if (i == priv->gmac_id)
+   continue;
+
+   mtk_gdma_write(priv, i, GDMA_IG_CTRL_REG, GDMA_FWD_DISCARD);
+   }
+
+   if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V3)) {
+   mtk_gdma_write(priv, priv->gmac_id, GDMA_EG_CTRL_REG,
+  GDMA_CPU_BRIDGE_EN);
+   }
 
udelay(500);
 
@@ -1557,7 +1573,8 @@ 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));
 
-   if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2))
+   if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2) ||
+   MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V3))
txd->txd2 = PDMA_TXD2_LS0 | PDMA_V2_TXD2_SDL0_SET(length);
else
txd->txd2 = PDMA_TXD2_LS0 | PDMA_V1_TXD2_SDL0_SET(length);
@@ -1583,7 +1600,8 @@ static int mtk_eth_recv(struct udevice *dev, int flags, 
uchar **packetp)
return -EAGAIN;
}
 
-   if (MTK_HAS_CAPS(priv->soc->caps, 

[PATCH 24/29] net: mediatek: add USXGMII support

2023-07-19 Thread Weijie Gao
This patch adds support for USXGMII of SoC.

Signed-off-by: Weijie Gao 
---
 drivers/net/mtk_eth.c | 230 +-
 drivers/net/mtk_eth.h |  24 +
 2 files changed, 251 insertions(+), 3 deletions(-)

diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c
index 064b4a41db..c99ab5dbea 100644
--- a/drivers/net/mtk_eth.c
+++ b/drivers/net/mtk_eth.c
@@ -105,6 +105,11 @@ struct mtk_eth_priv {
 
struct regmap *infra_regmap;
 
+   struct regmap *usxgmii_regmap;
+   struct regmap *xfi_pextp_regmap;
+   struct regmap *xfi_pll_regmap;
+   struct regmap *toprgu_regmap;
+
struct mii_dev *mdio_bus;
int (*mii_read)(struct mtk_eth_priv *priv, u8 phy, u8 reg);
int (*mii_write)(struct mtk_eth_priv *priv, u8 phy, u8 reg, u16 val);
@@ -989,6 +994,42 @@ static int mt753x_switch_init(struct mtk_eth_priv *priv)
return 0;
 }
 
+static void mtk_xphy_link_adjust(struct mtk_eth_priv *priv)
+{
+   u16 lcl_adv = 0, rmt_adv = 0;
+   u8 flowctrl;
+   u32 mcr;
+
+   mcr = mtk_gmac_read(priv, XGMAC_PORT_MCR(priv->gmac_id));
+   mcr &= ~(XGMAC_FORCE_TX_FC | XGMAC_FORCE_RX_FC);
+
+   if (priv->phydev->duplex) {
+   if (priv->phydev->pause)
+   rmt_adv = LPA_PAUSE_CAP;
+   if (priv->phydev->asym_pause)
+   rmt_adv |= LPA_PAUSE_ASYM;
+
+   if (priv->phydev->advertising & ADVERTISED_Pause)
+   lcl_adv |= ADVERTISE_PAUSE_CAP;
+   if (priv->phydev->advertising & ADVERTISED_Asym_Pause)
+   lcl_adv |= ADVERTISE_PAUSE_ASYM;
+
+   flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
+
+   if (flowctrl & FLOW_CTRL_TX)
+   mcr |= XGMAC_FORCE_TX_FC;
+   if (flowctrl & FLOW_CTRL_RX)
+   mcr |= XGMAC_FORCE_RX_FC;
+
+   debug("rx pause %s, tx pause %s\n",
+ flowctrl & FLOW_CTRL_RX ? "enabled" : "disabled",
+ flowctrl & FLOW_CTRL_TX ? "enabled" : "disabled");
+   }
+
+   mcr &= ~(XGMAC_TRX_DISABLE);
+   mtk_gmac_write(priv, XGMAC_PORT_MCR(priv->gmac_id), mcr);
+}
+
 static void mtk_phy_link_adjust(struct mtk_eth_priv *priv)
 {
u16 lcl_adv = 0, rmt_adv = 0;
@@ -1063,8 +1104,12 @@ static int mtk_phy_start(struct mtk_eth_priv *priv)
return 0;
}
 
-   if (!priv->force_mode)
-   mtk_phy_link_adjust(priv);
+   if (!priv->force_mode) {
+   if (priv->phy_interface == PHY_INTERFACE_MODE_USXGMII)
+   mtk_xphy_link_adjust(priv);
+   else
+   mtk_phy_link_adjust(priv);
+   }
 
debug("Speed: %d, %s duplex%s\n", phydev->speed,
  (phydev->duplex) ? "full" : "half",
@@ -1140,6 +1185,112 @@ static void mtk_sgmii_force_init(struct mtk_eth_priv 
*priv)
SGMII_PHYA_PWD, 0);
 }
 
+static void mtk_xfi_pll_enable(struct mtk_eth_priv *priv)
+{
+   u32 val = 0;
+
+   /* Add software workaround for USXGMII PLL TCL issue */
+   regmap_write(priv->xfi_pll_regmap, XFI_PLL_ANA_GLB8,
+RG_XFI_PLL_ANA_SWWA);
+
+   regmap_read(priv->xfi_pll_regmap, XFI_PLL_DIG_GLB8, );
+   val |= RG_XFI_PLL_EN;
+   regmap_write(priv->xfi_pll_regmap, XFI_PLL_DIG_GLB8, val);
+}
+
+static void mtk_usxgmii_reset(struct mtk_eth_priv *priv)
+{
+   switch (priv->gmac_id) {
+   case 1:
+   regmap_write(priv->toprgu_regmap, 0xFC, 0xA004);
+   regmap_write(priv->toprgu_regmap, 0x18, 0x88F0A004);
+   regmap_write(priv->toprgu_regmap, 0xFC, 0x);
+   regmap_write(priv->toprgu_regmap, 0x18, 0x88F0);
+   regmap_write(priv->toprgu_regmap, 0x18, 0x00F0);
+   break;
+   case 2:
+   regmap_write(priv->toprgu_regmap, 0xFC, 0x5002);
+   regmap_write(priv->toprgu_regmap, 0x18, 0x88F05002);
+   regmap_write(priv->toprgu_regmap, 0xFC, 0x);
+   regmap_write(priv->toprgu_regmap, 0x18, 0x88F0);
+   regmap_write(priv->toprgu_regmap, 0x18, 0x00F0);
+   break;
+   }
+
+   mdelay(10);
+}
+
+static void mtk_usxgmii_setup_phya_an_1(struct mtk_eth_priv *priv)
+{
+   regmap_write(priv->usxgmii_regmap, 0x810, 0x000FFE6D);
+   regmap_write(priv->usxgmii_regmap, 0x818, 0x07B1EC7B);
+   regmap_write(priv->usxgmii_regmap, 0x80C, 0x3000);
+   ndelay(1020);
+   regmap_write(priv->usxgmii_regmap, 0x80C, 0x1000);
+   ndelay(1020);
+   regmap_write(priv->usxgmii_regmap, 0x80C, 0x);
+
+  

[PATCH 23/29] arm: dts: mediatek: add infracfg registers to support GMAC/USB3 Co-PHY

2023-07-19 Thread Weijie Gao
This patch adds infracfg to eth node to support enabling GMAC2.

Signed-off-by: Weijie Gao 
---
 arch/arm/dts/mt7981.dtsi | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/dts/mt7981.dtsi b/arch/arm/dts/mt7981.dtsi
index 2053e2ca00..7aaa7770f8 100644
--- a/arch/arm/dts/mt7981.dtsi
+++ b/arch/arm/dts/mt7981.dtsi
@@ -237,6 +237,7 @@
reset-names = "fe";
mediatek,ethsys = <>;
mediatek,sgmiisys = <>;
+   mediatek,infracfg = <>;
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -255,6 +256,12 @@
#clock-cells = <1>;
};
 
+   topmisc: topmisc@11d1 {
+   compatible = "mediatek,mt7981-topmisc", "syscon";
+   reg = <0x11d1 0x1>;
+   #clock-cells = <1>;
+   };
+
spi0: spi@1100a000 {
compatible = "mediatek,ipm-spi";
reg = <0x1100a000 0x100>;
-- 
2.17.1



[PATCH 22/29] net: mediatek: add support for GMAC/USB3 PHY mux mode for MT7981

2023-07-19 Thread Weijie Gao
MT7981 has its GMAC2 PHY shared with USB3. To enable GMAC2, mux
register must be set to connect the SGMII phy to GMAC2.

Signed-off-by: Weijie Gao 
---
 drivers/net/mtk_eth.c | 33 -
 drivers/net/mtk_eth.h | 16 
 2 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c
index e0064276d0..064b4a41db 100644
--- a/drivers/net/mtk_eth.c
+++ b/drivers/net/mtk_eth.c
@@ -103,6 +103,8 @@ struct mtk_eth_priv {
 
struct regmap *ethsys_regmap;
 
+   struct regmap *infra_regmap;
+
struct mii_dev *mdio_bus;
int (*mii_read)(struct mtk_eth_priv *priv, u8 phy, u8 reg);
int (*mii_write)(struct mtk_eth_priv *priv, u8 phy, u8 reg, u16 val);
@@ -186,6 +188,17 @@ static void mtk_ethsys_rmw(struct mtk_eth_priv *priv, u32 
reg, u32 clr,
regmap_write(priv->ethsys_regmap, reg, val);
 }
 
+static void mtk_infra_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr,
+ u32 set)
+{
+   uint val;
+
+   regmap_read(priv->infra_regmap, reg, );
+   val &= ~clr;
+   val |= set;
+   regmap_write(priv->infra_regmap, reg, val);
+}
+
 /* Direct MDIO clause 22/45 access via SoC */
 static int mtk_mii_rw(struct mtk_eth_priv *priv, u8 phy, u8 reg, u16 data,
  u32 cmd, u32 st)
@@ -1139,6 +1152,11 @@ static void mtk_mac_init(struct mtk_eth_priv *priv)
break;
case PHY_INTERFACE_MODE_SGMII:
case PHY_INTERFACE_MODE_2500BASEX:
+   if (MTK_HAS_CAPS(priv->soc->caps, MTK_GMAC2_U3_QPHY)) {
+   mtk_infra_rmw(priv, USB_PHY_SWITCH_REG, QPHY_SEL_MASK,
+ SGMII_QPHY_SEL);
+   }
+
ge_mode = GE_MODE_RGMII;
mtk_ethsys_rmw(priv, ETHSYS_SYSCFG0_REG, SYSCFG0_SGMII_SEL_M,
   SYSCFG0_SGMII_SEL(priv->gmac_id));
@@ -1497,6 +1515,19 @@ static int mtk_eth_of_to_plat(struct udevice *dev)
if (IS_ERR(priv->ethsys_regmap))
return PTR_ERR(priv->ethsys_regmap);
 
+   if (MTK_HAS_CAPS(priv->soc->caps, MTK_INFRA)) {
+   /* get corresponding infracfg phandle */
+   ret = dev_read_phandle_with_args(dev, "mediatek,infracfg",
+NULL, 0, 0, );
+
+   if (ret)
+   return ret;
+
+   priv->infra_regmap = syscon_node_to_regmap(args.node);
+   if (IS_ERR(priv->infra_regmap))
+   return PTR_ERR(priv->infra_regmap);
+   }
+
/* Reset controllers */
ret = reset_get_by_name(dev, "fe", >rst_fe);
if (ret) {
@@ -1614,7 +1645,7 @@ static const struct mtk_soc_data mt7986_data = {
 };
 
 static const struct mtk_soc_data mt7981_data = {
-   .caps = MT7986_CAPS,
+   .caps = MT7981_CAPS,
.ana_rgc3 = 0x128,
.pdma_base = PDMA_V2_BASE,
.txd_size = sizeof(struct mtk_tx_dma_v2),
diff --git a/drivers/net/mtk_eth.h b/drivers/net/mtk_eth.h
index 320266cd82..519986c01e 100644
--- a/drivers/net/mtk_eth.h
+++ b/drivers/net/mtk_eth.h
@@ -15,27 +15,38 @@
 enum mkt_eth_capabilities {
MTK_TRGMII_BIT,
MTK_TRGMII_MT7621_CLK_BIT,
+   MTK_U3_COPHY_V2_BIT,
+   MTK_INFRA_BIT,
MTK_NETSYS_V2_BIT,
 
/* PATH BITS */
MTK_ETH_PATH_GMAC1_TRGMII_BIT,
+   MTK_ETH_PATH_GMAC2_SGMII_BIT,
 };
 
 #define MTK_TRGMII BIT(MTK_TRGMII_BIT)
 #define MTK_TRGMII_MT7621_CLK  BIT(MTK_TRGMII_MT7621_CLK_BIT)
+#define MTK_U3_COPHY_V2BIT(MTK_U3_COPHY_V2_BIT)
+#define MTK_INFRA  BIT(MTK_INFRA_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)
 
+#define MTK_ETH_PATH_GMAC2_SGMII   BIT(MTK_ETH_PATH_GMAC2_SGMII_BIT)
+
 #define MTK_GMAC1_TRGMII   (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII)
 
+#define MTK_GMAC2_U3_QPHY  (MTK_ETH_PATH_GMAC2_SGMII | MTK_U3_COPHY_V2 | 
MTK_INFRA)
+
 #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)
 
+#define MT7981_CAPS  (MTK_GMAC2_U3_QPHY | MTK_NETSYS_V2)
+
 #define MT7986_CAPS  (MTK_NETSYS_V2)
 
 /* Frame Engine Register Bases */
@@ -56,6 +67,11 @@ enum mkt_eth_capabilities {
 #define ETHSYS_CLKCFG0_REG 0x2c
 #define ETHSYS_TRGMII_CLK_SEL362_5 BIT(11)
 
+/* Top misc registers */
+#define USB_PHY_SWITCH_REG 0x218
+#define QPHY_SEL_MASK  0x3
+#define SGMII_QPHY_SEL 0x2
+
 /* SYSCFG0_GE_MODE: GE Modes */
 #define GE_MODE_RGMII  0
 #define GE_MODE_MII1
-- 
2.17.1



[PATCH 21/29] arm: dts: medaitek: convert gmac link mode to 2500base-x

2023-07-19 Thread Weijie Gao
Now that individual 2.5Gbps SGMII support has been added to
mtk-eth, all boards that use 2.5Gbps link with mt7531 must be
converted to use "2500base-x" instead of "sgmii".

Signed-off-by: Weijie Gao 
---
 arch/arm/dts/mt7622-bananapi-bpi-r64.dts | 4 ++--
 arch/arm/dts/mt7622-rfb.dts  | 4 ++--
 arch/arm/dts/mt7629-rfb.dts  | 4 ++--
 arch/arm/dts/mt7981-emmc-rfb.dts | 4 ++--
 arch/arm/dts/mt7981-rfb.dts  | 4 ++--
 arch/arm/dts/mt7981-sd-rfb.dts   | 4 ++--
 arch/arm/dts/mt7986a-rfb.dts | 4 ++--
 arch/arm/dts/mt7986a-sd-rfb.dts  | 4 ++--
 arch/arm/dts/mt7986b-rfb.dts | 4 ++--
 arch/arm/dts/mt7986b-sd-rfb.dts  | 4 ++--
 10 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/arch/arm/dts/mt7622-bananapi-bpi-r64.dts 
b/arch/arm/dts/mt7622-bananapi-bpi-r64.dts
index 7c55744ac7..717baf26d3 100644
--- a/arch/arm/dts/mt7622-bananapi-bpi-r64.dts
+++ b/arch/arm/dts/mt7622-bananapi-bpi-r64.dts
@@ -224,12 +224,12 @@
  {
status = "okay";
mediatek,gmac-id = <0>;
-   phy-mode = "sgmii";
+   phy-mode = "2500base-x";
mediatek,switch = "mt7531";
reset-gpios = < 54 GPIO_ACTIVE_HIGH>;
 
fixed-link {
-   speed = <1000>;
+   speed = <2500>;
full-duplex;
};
 };
diff --git a/arch/arm/dts/mt7622-rfb.dts b/arch/arm/dts/mt7622-rfb.dts
index 886a133e05..321de75ae3 100644
--- a/arch/arm/dts/mt7622-rfb.dts
+++ b/arch/arm/dts/mt7622-rfb.dts
@@ -233,12 +233,12 @@
  {
status = "okay";
mediatek,gmac-id = <0>;
-   phy-mode = "sgmii";
+   phy-mode = "2500base-x";
mediatek,switch = "mt7531";
reset-gpios = < 54 GPIO_ACTIVE_HIGH>;
 
fixed-link {
-   speed = <1000>;
+   speed = <2500>;
full-duplex;
};
 };
diff --git a/arch/arm/dts/mt7629-rfb.dts b/arch/arm/dts/mt7629-rfb.dts
index 82f6a34162..f347725f2f 100644
--- a/arch/arm/dts/mt7629-rfb.dts
+++ b/arch/arm/dts/mt7629-rfb.dts
@@ -25,12 +25,12 @@
  {
status = "okay";
mediatek,gmac-id = <0>;
-   phy-mode = "sgmii";
+   phy-mode = "2500base-x";
mediatek,switch = "mt7531";
reset-gpios = < 28 GPIO_ACTIVE_HIGH>;
 
fixed-link {
-   speed = <1000>;
+   speed = <2500>;
full-duplex;
};
 };
diff --git a/arch/arm/dts/mt7981-emmc-rfb.dts b/arch/arm/dts/mt7981-emmc-rfb.dts
index a0913c5b7c..9aa7cd8f6e 100644
--- a/arch/arm/dts/mt7981-emmc-rfb.dts
+++ b/arch/arm/dts/mt7981-emmc-rfb.dts
@@ -46,12 +46,12 @@
  {
status = "okay";
mediatek,gmac-id = <0>;
-   phy-mode = "sgmii";
+   phy-mode = "2500base-x";
mediatek,switch = "mt7531";
reset-gpios = < 39 GPIO_ACTIVE_HIGH>;
 
fixed-link {
-   speed = <1000>;
+   speed = <2500>;
full-duplex;
};
 };
diff --git a/arch/arm/dts/mt7981-rfb.dts b/arch/arm/dts/mt7981-rfb.dts
index 1dc90ac63f..22a022acb6 100644
--- a/arch/arm/dts/mt7981-rfb.dts
+++ b/arch/arm/dts/mt7981-rfb.dts
@@ -37,12 +37,12 @@
  {
status = "okay";
mediatek,gmac-id = <0>;
-   phy-mode = "sgmii";
+   phy-mode = "2500base-x";
mediatek,switch = "mt7531";
reset-gpios = < 39 GPIO_ACTIVE_HIGH>;
 
fixed-link {
-   speed = <1000>;
+   speed = <2500>;
full-duplex;
};
 };
diff --git a/arch/arm/dts/mt7981-sd-rfb.dts b/arch/arm/dts/mt7981-sd-rfb.dts
index 05f3fdb5ef..7d70808404 100644
--- a/arch/arm/dts/mt7981-sd-rfb.dts
+++ b/arch/arm/dts/mt7981-sd-rfb.dts
@@ -46,12 +46,12 @@
  {
status = "okay";
mediatek,gmac-id = <0>;
-   phy-mode = "sgmii";
+   phy-mode = "2500base-x";
mediatek,switch = "mt7531";
reset-gpios = < 39 GPIO_ACTIVE_HIGH>;
 
fixed-link {
-   speed = <1000>;
+   speed = <2500>;
full-duplex;
};
 };
diff --git a/arch/arm/dts/mt7986a-rfb.dts b/arch/arm/dts/mt7986a-rfb.dts
index dce85d8277..e5c9be7da8 100644
--- a/arch/arm/dts/mt7986a-rfb.dts
+++ b/arch/arm/dts/mt7986a-rfb.dts
@@ -55,12 +55,12 @@
  {
status = "okay";
mediatek,gmac-id = <0>;
-   phy-mode = "sgmii";
+   phy-mode = "2500base-x";
mediatek,switch = "mt7531";
reset-gpios = < 5 GPIO_ACTIVE_HIGH>;
 
fixed-link {
-   speed = <1000>;
+   speed = &

[PATCH 20/29] net: mediatek: add support for SGMII 1Gbps auto-negotiation mode

2023-07-19 Thread Weijie Gao
Existing SGMII support of mtk-eth is actually a MediaTek-specific
2.5Gbps high-speed SGMII (HSGMII) which does not support
auto-negotiation mode.

This patch adds SGMII 1Gbps auto-negotiation mode and rename the
existing HSGMII to 2500basex.

Signed-off-by: Weijie Gao 
---
 drivers/net/mtk_eth.c | 46 +--
 drivers/net/mtk_eth.h |  2 ++
 2 files changed, 42 insertions(+), 6 deletions(-)

diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c
index 2b4a862695..e0064276d0 100644
--- a/drivers/net/mtk_eth.c
+++ b/drivers/net/mtk_eth.c
@@ -893,7 +893,7 @@ static int mt7531_setup(struct mtk_eth_priv *priv)
if (!port5_sgmii)
mt7531_port_rgmii_init(priv, 5);
break;
-   case PHY_INTERFACE_MODE_SGMII:
+   case PHY_INTERFACE_MODE_2500BASEX:
mt7531_port_sgmii_init(priv, 6);
if (port5_sgmii)
mt7531_port_sgmii_init(priv, 5);
@@ -986,6 +986,7 @@ static void mtk_phy_link_adjust(struct mtk_eth_priv *priv)
  (MAC_RX_PKT_LEN_1536 << MAC_RX_PKT_LEN_S) |
  MAC_MODE | FORCE_MODE |
  MAC_TX_EN | MAC_RX_EN |
+ DEL_RXFIFO_CLR |
  BKOFF_EN | BACKPR_EN;
 
switch (priv->phydev->speed) {
@@ -996,6 +997,7 @@ static void mtk_phy_link_adjust(struct mtk_eth_priv *priv)
mcr |= (SPEED_100M << FORCE_SPD_S);
break;
case SPEED_1000:
+   case SPEED_2500:
mcr |= (SPEED_1000M << FORCE_SPD_S);
break;
};
@@ -1048,7 +1050,8 @@ static int mtk_phy_start(struct mtk_eth_priv *priv)
return 0;
}
 
-   mtk_phy_link_adjust(priv);
+   if (!priv->force_mode)
+   mtk_phy_link_adjust(priv);
 
debug("Speed: %d, %s duplex%s\n", phydev->speed,
  (phydev->duplex) ? "full" : "half",
@@ -1076,7 +1079,31 @@ static int mtk_phy_probe(struct udevice *dev)
return 0;
 }
 
-static void mtk_sgmii_init(struct mtk_eth_priv *priv)
+static void mtk_sgmii_an_init(struct mtk_eth_priv *priv)
+{
+   /* Set SGMII GEN1 speed(1G) */
+   clrsetbits_le32(priv->sgmii_base + priv->soc->ana_rgc3,
+   SGMSYS_SPEED_2500, 0);
+
+   /* Enable SGMII AN */
+   setbits_le32(priv->sgmii_base + SGMSYS_PCS_CONTROL_1,
+SGMII_AN_ENABLE);
+
+   /* SGMII AN mode setting */
+   writel(SGMII_AN_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);
+}
+
+static void mtk_sgmii_force_init(struct mtk_eth_priv *priv)
 {
/* Set SGMII GEN2 speed(2.5G) */
setbits_le32(priv->sgmii_base + priv->soc->ana_rgc3,
@@ -,10 +1138,14 @@ static void mtk_mac_init(struct mtk_eth_priv *priv)
ge_mode = GE_MODE_RGMII;
break;
case PHY_INTERFACE_MODE_SGMII:
+   case PHY_INTERFACE_MODE_2500BASEX:
ge_mode = GE_MODE_RGMII;
mtk_ethsys_rmw(priv, ETHSYS_SYSCFG0_REG, SYSCFG0_SGMII_SEL_M,
   SYSCFG0_SGMII_SEL(priv->gmac_id));
-   mtk_sgmii_init(priv);
+   if (priv->phy_interface == PHY_INTERFACE_MODE_SGMII)
+   mtk_sgmii_an_init(priv);
+   else
+   mtk_sgmii_force_init(priv);
break;
case PHY_INTERFACE_MODE_MII:
case PHY_INTERFACE_MODE_GMII:
@@ -1148,6 +1179,7 @@ static void mtk_mac_init(struct mtk_eth_priv *priv)
mcr |= SPEED_100M << FORCE_SPD_S;
break;
case SPEED_1000:
+   case SPEED_2500:
mcr |= SPEED_1000M << FORCE_SPD_S;
break;
}
@@ -1490,13 +1522,15 @@ static int mtk_eth_of_to_plat(struct udevice *dev)
priv->duplex = ofnode_read_bool(subnode, "full-duplex");
 
if (priv->speed != SPEED_10 && priv->speed != SPEED_100 &&
-   priv->speed != SPEED_1000) {
+   priv->speed != SPEED_1000 && priv->speed != SPEED_2500 &&
+   priv->speed != SPEED_1) {
printf("error: no valid speed set in fixed-link\n");
return -EINVAL;
}
}
 
-   if (priv->phy_interface == PHY_INTERFACE_MODE_SGMII) {
+   if (priv->phy_interface == PHY_INTERFACE_MODE_SGMII ||

[PATCH 19/29] net: mediatek: add missing static qualifier

2023-07-19 Thread Weijie Gao
mt7531_mmd_ind_read and mt753x_switch_init are defined without static.
Since they're not used outside this file, we should add them back.

Signed-off-by: Weijie Gao 

fixup to add static qualifier
---
 drivers/net/mtk_eth.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c
index 61a1c29e36..2b4a862695 100644
--- a/drivers/net/mtk_eth.c
+++ b/drivers/net/mtk_eth.c
@@ -436,7 +436,8 @@ static int mt7531_mii_ind_write(struct mtk_eth_priv *priv, 
u8 phy, u8 reg,
 MDIO_ST_C22);
 }
 
-int mt7531_mmd_ind_read(struct mtk_eth_priv *priv, u8 addr, u8 devad, u16 reg)
+static int mt7531_mmd_ind_read(struct mtk_eth_priv *priv, u8 addr, u8 devad,
+  u16 reg)
 {
u8 phy_addr;
int ret;
@@ -934,7 +935,7 @@ static int mt7531_setup(struct mtk_eth_priv *priv)
return 0;
 }
 
-int mt753x_switch_init(struct mtk_eth_priv *priv)
+static int mt753x_switch_init(struct mtk_eth_priv *priv)
 {
int ret;
int i;
-- 
2.17.1



[PATCH 18/29] net: mediatek: fix direct MDIO clause 45 access via SoC

2023-07-19 Thread Weijie Gao
The original direct MDIO clause 45 access via SoC is missing the
data output. This patch adds it back to ensure MDIO clause 45 can
work properly for external PHYs.

Signed-off-by: Weijie Gao 
---
 drivers/net/mtk_eth.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c
index cd72070ff6..61a1c29e36 100644
--- a/drivers/net/mtk_eth.c
+++ b/drivers/net/mtk_eth.c
@@ -198,7 +198,7 @@ static int mtk_mii_rw(struct mtk_eth_priv *priv, u8 phy, u8 
reg, u16 data,
  (((u32)phy << MDIO_PHY_ADDR_S) & MDIO_PHY_ADDR_M) |
  (((u32)reg << MDIO_REG_ADDR_S) & MDIO_REG_ADDR_M);
 
-   if (cmd == MDIO_CMD_WRITE)
+   if (cmd == MDIO_CMD_WRITE || cmd == MDIO_CMD_ADDR)
val |= data & MDIO_RW_DATA_M;
 
mtk_gmac_write(priv, GMAC_PIAC_REG, val | PHY_ACS_ST);
@@ -210,7 +210,7 @@ static int mtk_mii_rw(struct mtk_eth_priv *priv, u8 phy, u8 
reg, u16 data,
return ret;
}
 
-   if (cmd == MDIO_CMD_READ) {
+   if (cmd == MDIO_CMD_READ || cmd == MDIO_CMD_READ_C45) {
val = mtk_gmac_read(priv, GMAC_PIAC_REG);
return val & MDIO_RW_DATA_M;
}
-- 
2.17.1



[PATCH 16/29] net: mediatek: connect switch to PSE only when starting eth is requested

2023-07-19 Thread Weijie Gao
So far the switch is initialized in probe stage and is connected to PSE
unconditionally. This will cause all packets being flooded to PSE and may
cause PSE hang before entering linux.

This patch changes the connection between switch and PSE:
- Still initialize switch in probe stage, but disconnect it with PSE
- Connect switch with PSE on eth start
- Disconnect on eth stop

Signed-off-by: Weijie Gao 
---
 drivers/net/mtk_eth.c | 44 ---
 1 file changed, 41 insertions(+), 3 deletions(-)

diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c
index 4c9fb266c7..90f1d2591b 100644
--- a/drivers/net/mtk_eth.c
+++ b/drivers/net/mtk_eth.c
@@ -123,8 +123,10 @@ struct mtk_eth_priv {
 
enum mtk_switch sw;
int (*switch_init)(struct mtk_eth_priv *priv);
+   void (*switch_mac_control)(struct mtk_eth_priv *priv, bool enable);
u32 mt753x_smi_addr;
u32 mt753x_phy_base;
+   u32 mt753x_pmcr;
 
struct gpio_desc rst_gpio;
int mcm;
@@ -613,6 +615,16 @@ static int mt7530_pad_clk_setup(struct mtk_eth_priv *priv, 
int mode)
return 0;
 }
 
+static void mt7530_mac_control(struct mtk_eth_priv *priv, bool enable)
+{
+   u32 pmcr = FORCE_MODE;
+
+   if (enable)
+   pmcr = priv->mt753x_pmcr;
+
+   mt753x_reg_write(priv, PMCR_REG(6), pmcr);
+}
+
 static int mt7530_setup(struct mtk_eth_priv *priv)
 {
u16 phy_addr, phy_val;
@@ -663,11 +675,14 @@ static int mt7530_setup(struct mtk_eth_priv *priv)
  FORCE_DPX | FORCE_LINK;
 
/* MT7530 Port6: Forced 1000M/FD, FC disabled */
-   mt753x_reg_write(priv, PMCR_REG(6), val);
+   priv->mt753x_pmcr = val;
 
/* MT7530 Port5: Forced link down */
mt753x_reg_write(priv, PMCR_REG(5), FORCE_MODE);
 
+   /* Keep MAC link down before starting eth */
+   mt753x_reg_write(priv, PMCR_REG(6), FORCE_MODE);
+
/* MT7530 Port6: Set to RGMII */
mt753x_reg_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_M, P6_INTF_MODE_RGMII);
 
@@ -823,6 +838,17 @@ static void mt7531_phy_setting(struct mtk_eth_priv *priv)
}
 }
 
+static void mt7531_mac_control(struct mtk_eth_priv *priv, bool enable)
+{
+   u32 pmcr = FORCE_MODE_LNK;
+
+   if (enable)
+   pmcr = priv->mt753x_pmcr;
+
+   mt753x_reg_write(priv, PMCR_REG(5), pmcr);
+   mt753x_reg_write(priv, PMCR_REG(6), pmcr);
+}
+
 static int mt7531_setup(struct mtk_eth_priv *priv)
 {
u16 phy_addr, phy_val;
@@ -882,8 +908,11 @@ static int mt7531_setup(struct mtk_eth_priv *priv)
   (SPEED_1000M << FORCE_SPD_S) | FORCE_DPX |
   FORCE_LINK;
 
-   mt753x_reg_write(priv, PMCR_REG(5), pmcr);
-   mt753x_reg_write(priv, PMCR_REG(6), pmcr);
+   priv->mt753x_pmcr = pmcr;
+
+   /* Keep MAC link down before starting eth */
+   mt753x_reg_write(priv, PMCR_REG(5), FORCE_MODE_LNK);
+   mt753x_reg_write(priv, PMCR_REG(6), FORCE_MODE_LNK);
 
/* Turn on PHYs */
for (i = 0; i < MT753X_NUM_PHYS; i++) {
@@ -1227,6 +1256,9 @@ static int mtk_eth_start(struct udevice *dev)
 
mtk_eth_fifo_init(priv);
 
+   if (priv->switch_mac_control)
+   priv->switch_mac_control(priv, true);
+
/* Start PHY */
if (priv->sw == SW_NONE) {
ret = mtk_phy_start(priv);
@@ -1245,6 +1277,9 @@ static void mtk_eth_stop(struct udevice *dev)
 {
struct mtk_eth_priv *priv = dev_get_priv(dev);
 
+   if (priv->switch_mac_control)
+   priv->switch_mac_control(priv, false);
+
mtk_pdma_rmw(priv, PDMA_GLO_CFG_REG,
 TX_WB_DDONE | RX_DMA_EN | TX_DMA_EN, 0);
udelay(500);
@@ -1484,16 +1519,19 @@ static int mtk_eth_of_to_plat(struct udevice *dev)
/* check for switch first, otherwise phy will be used */
priv->sw = SW_NONE;
priv->switch_init = NULL;
+   priv->switch_mac_control = NULL;
str = dev_read_string(dev, "mediatek,switch");
 
if (str) {
if (!strcmp(str, "mt7530")) {
priv->sw = SW_MT7530;
priv->switch_init = mt7530_setup;
+   priv->switch_mac_control = mt7530_mac_control;
priv->mt753x_smi_addr = MT753X_DFL_SMI_ADDR;
} else if (!strcmp(str, "mt7531")) {
priv->sw = SW_MT7531;
priv->switch_init = mt7531_setup;
+   priv->switch_mac_control = mt7531_mac_control;
priv->mt753x_smi_addr = MT753X_DFL_SMI_ADDR;
} else {
printf("error: unsupported switch\n");
-- 
2.17.1



[PATCH 17/29] net: mediatek: optimize the switch reset delay wait time

2023-07-19 Thread Weijie Gao
Not all switches requires 1 second delay after deasserting reset.
MT7531 requires only maximum 200ms.

This patch defines dedicated reset wait time for each switch chip, and will
significantly improve the boot time for boards using MT7531.

Signed-off-by: Weijie Gao 
---
 drivers/net/mtk_eth.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c
index 90f1d2591b..cd72070ff6 100644
--- a/drivers/net/mtk_eth.c
+++ b/drivers/net/mtk_eth.c
@@ -127,6 +127,7 @@ struct mtk_eth_priv {
u32 mt753x_smi_addr;
u32 mt753x_phy_base;
u32 mt753x_pmcr;
+   u32 mt753x_reset_wait_time;
 
struct gpio_desc rst_gpio;
int mcm;
@@ -943,12 +944,12 @@ int mt753x_switch_init(struct mtk_eth_priv *priv)
reset_assert(>rst_mcm);
udelay(1000);
reset_deassert(>rst_mcm);
-   mdelay(1000);
+   mdelay(priv->mt753x_reset_wait_time);
} else if (dm_gpio_is_valid(>rst_gpio)) {
dm_gpio_set_value(>rst_gpio, 0);
udelay(1000);
dm_gpio_set_value(>rst_gpio, 1);
-   mdelay(1000);
+   mdelay(priv->mt753x_reset_wait_time);
}
 
ret = priv->switch_init(priv);
@@ -1528,11 +1529,13 @@ static int mtk_eth_of_to_plat(struct udevice *dev)
priv->switch_init = mt7530_setup;
priv->switch_mac_control = mt7530_mac_control;
priv->mt753x_smi_addr = MT753X_DFL_SMI_ADDR;
+   priv->mt753x_reset_wait_time = 1000;
} else if (!strcmp(str, "mt7531")) {
priv->sw = SW_MT7531;
priv->switch_init = mt7531_setup;
priv->switch_mac_control = mt7531_mac_control;
priv->mt753x_smi_addr = MT753X_DFL_SMI_ADDR;
+   priv->mt753x_reset_wait_time = 200;
} else {
printf("error: unsupported switch\n");
return -EINVAL;
-- 
2.17.1



[PATCH 15/29] pinctrl: mediatek: add pinctrl driver for MT7988 SoC

2023-07-19 Thread Weijie Gao
This patch adds pinctrl and gpio support for MT7988 SoC

Signed-off-by: Weijie Gao 
---
 drivers/pinctrl/mediatek/Kconfig  |4 +
 drivers/pinctrl/mediatek/Makefile |1 +
 drivers/pinctrl/mediatek/pinctrl-mt7988.c | 1274 +
 3 files changed, 1279 insertions(+)
 create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt7988.c

diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
index 27e8998e59..34d23cece5 100644
--- a/drivers/pinctrl/mediatek/Kconfig
+++ b/drivers/pinctrl/mediatek/Kconfig
@@ -24,6 +24,10 @@ config PINCTRL_MT7986
bool "MT7986 SoC pinctrl driver"
select PINCTRL_MTK
 
+config PINCTRL_MT7988
+   bool "MT7988 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 6e733759f5..de39d1ea43 100644
--- a/drivers/pinctrl/mediatek/Makefile
+++ b/drivers/pinctrl/mediatek/Makefile
@@ -8,6 +8,7 @@ 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_MT7988) += pinctrl-mt7988.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-mt7988.c 
b/drivers/pinctrl/mediatek/pinctrl-mt7988.c
new file mode 100644
index 00..03a38e83df
--- /dev/null
+++ b/drivers/pinctrl/mediatek/pinctrl-mt7988.c
@@ -0,0 +1,1274 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Sam Shih 
+ */
+
+#include 
+#include "pinctrl-mtk-common.h"
+
+enum MT7988_PINCTRL_REG_PAGE {
+   GPIO_BASE,
+   IOCFG_TR_BASE,
+   IOCFG_BR_BASE,
+   IOCFG_RB_BASE,
+   IOCFG_LB_BASE,
+   IOCFG_TL_BASE,
+};
+
+#define MT7988_TYPE0_PIN(_number, _name)   
\
+   MTK_TYPED_PIN(_number, _name, DRV_GRP4, IO_TYPE_GRP0)
+
+#define MT7988_TYPE1_PIN(_number, _name)   
\
+   MTK_TYPED_PIN(_number, _name, DRV_GRP4, IO_TYPE_GRP1)
+
+#define MT7988_TYPE2_PIN(_number, _name)   
\
+   MTK_TYPED_PIN(_number, _name, DRV_FIXED, IO_TYPE_GRP2)
+
+#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)
+
+#define PINS_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, 1)
+
+static const struct mtk_pin_field_calc mt7988_pin_mode_range[] = {
+   PIN_FIELD_GPIO(0, 83, 0x300, 0x10, 0, 4),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_dir_range[] = {
+   PIN_FIELD_GPIO(0, 83, 0x0, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_di_range[] = {
+   PIN_FIELD_GPIO(0, 83, 0x200, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_do_range[] = {
+   PIN_FIELD_GPIO(0, 83, 0x100, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_ies_range[] = {
+   PIN_FIELD_BASE(0, 0, IOCFG_TL_BASE, 0x30, 0x10, 13, 1),
+   PIN_FIELD_BASE(1, 1, IOCFG_TL_BASE, 0x30, 0x10, 14, 1),
+   PIN_FIELD_BASE(2, 2, IOCFG_TL_BASE, 0x30, 0x10, 11, 1),
+   PIN_FIELD_BASE(3, 3, IOCFG_TL_BASE, 0x30, 0x10, 12, 1),
+   PIN_FIELD_BASE(4, 4, IOCFG_TL_BASE, 0x30, 0x10, 0, 1),
+   PIN_FIELD_BASE(5, 5, IOCFG_TL_BASE, 0x30, 0x10, 9, 1),
+   PIN_FIELD_BASE(6, 6, IOCFG_TL_BASE, 0x30, 0x10, 10, 1),
+
+   PIN_FIELD_BASE(7, 7, IOCFG_LB_BASE, 0x30, 0x10, 8, 1),
+   PIN_FIELD_BASE(8, 8, IOCFG_LB_BASE, 0x30, 0x10, 6, 1),
+   PIN_FIELD_BASE(9, 9, IOCFG_LB_BASE, 0x30, 0x10, 5, 1),
+   PIN_FIELD_BASE(10, 10, IOCFG_LB_BASE, 0x30, 0x10, 3, 1),
+
+   PIN_FIELD_BASE(11, 11, IOCFG_TR_BASE, 0x40, 0x10, 0, 1),
+   PIN_FIELD_BASE(12, 12, IOCFG_TR_BASE, 0x40, 0x10, 21, 1),
+   PIN_FIELD_BASE(13, 13, IOCFG_TR_BASE, 0x40, 0x10, 1, 1),
+   PIN_FIELD_BASE(14, 14, IOCFG_TR_BASE, 0x40, 0x10, 2, 1),
+
+   PIN_FIELD_BASE(15, 15, IOCFG_TL_BASE, 0x30, 0x10, 7, 1),
+   PIN_FIELD_BASE(16, 16, IOCFG_TL_BASE, 0x30, 0x10, 8, 1),
+   PIN_FIELD_BASE

[PATCH 14/29] pinctrl: mediatek: add pinmux_set ops support

2023-07-19 Thread Weijie Gao
This patch adds pinmux_set ops for mediatek pinctrl framework

Signed-off-by: Sam Shih 
Signed-off-by: Weijie Gao 
---
 drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c 
b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
index 623a094c39..0baef57c1c 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
@@ -304,6 +304,19 @@ static const char *mtk_get_function_name(struct udevice 
*dev,
return priv->soc->funcs[selector].name;
 }
 
+static int mtk_pinmux_set(struct udevice *dev, unsigned int pin_selector,
+ unsigned int func_selector)
+{
+   int err;
+
+   err = mtk_hw_set_value(dev, pin_selector, PINCTRL_PIN_REG_MODE,
+  func_selector);
+   if (err)
+   return err;
+
+   return 0;
+}
+
 static int mtk_pinmux_group_set(struct udevice *dev,
unsigned int group_selector,
unsigned int func_selector)
@@ -647,6 +660,7 @@ const struct pinctrl_ops mtk_pinctrl_ops = {
.get_group_name = mtk_get_group_name,
.get_functions_count = mtk_get_functions_count,
.get_function_name = mtk_get_function_name,
+   .pinmux_set = mtk_pinmux_set,
.pinmux_group_set = mtk_pinmux_group_set,
 #if CONFIG_IS_ENABLED(PINCONF)
.pinconf_num_params = ARRAY_SIZE(mtk_conf_params),
-- 
2.17.1



[PATCH 13/29] pinctrl: mediatek: fix the return value in driving configuration functions

2023-07-19 Thread Weijie Gao
The original mediatek pinctrl functions for driving configuration
'mtk_pinconf_drive_set_*' do not return -ENOSUPP even if input
parameters are not supported.
This patch fixes the return value in those functions.

Signed-off-by: Sam Shih 
Signed-off-by: Weijie Gao 
---
 drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c 
b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
index 1caca3496c..623a094c39 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
@@ -513,7 +513,7 @@ int mtk_pinconf_drive_set_v0(struct udevice *dev, u32 pin, 
u32 arg)
return err;
}
 
-   return 0;
+   return err;
 }
 
 int mtk_pinconf_drive_set_v1(struct udevice *dev, u32 pin, u32 arg)
@@ -531,7 +531,7 @@ int mtk_pinconf_drive_set_v1(struct udevice *dev, u32 pin, 
u32 arg)
return err;
}
 
-   return 0;
+   return err;
 }
 
 int mtk_pinconf_drive_set(struct udevice *dev, u32 pin, u32 arg)
-- 
2.17.1



[PATCH 10/29] clk: mediatek: add clock driver support for MediaTek MT7988 SoC

2023-07-19 Thread Weijie Gao
This patch adds clock driver support for MediaTek MT7988 SoC

Signed-off-by: Weijie Gao 
---
 drivers/clk/mediatek/Makefile  |1 +
 drivers/clk/mediatek/clk-mt7988.c  | 1123 
 include/dt-bindings/clock/mt7988-clk.h |  349 
 3 files changed, 1473 insertions(+)
 create mode 100644 drivers/clk/mediatek/clk-mt7988.c
 create mode 100644 include/dt-bindings/clock/mt7988-clk.h

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 1decf31a77..e74c6f9780 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -9,6 +9,7 @@ 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_MT7988) += clk-mt7988.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-mt7988.c 
b/drivers/clk/mediatek/clk-mt7988.c
new file mode 100644
index 00..34e7b2d734
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt7988.c
@@ -0,0 +1,1123 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek clock driver for MT7988 SoC
+ *
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Sam Shih 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "clk-mtk.h"
+
+#define MT7988_CLK_PDN 0x250
+#define MT7988_CLK_PDN_EN_WRITE BIT(31)
+
+#define MT7988_ETHDMA_RST_CTRL_OFS 0x34
+#define MT7988_ETHWARP_RST_CTRL_OFS0x8
+
+#define XTAL_FACTOR(_id, _name, _parent, _mult, _div)  
\
+   FACTOR(_id, _parent, _mult, _div, CLK_PARENT_XTAL)
+
+#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 apmixedsys_mtk_plls[] = {
+   FIXED_CLK(CK_APMIXED_NETSYSPLL, CLK_XTAL, 85000),
+   FIXED_CLK(CK_APMIXED_MPLL, CLK_XTAL, 41600),
+   FIXED_CLK(CK_APMIXED_MMPLL, CLK_XTAL, 72000),
+   FIXED_CLK(CK_APMIXED_APLL2, CLK_XTAL, 196608000),
+   FIXED_CLK(CK_APMIXED_NET1PLL, CLK_XTAL, 25),
+   FIXED_CLK(CK_APMIXED_NET2PLL, CLK_XTAL, 8),
+   FIXED_CLK(CK_APMIXED_WEDMCUPLL, CLK_XTAL, 20800),
+   FIXED_CLK(CK_APMIXED_SGMPLL, CLK_XTAL, 32500),
+   FIXED_CLK(CK_APMIXED_ARM_B, CLK_XTAL, 15),
+   FIXED_CLK(CK_APMIXED_CCIPLL2_B, CLK_XTAL, 96000),
+   FIXED_CLK(CK_APMIXED_USXGMIIPLL, CLK_XTAL, 644533000),
+   FIXED_CLK(CK_APMIXED_MSDCPLL, CLK_XTAL, 4),
+};
+
+/* TOPCKGEN FIXED DIV */
+static const struct mtk_fixed_factor topckgen_mtk_fixed_factors[] = {
+   XTAL_FACTOR(CK_TOP_CB_CKSQ_40M, "cb_cksq_40m", CLK_XTAL, 1, 1),
+   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_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_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_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_CB_APLL2_D4, "cb_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_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

[PATCH 11/29] reset: mediatek: add reset definition for MediaTek MT7988 SoC

2023-07-19 Thread Weijie Gao
This patch adds reset bits for MediaTek MT7988

Signed-off-by: Sam Shih 
Signed-off-by: Weijie Gao 
---
 include/dt-bindings/reset/mt7988-reset.h | 31 
 1 file changed, 31 insertions(+)
 create mode 100644 include/dt-bindings/reset/mt7988-reset.h

diff --git a/include/dt-bindings/reset/mt7988-reset.h 
b/include/dt-bindings/reset/mt7988-reset.h
new file mode 100644
index 00..d30011f941
--- /dev/null
+++ b/include/dt-bindings/reset/mt7988-reset.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2023 MediaTek Inc.
+ */
+
+#ifndef _DT_BINDINGS_MTK_RESET_H_
+#define _DT_BINDINGS_MTK_RESET_H_
+
+/* ETHDMA Subsystem resets */
+#define ETHDMA_FE_RST  6
+#define ETHDMA_PMTR_RST8
+#define ETHDMA_GMAC_RST23
+#define ETHDMA_WDMA0_RST   24
+#define ETHDMA_WDMA1_RST   25
+#define ETHDMA_WDMA2_RST   26
+#define ETHDMA_PPE0_RST29
+#define ETHDMA_PPE1_RST30
+#define ETHDMA_PPE2_RST31
+
+/* ETHWARP Subsystem resets */
+#define ETHWARP_GSW_RST9
+#define ETHWARP_EIP197_RST 10
+#define ETHWARP_WOCPU0_RST 32
+#define ETHWARP_WOCPU1_RST 33
+#define ETHWARP_WOCPU2_RST 34
+#define ETHWARP_WOX_NET_MUX_RST35
+#define ETHWARP_WED0_RST   36
+#define ETHWARP_WED1_RST   37
+#define ETHWARP_WED2_RST   38
+
+#endif /* _DT_BINDINGS_MTK_RESET_H_ */
-- 
2.17.1



[PATCH 09/29] pwm: mtk: add support for MediaTek MT7988 SoC

2023-07-19 Thread Weijie Gao
This patch adds PWM support for MediaTek MT7988 SoC.

Signed-off-by: Weijie Gao 
---
 drivers/pwm/pwm-mtk.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/pwm/pwm-mtk.c b/drivers/pwm/pwm-mtk.c
index 605142eab0..11e7444019 100644
--- a/drivers/pwm/pwm-mtk.c
+++ b/drivers/pwm/pwm-mtk.c
@@ -205,12 +205,19 @@ static const struct mtk_pwm_soc mt7986_data = {
.reg_ver = PWM_REG_V1,
 };
 
+static const struct mtk_pwm_soc mt7988_data = {
+   .num_pwms = 8,
+   .pwm45_fixup = false,
+   .reg_ver = PWM_REG_V2,
+};
+
 static const struct udevice_id mtk_pwm_ids[] = {
{ .compatible = "mediatek,mt7622-pwm", .data = (ulong)_data },
{ .compatible = "mediatek,mt7623-pwm", .data = (ulong)_data },
{ .compatible = "mediatek,mt7629-pwm", .data = (ulong)_data },
{ .compatible = "mediatek,mt7981-pwm", .data = (ulong)_data },
{ .compatible = "mediatek,mt7986-pwm", .data = (ulong)_data },
+   { .compatible = "mediatek,mt7988-pwm", .data = (ulong)_data },
{ }
 };
 
-- 
2.17.1



[PATCH 08/29] arm: dts: enable i2c support for MediaTek MT7981

2023-07-19 Thread Weijie Gao
This patch enables i2c support for MediaTek MT7981

Signed-off-by: Sam Shih 
Signed-off-by: Weijie Gao 
---
 arch/arm/dts/mt7981.dtsi | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm/dts/mt7981.dtsi b/arch/arm/dts/mt7981.dtsi
index 2c8ef14f98..2053e2ca00 100644
--- a/arch/arm/dts/mt7981.dtsi
+++ b/arch/arm/dts/mt7981.dtsi
@@ -152,6 +152,20 @@
status = "disabled";
};
 
+   i2c0: i2c@11007000 {
+   compatible = "mediatek,mt7981-i2c";
+   reg = <0x11007000 0x1000>,
+ <0x10217080 0x80>;
+   interrupts = ;
+   clock-div = <1>;
+   clocks = <_ao CK_INFRA_I2CO_CK>,
+<_ao CK_INFRA_AP_DMA_CK>;
+   clock-names = "main", "dma";
+   #address-cells = <1>;
+   #size-cells = <0>;
+   status = "disabled";
+   };
+
uart0: serial@11002000 {
compatible = "mediatek,hsuart";
reg = <0x11002000 0x400>;
-- 
2.17.1



[PATCH 07/29] i2c: mediatek: fix I2C usability for MT7981

2023-07-19 Thread Weijie Gao
MT7981 actually uses MediaTek I2C controller v3 instead of v1.
This patch adds support for I2C controller v3 fix fixes the I2C usability
for MT7981.

Signed-off-by: Sam Shih 
Signed-off-by: Weijie Gao 
---
 drivers/i2c/mtk_i2c.c | 45 +--
 1 file changed, 43 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/mtk_i2c.c b/drivers/i2c/mtk_i2c.c
index 5528bcd7cc..2f331d3216 100644
--- a/drivers/i2c/mtk_i2c.c
+++ b/drivers/i2c/mtk_i2c.c
@@ -183,9 +183,36 @@ static const uint mt_i2c_regs_v2[] = {
[REG_DCM_EN] = 0xf88,
 };
 
+static const uint mt_i2c_regs_v3[] = {
+   [REG_PORT] = 0x0,
+   [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_SLAVE_ADDR] = 0x94,
+   [REG_DEBUGSTAT] = 0xe4,
+   [REG_DEBUGCTRL] = 0xe8,
+   [REG_FIFO_STAT] = 0xf4,
+   [REG_FIFO_THRESH] = 0xf8,
+   [REG_DCM_EN] = 0xf88,
+};
+
 struct mtk_i2c_soc_data {
const uint *regs;
uint dma_sync: 1;
+   uint ltiming_adjust: 1;
 };
 
 struct mtk_i2c_priv {
@@ -401,6 +428,10 @@ static int mtk_i2c_set_speed(struct udevice *dev, uint 
speed)
(sample_cnt << HS_SAMPLE_OFFSET) |
(step_cnt << HS_STEP_OFFSET);
i2c_writel(priv, REG_HS, high_speed_reg);
+   if (priv->soc_data->ltiming_adjust) {
+   timing_reg = (sample_cnt << 12) | (step_cnt << 9);
+   i2c_writel(priv, REG_LTIMING, timing_reg);
+   }
} else {
ret = mtk_i2c_calculate_speed(clk_src, priv->speed,
  _cnt, _cnt);
@@ -412,7 +443,12 @@ static int mtk_i2c_set_speed(struct udevice *dev, uint 
speed)
high_speed_reg = I2C_TIME_CLR_VALUE;
i2c_writel(priv, REG_TIMING, timing_reg);
i2c_writel(priv, REG_HS, high_speed_reg);
+   if (priv->soc_data->ltiming_adjust) {
+   timing_reg = (sample_cnt << 6) | step_cnt;
+   i2c_writel(priv, REG_LTIMING, timing_reg);
+   }
}
+
 exit:
if (mtk_i2c_clk_disable(priv))
return log_msg_ret("set_speed disable clk", -1);
@@ -725,7 +761,6 @@ static int mtk_i2c_probe(struct udevice *dev)
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);
 
@@ -750,31 +785,37 @@ static int mtk_i2c_deblock(struct udevice *dev)
 static const struct mtk_i2c_soc_data mt76xx_soc_data = {
.regs = mt_i2c_regs_v1,
.dma_sync = 0,
+   .ltiming_adjust = 0,
 };
 
 static const struct mtk_i2c_soc_data mt7981_soc_data = {
-   .regs = mt_i2c_regs_v1,
+   .regs = mt_i2c_regs_v3,
.dma_sync = 1,
+   .ltiming_adjust = 1,
 };
 
 static const struct mtk_i2c_soc_data mt7986_soc_data = {
.regs = mt_i2c_regs_v1,
.dma_sync = 1,
+   .ltiming_adjust = 0,
 };
 
 static const struct mtk_i2c_soc_data mt8183_soc_data = {
.regs = mt_i2c_regs_v2,
.dma_sync = 1,
+   .ltiming_adjust = 0,
 };
 
 static const struct mtk_i2c_soc_data mt8518_soc_data = {
.regs = mt_i2c_regs_v1,
.dma_sync = 0,
+   .ltiming_adjust = 0,
 };
 
 static const struct mtk_i2c_soc_data mt8512_soc_data = {
.regs = mt_i2c_regs_v1,
.dma_sync = 1,
+   .ltiming_adjust = 0,
 };
 
 static const struct dm_i2c_ops mtk_i2c_ops = {
-- 
2.17.1



[PATCH 06/29] reset: mediatek: check malloc return valaue before use

2023-07-19 Thread Weijie Gao
This patch add missing return value check for allocating the driver's
private data. -ENOMEM will be returned if malloc() fails.

Signed-off-by: Sam Shih 
Signed-off-by: Weijie Gao 
---
 drivers/reset/reset-mediatek.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/reset/reset-mediatek.c b/drivers/reset/reset-mediatek.c
index 8b62d91777..97ed221f73 100644
--- a/drivers/reset/reset-mediatek.c
+++ b/drivers/reset/reset-mediatek.c
@@ -79,6 +79,9 @@ int mediatek_reset_bind(struct udevice *pdev, u32 regofs, u32 
num_regs)
return ret;
 
priv = malloc(sizeof(struct mediatek_reset_priv));
+   if (!priv)
+   return -ENOMEM;
+
priv->regofs = regofs;
priv->nr_resets = num_regs * 32;
dev_set_priv(rst_dev, priv);
-- 
2.17.1



[PATCH 05/29] serial: mtk: initial priv data before using

2023-07-19 Thread Weijie Gao
This patch ensures driver private data being fully initialized in
_debug_uart_init which is not covered by .priv_auto ops.

Signed-off-by: Sam Shih 
Signed-off-by: Weijie Gao 
---
 drivers/serial/serial_mtk.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/serial/serial_mtk.c b/drivers/serial/serial_mtk.c
index ded7346a13..2dffa14ea7 100644
--- a/drivers/serial/serial_mtk.c
+++ b/drivers/serial/serial_mtk.c
@@ -439,6 +439,7 @@ static inline void _debug_uart_init(void)
 {
struct mtk_serial_priv priv;
 
+   memset(, 0, sizeof(struct mtk_serial_priv));
priv.regs = (void *) CONFIG_VAL(DEBUG_UART_BASE);
priv.fixed_clk_rate = CONFIG_DEBUG_UART_CLOCK;
 
-- 
2.17.1



[PATCH 04/29] spi: mtk_spim: clear IRQ enable bits

2023-07-19 Thread Weijie Gao
In u-boot we don't use IRQ. Instead, we poll busy bit in SPI_STATUS.

However these IRQ enable bits may be set in previous boot stage (BootROM).

If we leave these bits not cleared, although u-boot has disabled IRQ and
nothing will happen, the linux kernel may encounter panic during
initializing the spim driver due to IRQ event happens before IRQ handler
is properly setup.

This patch clear IRQ bits to prevent this from happening.

Signed-off-by: SkyLake.Huang 
Signed-off-by: Weijie Gao 
---
 drivers/spi/mtk_spim.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/spi/mtk_spim.c b/drivers/spi/mtk_spim.c
index 3a742d160c..418e586b91 100644
--- a/drivers/spi/mtk_spim.c
+++ b/drivers/spi/mtk_spim.c
@@ -242,6 +242,9 @@ static int mtk_spim_hw_init(struct spi_slave *slave)
reg_val &= ~SPI_CMD_SAMPLE_SEL;
}
 
+   /* Disable interrupt enable for pause mode & normal mode */
+   reg_val &= ~(SPI_CMD_PAUSE_IE | SPI_CMD_FINISH_IE);
+
/* disable dma mode */
reg_val &= ~(SPI_CMD_TX_DMA | SPI_CMD_RX_DMA);
 
-- 
2.17.1



[PATCH 01/29] arm: mediatek: retrieve ram_base from dts node for armv8 platform

2023-07-19 Thread Weijie Gao
Now we use fdtdec_setup_mem_size_base() to get DRAM base from fdt ram node
and update gd->ram_base. CFG_SYS_SDRAM_BASE is unused and will be removed.

Also, since mt7622 always passes fdt to linux kernel, there's no need to
assign value to gd->bd->bi_boot_params.

Signed-off-by: Weijie Gao 
---
 arch/arm/dts/mt7981-emmc-rfb.dts |  5 +
 arch/arm/dts/mt7981-rfb.dts  |  5 +
 arch/arm/dts/mt7981-sd-rfb.dts   |  5 +
 arch/arm/dts/mt7986a-bpi-r3-sd.dts   |  5 +
 arch/arm/dts/mt7986a-rfb.dts |  5 +
 arch/arm/dts/mt7986a-sd-rfb.dts  |  5 +
 arch/arm/dts/mt7986b-rfb.dts |  5 +
 arch/arm/dts/mt7986b-sd-rfb.dts  |  5 +
 arch/arm/mach-mediatek/mt7622/init.c | 13 +
 arch/arm/mach-mediatek/mt7981/init.c | 11 +--
 arch/arm/mach-mediatek/mt7986/init.c | 11 +--
 board/mediatek/mt7622/mt7622_rfb.c   |  1 -
 include/configs/mt7622.h | 10 --
 include/configs/mt7981.h |  9 -
 include/configs/mt7986.h |  9 -
 15 files changed, 67 insertions(+), 37 deletions(-)

diff --git a/arch/arm/dts/mt7981-emmc-rfb.dts b/arch/arm/dts/mt7981-emmc-rfb.dts
index 2b7eae99ce..a0913c5b7c 100644
--- a/arch/arm/dts/mt7981-emmc-rfb.dts
+++ b/arch/arm/dts/mt7981-emmc-rfb.dts
@@ -18,6 +18,11 @@
tick-timer = 
};
 
+   memory@4000 {
+   device_type = "memory";
+   reg = <0x4000 0x1000>;
+   };
+
reg_3p3v: regulator-3p3v {
  compatible = "regulator-fixed";
  regulator-name = "fixed-3.3V";
diff --git a/arch/arm/dts/mt7981-rfb.dts b/arch/arm/dts/mt7981-rfb.dts
index 5559ace953..1dc90ac63f 100644
--- a/arch/arm/dts/mt7981-rfb.dts
+++ b/arch/arm/dts/mt7981-rfb.dts
@@ -17,6 +17,11 @@
stdout-path = 
tick-timer = 
};
+
+   memory@4000 {
+   device_type = "memory";
+   reg = <0x4000 0x1000>;
+   };
 };
 
  {
diff --git a/arch/arm/dts/mt7981-sd-rfb.dts b/arch/arm/dts/mt7981-sd-rfb.dts
index 34ac227ecf..05f3fdb5ef 100644
--- a/arch/arm/dts/mt7981-sd-rfb.dts
+++ b/arch/arm/dts/mt7981-sd-rfb.dts
@@ -18,6 +18,11 @@
tick-timer = 
};
 
+   memory@4000 {
+   device_type = "memory";
+   reg = <0x4000 0x1000>;
+   };
+
reg_3p3v: regulator-3p3v {
  compatible = "regulator-fixed";
  regulator-name = "fixed-3.3V";
diff --git a/arch/arm/dts/mt7986a-bpi-r3-sd.dts 
b/arch/arm/dts/mt7986a-bpi-r3-sd.dts
index 4d12440fa3..15256302b8 100644
--- a/arch/arm/dts/mt7986a-bpi-r3-sd.dts
+++ b/arch/arm/dts/mt7986a-bpi-r3-sd.dts
@@ -19,6 +19,11 @@
tick-timer = 
};
 
+   memory@4000 {
+   device_type = "memory";
+   reg = <0x4000 0x8000>;
+   };
+
reg_3p3v: regulator-3p3v {
compatible = "regulator-fixed";
regulator-name = "fixed-3.3V";
diff --git a/arch/arm/dts/mt7986a-rfb.dts b/arch/arm/dts/mt7986a-rfb.dts
index 80def57e1a..dce85d8277 100644
--- a/arch/arm/dts/mt7986a-rfb.dts
+++ b/arch/arm/dts/mt7986a-rfb.dts
@@ -18,6 +18,11 @@
tick-timer = 
};
 
+   memory@4000 {
+   device_type = "memory";
+   reg = <0x4000 0x1000>;
+   };
+
reg_1p8v: regulator-1p8v {
compatible = "regulator-fixed";
regulator-name = "fixed-1.8V";
diff --git a/arch/arm/dts/mt7986a-sd-rfb.dts b/arch/arm/dts/mt7986a-sd-rfb.dts
index 5807c5d5cc..7f32607589 100644
--- a/arch/arm/dts/mt7986a-sd-rfb.dts
+++ b/arch/arm/dts/mt7986a-sd-rfb.dts
@@ -19,6 +19,11 @@
tick-timer = 
};
 
+   memory@4000 {
+   device_type = "memory";
+   reg = <0x4000 0x1000>;
+   };
+
reg_3p3v: regulator-3p3v {
compatible = "regulator-fixed";
regulator-name = "fixed-3.3V";
diff --git a/arch/arm/dts/mt7986b-rfb.dts b/arch/arm/dts/mt7986b-rfb.dts
index 0c4e3e878f..3349e38a90 100644
--- a/arch/arm/dts/mt7986b-rfb.dts
+++ b/arch/arm/dts/mt7986b-rfb.dts
@@ -18,6 +18,11 @@
tick-timer = 
};
 
+   memory@4000 {
+   device_type = "memory";
+   reg = <0x4000 0x1000>;
+   };
+
reg_3p3v: regulator-3p3v {
compatible = "regulator-fixed";
regulator-name = "fixed-3.3V";
diff --git a/arch/arm/dts/mt7986b-sd-rfb.dts b/arch/arm/dts/mt7986b-sd-rfb.dts
index 48f9320e7a..6c9203332b 100644
--- a/arch/arm/dts/mt7986b-sd-rfb.dts
+++ b/arch/arm/dt

[PATCH 03/29] spi: mtk_spim: get spi clk rate only once

2023-07-19 Thread Weijie Gao
We don't really need to switch clk rate during operating SPIM controller.
Get clk rate only once at driver probing.

Signed-off-by: SkyLake.Huang 
Signed-off-by: Weijie Gao 
---
 drivers/spi/mtk_spim.c | 21 +
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/spi/mtk_spim.c b/drivers/spi/mtk_spim.c
index ebb8ee8ef4..3a742d160c 100644
--- a/drivers/spi/mtk_spim.c
+++ b/drivers/spi/mtk_spim.c
@@ -137,6 +137,8 @@ struct mtk_spim_capability {
  * @state: Controller state
  * @sel_clk:   Pad clock
  * @spi_clk:   Core clock
+ * @pll_clk_rate:  Controller's PLL source clock rate, which is different
+ * from SPI bus clock rate
  * @xfer_len:  Current length of data for transfer
  * @hw_cap:Controller capabilities
  * @tick_dly:  Used to postpone SPI sampling time
@@ -149,6 +151,7 @@ struct mtk_spim_priv {
void __iomem *base;
u32 state;
struct clk sel_clk, spi_clk;
+   u32 pll_clk_rate;
u32 xfer_len;
struct mtk_spim_capability hw_cap;
u32 tick_dly;
@@ -253,11 +256,10 @@ static int mtk_spim_hw_init(struct spi_slave *slave)
 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;
+   u32 div, sck_time, cs_time, reg_val;
 
-   spi_clk_hz = clk_get_rate(>spi_clk);
-   if (speed_hz <= spi_clk_hz / 4)
-   div = DIV_ROUND_UP(spi_clk_hz, speed_hz);
+   if (speed_hz <= priv->pll_clk_rate / 4)
+   div = DIV_ROUND_UP(priv->pll_clk_rate, speed_hz);
else
div = 4;
 
@@ -404,7 +406,7 @@ static int mtk_spim_transfer_wait(struct spi_slave *slave,
 {
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;
+   u32 sck_l, sck_h, clk_count, reg;
ulong us = 1;
int ret = 0;
 
@@ -413,12 +415,11 @@ static int mtk_spim_transfer_wait(struct spi_slave *slave,
else
clk_count = op->data.nbytes;
 
-   spi_bus_clk = clk_get_rate(>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);
+   do_div(priv->pll_clk_rate, sck_l + sck_h + 2);
 
-   us = CLK_TO_US(spi_bus_clk, clk_count * 8);
+   us = CLK_TO_US(priv->pll_clk_rate, clk_count * 8);
us += 1000 * 1000; /* 1s tolerance */
 
if (us > UINT_MAX)
@@ -662,6 +663,10 @@ static int mtk_spim_probe(struct udevice *dev)
clk_enable(>sel_clk);
clk_enable(>spi_clk);
 
+   priv->pll_clk_rate = clk_get_rate(>spi_clk);
+   if (priv->pll_clk_rate == 0)
+   return -EINVAL;
+
return 0;
 }
 
-- 
2.17.1



[PATCH 02/29] board: mediatek: update config headers

2023-07-19 Thread Weijie Gao
Remove unused information from include/configs/mt.h

Signed-off-by: Weijie Gao 
---
 include/configs/mt7620.h |  3 +--
 include/configs/mt7621.h |  6 ++
 include/configs/mt7623.h |  8 
 include/configs/mt7628.h |  5 ++---
 include/configs/mt7629.h | 13 +
 5 files changed, 6 insertions(+), 29 deletions(-)

diff --git a/include/configs/mt7620.h b/include/configs/mt7620.h
index d5bd492634..d69d35fa96 100644
--- a/include/configs/mt7620.h
+++ b/include/configs/mt7620.h
@@ -10,10 +10,9 @@
 
 #define CFG_SYS_SDRAM_BASE 0x8000
 
-#define CFG_SYS_INIT_SP_OFFSET 0x40
+#define CFG_SYS_INIT_SP_OFFSET 0x40
 
 /* SPL */
-
 #define CFG_SYS_UBOOT_STARTCONFIG_TEXT_BASE
 
 /* Dummy value */
diff --git a/include/configs/mt7621.h b/include/configs/mt7621.h
index a9574940d4..bf2bc2d45c 100644
--- a/include/configs/mt7621.h
+++ b/include/configs/mt7621.h
@@ -12,13 +12,11 @@
 
 #define CFG_MAX_MEM_MAPPED 0x1c00
 
-#define CFG_SYS_INIT_SP_OFFSET 0x80
+#define CFG_SYS_INIT_SP_OFFSET 0x80
 
 /* MMC */
 #define MMC_SUPPORTS_TUNING
 
-/* NAND */
-
 /* Serial SPL */
 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_SERIAL)
 #define CFG_SYS_NS16550_CLK5000
@@ -26,7 +24,7 @@
 #endif
 
 /* Serial common */
-#define CFG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \
+#define CFG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \
  230400, 460800, 921600 }
 
 /* Dummy value */
diff --git a/include/configs/mt7623.h b/include/configs/mt7623.h
index db12377b00..fca234a1dc 100644
--- a/include/configs/mt7623.h
+++ b/include/configs/mt7623.h
@@ -11,12 +11,6 @@
 
 #include 
 
-/* Miscellaneous configurable options */
-
-/* Environment */
-
-/* Preloader -> Uboot */
-
 /* MMC */
 #define MMC_SUPPORTS_TUNING
 
@@ -32,8 +26,6 @@
"fdt_addr_r=" FDT_HIGH "\0" \
"fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0"
 
-/* Ethernet */
-
 #ifdef CONFIG_DISTRO_DEFAULTS
 
 #define BOOT_TARGET_DEVICES(func)  \
diff --git a/include/configs/mt7628.h b/include/configs/mt7628.h
index 9df2715fc7..0ac376d33c 100644
--- a/include/configs/mt7628.h
+++ b/include/configs/mt7628.h
@@ -10,7 +10,7 @@
 
 #define CFG_SYS_SDRAM_BASE 0x8000
 
-#define CFG_SYS_INIT_SP_OFFSET 0x8
+#define CFG_SYS_INIT_SP_OFFSET 0x8
 
 /* Serial SPL */
 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_SERIAL)
@@ -19,11 +19,10 @@
 #endif
 
 /* Serial common */
-#define CFG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \
+#define CFG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \
  230400, 460800, 921600 }
 
 /* SPL */
-
 #define CFG_SYS_UBOOT_STARTCONFIG_TEXT_BASE
 
 /* Dummy value */
diff --git a/include/configs/mt7629.h b/include/configs/mt7629.h
index f6ab486fa2..59cdd22a1c 100644
--- a/include/configs/mt7629.h
+++ b/include/configs/mt7629.h
@@ -9,21 +9,10 @@
 #ifndef __MT7629_H
 #define __MT7629_H
 
-#include 
-
-/* Miscellaneous configurable options */
-
-/* Environment */
-
+/* SPL */
 #define CFG_SYS_UBOOT_BASE (0x3000 + CONFIG_SPL_PAD_TO)
 
-/* SPL -> Uboot */
-
-/* UBoot -> Kernel */
-
 /* DRAM */
 #define CFG_SYS_SDRAM_BASE 0x4000
 
-/* Ethernet */
-
 #endif
-- 
2.17.1



[PATCH 00/29] Add support for MediaTek MT7988 SoC

2023-07-19 Thread Weijie Gao
This patch series add support for MediaTek MT7988 SoC with its 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 MT7988:
https://www.mediatek.com/products/broadband-wifi/mediatek-filogic-880

Weijie Gao (29):
  arm: mediatek: retrieve ram_base from dts node for armv8 platform
  board: mediatek: update config headers
  spi: mtk_spim: get spi clk rate only once
  spi: mtk_spim: clear IRQ enable bits
  serial: mtk: initial priv data before using
  reset: mediatek: check malloc return valaue before use
  i2c: mediatek: fix I2C usability for MT7981
  arm: dts: enable i2c support for MediaTek MT7981
  pwm: mtk: add support for MediaTek MT7988 SoC
  clk: mediatek: add clock driver support for MediaTek MT7988 SoC
  reset: mediatek: add reset definition for MediaTek MT7988 SoC
  pinctrl: mediatek: convert most definitions to const
  pinctrl: mediatek: fix the return value in driving configuration
functions
  pinctrl: mediatek: add pinmux_set ops support
  pinctrl: mediatek: add pinctrl driver for MT7988 SoC
  net: mediatek: connect switch to PSE only when starting eth is
requested
  net: mediatek: optimize the switch reset delay wait time
  net: mediatek: fix direct MDIO clause 45 access via SoC
  net: mediatek: add missing static qualifier
  net: mediatek: add support for SGMII 1Gbps auto-negotiation mode
  arm: dts: medaitek: convert gmac link mode to 2500base-x
  net: mediatek: add support for GMAC/USB3 PHY mux mode for MT7981
  arm: dts: mediatek: add infracfg registers to support GMAC/USB3 Co-PHY
  net: mediatek: add USXGMII support
  net: mediatek: add support for NETSYS v3
  net: mediatek: add support for MediaTek MT7988 SoC
  tools: mtk_image: use uint32_t for ghf header magic and version
  arm: mediatek: add support for MediaTek MT7988 SoC
  board: mediatek: add MT7988 reference boards

 arch/arm/dts/Makefile |2 +
 arch/arm/dts/mt7622-bananapi-bpi-r64.dts  |4 +-
 arch/arm/dts/mt7622-rfb.dts   |4 +-
 arch/arm/dts/mt7629-rfb.dts   |4 +-
 arch/arm/dts/mt7981-emmc-rfb.dts  |9 +-
 arch/arm/dts/mt7981-rfb.dts   |9 +-
 arch/arm/dts/mt7981-sd-rfb.dts|9 +-
 arch/arm/dts/mt7981.dtsi  |   21 +
 arch/arm/dts/mt7986a-bpi-r3-sd.dts|5 +
 arch/arm/dts/mt7986a-rfb.dts  |9 +-
 arch/arm/dts/mt7986a-sd-rfb.dts   |9 +-
 arch/arm/dts/mt7986b-rfb.dts  |9 +-
 arch/arm/dts/mt7986b-sd-rfb.dts   |9 +-
 arch/arm/dts/mt7988-rfb.dts   |  182 +++
 arch/arm/dts/mt7988-sd-rfb.dts|  134 ++
 arch/arm/dts/mt7988-u-boot.dtsi   |   25 +
 arch/arm/dts/mt7988.dtsi  |  391 +
 arch/arm/mach-mediatek/Kconfig|   13 +-
 arch/arm/mach-mediatek/Makefile   |1 +
 arch/arm/mach-mediatek/mt7622/init.c  |   13 +-
 arch/arm/mach-mediatek/mt7981/init.c  |   11 +-
 arch/arm/mach-mediatek/mt7986/init.c  |   11 +-
 arch/arm/mach-mediatek/mt7988/Makefile|4 +
 arch/arm/mach-mediatek/mt7988/init.c  |   63 +
 arch/arm/mach-mediatek/mt7988/lowlevel_init.S |   30 +
 board/mediatek/mt7622/mt7622_rfb.c|1 -
 board/mediatek/mt7988/MAINTAINERS |7 +
 board/mediatek/mt7988/Makefile|3 +
 board/mediatek/mt7988/mt7988_rfb.c|   10 +
 configs/mt7988_rfb_defconfig  |   83 ++
 configs/mt7988_sd_rfb_defconfig   |   71 +
 drivers/clk/mediatek/Makefile |1 +
 drivers/clk/mediatek/clk-mt7988.c | 1123 +++
 drivers/i2c/mtk_i2c.c |   45 +-
 drivers/net/mtk_eth.c |  572 +++-
 drivers/net/mtk_eth.h |   69 +
 drivers/pinctrl/mediatek/Kconfig  |4 +
 drivers/pinctrl/mediatek/Makefile |1 +
 drivers/pinctrl/mediatek/pinctrl-mt7622.c |  474 +++---
 drivers/pinctrl/mediatek/pinctrl-mt7623.c |  650 -
 drivers/pinctrl/mediatek/pinctrl-mt7629.c |  174 +--
 drivers/pinctrl/mediatek/pinctrl-mt7981.c |  270 ++--
 drivers/pinctrl/mediatek/pinctrl-mt7986.c |  145 +-
 drivers/pinctrl/mediatek/pinctrl-mt7988.c | 1274 +
 drivers/pinctrl/mediatek/pinctrl-mt8512.c |   24 +-
 drivers/pinctrl/mediatek/pinctrl-mt8516.c |   18 +-
 drivers/pinctrl/mediatek/pinctrl-mt8518.c |   20 +-
 drivers/pinctrl/mediatek/pinctrl-mtk-common.c |   22 +-
 drivers/pinctrl/mediatek/pinctrl-mtk-common.h |8 +-
 drivers/pwm/pwm-mtk.c |7 +
 drivers/reset/reset-mediatek.c|3 +
 drivers/serial/serial_mtk.c   |1

[PATCH v3 30/32] tools: mtk_image: split the code of generating NAND header into a new file

2022-09-09 Thread 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.

Reviewed-by: Simon Glass 
Tested-by: Daniel Golle 
Signed-off-by: Weijie Gao 
---
v3 changes: none
v2 changes:
  Add comments
  Call mtk_nand_header_size only for NAND/SNAND to avoid NULL pointer access
---
 tools/Makefile   |   1 +
 tools/mtk_image.c| 305 ++-
 tools/mtk_image.h|  25 
 tools/mtk_nand_headers.c | 286 
 tools/mtk_nand_headers.h |  61 
 5 files changed, 389 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 3626919633..34a1aa7a8b 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..1f7396aa69 100644
--- a/tools/mtk_image.c
+++ b/tools/mtk_image.c
@@ -12,216 +12,7 @@
 #include 
 #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, 0x

[PATCH v3 31/32] tools: mtk_image: add support for nand headers used by newer chips

2022-09-09 Thread 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.

Tested-by: Daniel Golle 
Signed-off-by: Weijie Gao 
---
v3 changes: none
v2 changes: none
---
 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 1f7396aa69..9b3136afa3 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 */
@@ -366,20 +369,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,

[PATCH v3 27/32] clk: mediatek: add clock driver support for MediaTek MT7981 SoC

2022-09-09 Thread Weijie Gao
This patch adds clock driver support for MediaTek MT7981 SoC

Reviewed-by: Sean Anderson 
Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v3 changes: none
v2 changes:
  Fix coding style
---
 drivers/clk/mediatek/Makefile  |   1 +
 drivers/clk/mediatek/clk-mt7981.c  | 683 +
 include/dt-bindings/clock/mt7981-clk.h | 267 ++
 3 files changed, 951 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 00..7fcb81419c
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt7981.c
@@ -0,0 +1,683 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek clock driver for MT7981 SoC
+ *
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Sam Shih 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#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, 13),
+   FIXED_CLK(CK_APMIXED_NET2PLL, CLK_XTAL, 8),
+   FIXED_CLK(CK_APMIXED_MMPLL, CLK_XTAL, 72000),
+   FIXED_CLK(CK_APMIXED_SGMPLL, CLK_XTAL, 32500),
+   FIXED_CLK(CK_APMIXED_WEDMCUPLL, CLK_XTAL, 20800),
+   FIXED_CLK(CK_APMIXED_NET1PLL, CLK_XTAL, 25),
+   FIXED_CLK(CK_APMIXED_MPLL, CLK_XTAL, 41600),
+   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, 4000),
+};
+
+/* 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)

[PATCH v3 32/32] MAINTAINERS: update maintainer for MediaTek ARM platform

2022-09-09 Thread Weijie Gao
Add new files for MediaTek ARM platform

Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v3 changes:
v2 changes:
  Add cpu driver file
---
 MAINTAINERS | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 36a2b69fcb..d47674c476 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -355,20 +355,26 @@ 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/cpu/mtk_cpu.c
+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



[PATCH v3 29/32] tools: mtk_image: split gfh header verification into a new function

2022-09-09 Thread 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.

Reviewed-by: Simon Glass 
Tested-by: Daniel Golle 
Signed-off-by: Weijie Gao 
---
v3 changes: none
v2 changes: none
---
 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



[PATCH v3 28/32] cpu: add basic cpu driver for MediaTek ARM chips

2022-09-09 Thread Weijie Gao
Add basic CPU driver used to retrieve CPU model information.

Tested-by: Daniel Golle 
Signed-off-by: Weijie Gao 
---
v3 changes:
  Use regmap to read hwver registers
v2 changes: new
---
 drivers/cpu/Makefile  |  1 +
 drivers/cpu/mtk_cpu.c | 86 +++
 2 files changed, 87 insertions(+)
 create mode 100644 drivers/cpu/mtk_cpu.c

diff --git a/drivers/cpu/Makefile b/drivers/cpu/Makefile
index 20884b1795..3b38ba9c58 100644
--- a/drivers/cpu/Makefile
+++ b/drivers/cpu/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_CPU) += cpu-uclass.o
 obj-$(CONFIG_ARCH_BMIPS) += bmips_cpu.o
 obj-$(CONFIG_ARCH_IMX8) += imx8_cpu.o
 obj-$(CONFIG_ARCH_AT91) += at91_cpu.o
+obj-$(CONFIG_ARCH_MEDIATEK) += mtk_cpu.o
 obj-$(CONFIG_CPU_MPC83XX) += mpc83xx_cpu.o
 obj-$(CONFIG_CPU_RISCV) += riscv_cpu.o
 obj-$(CONFIG_CPU_MICROBLAZE) += microblaze_cpu.o
diff --git a/drivers/cpu/mtk_cpu.c b/drivers/cpu/mtk_cpu.c
new file mode 100644
index 00..2a08be9b6d
--- /dev/null
+++ b/drivers/cpu/mtk_cpu.c
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 MediaTek Inc. All rights reserved.
+ *
+ * Author: Weijie Gao 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct mtk_cpu_plat {
+   struct regmap *hwver;
+};
+
+static int mtk_cpu_get_desc(const struct udevice *dev, char *buf, int size)
+{
+   struct mtk_cpu_plat *plat = dev_get_plat(dev);
+   uint val;
+
+   regmap_read(plat->hwver, 0, );
+
+   snprintf(buf, size, "MediaTek MT%04X", val);
+
+   return 0;
+}
+
+static int mtk_cpu_get_count(const struct udevice *dev)
+{
+   return 1;
+}
+
+static int mtk_cpu_get_vendor(const struct udevice *dev, char *buf, int size)
+{
+   snprintf(buf, size, "MediaTek");
+
+   return 0;
+}
+
+static int mtk_cpu_probe(struct udevice *dev)
+{
+   struct mtk_cpu_plat *plat = dev_get_plat(dev);
+   struct ofnode_phandle_args args;
+   int ret;
+
+   ret = dev_read_phandle_with_args(dev, "mediatek,hwver", NULL, 0, 0,
+);
+   if (ret)
+   return ret;
+
+   plat->hwver = syscon_node_to_regmap(args.node);
+   if (IS_ERR(plat->hwver))
+   return PTR_ERR(plat->hwver);
+
+   return 0;
+}
+
+static const struct cpu_ops mtk_cpu_ops = {
+   .get_desc   = mtk_cpu_get_desc,
+   .get_count  = mtk_cpu_get_count,
+   .get_vendor = mtk_cpu_get_vendor,
+};
+
+static const struct udevice_id mtk_cpu_ids[] = {
+   { .compatible = "arm,cortex-a7" },
+   { .compatible = "arm,cortex-a53" },
+   { .compatible = "arm,cortex-a73" },
+   { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(cpu_mtk) = {
+   .name   = "mtk-cpu",
+   .id = UCLASS_CPU,
+   .of_match   = mtk_cpu_ids,
+   .ops= _cpu_ops,
+   .probe  = mtk_cpu_probe,
+   .plat_auto  = sizeof(struct mtk_cpu_plat),
+   .flags  = DM_FLAG_PRE_RELOC,
+};
-- 
2.17.1



[PATCH v3 26/32] clk: mediatek: add clock driver support for MediaTek MT7986 SoC

2022-09-09 Thread Weijie Gao
This patch adds clock driver support for MediaTek MT7986 SoC

Reviewed-by: Sean Anderson 
Reviewed-by: Simon Glass 
Tested-by: Daniel Golle 
Signed-off-by: Weijie Gao 
---
v3 changes: none
v2 changes:
  Fix coding style
---
 drivers/clk/mediatek/Makefile  |   1 +
 drivers/clk/mediatek/clk-mt7986.c  | 672 +
 include/dt-bindings/clock/mt7986-clk.h | 249 +
 3 files changed, 922 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 00..b3fa63fc0a
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt7986.c
@@ -0,0 +1,672 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek clock driver for MT7986 SoC
+ *
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Sam Shih 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#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, 20),
+   FIXED_CLK(CK_APMIXED_NET2PLL, CLK_XTAL, 8),
+   FIXED_CLK(CK_APMIXED_MMPLL, CLK_XTAL, 144000),
+   FIXED_CLK(CK_APMIXED_SGMPLL, CLK_XTAL, 32500),
+   FIXED_CLK(CK_APMIXED_WEDMCUPLL, CLK_XTAL, 76000),
+   FIXED_CLK(CK_APMIXED_NET1PLL, CLK_XTAL, 25),
+   FIXED_CLK(CK_APMIXED_MPLL, CLK_XTAL, 41600),
+   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, 4000),
+};
+
+/* 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_FA

[PATCH v3 20/32] pinctrl: mediatek: add pinctrl driver for MT7981 SoC

2022-09-09 Thread Weijie Gao
This patch adds pinctrl and gpio support for MT7981 SoC

Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v3 changes: none
v2 changes: none
---
 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 00..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 
+ */
+
+#include 
+#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:0x11c0, iocfg_rm:0x11c1, iocfg_rb:0x11d2,
+ * iocfg_lb:0x11e0, iocfg_bl:0x11e2, iocfg_tm:0x11f0,
+ * iocfg_tl:0x11f1,
+ * _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),
+   

[PATCH v3 24/32] clk: mediatek: add infrasys clock mux support

2022-09-09 Thread Weijie Gao
This patch adds infrasys clock mux support for mediatek clock drivers.

Reviewed-by: Simon Glass 
Tested-by: Daniel Golle 
Signed-off-by: Weijie Gao 
---
v3 changes: none
v2 changes:
  Fix the if condition of CLK_BYPASS_XTAL
---
 drivers/clk/mediatek/clk-mtk.c | 71 ++
 drivers/clk/mediatek/clk-mtk.h |  4 +-
 2 files changed, 74 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index a537ff259f..207a4c6b11 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 = >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);
@@ -331,6 +349,33 @@ 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 = >tree->muxes[off];
+   u32 index;
+
+   index = readl(priv->base + mux->mux_reg);
+   index &= mux->mux_mask << mux->mux_shift;
+   index = index >> mux->mux_shift;
+
+   if (mux->parent[index] > 0 ||
+   (mux->parent[index] == CLK_XTAL &&
+priv->tree->flags & CLK_BYPASS_XTAL)) {
+   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);
@@ -345,6 +390,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);
@@ -493,6 +557,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 41854879c6..e7c61ae483 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -28,7 +28,8 @@
 
 #define CLK_PARENT_APMIXED BIT(4)
 #define CLK_PARENT_TOPCKGENBIT(5)
-#define CLK_PARENT_MASKGENMASK(5, 4)
+#define CLK_PARENT_INFRASYSBIT(6)
+#define CLK_PARENT_MASKGENMASK(6, 4)
 
 #define ETHSYS_HIFSYS_RST_CTRL_OFS 0x34
 
@@ -220,6 +221,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



[PATCH v3 25/32] clk: mediatek: add CLK_XTAL support for clock driver

2022-09-09 Thread Weijie Gao
This adds the CLK_XTAL macro/flag to allow modeling clocks which are
directly connected to the xtal clock.

Reviewed-by: Simon Glass 
Tested-by: Daniel Golle 
Signed-off-by: Weijie Gao 
---
v3 changes: none
v2 changes:
  Fix incorrect fallback in mtk_infrasys_get_factor_rate
  Fix commit description
---
 drivers/clk/mediatek/clk-mtk.c | 4 
 drivers/clk/mediatek/clk-mtk.h | 3 ++-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index 207a4c6b11..4303300d3a 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,9 @@ 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;
+   break;
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 e7c61ae483..48ce16484e 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -29,7 +29,8 @@
 #define CLK_PARENT_APMIXED BIT(4)
 #define CLK_PARENT_TOPCKGENBIT(5)
 #define CLK_PARENT_INFRASYSBIT(6)
-#define CLK_PARENT_MASKGENMASK(6, 4)
+#define CLK_PARENT_XTALBIT(7)
+#define CLK_PARENT_MASKGENMASK(7, 4)
 
 #define ETHSYS_HIFSYS_RST_CTRL_OFS 0x34
 
-- 
2.17.1



[PATCH v3 23/32] clk: mediatek: add support to configure clock driver parent

2022-09-09 Thread Weijie Gao
This patch adds support for a clock node to configure its parent clock
where possible.

Reviewed-by: Simon Glass 
Tested-by: Daniel Golle 
Signed-off-by: Weijie Gao 
---
v3 changes: none
v2 changes: none
---
 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 7d145f4975..a537ff259f 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, ))
-   return -ENODEV;
-
-   parent.dev = dev;
-   } else {
+   if (pdev)
+   parent.dev = pdev;
+   else
parent.dev = clk->dev;
-   }
 
return 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);
@@ -321,9 +315,18 @@ static ulong mtk_topckgen_get_mux_rate(struct clk *clk, 
u32 off)
 
if (mux->parent[index] > 0 ||
(mux->parent[index] == CLK_XTAL &&
-priv->tree->flags & CLK_BYPASS_XTAL))
-   return mtk_clk_find_parent_rate(clk, mux->parent[index],
-   NULL);
+priv->tree->flags & CLK_BYPASS_XTAL)) {
+   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;
 }
@@ -342,7 +345,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;
@@ -375,7 +378,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;
@@ -401,7 +404,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);
 
@@ -473,19 +476,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 = >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 = {
@@ -496,10 +487,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_

[PATCH v3 21/32] pinctrl: mediatek: add pinctrl driver for MT7986 SoC

2022-09-09 Thread Weijie Gao
This patch adds pinctrl and gpio support for MT7986 SoC

Reviewed-by: Simon Glass 
Tested-by: Daniel Golle 
Signed-off-by: Weijie Gao 
---
v3 changes: none
v2 changes: none
---
 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 00..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 
+ */
+
+#include 
+#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:0x11c3, iocfg_rb:0x11c4, iocfg_lt:0x11e2,
+ * iocfg_lb:0x11e3, iocfg_tr:0x11f0, iocfg_tl:0x11f1,
+ * _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_FIE

[PATCH v3 22/32] clk: mediatek: add CLK_BYPASS_XTAL flag to allow bypassing searching clock parent of xtal clock

2022-09-09 Thread 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.

Reviewed-by: Simon Glass 
Tested-by: Daniel Golle 
Signed-off-by: Weijie Gao 
---
v3 changes: none
v2 changes:
  Add comment for flags
  Fix the if condition of CLK_BYPASS_XTAL
---
 drivers/clk/mediatek/clk-mtk.c | 4 +++-
 drivers/clk/mediatek/clk-mtk.h | 6 ++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index d43b8a0648..7d145f4975 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -319,7 +319,9 @@ static ulong mtk_topckgen_get_mux_rate(struct clk *clk, u32 
off)
index &= mux->mux_mask << mux->mux_shift;
index = index >> mux->mux_shift;
 
-   if (mux->parent[index])
+   if (mux->parent[index] > 0 ||
+   (mux->parent[index] == CLK_XTAL &&
+priv->tree->flags & CLK_BYPASS_XTAL))
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..e0c5550c80 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -11,6 +11,11 @@
 #define CLK_XTAL   0
 #define MHZ(1000 * 1000)
 
+/* flags in struct mtk_clk_tree */
+
+/* clk id == 0 doesn't mean it's xtal clk */
+#define CLK_BYPASS_XTALBIT(0)
+
 #define HAVE_RST_BAR   BIT(0)
 #define CLK_DOMAIN_SCPSYS  BIT(0)
 #define CLK_MUX_SETCLR_UPD BIT(1)
@@ -197,6 +202,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



[PATCH v3 19/32] dt-bindings: pinctrl: mediatek: add a header for common pinconf parameters

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

Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v3 changes: none
v2 changes: none
---
 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 00..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 
+ */
+
+#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



[PATCH v3 16/32] spi: add support for MediaTek spi-mem controller

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

Reviewed-by: Simon Glass 
Tested-by: Daniel Golle 
Signed-off-by: SkyLake.Huang 
---
v3 changes: none
v2 changes:
  Remove unused code
  Fix coding style
  Add description for struct fields
---
 drivers/spi/Kconfig|   8 +
 drivers/spi/Makefile   |   1 +
 drivers/spi/mtk_spim.c | 701 +
 3 files changed, 710 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 00..b45ef529a5
--- /dev/null
+++ b/drivers/spi/mtk_spim.c
@@ -0,0 +1,701 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 MediaTek Inc. All Rights Reserved.
+ *
+ * Author: SkyLake.Huang 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define SPI_CFG0_REG   0x
+#define SPI_CFG1_REG   0x0004
+#define SPI_TX_SRC_REG 0x0008
+#define SPI_RX_DST_REG 0x000c
+#define SPI_TX_DATA_REG0x0010
+#define SPI_RX_DATA_REG0x0014
+#define SPI_CMD_REG0x0018
+#define SPI_IRQ_REG0x001c
+#define SPI_STATUS_REG 0x0020
+#define SPI_PAD_SEL_REG0x0024
+#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_OFFSET8
+#define SPI_CFG0_CS_HOLD_OFFSET16
+#define SPI_CFG0_CS_SETUP_OFFSET   24
+#define SPI_ADJUST_CFG0_CS_HOLD_OFFSET 0
+#define SPI_ADJUST_CFG0_CS_SETUP_OFFSET16
+
+#define SPI_CFG1_CS_IDLE_OFFSET0
+#define SPI_CFG1_PACKET_LOOP_OFFSET8
+#define SPI_CFG1_PACKET_LENGTH_OFFSET  16
+#define SPI_CFG1_GET_TICKDLY_OFFSET29
+
+#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_MASK0x3ff
+#define SPI_CFG1_IPM_PACKET_LENGTH_MASKGENMASK(31, 16)
+#define SPI_CFG2_SCK_HIGH_OFFSET   0
+#define SPI_CFG2_SCK_LOW_OFFSET16
+#define SPI_CFG2_SCK_HIGH_MASK GENMASK(15, 0)
+#define SPI_CFG2_SCK_LOW_MASK  GENMASK(31, 16)
+
+#define SPI_CMD_ACTBIT(0)
+#define SPI_CMD_RESUME BIT(1)
+#define SPI_CMD_RSTBIT(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 

[PATCH v3 18/32] arm: dts: mt7622: add i2c support

2022-09-09 Thread Weijie Gao
Add both hardware and software i2c support for mt7622.

Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v3 changes: none
v2 changes: none
---
 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";
+   };
+   };
+
 };
 
  {
@@ -242,3 +250,13 @@
  {
status = "okay";
 };
+
+_i2c {
+   status = "disabled";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_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 = < 56 GPIO_ACTIVE_HIGH>, /* SDA */
+   < 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 = ;
+   clock-div = <16>;
+   clocks = < CLK_PERI_I2C1_PD>,
+< CLK_PERI_AP_DMA_PD>;
+   clock-names = "main", "dma";
+   #address-cells = <1>;
+   #size-cells = <0>;
+   status = "disabled";
+   };
+
 };
-- 
2.17.1



[PATCH v3 17/32] i2c: add support for MediaTek I2C interface

2022-09-09 Thread Weijie Gao
This patch adds support for MediaTek I2C interface

Reviewed-by: Heiko Schocher 
Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v3 changes: none
v2 changes:
  Reorganize code to reduce duplicated code
  Rename mtk_i2c_ofdata_to_platdata to mtk_i2c_of_to_plat
---
 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 00..5528bcd7cc
--- /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 
+ *
+ * MediaTek I2C Interface driver
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define I2C_RS_TRANSFERBIT(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_CNFGBIT(15)
+#define I2C_RS_MUL_TRIGBIT(14)
+#define I2C_DCM_DISABLE0x
+#define I2C_IO_CONFIG_OPEN_DRAIN   0x0003
+#define I2C_IO_CONFIG_PUSH_PULL0x
+#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 0x
+#define I2C_TIME_DEFAULT_VALUE 0x0003
+#define I2C_WRRD_TRANAC_VALUE  0x0002
+#define I2C_RD_TRANAC_VALUE0x0001
+
+#define I2C_DMA_CON_TX 0x
+#define I2C_DMA_CON_RX 0x0001
+#define I2C_DMA_START_EN   0x0001
+#define I2C_DMA_INT_FLAG_NONE  0x
+#define I2C_DMA_CLR_FLAG   0x
+#define I2C_DMA_TX_RX  0x
+#define I2C_DMA_HARD_RST   0x0002
+
+#define MAX_ST_MODE_SPEED  10
+#define MAX_FS_MODE_SPEED  40
+#define MAX_HS_MODE_SPEED  340
+#define MAX_SAMPLE_CNT_DIV 8
+#define MAX_STEP_CNT_DIV   64
+#define MAX_HS_STEP_CNT_DIV8
+#define I2C_DEFAULT_CLK_DIV4
+
+#define MAX_I2C_ADDR   0x7f
+#define MAX_I2C_LEN0xff
+#define TRANS_ADDR_ONLYBIT(8)
+#define TRANSFER_TIMEOUT   5  /* us */
+#define I2C_FIFO_STAT1_MASK0x001f
+#define TIMING_SAMPLE_OFFSET   8
+#define HS_SAMPLE_OFFSET   12
+#define HS_STEP_OFFSET 8
+
+#define I2C_CONTROL_WRAPPERBIT(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)
+
+#define I2C_MASTER_WR  BIT(0)
+#define I2C_MASTER_RD  BIT(1)
+#define I2C_MASTER_WRRD(I2C_MASTER_WR | I2C_MASTER_RD)
+
+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,

[PATCH v3 15/32] watchdog: mediatek: add support for MediaTek MT7986 SoC

2022-09-09 Thread Weijie Gao
Add watchdog support for MediaTek MT7986 SoC

Reviewed-by: Simon Glass 
Tested-by: Daniel Golle 
Signed-off-by: Weijie Gao 
---
v3 changes: none
v2 changes: none
---
 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



[PATCH v3 14/32] timer: mtk: add support for MediaTek MT7981/MT7986 SoCs

2022-09-09 Thread 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.

Reviewed-by: Simon Glass 
Tested-by: Daniel Golle 
Signed-off-by: Weijie Gao 
---
v3 changes: none
v2 changes: none
---
 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 
 #include 
 
-#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_ENABLEBIT(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_CON0x0
+#define MTK_GPT_V1_CLK 0x4
+#define MTK_GPT_CNT0x8
+
+#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, );
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



[PATCH v3 13/32] pwm: mtk: add support for MediaTek MT7981 SoC

2022-09-09 Thread 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.

Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v3 changes: none
v2 changes: none
---
 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 10L
 
-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)_data },
{ .compatible = "mediatek,mt7623-pwm", .data = (ulong)_data },
{ .compatible = "mediatek,mt7629-pwm", .data = (ulong)_data },
+   { .compatible = "mediatek,mt7981-pwm", .data = (ulong)_data },
{ .compatible = "mediatek,mt7986-pwm", .data = (ulong)_data },
{ }
 };
-- 
2.17.1



[PATCH v3 11/32] arm: dts: mt7622: force high-speed mode for uart

2022-09-09 Thread 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.

Reviewed-by: Simon Glass 
Tested-by: Daniel Golle 
Signed-off-by: Weijie Gao 
---
v3 changes: none
v2 changes: none
---
 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 = < CLK_TOP_AXI_SEL>;
assigned-clock-parents = < CLK_TOP_SYSPLL1_D2>;
+   mediatek,force-highspeed;
};
 
mmc0: mmc@1123 {
-- 
2.17.1



[PATCH v3 12/32] pwm: mtk: add support for MediaTek MT7986 SoC

2022-09-09 Thread Weijie Gao
This patch adds PWM support for MediaTek MT7986 SoC.

Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v3 changes: none
v2 changes: none
---
 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)_data },
{ .compatible = "mediatek,mt7623-pwm", .data = (ulong)_data },
{ .compatible = "mediatek,mt7629-pwm", .data = (ulong)_data },
+   { .compatible = "mediatek,mt7986-pwm", .data = (ulong)_data },
{ }
 };
 
-- 
2.17.1



[PATCH v3 09/32] net: mediatek: add support for MediaTek MT7981/MT7986

2022-09-09 Thread Weijie Gao
This patch adds support for MediaTek MT7981 and MT7986. Both chips uses
PDMA v2.

Reviewed-by: Ramon Fried 
Tested-by: Daniel Golle 
Signed-off-by: Weijie Gao 
---
v3 changes: none
v2 changes: none
---
 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 fb72baae68..4c9fb266c7 100644
--- a/drivers/net/mtk_eth.c
+++ b/drivers/net/mtk_eth.c
@@ -115,6 +115,7 @@ struct mtk_eth_priv {
int force_mode;
int speed;
int duplex;
+   bool pn_swap;
 
struct phy_device *phydev;
int phy_interface;
@@ -1057,6 +1058,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);
@@ -1470,6 +1477,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 */
@@ -1520,6 +1529,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,
@@ -1549,6 +1574,8 @@ static const struct mtk_soc_data mt7621_data = {
 };
 
 static const struct udevice_id mtk_eth_ids[] = {
+   { .compatible = "mediatek,mt7986-eth", .data = (ulong)_data },
+   { .compatible = "mediatek,mt7981-eth", .data = (ulong)_data },
{ .compatible = "mediatek,mt7629-eth", .data = (ulong)_data },
{ .compatible = "mediatek,mt7623-eth", .data = (ulong)_data },
{ .compatible = "mediatek,mt7622-eth", .data = (ulong)_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_RX0x03
+
 #define SGMSYS_GEN2_SPEED  0x2028
 #define SGMSYS_GEN2_SPEED_V2   0x128
 #define SGMSYS_SPEED_2500  BIT(2)
-- 
2.17.1



[PATCH v3 10/32] serial: mtk: add support for using dynamic baud clock souce

2022-09-09 Thread 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().

Reviewed-by: Simon Glass 
Tested-by: Daniel Golle 
Signed-off-by: Weijie Gao 
---
v3 changes: none
v2 changes:
  Add description for priv struct
  Fix the type of clk_rate
---
 drivers/serial/serial_mtk.c | 80 ++---
 1 file changed, 47 insertions(+), 33 deletions(-)

diff --git a/drivers/serial/serial_mtk.c b/drivers/serial/serial_mtk.c
index a84f39b3fa..1d7cc9f7b6 100644
--- a/drivers/serial/serial_mtk.c
+++ b/drivers/serial/serial_mtk.c
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -70,27 +71,37 @@ struct mtk_serial_regs {
 #define BAUD_ALLOW_MAX(baud)   ((baud) + (baud) * 3 / 100)
 #define BAUD_ALLOW_MIX(baud)   ((baud) - (baud) * 3 / 100)
 
+/* struct mtk_serial_priv -Structure holding all information used by the
+ * driver
+ * @regs:  Register base of the serial port
+ * @clk:   The baud clock device
+ * @fixed_clk_rate:Fallback fixed baud clock rate if baud clock
+ * device is not specified
+ * @force_highspeed:   Force using high-speed mode
+ */
 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,
+  uint clk_rate)
 {
u32 quot, realbaud, samplecount = 1;
 
/* Special case for low baud clock */
-   if (baud <= 115200 && priv->clock <= 1200) {
+   if (baud <= 115200 && clk_rate == 1200) {
writel(3, >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 +115,7 @@ static void _mtk_serial_setbrg(struct mtk_serial_priv 
*priv, int baud)
 
if (baud <= 115200) {
writel(0, >regs->highspeed);
-   quot = DIV_ROUND_CLOSEST(priv->clock, 16 * baud);
+   quot = DIV_ROUND_CLOSEST(clk_rate, 16 * baud);
} else if (baud <= 576000) {
writel(2, >regs->highspeed);
 
@@ -112,13 +123,13 @@ static void _mtk_serial_setbrg(struct mtk_serial_priv 
*priv, int baud)
if ((baud == 50) || (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, >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 +178,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(>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 +227,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 +235,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, );
-   if (!err) {
-  

[PATCH v3 08/32] net: mediatek: add support for PDMA v2

2022-09-09 Thread 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.

Reviewed-by: Ramon Fried 
Reviewed-by: Simon Glass 
Tested-by: Daniel Golle 
Signed-off-by: Weijie Gao 
---
v3 changes: none
v2 changes:
  Add description for new fields
---
 drivers/net/mtk_eth.c | 54 ---
 drivers/net/mtk_eth.h | 53 +++---
 2 files changed, 86 insertions(+), 21 deletions(-)

diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c
index e3738b9277..fb72baae68 100644
--- a/drivers/net/mtk_eth.c
+++ b/drivers/net/mtk_eth.c
@@ -76,10 +76,14 @@ enum mtk_switch {
  * @caps   Flags shown the extra capability for the SoC
  * @ana_rgc3:  The offset for register ANA_RGC3 related to
  * sgmiisys syscon
+ * @pdma_base: Register base of PDMA block
+ * @txd_size:  Tx DMA descriptor size.
+ * @rxd_size:  Rx DMA descriptor size.
  */
 struct mtk_soc_data {
u32 caps;
u32 ana_rgc3;
+   u32 pdma_base;
u32 txd_size;
u32 rxd_size;
 };
@@ -130,13 +134,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,
@@ -1133,8 +1137,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, 0x, 0);
@@ -1155,7 +1159,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;
}
@@ -1164,7 +1172,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;
}
@@ -1193,6 +1205,9 @@ static int mtk_eth_start(struct udevice *dev)
reset_deassert(>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);
 
@@ -1227,7 +1242,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);
 }
 
@@ -1252,7 +1267,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;
@@ -1267,7 +1282,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(len

[PATCH v3 06/32] net: mediatek: use a struct to cover variations of all SoCs

2022-09-09 Thread 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.

Reviewed-by: Simon Glass 
Tested-by: Daniel Golle 
Signed-off-by: Weijie Gao 
---
v3 changes: none
v2 changes:
  Add description for new struct
---
 drivers/net/mtk_eth.c | 56 ++-
 drivers/net/mtk_eth.h | 25 ++-
 2 files changed, 64 insertions(+), 17 deletions(-)

diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c
index 4fe7ee0d36..ce4aa6e065 100644
--- a/drivers/net/mtk_eth.c
+++ b/drivers/net/mtk_eth.c
@@ -142,11 +142,15 @@ enum mtk_switch {
SW_MT7531
 };
 
-enum mtk_soc {
-   SOC_MT7623,
-   SOC_MT7629,
-   SOC_MT7622,
-   SOC_MT7621
+/* struct mtk_soc_data -   This is the structure holding all differences
+ * among various plaforms
+ * @caps   Flags shown the extra capability for the SoC
+ * @ana_rgc3:  The offset for register ANA_RGC3 related to
+ * sgmiisys syscon
+ */
+struct mtk_soc_data {
+   u32 caps;
+   u32 ana_rgc3;
 };
 
 struct mtk_eth_priv {
@@ -171,7 +175,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 +683,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 +1112,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 +1185,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 +1435,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 +1552,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)_data },
+   { .compatible = "mediatek,mt7623-eth", .data = (ulong)_data },
+   { .compatible = "mediatek,mt7622-eth", .data = (ulong)_data },
+   { .compatible = "mediatek,mt7621-eth", .data = (ulong)_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_
 

[PATCH v3 07/32] net: mediatek: stop using bitfileds for DMA descriptors

2022-09-09 Thread 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.

Reviewed-by: Simon Glass 
Tested-by: Daniel Golle 
Signed-off-by: Weijie Gao 
---
v3 changes: none
v2 changes:
  Fix typo in commit message
---
 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 ce4aa6e065..e3738b9277 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,
@@ -151,13 +80,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;
@@ -1202,14 +1133,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, 0x, 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));
@@ -1218,17 +1151,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;
}
 
@@ -1315,20 +1252,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_i

[PATCH v3 05/32] mmc: mediatek: add support for MediaTek MT7891/MT7986 SoCs

2022-09-09 Thread Weijie Gao
Add eMMC and SDXC support for MediaTek MT7981/MT7986 SoCs
Both chips support SDXC and eMMC 4.5. MT7986A supports eMMC 5.1.

Reviewed-by: Jaehoon Chung 
Reviewed-by: Simon Glass 
Tested-by: Daniel Golle 
Signed-off-by: Weijie Gao 
---
v3 changes: none
v2 changes: none
---
 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, >base->msdc_inten);
 
-   writel(0, tune_reg);
+   if (host->top_base) {
+   writel(0, >top_base->emmc_top_control);
+   writel(0, >top_base->emmc_top_cmd);
+   } else {
+   writel(0, tune_reg);
+   }
writel(0, >base->msdc_iocon);
 
if (host->r_smpl)
@@ -1507,9 +1512,14 @@ static void msdc_init_hw(struct msdc_host *host)
writel(0x403c0046, >base->patch_bit0);
writel(0x4089, >base->patch_bit1);
 
-   if (host->dev_comp->stop_clk_fix)
+   if (host->dev_comp->stop_clk_fix) {
clrsetbits_le32(>base->patch_bit1, MSDC_PB1_STOP_DLY_M,
3 << MSDC_PB1_STOP_DLY_S);
+   clrbits_le32(>base->sdc_fifo_cfg,
+SDC_FIFO_CFG_WRVALIDSEL);
+   clrbits_le32(>base->sdc_fifo_cfg,
+SDC_FIFO_CFG_RDVALIDSEL);
+   }
 
if (host->dev_comp->busy_check)
clrbits_le32(>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(>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(>top_base->emmc_top_control,
+PAD_DAT_RD_RXDLY_SEL);
+   clrbits_le32(>top_base->emmc_top_control,
+DATA_K_VALUE_SEL);
+   setbits_le32(>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(>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(>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(>base->sdc_cfg, SDC_CFG_DTOC_M,
3 << SDC_CFG_DTOC_S);
 
-   if (host->dev_comp->stop_clk_fix) {
-   clrbits_le32(>base->sdc_fifo_cfg,
-SDC_FIFO_CFG_WRVALIDSEL);
-   clrbits_le32(>base->sdc_fifo_cfg,
-SDC_FIFO_CFG_RDVALIDSEL);
-   }
 
host->def_tune_para.iocon = readl(>base->msdc_iocon);
host->def_tune_para.pad_tune = readl(>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 str

[PATCH v3 04/32] board: mediatek: add MT7981 reference boards

2022-09-09 Thread Weijie Gao
This patch adds general board files based on MT7981 SoCs.

MT7981 uses one mmc controller for booting from both SD and eMMC, and the
pins of mmc controller are also shared with spi controller.
So three configs are need for these boot types:

1. mt7981_rfb_defconfig - SPI-NOR and SPI-NAND
2. mt7981_emmc_rfb_defconfig - eMMC only
3. mt7981_sd_rfb_defconfig - SD only

Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v3 changes: none
v2 changes:
  Remove mt7981_spim_nand_rfb_defconfig and mt7981_spim_nor_rfb_defconfig
---
 arch/arm/dts/Makefile  |   3 +
 arch/arm/dts/mt7981-emmc-rfb.dts   | 139 +++
 arch/arm/dts/mt7981-rfb.dts| 173 +
 arch/arm/dts/mt7981-sd-rfb.dts | 139 +++
 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   |  69 
 configs/mt7981_sd_rfb_defconfig|  64 +++
 include/configs/mt7981.h   |  26 +
 11 files changed, 700 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 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 include/configs/mt7981.h

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index ee86e467f7..3436b20917 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -1230,6 +1230,9 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \
mt7622-bananapi-bpi-r64.dtb \
mt7623n-bananapi-bpi-r2.dtb \
mt7629-rfb.dtb \
+   mt7981-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 00..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 
+ */
+
+/dts-v1/;
+#include "mt7981.dtsi"
+#include 
+
+/ {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   model = "mt7981-rfb";
+   compatible = "mediatek,mt7981", "mediatek,mt7981-rfb";
+   chosen {
+   stdout-path = 
+   tick-timer = 
+   };
+
+   reg_3p3v: regulator-3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-3.3V";
+ regulator-min-microvolt = <330>;
+ regulator-max-microvolt = <330>;
+ regulator-boot-on;
+ regulator-always-on;
+   };
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+   status = "disabled";
+};
+
+ {
+   status = "okay";
+   mediatek,gmac-id = <0>;
+   phy-mode = "sgmii";
+   mediatek,switch = "mt7531";
+   reset-gpios = < 39 GPIO_ACTIVE_HIGH>;
+
+   fixed-link {
+   speed = <1000>;
+   full-duplex;
+   };
+};
+
+ {
+   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

[PATCH v3 03/32] board: mediatek: add MT7986 reference boards

2022-09-09 Thread Weijie Gao
Add general board files based on MT7986 SoCs.

MT7986 uses one mmc controller for booting from both SD and eMMC.
Both MT7986A and MT7986B use the same pins for spi controller.

Configs for various boot types:
1. mt7986_rfb_defconfig - SPI-NOR and SPI-NAND for MT7986A/B
2. mt7986a_bpir3_emmc_defconfig - eMMC for MT7986A only
3. mt7986a_bpir3_sd_defconfig - SD for MT7986A only

Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v3 changes: none
v2 changes:
  Rename mt7986a_emmc_rfb_defconfig to mt7986a_bpir3_emmc_defconfig
  Rename mt7986a_sd_rfb_defconfig to mt7986a_bpir3_sd_defconfig
  Remove mt7986b defconfig
---
 arch/arm/dts/Makefile|   6 +
 arch/arm/dts/mt7986a-emmc-rfb.dts|  16 ++
 arch/arm/dts/mt7986a-rfb.dts | 218 +++
 arch/arm/dts/mt7986a-sd-rfb.dts  | 177 ++
 arch/arm/dts/mt7986b-emmc-rfb.dts|  16 ++
 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_bpir3_emmc_defconfig |  64 
 configs/mt7986a_bpir3_sd_defconfig   |  64 
 include/configs/mt7986.h |  26 
 14 files changed, 1053 insertions(+)
 create mode 100644 arch/arm/dts/mt7986a-emmc-rfb.dts
 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-emmc-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_bpir3_emmc_defconfig
 create mode 100644 configs/mt7986a_bpir3_sd_defconfig
 create mode 100644 include/configs/mt7986.h

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 7330121dba..ee86e467f7 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -1230,6 +1230,12 @@ 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 \
+   mt7986a-emmc-rfb.dtb \
+   mt7986b-emmc-rfb.dtb \
mt8183-pumpkin.dtb \
mt8512-bm1-emmc.dtb \
mt8516-pumpkin.dtb \
diff --git a/arch/arm/dts/mt7986a-emmc-rfb.dts 
b/arch/arm/dts/mt7986a-emmc-rfb.dts
new file mode 100644
index 00..315bdd0b14
--- /dev/null
+++ b/arch/arm/dts/mt7986a-emmc-rfb.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Sam Shih 
+ */
+
+/dts-v1/;
+#include "mt7986a-rfb.dts"
+
+/ {
+   compatible = "mediatek,mt7986", "mediatek,mt7986-rfb",
+"mediatek,mt7986-emmc-rfb";
+   bl2_verify {
+   bl2_compatible = "emmc";
+   };
+};
diff --git a/arch/arm/dts/mt7986a-rfb.dts b/arch/arm/dts/mt7986a-rfb.dts
new file mode 100644
index 00..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 
+ */
+
+/dts-v1/;
+#include "mt7986.dtsi"
+#include 
+
+/ {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   model = "mt7986-rfb";
+   compatible = "mediatek,mt7986", "mediatek,mt7986-rfb";
+   chosen {
+   stdout-path = 
+   tick-timer = 
+   };
+
+   reg_1p8v: regulator-1p8v {
+   compatible = "regulator-fixed";
+   regulator-name = "fixed-1.8V";
+   regulator-min-microvolt = <180>;
+   regulator-max-microvolt = <180>;
+   regulator-boot-on;
+   regulator-always-on;
+   };
+
+   reg_3p3v: regulator-3p3v {
+   compatible = "regulator-fixed";
+   regulator-name = "fixed-3.3V";
+   regulator-min-microvolt = <330>;
+   regulator-max-microvolt = <330>;
+   regulator-boot-on;
+   regulator-always-on;
+   };
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+   status = "disabled";
+};
+
+ {
+   status = "okay";
+   mediatek,gmac-id = <0>;
+   phy-mode = "sgmii";
+   mediatek,switch = "mt7531";
+   reset-gpio

[PATCH v3 02/32] arm: mediatek: add support for MediaTek MT7981 SoC

2022-09-09 Thread 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.

Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v3 changes:
  Add syscon to hwver node
  Add reference of hwver to cpu nodes
v2 changes:
  Sort include lines
  Add reference link for armv8_el2_to_aarch32 in lowlevel_init.S
  Remove print_cpuinfo and use cpu driver instead
---
 arch/arm/dts/mt7981.dtsi  | 295 ++
 arch/arm/mach-mediatek/Kconfig|  13 +-
 arch/arm/mach-mediatek/Makefile   |   1 +
 arch/arm/mach-mediatek/mt7981/Makefile|   4 +
 arch/arm/mach-mediatek/mt7981/init.c  |  45 +++
 arch/arm/mach-mediatek/mt7981/lowlevel_init.S |  32 ++
 6 files changed, 389 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 00..3089371805
--- /dev/null
+++ b/arch/arm/dts/mt7981.dtsi
@@ -0,0 +1,295 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Sam Shih 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/ {
+   compatible = "mediatek,mt7981";
+   interrupt-parent = <>;
+   #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>;
+   mediatek,hwver = <>;
+   };
+   cpu1: cpu@1 {
+   device_type = "cpu";
+   compatible = "arm,cortex-a53";
+   reg = <0x1>;
+   mediatek,hwver = <>;
+   };
+   };
+
+   gpt_clk: gpt_dummy20m {
+   compatible = "fixed-clock";
+   clock-frequency = <1300>;
+   #clock-cells = <0>;
+   u-boot,dm-pre-reloc;
+   };
+
+   hwver: hwver {
+   compatible = "mediatek,hwver", "syscon";
+   reg = <0x800 0x1000>;
+   };
+
+   timer {
+   compatible = "arm,armv8-timer";
+   interrupt-parent = <>;
+   clock-frequency = <1300>;
+   interrupts = ,
+,
+,
+;
+   arm,cpu-registers-not-fw-configured;
+   };
+
+   timer0: timer@10008000 {
+   compatible = "mediatek,mt7986-timer";
+   reg = <0x10008000 0x1000>;
+   interrupts = ;
+   clocks = <_clk>;
+   clock-names = "gpt-clk";
+   u-boot,dm-pre-reloc;
+   };
+
+   watchdog: watchdog@1001c000 {
+   compatible = "mediatek,mt7986-wdt";
+   reg = <0x1001c000 0x1000>;
+   interrupts = ;
+   #reset-cells = <1>;
+   status = "disabled";
+   };
+
+   gic: interrupt-controller@c00 {
+   compatible = "arm,gic-v3";
+   #interrupt-cells = <3>;
+   interrupt-parent = <>;
+   interrupt-controller;
+   reg = <0x0c00 0x4>,  /* GICD */
+ <0x0c08 0x20>; /* GICR */
+
+   interrupts = ;
+   };
+
+   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 = <_plls>;
+   #clock-cells = <1>;
+   u-boot,dm-pre-reloc;
+   };
+
+   infracfg_ao: infracfg_ao@10001000 {
+   compatible = "mediatek,mt7981-infracfg_ao";
+   reg = <0x10001000 0x80>;
+   clock-parent = <>;
+   #clock-cells = <1>;
+   u-boot,dm-pre-reloc;
+   };
+
+   infracfg: infracfg@10001000 {
+   compatible = "mediatek,mt7981-infracfg";
+   reg = <0x10001000 0x30>;
+   clock-parent = <>;
+   #c

[PATCH v3 01/32] arm: mediatek: add support for MediaTek MT7986 SoC

2022-09-09 Thread 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.

Reviewed-by: Simon Glass 
Tested-by: Daniel Golle 
Signed-off-by: Weijie Gao 
---
v3 changes:
  Add syscon to hwver node
  Add reference of hwver to cpu nodes
v2 changes:
  Sort include lines
  Add reference link for armv8_el2_to_aarch32 in lowlevel_init.S
  Remove print_cpuinfo and use cpu driver instead
---
 arch/arm/dts/mt7986-u-boot.dtsi   |  33 ++
 arch/arm/dts/mt7986.dtsi  | 350 ++
 arch/arm/mach-mediatek/Kconfig|  12 +
 arch/arm/mach-mediatek/Makefile   |   1 +
 arch/arm/mach-mediatek/mt7986/Makefile|   4 +
 arch/arm/mach-mediatek/mt7986/init.c  |  45 +++
 arch/arm/mach-mediatek/mt7986/lowlevel_init.S |  32 ++
 7 files changed, 477 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 00..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 
+ */
+
+ {
+   u-boot,dm-pre-reloc;
+};
+
+ {
+   u-boot,dm-pre-reloc;
+};
+
+ {
+   u-boot,dm-pre-reloc;
+};
+
+ {
+   u-boot,dm-pre-reloc;
+};
+
+ {
+   u-boot,dm-pre-reloc;
+};
+
+ {
+   u-boot,dm-pre-reloc;
+};
+
+ {
+   u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/mt7986.dtsi b/arch/arm/dts/mt7986.dtsi
new file mode 100644
index 00..794ab1f4bd
--- /dev/null
+++ b/arch/arm/dts/mt7986.dtsi
@@ -0,0 +1,350 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Sam Shih 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/ {
+   compatible = "mediatek,mt7986";
+   interrupt-parent = <>;
+   #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>;
+   mediatek,hwver = <>;
+   };
+   cpu1: cpu@1 {
+   device_type = "cpu";
+   compatible = "arm,cortex-a53";
+   reg = <0x1>;
+   mediatek,hwver = <>;
+   };
+   cpu2: cpu@2 {
+   device_type = "cpu";
+   compatible = "arm,cortex-a53";
+   reg = <0x2>;
+   mediatek,hwver = <>;
+   };
+   cpu3: cpu@3 {
+   device_type = "cpu";
+   compatible = "arm,cortex-a53";
+   reg = <0x3>;
+   mediatek,hwver = <>;
+   };
+   };
+
+   dummy_clk: dummy12m {
+   compatible = "fixed-clock";
+   clock-frequency = <1200>;
+   #clock-cells = <0>;
+   /* must need this line, or uart uanable to get dummy_clk */
+   u-boot,dm-pre-reloc;
+   };
+
+   hwver: hwver {
+   compatible = "mediatek,hwver", "syscon";
+   reg = <0x800 0x1000>;
+   };
+
+   timer {
+   compatible = "arm,armv8-timer";
+   interrupt-parent = <>;
+   clock-frequency = <1300>;
+   interrupts = ,
+,
+,
+;
+   arm,cpu-registers-not-fw-configured;
+   };
+
+   timer0: timer@10008000 {
+   compatible = "mediatek,mt7986-timer";
+   reg = <0x10008000 0x1000>;
+   interrupts = ;
+   clocks = < CK_INFRA_CK_F26M>;
+   clock-names = "gpt-clk";
+   u-boot,dm-pre-reloc;
+   };
+
+   watchdog: watchdog@1001c000 {
+   compatible = "mediatek,mt7986-wdt";
+   reg = <0x1001c000 0x1000>;
+   interrupts = ;
+   #reset-cells = <1>;
+   status = "disabled";
+   };
+
+   gic: interrupt-controlle

[PATCH v3 00/32] Add support for MediaTek MT7981/MT7986 SoCs - v3

2022-09-09 Thread 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

Changes of v3:
- Use regmap for cpu driver to access hwver registers

Changes of v2:
- Add cpu driver for print_cpuinfo()
- Fix NULL pointer dereference in mtk_image
- Fix coding style
- Minor changes

Weijie Gao (32):
  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
  cpu: add basic cpu driver for MediaTek ARM chips
  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   |6 +
 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   |  173 +++
 arch/arm/dts/mt7981-sd-rfb.dts|  139 +++
 arch/arm/dts/mt7981.dtsi  |  295 +
 arch/arm/dts/mt7986-u-boot.dtsi   |   33 +
 arch/arm/dts/mt7986.dtsi  |  350 ++
 arch/arm/dts/mt7986a-emmc-rfb.dts |   16 +
 arch/arm/dts/mt7986a-rfb.dts  |  218 
 arch/arm/dts/mt7986a-sd-rfb.dts   |  177 +++
 arch/arm/dts/mt7986b-emmc-rfb.dts |   16 +
 arch/arm/dts/mt7986b-rfb.dts  |  204 
 arch/arm/dts/mt7986b-sd-rfb.dts   |  173 +++
 arch/arm/mach-mediatek/Kconfig|   23 +
 arch/arm/mach-mediatek/Makefile   |2 +
 arch/arm/mach-mediatek/mt7981/Makefile|4 +
 arch/arm/mach-mediatek/mt7981/init.c  |   45 +
 arch/arm/mach-mediatek/mt7981/lowlevel_init.S |   32 +
 arch/arm/mach-mediatek/mt7986/Makefile|4 +
 arch/arm/mach-mediatek/mt7986/init.c  |   45 +
 arch/arm/mach-mediatek/mt7986/lowlevel_init.S |   32 +
 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  |   69 ++
 configs/mt7981_sd_rfb_defconfig   |   64 +
 configs/mt7986_rfb_defconfig  |   66 ++
 configs/mt7986a_bpir3_emmc_defconfig  |   64 +
 configs/mt7986a_bpir3_sd_defconfig|   64 +
 drivers/clk/mediatek/Makefile |2 +
 drivers/clk/mediatek/clk-mt7981.c |  683 +++
 drivers/clk/mediatek/clk-mt7986.c |  672 +++
 drivers/clk/mediatek/clk-mtk.c|  156 ++-
 drivers/clk/mediatek/clk-mtk.h|   13 +-
 drivers/cpu/Makefile  |1 +
 drivers/cpu/mtk_cpu.c |   86 ++
 drivers/i2c/Kconfig   |9 +
 drivers/i2c/Makefile

Re: [PATCH v2 28/32] cpu: add basic cpu driver for MediaTek ARM chips

2022-08-31 Thread Weijie Gao
On Wed, 2022-08-31 at 07:46 -0600, Simon Glass wrote:
> Hi Weijie,
> 
> On Wed, 31 Aug 2022 at 05:08, Weijie Gao 
> wrote:
> > 
> > Add basic CPU driver used to retrieve CPU model information.
> > 
> > Signed-off-by: Weijie Gao 
> > ---
> >   v2 changes: new
> > ---
> >  drivers/cpu/Makefile  |   1 +
> >  drivers/cpu/mtk_cpu.c | 106
> > ++
> >  2 files changed, 107 insertions(+)
> >  create mode 100644 drivers/cpu/mtk_cpu.c
> > 
> > diff --git a/drivers/cpu/Makefile b/drivers/cpu/Makefile
> > index 20884b1795..3b38ba9c58 100644
> > --- a/drivers/cpu/Makefile
> > +++ b/drivers/cpu/Makefile
> > @@ -9,6 +9,7 @@ obj-$(CONFIG_CPU) += cpu-uclass.o
> >  obj-$(CONFIG_ARCH_BMIPS) += bmips_cpu.o
> >  obj-$(CONFIG_ARCH_IMX8) += imx8_cpu.o
> >  obj-$(CONFIG_ARCH_AT91) += at91_cpu.o
> > +obj-$(CONFIG_ARCH_MEDIATEK) += mtk_cpu.o
> >  obj-$(CONFIG_CPU_MPC83XX) += mpc83xx_cpu.o
> >  obj-$(CONFIG_CPU_RISCV) += riscv_cpu.o
> >  obj-$(CONFIG_CPU_MICROBLAZE) += microblaze_cpu.o
> > diff --git a/drivers/cpu/mtk_cpu.c b/drivers/cpu/mtk_cpu.c
> > new file mode 100644
> > index 00..d00b4c669e
> > --- /dev/null
> > +++ b/drivers/cpu/mtk_cpu.c
> > @@ -0,0 +1,106 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
> > + *
> > + * Author: Weijie Gao 
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +DECLARE_GLOBAL_DATA_PTR;
> 
> dont't need this?
> 
> > +
> > +struct mtk_cpu_plat {
> > +   void __iomem *hwver_base;
> > +};
> > +
> > +static int mtk_cpu_get_desc(const struct udevice *dev, char *buf,
> > int size)
> > +{
> > +   struct mtk_cpu_plat *plat = dev_get_plat(dev);
> > +
> > +   snprintf(buf, size, "MediaTek MT%04X", readl(plat-
> > >hwver_base));
> > +
> > +   return 0;
> > +}
> > +
> > +static int mtk_cpu_get_count(const struct udevice *dev)
> > +{
> > +   return 1;
> > +}
> > +
> > +static int mtk_cpu_get_vendor(const struct udevice *dev, char
> > *buf, int size)
> > +{
> > +   snprintf(buf, size, "MediaTek");
> > +
> > +   return 0;
> > +}
> > +
> > +static int mtk_cpu_probe(struct udevice *dev)
> > +{
> > +   struct mtk_cpu_plat *plat = dev_get_plat(dev);
> > +   const void *fdt = gd->fdt_blob, *reg;
> > +   int offset, parent, len, na, ns;
> > +   u64 addr;
> > +
> > +   if (!fdt)
> > +   return -ENODEV;
> > +
> > +   offset = fdt_path_offset(fdt, "/hwver");
> 
> This is very strange, but you should have a driver for that node,
> e.g.
> a SYSCON driver. Then from this driver you can obtain the address
> with
> syscon_get_first_range() or similar.
> 
> > +   if (offset < 0)
> > +   return -ENODEV;
> > +
> > +   parent = fdt_parent_offset(fdt, offset);
> > +   if (parent < 0)
> > +   return -ENODEV;
> > +
> > +   na = fdt_address_cells(fdt, parent);
> > +   if (na < 1)
> > +   return -ENODEV;
> > +
> > +   ns = fdt_size_cells(gd->fdt_blob, parent);
> > +   if (ns < 0)
> > +   return -ENODEV;
> > +
> > +   reg = fdt_getprop(gd->fdt_blob, offset, "reg", );
> > +   if (!reg)
> > +   return -ENODEV;
> > +
> > +   if (ns)
> > +   addr = fdt_translate_address(fdt, offset, reg);
> > +   else
> > +   addr = fdt_read_number(reg, na);
> > +
> 
> All of the above should go away. We should use dev_read() / ofnode...
> for device tree access.

OK. This is indeed tricky. I just didn't want to add reference to the
hwver node for every cpu node.
I'll change this using the regular way.

> 
> > +   plat->hwver_base = map_sysmem(addr, 0);
> > +   if (!plat->hwver_base)
> > +   return -EINVAL;
> > +
> > +   return 0;
> > +}
> > +
> > +static const struct cpu_ops mtk_cpu_ops = {
> > +   .get_desc   = mtk_cpu_get_desc,
> > +   .get_count  = mtk_cpu_get_count,
> > +   .get_vendor = mtk_cpu_get_vendor,
> > +};
> > +
> > +static const struct udevice_id mtk_cpu_ids[] = {
> > +   { .compatible = "arm,cortex-a7" },
> > +   { .compatible = "arm,cortex-a53" },
> > +   { .compatible = "arm,cortex-a73" },
> > +   { /* sentinel */ }
> > +};
> > +
> > +U_BOOT_DRIVER(cpu_mtk) = {
> > +   .name   = "mtk-cpu",
> > +   .id = UCLASS_CPU,
> > +   .of_match   = mtk_cpu_ids,
> > +   .ops= _cpu_ops,
> > +   .probe  = mtk_cpu_probe,
> > +   .plat_auto  = sizeof(struct mtk_cpu_plat),
> > +   .flags  = DM_FLAG_PRE_RELOC,
> > +};
> > --
> > 2.17.1
> > 
> 
> Regards,
> Simon


[PATCH v2 31/32] tools: mtk_image: add support for nand headers used by newer chips

2022-08-31 Thread 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 
---
v2 changes: none
---
 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 1f7396aa69..9b3136afa3 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 */
@@ -366,20 +369,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, 0

[PATCH v2 30/32] tools: mtk_image: split the code of generating NAND header into a new file

2022-08-31 Thread 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.

Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v2 changes:
  Add comments
  Call mtk_nand_header_size only for NAND/SNAND to avoid NULL pointer access
---
 tools/Makefile   |   1 +
 tools/mtk_image.c| 305 ++-
 tools/mtk_image.h|  25 
 tools/mtk_nand_headers.c | 286 
 tools/mtk_nand_headers.h |  61 
 5 files changed, 389 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 3626919633..34a1aa7a8b 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..1f7396aa69 100644
--- a/tools/mtk_image.c
+++ b/tools/mtk_image.c
@@ -12,216 +12,7 @@
 #include 
 #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, 0x

[PATCH v2 32/32] MAINTAINERS: update maintainer for MediaTek ARM platform

2022-08-31 Thread Weijie Gao
Add new files for MediaTek ARM platform

Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v2 changes:
  Add cpu driver file
---
 MAINTAINERS | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 36a2b69fcb..d47674c476 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -355,20 +355,26 @@ 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/cpu/mtk_cpu.c
+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



[PATCH v2 27/32] clk: mediatek: add clock driver support for MediaTek MT7981 SoC

2022-08-31 Thread Weijie Gao
This patch adds clock driver support for MediaTek MT7981 SoC

Reviewed-by: Sean Anderson 
Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v2 changes:
  Fix coding style
---
 drivers/clk/mediatek/Makefile  |   1 +
 drivers/clk/mediatek/clk-mt7981.c  | 683 +
 include/dt-bindings/clock/mt7981-clk.h | 267 ++
 3 files changed, 951 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 00..7fcb81419c
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt7981.c
@@ -0,0 +1,683 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek clock driver for MT7981 SoC
+ *
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Sam Shih 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#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, 13),
+   FIXED_CLK(CK_APMIXED_NET2PLL, CLK_XTAL, 8),
+   FIXED_CLK(CK_APMIXED_MMPLL, CLK_XTAL, 72000),
+   FIXED_CLK(CK_APMIXED_SGMPLL, CLK_XTAL, 32500),
+   FIXED_CLK(CK_APMIXED_WEDMCUPLL, CLK_XTAL, 20800),
+   FIXED_CLK(CK_APMIXED_NET1PLL, CLK_XTAL, 25),
+   FIXED_CLK(CK_APMIXED_MPLL, CLK_XTAL, 41600),
+   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, 4000),
+};
+
+/* 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(

[PATCH v2 29/32] tools: mtk_image: split gfh header verification into a new function

2022-08-31 Thread 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.

Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v2 changes: none
---
 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



[PATCH v2 26/32] clk: mediatek: add clock driver support for MediaTek MT7986 SoC

2022-08-31 Thread Weijie Gao
This patch adds clock driver support for MediaTek MT7986 SoC

Reviewed-by: Sean Anderson 
Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v2 changes:
  Fix coding style
---
 drivers/clk/mediatek/Makefile  |   1 +
 drivers/clk/mediatek/clk-mt7986.c  | 672 +
 include/dt-bindings/clock/mt7986-clk.h | 249 +
 3 files changed, 922 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 00..b3fa63fc0a
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt7986.c
@@ -0,0 +1,672 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek clock driver for MT7986 SoC
+ *
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Sam Shih 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#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, 20),
+   FIXED_CLK(CK_APMIXED_NET2PLL, CLK_XTAL, 8),
+   FIXED_CLK(CK_APMIXED_MMPLL, CLK_XTAL, 144000),
+   FIXED_CLK(CK_APMIXED_SGMPLL, CLK_XTAL, 32500),
+   FIXED_CLK(CK_APMIXED_WEDMCUPLL, CLK_XTAL, 76000),
+   FIXED_CLK(CK_APMIXED_NET1PLL, CLK_XTAL, 25),
+   FIXED_CLK(CK_APMIXED_MPLL, CLK_XTAL, 41600),
+   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, 4000),
+};
+
+/* 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_760

[PATCH v2 28/32] cpu: add basic cpu driver for MediaTek ARM chips

2022-08-31 Thread Weijie Gao
Add basic CPU driver used to retrieve CPU model information.

Signed-off-by: Weijie Gao 
---
  v2 changes: new
---
 drivers/cpu/Makefile  |   1 +
 drivers/cpu/mtk_cpu.c | 106 ++
 2 files changed, 107 insertions(+)
 create mode 100644 drivers/cpu/mtk_cpu.c

diff --git a/drivers/cpu/Makefile b/drivers/cpu/Makefile
index 20884b1795..3b38ba9c58 100644
--- a/drivers/cpu/Makefile
+++ b/drivers/cpu/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_CPU) += cpu-uclass.o
 obj-$(CONFIG_ARCH_BMIPS) += bmips_cpu.o
 obj-$(CONFIG_ARCH_IMX8) += imx8_cpu.o
 obj-$(CONFIG_ARCH_AT91) += at91_cpu.o
+obj-$(CONFIG_ARCH_MEDIATEK) += mtk_cpu.o
 obj-$(CONFIG_CPU_MPC83XX) += mpc83xx_cpu.o
 obj-$(CONFIG_CPU_RISCV) += riscv_cpu.o
 obj-$(CONFIG_CPU_MICROBLAZE) += microblaze_cpu.o
diff --git a/drivers/cpu/mtk_cpu.c b/drivers/cpu/mtk_cpu.c
new file mode 100644
index 00..d00b4c669e
--- /dev/null
+++ b/drivers/cpu/mtk_cpu.c
@@ -0,0 +1,106 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 MediaTek Inc. All rights reserved.
+ *
+ * Author: Weijie Gao 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct mtk_cpu_plat {
+   void __iomem *hwver_base;
+};
+
+static int mtk_cpu_get_desc(const struct udevice *dev, char *buf, int size)
+{
+   struct mtk_cpu_plat *plat = dev_get_plat(dev);
+
+   snprintf(buf, size, "MediaTek MT%04X", readl(plat->hwver_base));
+
+   return 0;
+}
+
+static int mtk_cpu_get_count(const struct udevice *dev)
+{
+   return 1;
+}
+
+static int mtk_cpu_get_vendor(const struct udevice *dev, char *buf, int size)
+{
+   snprintf(buf, size, "MediaTek");
+
+   return 0;
+}
+
+static int mtk_cpu_probe(struct udevice *dev)
+{
+   struct mtk_cpu_plat *plat = dev_get_plat(dev);
+   const void *fdt = gd->fdt_blob, *reg;
+   int offset, parent, len, na, ns;
+   u64 addr;
+
+   if (!fdt)
+   return -ENODEV;
+
+   offset = fdt_path_offset(fdt, "/hwver");
+   if (offset < 0)
+   return -ENODEV;
+
+   parent = fdt_parent_offset(fdt, offset);
+   if (parent < 0)
+   return -ENODEV;
+
+   na = fdt_address_cells(fdt, parent);
+   if (na < 1)
+   return -ENODEV;
+
+   ns = fdt_size_cells(gd->fdt_blob, parent);
+   if (ns < 0)
+   return -ENODEV;
+
+   reg = fdt_getprop(gd->fdt_blob, offset, "reg", );
+   if (!reg)
+   return -ENODEV;
+
+   if (ns)
+   addr = fdt_translate_address(fdt, offset, reg);
+   else
+   addr = fdt_read_number(reg, na);
+
+   plat->hwver_base = map_sysmem(addr, 0);
+   if (!plat->hwver_base)
+   return -EINVAL;
+
+   return 0;
+}
+
+static const struct cpu_ops mtk_cpu_ops = {
+   .get_desc   = mtk_cpu_get_desc,
+   .get_count  = mtk_cpu_get_count,
+   .get_vendor = mtk_cpu_get_vendor,
+};
+
+static const struct udevice_id mtk_cpu_ids[] = {
+   { .compatible = "arm,cortex-a7" },
+   { .compatible = "arm,cortex-a53" },
+   { .compatible = "arm,cortex-a73" },
+   { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(cpu_mtk) = {
+   .name   = "mtk-cpu",
+   .id = UCLASS_CPU,
+   .of_match   = mtk_cpu_ids,
+   .ops= _cpu_ops,
+   .probe  = mtk_cpu_probe,
+   .plat_auto  = sizeof(struct mtk_cpu_plat),
+   .flags  = DM_FLAG_PRE_RELOC,
+};
-- 
2.17.1



[PATCH v2 25/32] clk: mediatek: add CLK_XTAL support for clock driver

2022-08-31 Thread Weijie Gao
This adds the CLK_XTAL macro/flag to allow modeling clocks which are
directly connected to the xtal clock.

Signed-off-by: Weijie Gao 
---
v2 changes:
  Fix incorrect fallback in mtk_infrasys_get_factor_rate
  Fix commit description
---
 drivers/clk/mediatek/clk-mtk.c | 4 
 drivers/clk/mediatek/clk-mtk.h | 3 ++-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index 207a4c6b11..4303300d3a 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,9 @@ 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;
+   break;
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 e7c61ae483..48ce16484e 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -29,7 +29,8 @@
 #define CLK_PARENT_APMIXED BIT(4)
 #define CLK_PARENT_TOPCKGENBIT(5)
 #define CLK_PARENT_INFRASYSBIT(6)
-#define CLK_PARENT_MASKGENMASK(6, 4)
+#define CLK_PARENT_XTALBIT(7)
+#define CLK_PARENT_MASKGENMASK(7, 4)
 
 #define ETHSYS_HIFSYS_RST_CTRL_OFS 0x34
 
-- 
2.17.1



[PATCH v2 23/32] clk: mediatek: add support to configure clock driver parent

2022-08-31 Thread Weijie Gao
This patch adds support for a clock node to configure its parent clock
where possible.

Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v2 changes: none
---
 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 7d145f4975..a537ff259f 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, ))
-   return -ENODEV;
-
-   parent.dev = dev;
-   } else {
+   if (pdev)
+   parent.dev = pdev;
+   else
parent.dev = clk->dev;
-   }
 
return 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);
@@ -321,9 +315,18 @@ static ulong mtk_topckgen_get_mux_rate(struct clk *clk, 
u32 off)
 
if (mux->parent[index] > 0 ||
(mux->parent[index] == CLK_XTAL &&
-priv->tree->flags & CLK_BYPASS_XTAL))
-   return mtk_clk_find_parent_rate(clk, mux->parent[index],
-   NULL);
+priv->tree->flags & CLK_BYPASS_XTAL)) {
+   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;
 }
@@ -342,7 +345,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;
@@ -375,7 +378,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;
@@ -401,7 +404,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);
 
@@ -473,19 +476,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 = >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 = {
@@ -496,10 +487,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_

[PATCH v2 24/32] clk: mediatek: add infrasys clock mux support

2022-08-31 Thread Weijie Gao
This patch adds infrasys clock mux support for mediatek clock drivers.

Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v2 changes:
  Fix the if condition of CLK_BYPASS_XTAL
---
 drivers/clk/mediatek/clk-mtk.c | 71 ++
 drivers/clk/mediatek/clk-mtk.h |  4 +-
 2 files changed, 74 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index a537ff259f..207a4c6b11 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 = >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);
@@ -331,6 +349,33 @@ 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 = >tree->muxes[off];
+   u32 index;
+
+   index = readl(priv->base + mux->mux_reg);
+   index &= mux->mux_mask << mux->mux_shift;
+   index = index >> mux->mux_shift;
+
+   if (mux->parent[index] > 0 ||
+   (mux->parent[index] == CLK_XTAL &&
+priv->tree->flags & CLK_BYPASS_XTAL)) {
+   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);
@@ -345,6 +390,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);
@@ -493,6 +557,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 41854879c6..e7c61ae483 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -28,7 +28,8 @@
 
 #define CLK_PARENT_APMIXED BIT(4)
 #define CLK_PARENT_TOPCKGENBIT(5)
-#define CLK_PARENT_MASKGENMASK(5, 4)
+#define CLK_PARENT_INFRASYSBIT(6)
+#define CLK_PARENT_MASKGENMASK(6, 4)
 
 #define ETHSYS_HIFSYS_RST_CTRL_OFS 0x34
 
@@ -220,6 +221,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



[PATCH v2 20/32] pinctrl: mediatek: add pinctrl driver for MT7981 SoC

2022-08-31 Thread Weijie Gao
This patch adds pinctrl and gpio support for MT7981 SoC

Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v2 changes: none
---
 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 00..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 
+ */
+
+#include 
+#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:0x11c0, iocfg_rm:0x11c1, iocfg_rb:0x11d2,
+ * iocfg_lb:0x11e0, iocfg_bl:0x11e2, iocfg_tm:0x11f0,
+ * iocfg_tl:0x11f1,
+ * _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, 0x1

[PATCH v2 22/32] clk: mediatek: add CLK_BYPASS_XTAL flag to allow bypassing searching clock parent of xtal clock

2022-08-31 Thread 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.

Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v2 changes:
  Add comment for flags
  Fix the if condition of CLK_BYPASS_XTAL
---
 drivers/clk/mediatek/clk-mtk.c | 4 +++-
 drivers/clk/mediatek/clk-mtk.h | 6 ++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index d43b8a0648..7d145f4975 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -319,7 +319,9 @@ static ulong mtk_topckgen_get_mux_rate(struct clk *clk, u32 
off)
index &= mux->mux_mask << mux->mux_shift;
index = index >> mux->mux_shift;
 
-   if (mux->parent[index])
+   if (mux->parent[index] > 0 ||
+   (mux->parent[index] == CLK_XTAL &&
+priv->tree->flags & CLK_BYPASS_XTAL))
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..e0c5550c80 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -11,6 +11,11 @@
 #define CLK_XTAL   0
 #define MHZ(1000 * 1000)
 
+/* flags in struct mtk_clk_tree */
+
+/* clk id == 0 doesn't mean it's xtal clk */
+#define CLK_BYPASS_XTALBIT(0)
+
 #define HAVE_RST_BAR   BIT(0)
 #define CLK_DOMAIN_SCPSYS  BIT(0)
 #define CLK_MUX_SETCLR_UPD BIT(1)
@@ -197,6 +202,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



[PATCH v2 21/32] pinctrl: mediatek: add pinctrl driver for MT7986 SoC

2022-08-31 Thread Weijie Gao
This patch adds pinctrl and gpio support for MT7986 SoC

Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v2 changes: none
---
 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 00..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 
+ */
+
+#include 
+#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:0x11c3, iocfg_rb:0x11c4, iocfg_lt:0x11e2,
+ * iocfg_lb:0x11e3, iocfg_tr:0x11f0, iocfg_tl:0x11f1,
+ * _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, 0

[PATCH v2 17/32] i2c: add support for MediaTek I2C interface

2022-08-31 Thread Weijie Gao
This patch adds support for MediaTek I2C interface

Reviewed-by: Heiko Schocher 
Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v2 changes:
  Reorganize code to reduce duplicated code
  Rename mtk_i2c_ofdata_to_platdata to mtk_i2c_of_to_plat
---
 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 00..5528bcd7cc
--- /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 
+ *
+ * MediaTek I2C Interface driver
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define I2C_RS_TRANSFERBIT(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_CNFGBIT(15)
+#define I2C_RS_MUL_TRIGBIT(14)
+#define I2C_DCM_DISABLE0x
+#define I2C_IO_CONFIG_OPEN_DRAIN   0x0003
+#define I2C_IO_CONFIG_PUSH_PULL0x
+#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 0x
+#define I2C_TIME_DEFAULT_VALUE 0x0003
+#define I2C_WRRD_TRANAC_VALUE  0x0002
+#define I2C_RD_TRANAC_VALUE0x0001
+
+#define I2C_DMA_CON_TX 0x
+#define I2C_DMA_CON_RX 0x0001
+#define I2C_DMA_START_EN   0x0001
+#define I2C_DMA_INT_FLAG_NONE  0x
+#define I2C_DMA_CLR_FLAG   0x
+#define I2C_DMA_TX_RX  0x
+#define I2C_DMA_HARD_RST   0x0002
+
+#define MAX_ST_MODE_SPEED  10
+#define MAX_FS_MODE_SPEED  40
+#define MAX_HS_MODE_SPEED  340
+#define MAX_SAMPLE_CNT_DIV 8
+#define MAX_STEP_CNT_DIV   64
+#define MAX_HS_STEP_CNT_DIV8
+#define I2C_DEFAULT_CLK_DIV4
+
+#define MAX_I2C_ADDR   0x7f
+#define MAX_I2C_LEN0xff
+#define TRANS_ADDR_ONLYBIT(8)
+#define TRANSFER_TIMEOUT   5  /* us */
+#define I2C_FIFO_STAT1_MASK0x001f
+#define TIMING_SAMPLE_OFFSET   8
+#define HS_SAMPLE_OFFSET   12
+#define HS_STEP_OFFSET 8
+
+#define I2C_CONTROL_WRAPPERBIT(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)
+
+#define I2C_MASTER_WR  BIT(0)
+#define I2C_MASTER_RD  BIT(1)
+#define I2C_MASTER_WRRD(I2C_MASTER_WR | I2C_MASTER_RD)
+
+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,
+ 

[PATCH v2 19/32] dt-bindings: pinctrl: mediatek: add a header for common pinconf parameters

2022-08-31 Thread Weijie Gao
This patch adds a pinctrl header for common pinconf parameters such as
pull-up/pull-down resistors and drive strengths.

Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v2 changes: none
---
 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 00..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 
+ */
+
+#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



[PATCH v2 18/32] arm: dts: mt7622: add i2c support

2022-08-31 Thread Weijie Gao
Add both hardware and software i2c support for mt7622.

Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v2 changes: none
---
 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";
+   };
+   };
+
 };
 
  {
@@ -242,3 +250,13 @@
  {
status = "okay";
 };
+
+_i2c {
+   status = "disabled";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_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 = < 56 GPIO_ACTIVE_HIGH>, /* SDA */
+   < 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 = ;
+   clock-div = <16>;
+   clocks = < CLK_PERI_I2C1_PD>,
+< CLK_PERI_AP_DMA_PD>;
+   clock-names = "main", "dma";
+   #address-cells = <1>;
+   #size-cells = <0>;
+   status = "disabled";
+   };
+
 };
-- 
2.17.1



[PATCH v2 16/32] spi: add support for MediaTek spi-mem controller

2022-08-31 Thread Weijie Gao
This patch adds support for spi-mem controller found on newer MediaTek SoCs
This controller supports Single/Dual/Quad SPI mode.

Reviewed-by: Simon Glass 
Signed-off-by: SkyLake.Huang 
---
v2 changes:
  Remove unused code
  Fix coding style
  Add description for struct fields
---
 drivers/spi/Kconfig|   8 +
 drivers/spi/Makefile   |   1 +
 drivers/spi/mtk_spim.c | 701 +
 3 files changed, 710 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 00..b45ef529a5
--- /dev/null
+++ b/drivers/spi/mtk_spim.c
@@ -0,0 +1,701 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 MediaTek Inc. All Rights Reserved.
+ *
+ * Author: SkyLake.Huang 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define SPI_CFG0_REG   0x
+#define SPI_CFG1_REG   0x0004
+#define SPI_TX_SRC_REG 0x0008
+#define SPI_RX_DST_REG 0x000c
+#define SPI_TX_DATA_REG0x0010
+#define SPI_RX_DATA_REG0x0014
+#define SPI_CMD_REG0x0018
+#define SPI_IRQ_REG0x001c
+#define SPI_STATUS_REG 0x0020
+#define SPI_PAD_SEL_REG0x0024
+#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_OFFSET8
+#define SPI_CFG0_CS_HOLD_OFFSET16
+#define SPI_CFG0_CS_SETUP_OFFSET   24
+#define SPI_ADJUST_CFG0_CS_HOLD_OFFSET 0
+#define SPI_ADJUST_CFG0_CS_SETUP_OFFSET16
+
+#define SPI_CFG1_CS_IDLE_OFFSET0
+#define SPI_CFG1_PACKET_LOOP_OFFSET8
+#define SPI_CFG1_PACKET_LENGTH_OFFSET  16
+#define SPI_CFG1_GET_TICKDLY_OFFSET29
+
+#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_MASK0x3ff
+#define SPI_CFG1_IPM_PACKET_LENGTH_MASKGENMASK(31, 16)
+#define SPI_CFG2_SCK_HIGH_OFFSET   0
+#define SPI_CFG2_SCK_LOW_OFFSET16
+#define SPI_CFG2_SCK_HIGH_MASK GENMASK(15, 0)
+#define SPI_CFG2_SCK_LOW_MASK  GENMASK(31, 16)
+
+#define SPI_CMD_ACTBIT(0)
+#define SPI_CMD_RESUME BIT(1)
+#define SPI_CMD_RSTBIT(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 

[PATCH v2 14/32] timer: mtk: add support for MediaTek MT7981/MT7986 SoCs

2022-08-31 Thread 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.

Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v2 changes: none
---
 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 
 #include 
 
-#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_ENABLEBIT(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_CON0x0
+#define MTK_GPT_V1_CLK 0x4
+#define MTK_GPT_CNT0x8
+
+#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, );
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



[PATCH v2 13/32] pwm: mtk: add support for MediaTek MT7981 SoC

2022-08-31 Thread 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.

Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v2 changes: none
---
 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 10L
 
-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)_data },
{ .compatible = "mediatek,mt7623-pwm", .data = (ulong)_data },
{ .compatible = "mediatek,mt7629-pwm", .data = (ulong)_data },
+   { .compatible = "mediatek,mt7981-pwm", .data = (ulong)_data },
{ .compatible = "mediatek,mt7986-pwm", .data = (ulong)_data },
{ }
 };
-- 
2.17.1



[PATCH v2 15/32] watchdog: mediatek: add support for MediaTek MT7986 SoC

2022-08-31 Thread Weijie Gao
Add watchdog support for MediaTek MT7986 SoC

Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v2 changes: none
---
 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



[PATCH v2 12/32] pwm: mtk: add support for MediaTek MT7986 SoC

2022-08-31 Thread Weijie Gao
This patch adds PWM support for MediaTek MT7986 SoC.

Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v2 changes: none
---
 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)_data },
{ .compatible = "mediatek,mt7623-pwm", .data = (ulong)_data },
{ .compatible = "mediatek,mt7629-pwm", .data = (ulong)_data },
+   { .compatible = "mediatek,mt7986-pwm", .data = (ulong)_data },
{ }
 };
 
-- 
2.17.1



[PATCH v2 11/32] arm: dts: mt7622: force high-speed mode for uart

2022-08-31 Thread 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.

Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v2 changes: none
---
 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 = < CLK_TOP_AXI_SEL>;
assigned-clock-parents = < CLK_TOP_SYSPLL1_D2>;
+   mediatek,force-highspeed;
};
 
mmc0: mmc@1123 {
-- 
2.17.1



[PATCH v2 10/32] serial: mtk: add support for using dynamic baud clock souce

2022-08-31 Thread 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().

Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v2 changes:
  Add description for priv struct
  Fix the type of clk_rate
---
 drivers/serial/serial_mtk.c | 80 ++---
 1 file changed, 47 insertions(+), 33 deletions(-)

diff --git a/drivers/serial/serial_mtk.c b/drivers/serial/serial_mtk.c
index a84f39b3fa..1d7cc9f7b6 100644
--- a/drivers/serial/serial_mtk.c
+++ b/drivers/serial/serial_mtk.c
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -70,27 +71,37 @@ struct mtk_serial_regs {
 #define BAUD_ALLOW_MAX(baud)   ((baud) + (baud) * 3 / 100)
 #define BAUD_ALLOW_MIX(baud)   ((baud) - (baud) * 3 / 100)
 
+/* struct mtk_serial_priv -Structure holding all information used by the
+ * driver
+ * @regs:  Register base of the serial port
+ * @clk:   The baud clock device
+ * @fixed_clk_rate:Fallback fixed baud clock rate if baud clock
+ * device is not specified
+ * @force_highspeed:   Force using high-speed mode
+ */
 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,
+  uint clk_rate)
 {
u32 quot, realbaud, samplecount = 1;
 
/* Special case for low baud clock */
-   if (baud <= 115200 && priv->clock <= 1200) {
+   if (baud <= 115200 && clk_rate == 1200) {
writel(3, >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 +115,7 @@ static void _mtk_serial_setbrg(struct mtk_serial_priv 
*priv, int baud)
 
if (baud <= 115200) {
writel(0, >regs->highspeed);
-   quot = DIV_ROUND_CLOSEST(priv->clock, 16 * baud);
+   quot = DIV_ROUND_CLOSEST(clk_rate, 16 * baud);
} else if (baud <= 576000) {
writel(2, >regs->highspeed);
 
@@ -112,13 +123,13 @@ static void _mtk_serial_setbrg(struct mtk_serial_priv 
*priv, int baud)
if ((baud == 50) || (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, >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 +178,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(>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 +227,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 +235,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, );
-   if (!err) {
-   err = clk_get_rate();
-   if 

[PATCH v2 09/32] net: mediatek: add support for MediaTek MT7981/MT7986

2022-08-31 Thread Weijie Gao
This patch adds support for MediaTek MT7981 and MT7986. Both chips uses
PDMA v2.

Reviewed-by: Ramon Fried 
Signed-off-by: Weijie Gao 
---
v2 changes: none
---
 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 fb72baae68..4c9fb266c7 100644
--- a/drivers/net/mtk_eth.c
+++ b/drivers/net/mtk_eth.c
@@ -115,6 +115,7 @@ struct mtk_eth_priv {
int force_mode;
int speed;
int duplex;
+   bool pn_swap;
 
struct phy_device *phydev;
int phy_interface;
@@ -1057,6 +1058,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);
@@ -1470,6 +1477,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 */
@@ -1520,6 +1529,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,
@@ -1549,6 +1574,8 @@ static const struct mtk_soc_data mt7621_data = {
 };
 
 static const struct udevice_id mtk_eth_ids[] = {
+   { .compatible = "mediatek,mt7986-eth", .data = (ulong)_data },
+   { .compatible = "mediatek,mt7981-eth", .data = (ulong)_data },
{ .compatible = "mediatek,mt7629-eth", .data = (ulong)_data },
{ .compatible = "mediatek,mt7623-eth", .data = (ulong)_data },
{ .compatible = "mediatek,mt7622-eth", .data = (ulong)_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_RX0x03
+
 #define SGMSYS_GEN2_SPEED  0x2028
 #define SGMSYS_GEN2_SPEED_V2   0x128
 #define SGMSYS_SPEED_2500  BIT(2)
-- 
2.17.1



[PATCH v2 07/32] net: mediatek: stop using bitfileds for DMA descriptors

2022-08-31 Thread 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.

Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v2 changes:
  Fix typo in commit message
---
 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 ce4aa6e065..e3738b9277 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,
@@ -151,13 +80,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;
@@ -1202,14 +1133,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, 0x, 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));
@@ -1218,17 +1151,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;
}
 
@@ -1315,20 +1252,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;

[PATCH v2 08/32] net: mediatek: add support for PDMA v2

2022-08-31 Thread 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.

Reviewed-by: Ramon Fried 
Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v2 changes:
  Add description for new fields
---
 drivers/net/mtk_eth.c | 54 ---
 drivers/net/mtk_eth.h | 53 +++---
 2 files changed, 86 insertions(+), 21 deletions(-)

diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c
index e3738b9277..fb72baae68 100644
--- a/drivers/net/mtk_eth.c
+++ b/drivers/net/mtk_eth.c
@@ -76,10 +76,14 @@ enum mtk_switch {
  * @caps   Flags shown the extra capability for the SoC
  * @ana_rgc3:  The offset for register ANA_RGC3 related to
  * sgmiisys syscon
+ * @pdma_base: Register base of PDMA block
+ * @txd_size:  Tx DMA descriptor size.
+ * @rxd_size:  Rx DMA descriptor size.
  */
 struct mtk_soc_data {
u32 caps;
u32 ana_rgc3;
+   u32 pdma_base;
u32 txd_size;
u32 rxd_size;
 };
@@ -130,13 +134,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,
@@ -1133,8 +1137,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, 0x, 0);
@@ -1155,7 +1159,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;
}
@@ -1164,7 +1172,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;
}
@@ -1193,6 +1205,9 @@ static int mtk_eth_start(struct udevice *dev)
reset_deassert(>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);
 
@@ -1227,7 +1242,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);
 }
 
@@ -1252,7 +1267,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;
@@ -1267,7 +1282,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

[PATCH v2 06/32] net: mediatek: use a struct to cover variations of all SoCs

2022-08-31 Thread 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.

Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v2c changes:
  Add description for new struct
---
 drivers/net/mtk_eth.c | 56 ++-
 drivers/net/mtk_eth.h | 25 ++-
 2 files changed, 64 insertions(+), 17 deletions(-)

diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c
index 4fe7ee0d36..ce4aa6e065 100644
--- a/drivers/net/mtk_eth.c
+++ b/drivers/net/mtk_eth.c
@@ -142,11 +142,15 @@ enum mtk_switch {
SW_MT7531
 };
 
-enum mtk_soc {
-   SOC_MT7623,
-   SOC_MT7629,
-   SOC_MT7622,
-   SOC_MT7621
+/* struct mtk_soc_data -   This is the structure holding all differences
+ * among various plaforms
+ * @caps   Flags shown the extra capability for the SoC
+ * @ana_rgc3:  The offset for register ANA_RGC3 related to
+ * sgmiisys syscon
+ */
+struct mtk_soc_data {
+   u32 caps;
+   u32 ana_rgc3;
 };
 
 struct mtk_eth_priv {
@@ -171,7 +175,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 +683,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 +1112,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 +1185,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 +1435,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 +1552,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)_data },
+   { .compatible = "mediatek,mt7623-eth", .data = (ulong)_data },
+   { .compatible = "mediatek,mt7622-eth", .data = (ulong)_data },
+   { .compatible = "mediatek,mt7621-eth", .data = (ulong)_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 
+
+enum mkt_eth_capabi

[PATCH v2 05/32] mmc: mediatek: add support for MediaTek MT7891/MT7986 SoCs

2022-08-31 Thread Weijie Gao
Add eMMC and SDXC support for MediaTek MT7981/MT7986 SoCs
Both chips support SDXC and eMMC 4.5. MT7986A supports eMMC 5.1.

Reviewed-by: Jaehoon Chung 
Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v2 changes: none
---
 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, >base->msdc_inten);
 
-   writel(0, tune_reg);
+   if (host->top_base) {
+   writel(0, >top_base->emmc_top_control);
+   writel(0, >top_base->emmc_top_cmd);
+   } else {
+   writel(0, tune_reg);
+   }
writel(0, >base->msdc_iocon);
 
if (host->r_smpl)
@@ -1507,9 +1512,14 @@ static void msdc_init_hw(struct msdc_host *host)
writel(0x403c0046, >base->patch_bit0);
writel(0x4089, >base->patch_bit1);
 
-   if (host->dev_comp->stop_clk_fix)
+   if (host->dev_comp->stop_clk_fix) {
clrsetbits_le32(>base->patch_bit1, MSDC_PB1_STOP_DLY_M,
3 << MSDC_PB1_STOP_DLY_S);
+   clrbits_le32(>base->sdc_fifo_cfg,
+SDC_FIFO_CFG_WRVALIDSEL);
+   clrbits_le32(>base->sdc_fifo_cfg,
+SDC_FIFO_CFG_RDVALIDSEL);
+   }
 
if (host->dev_comp->busy_check)
clrbits_le32(>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(>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(>top_base->emmc_top_control,
+PAD_DAT_RD_RXDLY_SEL);
+   clrbits_le32(>top_base->emmc_top_control,
+DATA_K_VALUE_SEL);
+   setbits_le32(>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(>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(>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(>base->sdc_cfg, SDC_CFG_DTOC_M,
3 << SDC_CFG_DTOC_S);
 
-   if (host->dev_comp->stop_clk_fix) {
-   clrbits_le32(>base->sdc_fifo_cfg,
-SDC_FIFO_CFG_WRVALIDSEL);
-   clrbits_le32(>base->sdc_fifo_cfg,
-SDC_FIFO_CFG_RDVALIDSEL);
-   }
 
host->def_tune_para.iocon = readl(>base->msdc_iocon);
host->def_tune_para.pad_tune = readl(>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[]

[PATCH v2 01/32] arm: mediatek: add support for MediaTek MT7986 SoC

2022-08-31 Thread 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 
---
v2 changes:
  Sort include lines
  Add reference link for armv8_el2_to_aarch32 in lowlevel_init.S
  Remove print_cpuinfo and use cpu driver instead
---
 arch/arm/dts/mt7986-u-boot.dtsi   |  33 ++
 arch/arm/dts/mt7986.dtsi  | 346 ++
 arch/arm/mach-mediatek/Kconfig|  12 +
 arch/arm/mach-mediatek/Makefile   |   1 +
 arch/arm/mach-mediatek/mt7986/Makefile|   4 +
 arch/arm/mach-mediatek/mt7986/init.c  |  45 +++
 arch/arm/mach-mediatek/mt7986/lowlevel_init.S |  32 ++
 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 00..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 
+ */
+
+ {
+   u-boot,dm-pre-reloc;
+};
+
+ {
+   u-boot,dm-pre-reloc;
+};
+
+ {
+   u-boot,dm-pre-reloc;
+};
+
+ {
+   u-boot,dm-pre-reloc;
+};
+
+ {
+   u-boot,dm-pre-reloc;
+};
+
+ {
+   u-boot,dm-pre-reloc;
+};
+
+ {
+   u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/mt7986.dtsi b/arch/arm/dts/mt7986.dtsi
new file mode 100644
index 00..25b81ab7e1
--- /dev/null
+++ b/arch/arm/dts/mt7986.dtsi
@@ -0,0 +1,346 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Sam Shih 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/ {
+   compatible = "mediatek,mt7986";
+   interrupt-parent = <>;
+   #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 = <1200>;
+   #clock-cells = <0>;
+   /* must need this line, or uart uanable to get dummy_clk */
+   u-boot,dm-pre-reloc;
+   };
+
+   hwver: hwver {
+   compatible = "mediatek,hwver";
+   reg = <0x800 0x1000>;
+   };
+
+   timer {
+   compatible = "arm,armv8-timer";
+   interrupt-parent = <>;
+   clock-frequency = <1300>;
+   interrupts = ,
+,
+,
+;
+   arm,cpu-registers-not-fw-configured;
+   };
+
+   timer0: timer@10008000 {
+   compatible = "mediatek,mt7986-timer";
+   reg = <0x10008000 0x1000>;
+   interrupts = ;
+   clocks = < CK_INFRA_CK_F26M>;
+   clock-names = "gpt-clk";
+   u-boot,dm-pre-reloc;
+   };
+
+   watchdog: watchdog@1001c000 {
+   compatible = "mediatek,mt7986-wdt";
+   reg = <0x1001c000 0x1000>;
+   interrupts = ;
+   #reset-cells = <1>;
+   status = "disabled";
+   };
+
+   gic: interrupt-controller@c00 {
+   compatible = "arm,gic-v3";
+   #interrupt-cells = <3>;
+   interrupt-parent = <>;
+   interrupt-controller;
+   reg = <0x0c00 0x4>,  /* GICD */
+ <0x0c08 0x20>; /* GICR */
+
+   i

[PATCH v2 04/32] board: mediatek: add MT7981 reference boards

2022-08-31 Thread Weijie Gao
This patch adds general board files based on MT7981 SoCs.

MT7981 uses one mmc controller for booting from both SD and eMMC, and the
pins of mmc controller are also shared with spi controller.
So three configs are need for these boot types:

1. mt7981_rfb_defconfig - SPI-NOR and SPI-NAND
2. mt7981_emmc_rfb_defconfig - eMMC only
3. mt7981_sd_rfb_defconfig - SD only

Signed-off-by: Weijie Gao 
---
v2 changes:
  Remove mt7981_spim_nand_rfb_defconfig and mt7981_spim_nor_rfb_defconfig
---
 arch/arm/dts/Makefile  |   3 +
 arch/arm/dts/mt7981-emmc-rfb.dts   | 139 +++
 arch/arm/dts/mt7981-rfb.dts| 173 +
 arch/arm/dts/mt7981-sd-rfb.dts | 139 +++
 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   |  69 
 configs/mt7981_sd_rfb_defconfig|  64 +++
 include/configs/mt7981.h   |  26 +
 11 files changed, 700 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 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 include/configs/mt7981.h

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index ee86e467f7..3436b20917 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -1230,6 +1230,9 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \
mt7622-bananapi-bpi-r64.dtb \
mt7623n-bananapi-bpi-r2.dtb \
mt7629-rfb.dtb \
+   mt7981-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 00..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 
+ */
+
+/dts-v1/;
+#include "mt7981.dtsi"
+#include 
+
+/ {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   model = "mt7981-rfb";
+   compatible = "mediatek,mt7981", "mediatek,mt7981-rfb";
+   chosen {
+   stdout-path = 
+   tick-timer = 
+   };
+
+   reg_3p3v: regulator-3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-3.3V";
+ regulator-min-microvolt = <330>;
+ regulator-max-microvolt = <330>;
+ regulator-boot-on;
+ regulator-always-on;
+   };
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+   status = "disabled";
+};
+
+ {
+   status = "okay";
+   mediatek,gmac-id = <0>;
+   phy-mode = "sgmii";
+   mediatek,switch = "mt7531";
+   reset-gpios = < 39 GPIO_ACTIVE_HIGH>;
+
+   fixed-link {
+   speed = <1000>;
+   full-duplex;
+   };
+};
+
+ {
+   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";
+  

[PATCH v2 03/32] board: mediatek: add MT7986 reference boards

2022-08-31 Thread Weijie Gao
Add general board files based on MT7986 SoCs.

MT7986 uses one mmc controller for booting from both SD and eMMC.
Both MT7986A and MT7986B use the same pins for spi controller.

Configs for various boot types:
1. mt7986_rfb_defconfig - SPI-NOR and SPI-NAND for MT7986A/B
2. mt7986a_bpir3_emmc_defconfig - eMMC for MT7986A only
3. mt7986a_bpir3_sd_defconfig - SD for MT7986A only

Reviewed-by: Simon Glass 
Signed-off-by: Weijie Gao 
---
v2 changes:
  Rename mt7986a_emmc_rfb_defconfig to mt7986a_bpir3_emmc_defconfig
  Rename mt7986a_sd_rfb_defconfig to mt7986a_bpir3_sd_defconfig
  Remove mt7986b defconfig
---
 arch/arm/dts/Makefile|   6 +
 arch/arm/dts/mt7986a-emmc-rfb.dts|  16 ++
 arch/arm/dts/mt7986a-rfb.dts | 218 +++
 arch/arm/dts/mt7986a-sd-rfb.dts  | 177 ++
 arch/arm/dts/mt7986b-emmc-rfb.dts|  16 ++
 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_bpir3_emmc_defconfig |  64 
 configs/mt7986a_bpir3_sd_defconfig   |  64 
 include/configs/mt7986.h |  26 
 14 files changed, 1053 insertions(+)
 create mode 100644 arch/arm/dts/mt7986a-emmc-rfb.dts
 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-emmc-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_bpir3_emmc_defconfig
 create mode 100644 configs/mt7986a_bpir3_sd_defconfig
 create mode 100644 include/configs/mt7986.h

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 7330121dba..ee86e467f7 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -1230,6 +1230,12 @@ 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 \
+   mt7986a-emmc-rfb.dtb \
+   mt7986b-emmc-rfb.dtb \
mt8183-pumpkin.dtb \
mt8512-bm1-emmc.dtb \
mt8516-pumpkin.dtb \
diff --git a/arch/arm/dts/mt7986a-emmc-rfb.dts 
b/arch/arm/dts/mt7986a-emmc-rfb.dts
new file mode 100644
index 00..315bdd0b14
--- /dev/null
+++ b/arch/arm/dts/mt7986a-emmc-rfb.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Sam Shih 
+ */
+
+/dts-v1/;
+#include "mt7986a-rfb.dts"
+
+/ {
+   compatible = "mediatek,mt7986", "mediatek,mt7986-rfb",
+"mediatek,mt7986-emmc-rfb";
+   bl2_verify {
+   bl2_compatible = "emmc";
+   };
+};
diff --git a/arch/arm/dts/mt7986a-rfb.dts b/arch/arm/dts/mt7986a-rfb.dts
new file mode 100644
index 00..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 
+ */
+
+/dts-v1/;
+#include "mt7986.dtsi"
+#include 
+
+/ {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   model = "mt7986-rfb";
+   compatible = "mediatek,mt7986", "mediatek,mt7986-rfb";
+   chosen {
+   stdout-path = 
+   tick-timer = 
+   };
+
+   reg_1p8v: regulator-1p8v {
+   compatible = "regulator-fixed";
+   regulator-name = "fixed-1.8V";
+   regulator-min-microvolt = <180>;
+   regulator-max-microvolt = <180>;
+   regulator-boot-on;
+   regulator-always-on;
+   };
+
+   reg_3p3v: regulator-3p3v {
+   compatible = "regulator-fixed";
+   regulator-name = "fixed-3.3V";
+   regulator-min-microvolt = <330>;
+   regulator-max-microvolt = <330>;
+   regulator-boot-on;
+   regulator-always-on;
+   };
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+   status = "disabled";
+};
+
+ {
+   status = "okay";
+   mediatek,gmac-id = <0>;
+   phy-mode = "sgmii";
+   mediatek,switch = "mt7531";
+   reset-gpios = < 5 GPIO_ACTIVE_HIGH>;

  1   2   3   4   5   6   7   >