Merge tag 'xilinx-for-v2023.01-rc1-v2' of https://gitlab.denx.de/u-boot/custodians/u-boot-microblaze into next
Xilinx changes for v2023.01-rc1 (round 2)
xilinx:
- Add support for new Versal NET SOC
zynqmp:
- Use mdio bus for ethernet phy description
- Wire ethernet phy reset via i2c-gpio
versal:
- Config cleanup
diff --git a/MAINTAINERS b/MAINTAINERS
index 65f26e3..b4b185a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -356,20 +356,26 @@
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
diff --git a/arch/Kconfig b/arch/Kconfig
index 994fd3b..1ffd77c 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -166,7 +166,6 @@
imply CMD_IO
imply CMD_IOTRACE
imply CMD_LZMADEC
- imply CMD_SATA
imply CMD_SF
imply CMD_SF_TEST
imply CRC32_VERIFY
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index d6832d1..71e9bd4 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -1238,6 +1238,15 @@
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 \
+ 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/imx8mm-venice-gw7901-u-boot.dtsi b/arch/arm/dts/imx8mm-venice-gw7901-u-boot.dtsi
index 11c773b..dc99e7b 100644
--- a/arch/arm/dts/imx8mm-venice-gw7901-u-boot.dtsi
+++ b/arch/arm/dts/imx8mm-venice-gw7901-u-boot.dtsi
@@ -129,6 +129,57 @@
phy-reset-post-delay = <1>;
};
+&switch {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ lan1: port@0 {
+ phy-handle = <&sw_phy0>;
+ };
+
+ lan2: port@1 {
+ phy-handle = <&sw_phy1>;
+ };
+
+ lan3: port@2 {
+ phy-handle = <&sw_phy2>;
+ };
+
+ lan4: port@3 {
+ phy-handle = <&sw_phy3>;
+ };
+ };
+
+ mdios {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ mdio@0 {
+ reg = <0>;
+ compatible = "microchip,ksz-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ sw_phy0: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+
+ sw_phy1: ethernet-phy@1 {
+ reg = <0x1>;
+ };
+
+ sw_phy2: ethernet-phy@2 {
+ reg = <0x2>;
+ };
+
+ sw_phy3: ethernet-phy@3 {
+ reg = <0x3>;
+ };
+ };
+ };
+};
+
&pinctrl_fec1 {
u-boot,dm-spl;
};
diff --git a/arch/arm/dts/imx8mp-venice-gw74xx-u-boot.dtsi b/arch/arm/dts/imx8mp-venice-gw74xx-u-boot.dtsi
index 920246d..caf5d3a 100644
--- a/arch/arm/dts/imx8mp-venice-gw74xx-u-boot.dtsi
+++ b/arch/arm/dts/imx8mp-venice-gw74xx-u-boot.dtsi
@@ -162,6 +162,65 @@
u-boot,dm-spl;
};
+&switch {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ lan1: port@0 {
+ phy-handle = <&sw_phy0>;
+ };
+
+ lan2: port@1 {
+ phy-handle = <&sw_phy1>;
+ };
+
+ lan3: port@2 {
+ phy-handle = <&sw_phy2>;
+ };
+
+ lan4: port@3 {
+ phy-handle = <&sw_phy3>;
+ };
+
+ lan5: port@4 {
+ phy-handle = <&sw_phy4>;
+ };
+ };
+
+ mdios {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ mdio@0 {
+ reg = <0>;
+ compatible = "microchip,ksz-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ sw_phy0: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+
+ sw_phy1: ethernet-phy@1 {
+ reg = <0x1>;
+ };
+
+ sw_phy2: ethernet-phy@2 {
+ reg = <0x2>;
+ };
+
+ sw_phy3: ethernet-phy@3 {
+ reg = <0x3>;
+ };
+
+ sw_phy4: ethernet-phy@4 {
+ reg = <0x4>;
+ };
+ };
+ };
+};
+
&usdhc2 {
assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_400M>;
assigned-clock-rates = <400000000>;
diff --git a/arch/arm/dts/mt7622-rfb.dts b/arch/arm/dts/mt7622-rfb.dts
index 30a9137..b44f19f 100644
--- a/arch/arm/dts/mt7622-rfb.dts
+++ b/arch/arm/dts/mt7622-rfb.dts
@@ -159,6 +159,14 @@
};
};
+
+ i2c1_pins_default: i2c1-default {
+ mux {
+ function = "i2c";
+ groups = "i2c1_0";
+ };
+ };
+
};
&snfi {
@@ -242,3 +250,13 @@
&u3phy {
status = "okay";
};
+
+&soft_i2c {
+ status = "disabled";
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_default>;
+ status = "okay";
+};
diff --git a/arch/arm/dts/mt7622.dtsi b/arch/arm/dts/mt7622.dtsi
index 0127474..2d89fa0 100644
--- a/arch/arm/dts/mt7622.dtsi
+++ b/arch/arm/dts/mt7622.dtsi
@@ -175,6 +175,7 @@
status = "disabled";
assigned-clocks = <&topckgen CLK_TOP_AXI_SEL>;
assigned-clock-parents = <&topckgen CLK_TOP_SYSPLL1_D2>;
+ mediatek,force-highspeed;
};
mmc0: mmc@11230000 {
@@ -423,4 +424,28 @@
status = "disabled";
};
+ soft_i2c: soft_i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "i2c-gpio";
+ gpios = <&gpio 56 GPIO_ACTIVE_HIGH>, /* SDA */
+ <&gpio 55 GPIO_ACTIVE_HIGH>; /* CLK */
+ i2c-gpio,delay-us = <5>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@11008000 {
+ compatible = "mediatek,mt7622-i2c";
+ reg = <0x11008000 0x90>,
+ <0x11000180 0x80>;
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_LOW>;
+ clock-div = <16>;
+ clocks = <&pericfg CLK_PERI_I2C1_PD>,
+ <&pericfg CLK_PERI_AP_DMA_PD>;
+ clock-names = "main", "dma";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
};
diff --git a/arch/arm/dts/mt7981-emmc-rfb.dts b/arch/arm/dts/mt7981-emmc-rfb.dts
new file mode 100644
index 0000000..2b7eae9
--- /dev/null
+++ b/arch/arm/dts/mt7981-emmc-rfb.dts
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+/dts-v1/;
+#include "mt7981.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ model = "mt7981-rfb";
+ compatible = "mediatek,mt7981", "mediatek,mt7981-rfb";
+ chosen {
+ stdout-path = &uart0;
+ tick-timer = &timer0;
+ };
+
+ reg_3p3v: regulator-3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+ status = "disabled";
+};
+
+ð {
+ status = "okay";
+ mediatek,gmac-id = <0>;
+ phy-mode = "sgmii";
+ mediatek,switch = "mt7531";
+ reset-gpios = <&gpio 39 GPIO_ACTIVE_HIGH>;
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+};
+
+&pinctrl {
+ spic_pins: spi1-pins-func-1 {
+ mux {
+ function = "spi";
+ groups = "spi1_1";
+ };
+ };
+
+ uart1_pins: spi1-pins-func-3 {
+ mux {
+ function = "uart";
+ groups = "uart1_2";
+ };
+ };
+
+ /* pin15 as pwm0 */
+ one_pwm_pins: one-pwm-pins {
+ mux {
+ function = "pwm";
+ groups = "pwm0_1";
+ };
+ };
+
+ /* pin15 as pwm0 and pin14 as pwm1 */
+ two_pwm_pins: two-pwm-pins {
+ mux {
+ function = "pwm";
+ groups = "pwm0_1", "pwm1_0";
+ };
+ };
+
+ /* pin15 as pwm0, pin14 as pwm1, pin7 as pwm2 */
+ three_pwm_pins: three-pwm-pins {
+ mux {
+ function = "pwm";
+ groups = "pwm0_1", "pwm1_0", "pwm2";
+ };
+ };
+
+ mmc0_pins_default: mmc0default {
+ mux {
+ function = "flash";
+ groups = "emmc_45";
+ };
+ conf-cmd-dat {
+ pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO",
+ "SPI0_CS", "SPI0_HOLD", "SPI0_WP",
+ "SPI1_CLK", "SPI1_MOSI", "SPI1_MISO";
+ input-enable;
+ drive-strength = <MTK_DRIVE_4mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+ conf-clk {
+ pins = "SPI1_CS";
+ drive-strength = <MTK_DRIVE_6mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ };
+ conf-rst {
+ pins = "PWM0";
+ drive-strength = <MTK_DRIVE_4mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+ };
+};
+
+&pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&two_pwm_pins>;
+ status = "okay";
+};
+
+&watchdog {
+ status = "disabled";
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_default>;
+ bus-width = <8>;
+ max-frequency = <52000000>;
+ cap-mmc-highspeed;
+ cap-mmc-hw-reset;
+ vmmc-supply = <®_3p3v>;
+ non-removable;
+ status = "okay";
+};
diff --git a/arch/arm/dts/mt7981-rfb.dts b/arch/arm/dts/mt7981-rfb.dts
new file mode 100644
index 0000000..5559ace
--- /dev/null
+++ b/arch/arm/dts/mt7981-rfb.dts
@@ -0,0 +1,173 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+/dts-v1/;
+#include "mt7981.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ model = "mt7981-rfb";
+ compatible = "mediatek,mt7981", "mediatek,mt7981-rfb";
+ chosen {
+ stdout-path = &uart0;
+ tick-timer = &timer0;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+ status = "disabled";
+};
+
+ð {
+ status = "okay";
+ mediatek,gmac-id = <0>;
+ phy-mode = "sgmii";
+ mediatek,switch = "mt7531";
+ reset-gpios = <&gpio 39 GPIO_ACTIVE_HIGH>;
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+};
+
+&pinctrl {
+ spi_flash_pins: spi0-pins-func-1 {
+ mux {
+ function = "flash";
+ groups = "spi0", "spi0_wp_hold";
+ };
+
+ conf-pu {
+ pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP";
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_11>;
+ };
+
+ conf-pd {
+ pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO";
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_11>;
+ };
+ };
+
+ spi2_flash_pins: spi2-spi2-pins {
+ mux {
+ function = "spi";
+ groups = "spi2", "spi2_wp_hold";
+ };
+
+ conf-pu {
+ pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP";
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_00>;
+ };
+
+ conf-pd {
+ pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO";
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_00>;
+ };
+ };
+
+ spic_pins: spi1-pins-func-1 {
+ mux {
+ function = "spi";
+ groups = "spi1_1";
+ };
+ };
+
+ uart1_pins: spi1-pins-func-3 {
+ mux {
+ function = "uart";
+ groups = "uart1_2";
+ };
+ };
+
+ /* pin15 as pwm0 */
+ one_pwm_pins: one-pwm-pins {
+ mux {
+ function = "pwm";
+ groups = "pwm0_1";
+ };
+ };
+
+ /* pin15 as pwm0 and pin14 as pwm1 */
+ two_pwm_pins: two-pwm-pins {
+ mux {
+ function = "pwm";
+ groups = "pwm0_1", "pwm1_0";
+ };
+ };
+
+ /* pin15 as pwm0, pin14 as pwm1, pin7 as pwm2 */
+ three_pwm_pins: three-pwm-pins {
+ mux {
+ function = "pwm";
+ groups = "pwm0_1", "pwm1_0", "pwm2";
+ };
+ };
+};
+
+&spi0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi_flash_pins>;
+ status = "okay";
+ must_tx;
+ enhance_timing;
+ dma_ext;
+ ipm_design;
+ support_quad;
+ tick_dly = <2>;
+ sample_sel = <0>;
+
+ spi_nand@0 {
+ compatible = "spi-nand";
+ reg = <0>;
+ spi-max-frequency = <52000000>;
+ };
+};
+
+&spi2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2_flash_pins>;
+ status = "okay";
+ must_tx;
+ enhance_timing;
+ dma_ext;
+ ipm_design;
+ support_quad;
+ tick_dly = <2>;
+ sample_sel = <0>;
+
+ spi_nor@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <52000000>;
+ };
+};
+
+&pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&two_pwm_pins>;
+ status = "okay";
+};
+
+&watchdog {
+ status = "disabled";
+};
diff --git a/arch/arm/dts/mt7981-sd-rfb.dts b/arch/arm/dts/mt7981-sd-rfb.dts
new file mode 100644
index 0000000..34ac227
--- /dev/null
+++ b/arch/arm/dts/mt7981-sd-rfb.dts
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+/dts-v1/;
+#include "mt7981.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ model = "mt7981-rfb";
+ compatible = "mediatek,mt7981", "mediatek,mt7981-sd-rfb";
+ chosen {
+ stdout-path = &uart0;
+ tick-timer = &timer0;
+ };
+
+ reg_3p3v: regulator-3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+ status = "disabled";
+};
+
+ð {
+ status = "okay";
+ mediatek,gmac-id = <0>;
+ phy-mode = "sgmii";
+ mediatek,switch = "mt7531";
+ reset-gpios = <&gpio 39 GPIO_ACTIVE_HIGH>;
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+};
+
+&pinctrl {
+ spic_pins: spi1-pins-func-1 {
+ mux {
+ function = "spi";
+ groups = "spi1_1";
+ };
+ };
+
+ uart1_pins: spi1-pins-func-3 {
+ mux {
+ function = "uart";
+ groups = "uart1_2";
+ };
+ };
+
+ /* pin15 as pwm0 */
+ one_pwm_pins: one-pwm-pins {
+ mux {
+ function = "pwm";
+ groups = "pwm0_1";
+ };
+ };
+
+ /* pin15 as pwm0 and pin14 as pwm1 */
+ two_pwm_pins: two-pwm-pins {
+ mux {
+ function = "pwm";
+ groups = "pwm0_1", "pwm1_0";
+ };
+ };
+
+ /* pin15 as pwm0, pin14 as pwm1, pin7 as pwm2 */
+ three_pwm_pins: three-pwm-pins {
+ mux {
+ function = "pwm";
+ groups = "pwm0_1", "pwm1_0", "pwm2";
+ };
+ };
+
+ mmc0_pins_default: mmc0default {
+ mux {
+ function = "flash";
+ groups = "emmc_45";
+ };
+ conf-cmd-dat {
+ pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO",
+ "SPI0_CS", "SPI0_HOLD", "SPI0_WP",
+ "SPI1_CLK", "SPI1_MOSI", "SPI1_MISO";
+ input-enable;
+ drive-strength = <MTK_DRIVE_4mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+ conf-clk {
+ pins = "SPI1_CS";
+ drive-strength = <MTK_DRIVE_6mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ };
+ conf-rst {
+ pins = "PWM0";
+ drive-strength = <MTK_DRIVE_4mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+ };
+};
+
+&pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&two_pwm_pins>;
+ status = "okay";
+};
+
+&watchdog {
+ status = "disabled";
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_default>;
+ bus-width = <4>;
+ max-frequency = <52000000>;
+ cap-sd-highspeed;
+ r_smpl = <0>;
+ vmmc-supply = <®_3p3v>;
+ vqmmc-supply = <®_3p3v>;
+ status = "okay";
+};
diff --git a/arch/arm/dts/mt7981.dtsi b/arch/arm/dts/mt7981.dtsi
new file mode 100644
index 0000000..3089371
--- /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 <sam.shih@mediatek.com>
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/mt7981-clk.h>
+#include <dt-bindings/reset/mt7629-reset.h>
+#include <dt-bindings/pinctrl/mt65xx.h>
+
+/ {
+ compatible = "mediatek,mt7981";
+ interrupt-parent = <&gic>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x0>;
+ mediatek,hwver = <&hwver>;
+ };
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x1>;
+ mediatek,hwver = <&hwver>;
+ };
+ };
+
+ gpt_clk: gpt_dummy20m {
+ compatible = "fixed-clock";
+ clock-frequency = <13000000>;
+ #clock-cells = <0>;
+ u-boot,dm-pre-reloc;
+ };
+
+ hwver: hwver {
+ compatible = "mediatek,hwver", "syscon";
+ reg = <0x8000000 0x1000>;
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupt-parent = <&gic>;
+ clock-frequency = <13000000>;
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+ arm,cpu-registers-not-fw-configured;
+ };
+
+ timer0: timer@10008000 {
+ compatible = "mediatek,mt7986-timer";
+ reg = <0x10008000 0x1000>;
+ interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gpt_clk>;
+ clock-names = "gpt-clk";
+ u-boot,dm-pre-reloc;
+ };
+
+ watchdog: watchdog@1001c000 {
+ compatible = "mediatek,mt7986-wdt";
+ reg = <0x1001c000 0x1000>;
+ interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+ #reset-cells = <1>;
+ status = "disabled";
+ };
+
+ gic: interrupt-controller@c000000 {
+ compatible = "arm,gic-v3";
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ interrupt-controller;
+ reg = <0x0c000000 0x40000>, /* GICD */
+ <0x0c080000 0x200000>; /* GICR */
+
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ fixed_plls: apmixedsys@1001e000 {
+ compatible = "mediatek,mt7981-fixed-plls";
+ reg = <0x1001e000 0x1000>;
+ #clock-cells = <1>;
+ u-boot,dm-pre-reloc;
+ };
+
+ topckgen: topckgen@1001b000 {
+ compatible = "mediatek,mt7981-topckgen";
+ reg = <0x1001b000 0x1000>;
+ clock-parent = <&fixed_plls>;
+ #clock-cells = <1>;
+ u-boot,dm-pre-reloc;
+ };
+
+ infracfg_ao: infracfg_ao@10001000 {
+ compatible = "mediatek,mt7981-infracfg_ao";
+ reg = <0x10001000 0x80>;
+ clock-parent = <&infracfg>;
+ #clock-cells = <1>;
+ u-boot,dm-pre-reloc;
+ };
+
+ infracfg: infracfg@10001000 {
+ compatible = "mediatek,mt7981-infracfg";
+ reg = <0x10001000 0x30>;
+ clock-parent = <&topckgen>;
+ #clock-cells = <1>;
+ u-boot,dm-pre-reloc;
+ };
+
+ pinctrl: pinctrl@11d00000 {
+ compatible = "mediatek,mt7981-pinctrl";
+ reg = <0x11d00000 0x1000>,
+ <0x11c00000 0x1000>,
+ <0x11c10000 0x1000>,
+ <0x11d20000 0x1000>,
+ <0x11e00000 0x1000>,
+ <0x11e20000 0x1000>,
+ <0x11f00000 0x1000>,
+ <0x11f10000 0x1000>,
+ <0x1000b000 0x1000>;
+ reg-names = "gpio_base", "iocfg_rt_base", "iocfg_rm_base",
+ "iocfg_rb_base", "iocfg_lb_base", "iocfg_bl_base",
+ "iocfg_tm_base", "iocfg_tl_base", "eint";
+ gpio: gpio-controller {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ };
+
+ pwm: pwm@10048000 {
+ compatible = "mediatek,mt7981-pwm";
+ reg = <0x10048000 0x1000>;
+ #clock-cells = <1>;
+ #pwm-cells = <2>;
+ interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&infracfg CK_INFRA_PWM>,
+ <&infracfg_ao CK_INFRA_PWM_BSEL>,
+ <&infracfg_ao CK_INFRA_PWM1_CK>,
+ <&infracfg_ao CK_INFRA_PWM2_CK>,
+ /* FIXME */
+ <&infracfg_ao CK_INFRA_PWM2_CK>;
+ assigned-clocks = <&topckgen CK_TOP_PWM_SEL>;
+ assigned-clock-parents = <&topckgen CK_TOP_CB_CKSQ_40M>;
+ clock-names = "top", "main", "pwm1", "pwm2", "pwm3";
+ status = "disabled";
+ };
+
+ uart0: serial@11002000 {
+ compatible = "mediatek,hsuart";
+ reg = <0x11002000 0x400>;
+ interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&infracfg_ao CK_INFRA_UART0_CK>;
+ assigned-clocks = <&topckgen CK_TOP_UART_SEL>,
+ <&infracfg_ao CK_INFRA_UART0_SEL>;
+ assigned-clock-parents = <&topckgen CK_TOP_CB_CKSQ_40M>,
+ <&infracfg CK_INFRA_UART>;
+ mediatek,force-highspeed;
+ status = "disabled";
+ u-boot,dm-pre-reloc;
+ };
+
+ uart1: serial@11003000 {
+ compatible = "mediatek,hsuart";
+ reg = <0x11003000 0x400>;
+ interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&infracfg_ao CK_INFRA_UART1_CK>;
+ assigned-clocks = <&topckgen CK_TOP_UART_SEL>,
+ <&infracfg_ao CK_INFRA_UART1_SEL>;
+ assigned-clock-parents = <&topckgen CK_TOP_CB_CKSQ_40M>,
+ <&infracfg CK_INFRA_UART>;
+ mediatek,force-highspeed;
+ status = "disabled";
+ };
+
+ uart2: serial@11004000 {
+ compatible = "mediatek,hsuart";
+ reg = <0x11004000 0x400>;
+ interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&infracfg_ao CK_INFRA_UART2_CK>;
+ assigned-clocks = <&topckgen CK_TOP_UART_SEL>,
+ <&infracfg_ao CK_INFRA_UART2_SEL>;
+ assigned-clock-parents = <&topckgen CK_TOP_CB_CKSQ_40M>,
+ <&infracfg CK_INFRA_UART>;
+ mediatek,force-highspeed;
+ status = "disabled";
+ };
+
+ snand: snand@11005000 {
+ compatible = "mediatek,mt7986-snand";
+ reg = <0x11005000 0x1000>,
+ <0x11006000 0x1000>;
+ reg-names = "nfi", "ecc";
+ clocks = <&infracfg_ao CK_INFRA_SPINFI1_CK>,
+ <&infracfg_ao CK_INFRA_NFI1_CK>,
+ <&infracfg_ao CK_INFRA_NFI_HCK_CK>;
+ clock-names = "pad_clk", "nfi_clk", "nfi_hclk";
+ assigned-clocks = <&topckgen CK_TOP_SPINFI_SEL>,
+ <&topckgen CK_TOP_NFI1X_SEL>;
+ assigned-clock-parents = <&topckgen CK_TOP_CB_M_D8>,
+ <&topckgen CK_TOP_CB_M_D8>;
+ status = "disabled";
+ };
+
+ ethsys: syscon@15000000 {
+ compatible = "mediatek,mt7981-ethsys", "syscon";
+ reg = <0x15000000 0x1000>;
+ clock-parent = <&topckgen>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ eth: ethernet@15100000 {
+ compatible = "mediatek,mt7981-eth", "syscon";
+ reg = <0x15100000 0x20000>;
+ resets = <ðsys ETHSYS_FE_RST>;
+ reset-names = "fe";
+ mediatek,ethsys = <ðsys>;
+ mediatek,sgmiisys = <&sgmiisys0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ sgmiisys0: syscon@10060000 {
+ compatible = "mediatek,mt7986-sgmiisys", "syscon";
+ reg = <0x10060000 0x1000>;
+ pn_swap;
+ #clock-cells = <1>;
+ };
+
+ sgmiisys1: syscon@10070000 {
+ compatible = "mediatek,mt7986-sgmiisys", "syscon";
+ reg = <0x10070000 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ spi0: spi@1100a000 {
+ compatible = "mediatek,ipm-spi";
+ reg = <0x1100a000 0x100>;
+ clocks = <&infracfg_ao CK_INFRA_SPI0_CK>,
+ <&topckgen CK_TOP_SPI_SEL>;
+ assigned-clocks = <&topckgen CK_TOP_SPI_SEL>,
+ <&infracfg CK_INFRA_SPI0_SEL>;
+ assigned-clock-parents = <&topckgen CK_TOP_CB_M_D2>,
+ <&topckgen CK_INFRA_ISPI0>;
+ clock-names = "sel-clk", "spi-clk";
+ interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ spi1: spi@1100b000 {
+ compatible = "mediatek,ipm-spi";
+ reg = <0x1100b000 0x100>;
+ interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ spi2: spi@11009000 {
+ compatible = "mediatek,ipm-spi";
+ reg = <0x11009000 0x100>;
+ clocks = <&infracfg_ao CK_INFRA_SPI0_CK>,
+ <&topckgen CK_TOP_SPI_SEL>;
+ assigned-clocks = <&topckgen CK_TOP_SPI_SEL>,
+ <&infracfg CK_INFRA_SPI0_SEL>;
+ assigned-clock-parents = <&topckgen CK_TOP_CB_M_D2>,
+ <&topckgen CK_INFRA_ISPI0>;
+ clock-names = "sel-clk", "spi-clk";
+ interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ mmc0: mmc@11230000 {
+ compatible = "mediatek,mt7981-mmc";
+ reg = <0x11230000 0x1000>,
+ <0x11C20000 0x1000>;
+ interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&topckgen CK_TOP_EMMC_400M>,
+ <&topckgen CK_TOP_EMMC_208M>,
+ <&infracfg_ao CK_INFRA_MSDC_CK>;
+ assigned-clocks = <&topckgen CK_TOP_EMMC_400M_SEL>,
+ <&topckgen CK_TOP_EMMC_208M_SEL>;
+ assigned-clock-parents = <&topckgen CK_TOP_CB_NET2_D2>,
+ <&topckgen CK_TOP_CB_M_D2>;
+ clock-names = "source", "hclk", "source_cg";
+ status = "disabled";
+ };
+
+};
diff --git a/arch/arm/dts/mt7986-u-boot.dtsi b/arch/arm/dts/mt7986-u-boot.dtsi
new file mode 100644
index 0000000..95671f8
--- /dev/null
+++ b/arch/arm/dts/mt7986-u-boot.dtsi
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+&topckgen {
+ u-boot,dm-pre-reloc;
+};
+
+&pericfg {
+ u-boot,dm-pre-reloc;
+};
+
+&apmixedsys {
+ u-boot,dm-pre-reloc;
+};
+
+&timer0 {
+ u-boot,dm-pre-reloc;
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+};
+
+&snand {
+ u-boot,dm-pre-reloc;
+};
+
+&pinctrl {
+ u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/mt7986.dtsi b/arch/arm/dts/mt7986.dtsi
new file mode 100644
index 0000000..794ab1f
--- /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 <sam.shih@mediatek.com>
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/clock/mt7986-clk.h>
+#include <dt-bindings/reset/mt7629-reset.h>
+#include <dt-bindings/pinctrl/mt65xx.h>
+
+/ {
+ compatible = "mediatek,mt7986";
+ interrupt-parent = <&gic>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ config {
+ u-boot,mmc-env-partition = "u-boot-env";
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x0>;
+ mediatek,hwver = <&hwver>;
+ };
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x1>;
+ mediatek,hwver = <&hwver>;
+ };
+ cpu2: cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x2>;
+ mediatek,hwver = <&hwver>;
+ };
+ cpu3: cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x3>;
+ mediatek,hwver = <&hwver>;
+ };
+ };
+
+ dummy_clk: dummy12m {
+ compatible = "fixed-clock";
+ clock-frequency = <12000000>;
+ #clock-cells = <0>;
+ /* must need this line, or uart uanable to get dummy_clk */
+ u-boot,dm-pre-reloc;
+ };
+
+ hwver: hwver {
+ compatible = "mediatek,hwver", "syscon";
+ reg = <0x8000000 0x1000>;
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupt-parent = <&gic>;
+ clock-frequency = <13000000>;
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+ arm,cpu-registers-not-fw-configured;
+ };
+
+ timer0: timer@10008000 {
+ compatible = "mediatek,mt7986-timer";
+ reg = <0x10008000 0x1000>;
+ interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&infracfg CK_INFRA_CK_F26M>;
+ clock-names = "gpt-clk";
+ u-boot,dm-pre-reloc;
+ };
+
+ watchdog: watchdog@1001c000 {
+ compatible = "mediatek,mt7986-wdt";
+ reg = <0x1001c000 0x1000>;
+ interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+ #reset-cells = <1>;
+ status = "disabled";
+ };
+
+ gic: interrupt-controller@c000000 {
+ compatible = "arm,gic-v3";
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ interrupt-controller;
+ reg = <0x0c000000 0x40000>, /* GICD */
+ <0x0c080000 0x200000>; /* GICR */
+
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ fixed_plls: apmixedsys@1001E000 {
+ compatible = "mediatek,mt7986-fixed-plls";
+ reg = <0x1001E000 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ topckgen: topckgen@1001B000 {
+ compatible = "mediatek,mt7986-topckgen";
+ reg = <0x1001B000 0x1000>;
+ clock-parent = <&fixed_plls>;
+ #clock-cells = <1>;
+ };
+
+ infracfg_ao: infracfg_ao@10001000 {
+ compatible = "mediatek,mt7986-infracfg_ao";
+ reg = <0x10001000 0x68>;
+ clock-parent = <&infracfg>;
+ #clock-cells = <1>;
+ };
+
+ infracfg: infracfg@10001040 {
+ compatible = "mediatek,mt7986-infracfg";
+ reg = <0x10001000 0x1000>;
+ clock-parent = <&topckgen>;
+ #clock-cells = <1>;
+ };
+
+ pinctrl: pinctrl@1001f000 {
+ compatible = "mediatek,mt7986-pinctrl";
+ reg = <0x1001f000 0x1000>,
+ <0x11c30000 0x1000>,
+ <0x11c40000 0x1000>,
+ <0x11e20000 0x1000>,
+ <0x11e30000 0x1000>,
+ <0x11f00000 0x1000>,
+ <0x11f10000 0x1000>,
+ <0x1000b000 0x1000>;
+ reg-names = "gpio_base", "iocfg_rt_base", "iocfg_rb_base",
+ "iocfg_lt_base", "iocfg_lb_base", "iocfg_tr_base",
+ "iocfg_tl_base", "eint";
+ gpio: gpio-controller {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ };
+
+ pwm: pwm@10048000 {
+ compatible = "mediatek,mt7986-pwm";
+ reg = <0x10048000 0x1000>;
+ #clock-cells = <1>;
+ #pwm-cells = <2>;
+ interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&infracfg CK_INFRA_PWM>,
+ <&infracfg_ao CK_INFRA_PWM_BSEL>,
+ <&infracfg_ao CK_INFRA_PWM1_CK>,
+ <&infracfg_ao CK_INFRA_PWM2_CK>;
+ assigned-clocks = <&topckgen CK_TOP_PWM_SEL>,
+ <&infracfg CK_INFRA_PWM_BSEL>,
+ <&infracfg CK_INFRA_PWM1_SEL>,
+ <&infracfg CK_INFRA_PWM2_SEL>;
+ assigned-clock-parents = <&topckgen CK_TOP_CB_M_D4>,
+ <&infracfg CK_INFRA_PWM>,
+ <&infracfg CK_INFRA_PWM>,
+ <&infracfg CK_INFRA_PWM>;
+ clock-names = "top", "main", "pwm1", "pwm2";
+ status = "disabled";
+ u-boot,dm-pre-reloc;
+ };
+
+ uart0: serial@11002000 {
+ compatible = "mediatek,hsuart";
+ reg = <0x11002000 0x400>;
+ interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&infracfg_ao CK_INFRA_UART0_CK>;
+ assigned-clocks = <&topckgen CK_TOP_UART_SEL>,
+ <&infracfg_ao CK_INFRA_UART0_SEL>;
+ assigned-clock-parents = <&topckgen CK_TOP_CB_CKSQ_40M>,
+ <&infracfg CK_INFRA_UART>;
+ mediatek,force-highspeed;
+ status = "disabled";
+ u-boot,dm-pre-reloc;
+ };
+
+ uart1: serial@11003000 {
+ compatible = "mediatek,hsuart";
+ reg = <0x11003000 0x400>;
+ interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&infracfg_ao CK_INFRA_UART1_CK>;
+ assigned-clocks = <&infracfg CK_INFRA_UART1_SEL>;
+ assigned-clock-parents = <&infracfg CK_INFRA_CK_F26M>;
+ mediatek,force-highspeed;
+ status = "disabled";
+ };
+
+ uart2: serial@11004000 {
+ compatible = "mediatek,hsuart";
+ reg = <0x11004000 0x400>;
+ interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&infracfg_ao CK_INFRA_UART2_CK>;
+ assigned-clocks = <&infracfg CK_INFRA_UART2_SEL>;
+ assigned-clock-parents = <&infracfg CK_INFRA_CK_F26M>;
+ mediatek,force-highspeed;
+ status = "disabled";
+ };
+
+ snand: snand@11005000 {
+ compatible = "mediatek,mt7986-snand";
+ reg = <0x11005000 0x1000>,
+ <0x11006000 0x1000>;
+ reg-names = "nfi", "ecc";
+ clocks = <&infracfg_ao CK_INFRA_SPINFI1_CK>,
+ <&infracfg_ao CK_INFRA_NFI1_CK>,
+ <&infracfg_ao CK_INFRA_NFI_HCK_CK>;
+ clock-names = "pad_clk", "nfi_clk", "nfi_hclk";
+ assigned-clocks = <&topckgen CK_TOP_SPINFI_SEL>,
+ <&topckgen CK_TOP_NFI1X_SEL>;
+ assigned-clock-parents = <&topckgen CK_TOP_CB_M_D8>,
+ <&topckgen CK_TOP_CB_M_D8>;
+ status = "disabled";
+ };
+
+ ethsys: syscon@15000000 {
+ compatible = "mediatek,mt7986-ethsys", "syscon";
+ reg = <0x15000000 0x1000>;
+ clock-parent = <&topckgen>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ eth: ethernet@15100000 {
+ compatible = "mediatek,mt7986-eth", "syscon";
+ reg = <0x15100000 0x20000>;
+ resets = <ðsys ETHSYS_FE_RST>;
+ reset-names = "fe";
+ mediatek,ethsys = <ðsys>;
+ mediatek,sgmiisys = <&sgmiisys0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ sgmiisys0: syscon@10060000 {
+ compatible = "mediatek,mt7986-sgmiisys", "syscon";
+ reg = <0x10060000 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ sgmiisys1: syscon@10070000 {
+ compatible = "mediatek,mt7986-sgmiisys", "syscon";
+ reg = <0x10070000 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ spi0: spi@1100a000 {
+ compatible = "mediatek,ipm-spi";
+ reg = <0x1100a000 0x100>;
+ clocks = <&infracfg_ao CK_INFRA_SPI0_CK>,
+ <&topckgen CK_TOP_SPI_SEL>;
+ assigned-clocks = <&topckgen CK_TOP_SPI_SEL>,
+ <&infracfg CK_INFRA_SPI0_SEL>;
+ assigned-clock-parents = <&topckgen CK_TOP_CB_M_D2>,
+ <&topckgen CK_INFRA_ISPI0>;
+ clock-names = "sel-clk", "spi-clk";
+ interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ spi1: spi@1100b000 {
+ compatible = "mediatek,ipm-spi";
+ reg = <0x1100b000 0x100>;
+ interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ mmc0: mmc@11230000 {
+ compatible = "mediatek,mt7986-mmc";
+ reg = <0x11230000 0x1000>,
+ <0x11C20000 0x1000>;
+ interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&topckgen CK_TOP_EMMC_416M>,
+ <&topckgen CK_TOP_EMMC_250M>,
+ <&infracfg_ao CK_INFRA_MSDC_CK>;
+ assigned-clocks = <&topckgen CK_TOP_EMMC_416M_SEL>,
+ <&topckgen CK_TOP_EMMC_250M_SEL>;
+ assigned-clock-parents = <&topckgen CK_TOP_CB_M_416M>,
+ <&topckgen CK_TOP_NET1_D5_D2>;
+ clock-names = "source", "hclk", "source_cg";
+ status = "disabled";
+ };
+
+ xhci: xhci@11200000 {
+ compatible = "mediatek,mt7986-xhci",
+ "mediatek,mtk-xhci";
+ reg = <0x11200000 0x2e00>,
+ <0x11203e00 0x0100>;
+ reg-names = "mac", "ippc";
+ interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&u2port0 PHY_TYPE_USB2>,
+ <&u3port0 PHY_TYPE_USB3>,
+ <&u2port1 PHY_TYPE_USB2>;
+ clocks = <&dummy_clk>,
+ <&dummy_clk>,
+ <&dummy_clk>,
+ <&dummy_clk>,
+ <&dummy_clk>;
+ clock-names = "sys_ck",
+ "xhci_ck",
+ "ref_ck",
+ "mcu_ck",
+ "dma_ck";
+ tpl-support;
+ status = "okay";
+ };
+
+ usbtphy: usb-phy@11e10000 {
+ compatible = "mediatek,mt7986",
+ "mediatek,generic-tphy-v2";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ status = "okay";
+
+ u2port0: usb-phy@11e10000 {
+ reg = <0x11e10000 0x700>;
+ clocks = <&dummy_clk>;
+ clock-names = "ref";
+ #phy-cells = <1>;
+ status = "okay";
+ };
+
+ u3port0: usb-phy@11e10700 {
+ reg = <0x11e10700 0x900>;
+ clocks = <&dummy_clk>;
+ clock-names = "ref";
+ #phy-cells = <1>;
+ status = "okay";
+ };
+
+ u2port1: usb-phy@11e11000 {
+ reg = <0x11e11000 0x700>;
+ clocks = <&dummy_clk>;
+ clock-names = "ref";
+ #phy-cells = <1>;
+ status = "okay";
+ };
+ };
+};
diff --git a/arch/arm/dts/mt7986a-emmc-rfb.dts b/arch/arm/dts/mt7986a-emmc-rfb.dts
new file mode 100644
index 0000000..315bdd0
--- /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 <sam.shih@mediatek.com>
+ */
+
+/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 0000000..80def57
--- /dev/null
+++ b/arch/arm/dts/mt7986a-rfb.dts
@@ -0,0 +1,218 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+/dts-v1/;
+#include "mt7986.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ model = "mt7986-rfb";
+ compatible = "mediatek,mt7986", "mediatek,mt7986-rfb";
+ chosen {
+ stdout-path = &uart0;
+ tick-timer = &timer0;
+ };
+
+ reg_1p8v: regulator-1p8v {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_3p3v: regulator-3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+ status = "disabled";
+};
+
+ð {
+ status = "okay";
+ mediatek,gmac-id = <0>;
+ phy-mode = "sgmii";
+ mediatek,switch = "mt7531";
+ reset-gpios = <&gpio 5 GPIO_ACTIVE_HIGH>;
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+};
+
+&pinctrl {
+ spi_flash_pins: spi0-pins-func-1 {
+ mux {
+ function = "flash";
+ groups = "spi0", "spi0_wp_hold";
+ };
+
+ conf-pu {
+ pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP";
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_11>;
+ };
+
+ conf-pd {
+ pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO";
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_11>;
+ };
+ };
+
+ snfi_pins: snfi-pins-func-1 {
+ mux {
+ function = "flash";
+ groups = "snfi";
+ };
+
+ clk {
+ pins = "SPI0_CLK";
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_00>;
+ };
+
+ conf-pu {
+ pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP";
+ drive-strength = <MTK_DRIVE_6mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_00>;
+ };
+
+ conf-pd {
+ pins = "SPI0_MOSI", "SPI0_MISO";
+ drive-strength = <MTK_DRIVE_6mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_00>;
+ };
+ };
+
+ spic_pins: spi1-pins-func-1 {
+ mux {
+ function = "spi";
+ groups = "spi1_2";
+ };
+ };
+
+ uart1_pins: spi1-pins-func-3 {
+ mux {
+ function = "uart";
+ groups = "uart1_2";
+ };
+ };
+
+ pwm_pins: pwm0-pins-func-1 {
+ mux {
+ function = "pwm";
+ groups = "pwm0";
+ };
+ };
+
+ mmc0_pins_default: mmc0default {
+ mux {
+ function = "flash";
+ groups = "emmc_51";
+ };
+
+ conf-cmd-dat {
+ pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2",
+ "EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5",
+ "EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD";
+ input-enable;
+ drive-strength = <MTK_DRIVE_4mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+
+ conf-clk {
+ pins = "EMMC_CK";
+ drive-strength = <MTK_DRIVE_6mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ };
+
+ conf-dsl {
+ pins = "EMMC_DSL";
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ };
+
+ conf-rst {
+ pins = "EMMC_RSTB";
+ drive-strength = <MTK_DRIVE_4mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+ };
+};
+
+&snand {
+ pinctrl-names = "default";
+ pinctrl-0 = <&snfi_pins>;
+ status = "okay";
+ quad-spi;
+};
+
+&spi0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi_flash_pins>;
+ status = "okay";
+ must_tx;
+ enhance_timing;
+ dma_ext;
+ ipm_design;
+ support_quad;
+ tick_dly = <2>;
+ sample_sel = <0>;
+
+ spi_nor@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <52000000>;
+ };
+
+ spi_nand@1 {
+ compatible = "spi-nand";
+ reg = <1>;
+ spi-max-frequency = <52000000>;
+ };
+};
+
+&pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm_pins>;
+ status = "okay";
+};
+
+&watchdog {
+ status = "disabled";
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_default>;
+ bus-width = <8>;
+ max-frequency = <52000000>;
+ cap-mmc-highspeed;
+ cap-mmc-hw-reset;
+ vmmc-supply = <®_3p3v>;
+ vqmmc-supply = <®_1p8v>;
+ non-removable;
+ status = "okay";
+};
diff --git a/arch/arm/dts/mt7986a-sd-rfb.dts b/arch/arm/dts/mt7986a-sd-rfb.dts
new file mode 100644
index 0000000..5807c5d
--- /dev/null
+++ b/arch/arm/dts/mt7986a-sd-rfb.dts
@@ -0,0 +1,177 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+/dts-v1/;
+#include "mt7986.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ model = "mt7986-rfb";
+ compatible = "mediatek,mt7986", "mediatek,mt7986-rfb",
+ "mediatek,mt7986-sd-rfb";
+ chosen {
+ stdout-path = &uart0;
+ tick-timer = &timer0;
+ };
+
+ reg_3p3v: regulator-3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+ status = "disabled";
+};
+
+ð {
+ status = "okay";
+ mediatek,gmac-id = <0>;
+ phy-mode = "sgmii";
+ mediatek,switch = "mt7531";
+ reset-gpios = <&gpio 5 GPIO_ACTIVE_HIGH>;
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+};
+
+&pinctrl {
+ spi_flash_pins: spi0-pins-func-1 {
+ mux {
+ function = "flash";
+ groups = "spi0", "spi0_wp_hold";
+ };
+
+ conf-pu {
+ pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP";
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_11>;
+ };
+
+ conf-pd {
+ pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO";
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_11>;
+ };
+ };
+
+ spic_pins: spi1-pins-func-1 {
+ mux {
+ function = "spi";
+ groups = "spi1_2";
+ };
+ };
+
+ uart1_pins: spi1-pins-func-3 {
+ mux {
+ function = "uart";
+ groups = "uart1_2";
+ };
+ };
+
+ pwm_pins: pwm0-pins-func-1 {
+ mux {
+ function = "pwm";
+ groups = "pwm0";
+ };
+ };
+
+ mmc0_pins_default: mmc0default {
+ mux {
+ function = "flash";
+ groups = "emmc_51";
+ };
+
+ conf-cmd-dat {
+ pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2",
+ "EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5",
+ "EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD";
+ input-enable;
+ drive-strength = <MTK_DRIVE_4mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+
+ conf-clk {
+ pins = "EMMC_CK";
+ drive-strength = <MTK_DRIVE_6mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ };
+
+ conf-dsl {
+ pins = "EMMC_DSL";
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ };
+
+ conf-rst {
+ pins = "EMMC_RSTB";
+ drive-strength = <MTK_DRIVE_4mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+ };
+};
+
+&spi0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi_flash_pins>;
+ status = "okay";
+ must_tx;
+ enhance_timing;
+ dma_ext;
+ ipm_design;
+ support_quad;
+ tick_dly = <2>;
+ sample_sel = <0>;
+
+ spi_nor@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <52000000>;
+ };
+
+ spi_nand@1 {
+ compatible = "spi-nand";
+ reg = <1>;
+ spi-max-frequency = <52000000>;
+ };
+};
+
+&pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm_pins>;
+ status = "okay";
+};
+
+&watchdog {
+ status = "disabled";
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_default>;
+ bus-width = <4>;
+ max-frequency = <52000000>;
+ cap-sd-highspeed;
+ r_smpl = <1>;
+ vmmc-supply = <®_3p3v>;
+ vqmmc-supply = <®_3p3v>;
+ status = "okay";
+};
diff --git a/arch/arm/dts/mt7986b-emmc-rfb.dts b/arch/arm/dts/mt7986b-emmc-rfb.dts
new file mode 100644
index 0000000..315bdd0
--- /dev/null
+++ b/arch/arm/dts/mt7986b-emmc-rfb.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+/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/mt7986b-rfb.dts b/arch/arm/dts/mt7986b-rfb.dts
new file mode 100644
index 0000000..0c4e3e8
--- /dev/null
+++ b/arch/arm/dts/mt7986b-rfb.dts
@@ -0,0 +1,204 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+/dts-v1/;
+#include "mt7986.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ model = "mt7986-rfb";
+ compatible = "mediatek,mt7986", "mediatek,mt7986-rfb";
+ chosen {
+ stdout-path = &uart0;
+ tick-timer = &timer0;
+ };
+
+ reg_3p3v: regulator-3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+ status = "disabled";
+};
+
+ð {
+ status = "okay";
+ mediatek,gmac-id = <0>;
+ phy-mode = "sgmii";
+ mediatek,switch = "mt7531";
+ reset-gpios = <&gpio 5 GPIO_ACTIVE_HIGH>;
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+};
+
+&pinctrl {
+ spi_flash_pins: spi0-pins-func-1 {
+ mux {
+ function = "flash";
+ groups = "spi0", "spi0_wp_hold";
+ };
+
+ conf-pu {
+ pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP";
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_11>;
+ };
+
+ conf-pd {
+ pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO";
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_11>;
+ };
+ };
+
+ snfi_pins: snfi-pins-func-1 {
+ mux {
+ function = "flash";
+ groups = "snfi";
+ };
+
+ clk {
+ pins = "SPI0_CLK";
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_00>;
+ };
+
+ conf-pu {
+ pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP";
+ drive-strength = <MTK_DRIVE_6mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_00>;
+ };
+
+ conf-pd {
+ pins = "SPI0_MOSI", "SPI0_MISO";
+ drive-strength = <MTK_DRIVE_6mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_00>;
+ };
+ };
+
+ spic_pins: spi1-pins-func-1 {
+ mux {
+ function = "spi";
+ groups = "spi1_2";
+ };
+ };
+
+ uart1_pins: spi1-pins-func-3 {
+ mux {
+ function = "uart";
+ groups = "uart1_2";
+ };
+ };
+
+ pwm_pins: pwm0-pins-func-1 {
+ mux {
+ function = "pwm";
+ groups = "pwm0";
+ };
+ };
+
+ mmc0_pins_default: mmc0default {
+ mux {
+ function = "flash";
+ groups = "emmc_45";
+ input-schmitt-enable;
+ };
+
+ conf-cmd-dat {
+ pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO",
+ "SPI0_CS", "SPI0_HOLD", "SPI0_WP",
+ "SPI1_CLK", "SPI1_MOSI", "SPI1_MISO";
+ input-enable;
+ drive-strength = <MTK_DRIVE_4mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+
+ conf-clk {
+ pins = "SPI1_CS";
+ drive-strength = <MTK_DRIVE_6mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ };
+
+ conf-rst {
+ pins = "PWM1";
+ drive-strength = <MTK_DRIVE_4mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+ };
+};
+
+&snand {
+ pinctrl-names = "default";
+ pinctrl-0 = <&snfi_pins>;
+ status = "okay";
+ quad-spi;
+};
+
+&spi0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi_flash_pins>;
+ status = "okay";
+ must_tx;
+ enhance_timing;
+ dma_ext;
+ ipm_design;
+ support_quad;
+ tick_dly = <2>;
+ sample_sel = <0>;
+
+ spi_nor@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <52000000>;
+ };
+
+ spi_nand@1 {
+ compatible = "spi-nand";
+ reg = <1>;
+ spi-max-frequency = <52000000>;
+ };
+};
+
+&pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm_pins>;
+ status = "okay";
+};
+
+&watchdog {
+ status = "disabled";
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_default>;
+ bus-width = <8>;
+ max-frequency = <52000000>;
+ cap-mmc-highspeed;
+ cap-mmc-hw-reset;
+ vmmc-supply = <®_3p3v>;
+ non-removable;
+ status = "okay";
+};
diff --git a/arch/arm/dts/mt7986b-sd-rfb.dts b/arch/arm/dts/mt7986b-sd-rfb.dts
new file mode 100644
index 0000000..48f9320
--- /dev/null
+++ b/arch/arm/dts/mt7986b-sd-rfb.dts
@@ -0,0 +1,173 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+/dts-v1/;
+#include "mt7986.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ model = "mt7986-rfb";
+ compatible = "mediatek,mt7986", "mediatek,mt7986-rfb",
+ "mediatek,mt7986-sd-rfb";
+ chosen {
+ stdout-path = &uart0;
+ tick-timer = &timer0;
+ };
+
+ reg_3p3v: regulator-3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+ status = "disabled";
+};
+
+ð {
+ status = "okay";
+ mediatek,gmac-id = <0>;
+ phy-mode = "sgmii";
+ mediatek,switch = "mt7531";
+ reset-gpios = <&gpio 5 GPIO_ACTIVE_HIGH>;
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+};
+
+&pinctrl {
+ spi_flash_pins: spi0-pins-func-1 {
+ mux {
+ function = "flash";
+ groups = "spi0", "spi0_wp_hold";
+ };
+
+ conf-pu {
+ pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP";
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_11>;
+ };
+
+ conf-pd {
+ pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO";
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_11>;
+ };
+ };
+
+ spic_pins: spi1-pins-func-1 {
+ mux {
+ function = "spi";
+ groups = "spi1_2";
+ };
+ };
+
+ uart1_pins: spi1-pins-func-3 {
+ mux {
+ function = "uart";
+ groups = "uart1_2";
+ };
+ };
+
+ pwm_pins: pwm0-pins-func-1 {
+ mux {
+ function = "pwm";
+ groups = "pwm0";
+ };
+ };
+
+ mmc0_pins_default: mmc0default {
+ mux {
+ function = "flash";
+ groups = "emmc_45";
+ input-schmitt-enable;
+ };
+
+ conf-cmd-dat {
+ pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO",
+ "SPI0_CS", "SPI0_HOLD", "SPI0_WP",
+ "SPI1_CLK", "SPI1_MOSI", "SPI1_MISO";
+ input-enable;
+ drive-strength = <MTK_DRIVE_4mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+
+ conf-clk {
+ pins = "SPI1_CS";
+ drive-strength = <MTK_DRIVE_6mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ };
+
+ conf-rst {
+ pins = "PWM1";
+ drive-strength = <MTK_DRIVE_4mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+ };
+};
+
+&spi0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi_flash_pins>;
+ status = "okay";
+ must_tx;
+ enhance_timing;
+ dma_ext;
+ ipm_design;
+ support_quad;
+ tick_dly = <2>;
+ sample_sel = <0>;
+
+ spi_nor@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <52000000>;
+ };
+
+ spi_nand@1 {
+ compatible = "spi-nand";
+ reg = <1>;
+ spi-max-frequency = <52000000>;
+ };
+};
+
+&pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm_pins>;
+ status = "okay";
+};
+
+&watchdog {
+ status = "disabled";
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_default>;
+ bus-width = <4>;
+ max-frequency = <52000000>;
+ cap-sd-highspeed;
+ r_smpl = <1>;
+ vmmc-supply = <®_3p3v>;
+ vqmmc-supply = <®_3p3v>;
+ status = "okay";
+};
diff --git a/arch/arm/include/asm/arch-imx8m/imx-regs.h b/arch/arm/include/asm/arch-imx8m/imx-regs.h
index ff3b9dd..29d5baa 100644
--- a/arch/arm/include/asm/arch-imx8m/imx-regs.h
+++ b/arch/arm/include/asm/arch-imx8m/imx-regs.h
@@ -27,6 +27,7 @@
#define IOMUXC_GPR_BASE_ADDR 0x30340000
#define OCOTP_BASE_ADDR 0x30350000
#define ANATOP_BASE_ADDR 0x30360000
+#define SNVS_BASE_ADDR 0x30370000
#define CCM_BASE_ADDR 0x30380000
#define SRC_BASE_ADDR 0x30390000
#define GPC_BASE_ADDR 0x303A0000
@@ -113,6 +114,10 @@
#define SRC_DDR1_RCR_CORE_RESET_N_MASK BIT(1)
#define SRC_DDR1_RCR_PRESET_N_MASK BIT(0)
+#define SNVS_LPSR 0x4c
+#define SNVS_LPLVDR 0x64
+#define SNVS_LPPGDR_INIT 0x41736166
+
struct iomuxc_gpr_base_regs {
u32 gpr[47];
};
diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c
index d115b25..a486328 100644
--- a/arch/arm/mach-imx/imx8m/soc.c
+++ b/arch/arm/mach-imx/imx8m/soc.c
@@ -327,7 +327,7 @@
}
}
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
ulong top_addr;
@@ -544,6 +544,16 @@
}
EVENT_SPY(EVT_DM_POST_INIT, imx8m_check_clock);
+static void imx8m_setup_snvs(void)
+{
+ /* Enable SNVS clock */
+ clock_enable(CCGR_SNVS, 1);
+ /* Initialize glitch detect */
+ writel(SNVS_LPPGDR_INIT, SNVS_BASE_ADDR + SNVS_LPLVDR);
+ /* Clear interrupt status */
+ writel(0xffffffff, SNVS_BASE_ADDR + SNVS_LPSR);
+}
+
int arch_cpu_init(void)
{
struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
@@ -594,6 +604,8 @@
writel(0x200, &ocotp->ctrl_clr);
}
+ imx8m_setup_snvs();
+
return 0;
}
diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
index f79a5c6..04aa2fd 100644
--- a/arch/arm/mach-mediatek/Kconfig
+++ b/arch/arm/mach-mediatek/Kconfig
@@ -40,6 +40,24 @@
including DDR3, crypto engine, 3x3 11n/ac Wi-Fi, Gigabit Ethernet,
switch, USB3.0, PCIe, UART, SPI, I2C and PWM.
+config TARGET_MT7981
+ bool "MediaTek MT7981 SoC"
+ select ARM64
+ select CPU
+ help
+ The MediaTek MT7981 is a ARM64-based SoC with a dual-core Cortex-A53.
+ including UART, SPI, USB, NAND, SNFI, PWM, Gigabit Ethernet, I2C,
+ built-in Wi-Fi, and PCIe.
+
+config TARGET_MT7986
+ bool "MediaTek MT7986 SoC"
+ select ARM64
+ select CPU
+ help
+ The MediaTek MT7986 is a ARM64-based SoC with a quad-core Cortex-A53.
+ including UART, SPI, SPI flash, USB3.0, MMC, NAND, SNFI, PWM, PCIe,
+ Gigabit Ethernet, I2C, built-in 4x4 Wi-Fi, and PCIe.
+
config TARGET_MT8183
bool "MediaTek MT8183 SoC"
select ARM64
@@ -84,6 +102,8 @@
default "mt7622" if TARGET_MT7622
default "mt7623" if TARGET_MT7623
default "mt7629" if TARGET_MT7629
+ default "mt7981" if TARGET_MT7981
+ default "mt7986" if TARGET_MT7986
default "mt8183" if TARGET_MT8183
default "mt8512" if TARGET_MT8512
default "mt8516" if TARGET_MT8516
@@ -99,6 +119,8 @@
default "mt7622" if TARGET_MT7622
default "mt7623" if TARGET_MT7623
default "mt7629" if TARGET_MT7629
+ default "mt7981" if TARGET_MT7981
+ default "mt7986" if TARGET_MT7986
default "mt8183" if TARGET_MT8183
default "mt8512" if TARGET_MT8512
default "mt8516" if TARGET_MT8516
@@ -113,6 +135,7 @@
string
default "media=nor" if TARGET_MT8518 || TARGET_MT8512 || TARGET_MT7629 || TARGET_MT7622
default "media=emmc" if TARGET_MT8516 || TARGET_MT8365 || TARGET_MT8183
+ default "media=snand;nandinfo=2k+64" if TARGET_MT7981 || TARGET_MT7986
default "lk=1" if TARGET_MT7623
endif
diff --git a/arch/arm/mach-mediatek/Makefile b/arch/arm/mach-mediatek/Makefile
index 0f5b0c1..fc85293 100644
--- a/arch/arm/mach-mediatek/Makefile
+++ b/arch/arm/mach-mediatek/Makefile
@@ -7,6 +7,8 @@
obj-$(CONFIG_TARGET_MT7622) += mt7622/
obj-$(CONFIG_TARGET_MT7623) += mt7623/
obj-$(CONFIG_TARGET_MT7629) += mt7629/
+obj-$(CONFIG_TARGET_MT7981) += mt7981/
+obj-$(CONFIG_TARGET_MT7986) += mt7986/
obj-$(CONFIG_TARGET_MT8183) += mt8183/
obj-$(CONFIG_TARGET_MT8516) += mt8516/
obj-$(CONFIG_TARGET_MT8518) += mt8518/
diff --git a/arch/arm/mach-mediatek/mt7981/Makefile b/arch/arm/mach-mediatek/mt7981/Makefile
new file mode 100644
index 0000000..007eb4a
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7981/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += init.o
+obj-y += lowlevel_init.o
diff --git a/arch/arm/mach-mediatek/mt7981/init.c b/arch/arm/mach-mediatek/mt7981/init.c
new file mode 100644
index 0000000..4f77a3d
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7981/init.c
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+#include <init.h>
+#include <asm/armv8/mmu.h>
+#include <asm/system.h>
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+ gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, SZ_2G);
+
+ return 0;
+}
+
+void reset_cpu(ulong addr)
+{
+ psci_system_reset();
+}
+
+static struct mm_region mt7981_mem_map[] = {
+ {
+ /* DDR */
+ .virt = 0x40000000UL,
+ .phys = 0x40000000UL,
+ .size = 0x80000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE,
+ }, {
+ .virt = 0x00000000UL,
+ .phys = 0x00000000UL,
+ .size = 0x40000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
+ 0,
+ }
+};
+
+struct mm_region *mem_map = mt7981_mem_map;
diff --git a/arch/arm/mach-mediatek/mt7981/lowlevel_init.S b/arch/arm/mach-mediatek/mt7981/lowlevel_init.S
new file mode 100644
index 0000000..85a1cea
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7981/lowlevel_init.S
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+/*
+ * Switch from AArch64 EL2 to AArch32 EL2
+ * @param inputs:
+ * x0: argument, zero
+ * x1: machine nr
+ * x2: fdt address
+ * x3: input argument
+ * x4: kernel entry point
+ * @param outputs for secure firmware:
+ * x0: function id
+ * x1: kernel entry point
+ * x2: machine nr
+ * x3: fdt address
+ *
+ * [1] https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/plat/mediatek/common/mtk_sip_svc.c
+*/
+
+.global armv8_el2_to_aarch32
+armv8_el2_to_aarch32:
+ mov x3, x2
+ mov x2, x1
+ mov x1, x4
+ mov x4, #0
+ ldr x0, =0x82000200 /* MTK_SIP_KERNEL_BOOT_AARCH32 */
+ SMC #0
+ ret
diff --git a/arch/arm/mach-mediatek/mt7986/Makefile b/arch/arm/mach-mediatek/mt7986/Makefile
new file mode 100644
index 0000000..007eb4a
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7986/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += init.o
+obj-y += lowlevel_init.o
diff --git a/arch/arm/mach-mediatek/mt7986/init.c b/arch/arm/mach-mediatek/mt7986/init.c
new file mode 100644
index 0000000..0fd4596
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7986/init.c
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+#include <init.h>
+#include <asm/armv8/mmu.h>
+#include <asm/system.h>
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+ gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, SZ_2G);
+
+ return 0;
+}
+
+void reset_cpu(ulong addr)
+{
+ psci_system_reset();
+}
+
+static struct mm_region mt7986_mem_map[] = {
+ {
+ /* DDR */
+ .virt = 0x40000000UL,
+ .phys = 0x40000000UL,
+ .size = 0x80000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE,
+ }, {
+ .virt = 0x00000000UL,
+ .phys = 0x00000000UL,
+ .size = 0x40000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
+ 0,
+ }
+};
+
+struct mm_region *mem_map = mt7986_mem_map;
diff --git a/arch/arm/mach-mediatek/mt7986/lowlevel_init.S b/arch/arm/mach-mediatek/mt7986/lowlevel_init.S
new file mode 100644
index 0000000..85a1cea
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7986/lowlevel_init.S
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+/*
+ * Switch from AArch64 EL2 to AArch32 EL2
+ * @param inputs:
+ * x0: argument, zero
+ * x1: machine nr
+ * x2: fdt address
+ * x3: input argument
+ * x4: kernel entry point
+ * @param outputs for secure firmware:
+ * x0: function id
+ * x1: kernel entry point
+ * x2: machine nr
+ * x3: fdt address
+ *
+ * [1] https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/plat/mediatek/common/mtk_sip_svc.c
+*/
+
+.global armv8_el2_to_aarch32
+armv8_el2_to_aarch32:
+ mov x3, x2
+ mov x2, x1
+ mov x1, x4
+ mov x4, #0
+ ldr x0, =0x82000200 /* MTK_SIP_KERNEL_BOOT_AARCH32 */
+ SMC #0
+ ret
diff --git a/arch/arm/mach-mvebu/arm64-common.c b/arch/arm/mach-mvebu/arm64-common.c
index 238edbe..63f6af5 100644
--- a/arch/arm/mach-mvebu/arm64-common.c
+++ b/arch/arm/mach-mvebu/arm64-common.c
@@ -30,7 +30,7 @@
*/
#define USABLE_RAM_SIZE 0x80000000ULL
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
unsigned long top = CONFIG_SYS_SDRAM_BASE + min(gd->ram_size, USABLE_RAM_SIZE);
diff --git a/arch/arm/mach-rockchip/sdram.c b/arch/arm/mach-rockchip/sdram.c
index 705ec7b..12f1d7e 100644
--- a/arch/arm/mach-rockchip/sdram.c
+++ b/arch/arm/mach-rockchip/sdram.c
@@ -205,7 +205,7 @@
return 0;
}
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
unsigned long top = CONFIG_SYS_SDRAM_BASE + SDRAM_MAX_SIZE;
diff --git a/arch/arm/mach-stm32mp/dram_init.c b/arch/arm/mach-stm32mp/dram_init.c
index 920b99b..9346fa8 100644
--- a/arch/arm/mach-stm32mp/dram_init.c
+++ b/arch/arm/mach-stm32mp/dram_init.c
@@ -40,7 +40,7 @@
return 0;
}
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
phys_size_t size;
phys_addr_t reg;
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
index 8f7c894..62bb40b 100644
--- a/arch/arm/mach-sunxi/board.c
+++ b/arch/arm/mach-sunxi/board.c
@@ -65,7 +65,7 @@
};
struct mm_region *mem_map = sunxi_mem_map;
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
/* Some devices (like the EMAC) have a 32-bit DMA limit. */
if (gd->ram_top > (1ULL << 32))
diff --git a/arch/arm/mach-tegra/board2.c b/arch/arm/mach-tegra/board2.c
index 8950e67..1994db0 100644
--- a/arch/arm/mach-tegra/board2.c
+++ b/arch/arm/mach-tegra/board2.c
@@ -401,7 +401,7 @@
* This function is called before dram_init_banksize(), so we can't simply
* return gd->bd->bi_dram[1].start + gd->bd->bi_dram[1].size.
*/
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
ulong ram_top;
diff --git a/arch/mips/mach-jz47xx/jz4780/jz4780.c b/arch/mips/mach-jz47xx/jz4780/jz4780.c
index fefba12..a57ec78 100644
--- a/arch/mips/mach-jz47xx/jz4780/jz4780.c
+++ b/arch/mips/mach-jz47xx/jz4780/jz4780.c
@@ -76,7 +76,7 @@
}
#endif /* CONFIG_SPL_BUILD */
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
return CONFIG_SYS_SDRAM_BASE + (256 * 1024 * 1024);
}
diff --git a/arch/mips/mach-octeon/dram.c b/arch/mips/mach-octeon/dram.c
index 4679260..9c5789b 100644
--- a/arch/mips/mach-octeon/dram.c
+++ b/arch/mips/mach-octeon/dram.c
@@ -77,7 +77,7 @@
return UBOOT_RAM_SIZE_MAX;
}
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
if (IS_ENABLED(CONFIG_RAM_OCTEON)) {
/* Map a maximum of 256MiB - return not size but address */
diff --git a/arch/powerpc/cpu/mpc85xx/tlb.c b/arch/powerpc/cpu/mpc85xx/tlb.c
index ab61649..e39fe14 100644
--- a/arch/powerpc/cpu/mpc85xx/tlb.c
+++ b/arch/powerpc/cpu/mpc85xx/tlb.c
@@ -312,7 +312,10 @@
if (size || memsize > CONFIG_MAX_MEM_MAPPED) {
print_size(memsize > CONFIG_MAX_MEM_MAPPED ?
memsize - CONFIG_MAX_MEM_MAPPED + size : size,
- " left unmapped\n");
+ " of DDR memory left unmapped in U-Boot\n");
+#ifndef CONFIG_SPL_BUILD
+ puts(" ");
+#endif
}
return memsize_in_meg;
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 78e964d..32a90b8 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -269,6 +269,20 @@
from a NOR flash memory without copying the code to ram.
Say yes here if U-Boot boots from flash directly.
+config SPL_XIP
+ bool "Enable XIP mode for SPL"
+ help
+ If SPL starts in read-only memory (XIP for example) then we shouldn't
+ rely on lock variables (for example hart_lottery and available_harts_lock),
+ this affects only SPL, other stages should proceed as non-XIP.
+
+config AVAILABLE_HARTS
+ bool "Send IPI by available harts"
+ default y
+ help
+ By default, IPI sending mechanism will depend on available_harts.
+ If disable this, it will send IPI by CPUs node numbers of device tree.
+
config SHOW_REGS
bool "Show registers on unhandled exception"
diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c
index 3ffcbbd..52ab025 100644
--- a/arch/riscv/cpu/cpu.c
+++ b/arch/riscv/cpu/cpu.c
@@ -19,15 +19,17 @@
* The variables here must be stored in the data section since they are used
* before the bss section is available.
*/
-#ifndef CONFIG_XIP
+#if !CONFIG_IS_ENABLED(XIP)
u32 hart_lottery __section(".data") = 0;
+#ifdef CONFIG_AVAILABLE_HARTS
/*
* The main hart running U-Boot has acquired available_harts_lock until it has
* finished initialization of global data.
*/
u32 available_harts_lock = 1;
#endif
+#endif
static inline bool supports_extension(char ext)
{
diff --git a/arch/riscv/cpu/fu540/dram.c b/arch/riscv/cpu/fu540/dram.c
index 1fdc783..44e11bd 100644
--- a/arch/riscv/cpu/fu540/dram.c
+++ b/arch/riscv/cpu/fu540/dram.c
@@ -21,7 +21,7 @@
return fdtdec_setup_memory_banksize();
}
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
/*
* Ensure that we run from first 4GB so that all
diff --git a/arch/riscv/cpu/fu740/dram.c b/arch/riscv/cpu/fu740/dram.c
index 1dc77ef..d6d4a41 100644
--- a/arch/riscv/cpu/fu740/dram.c
+++ b/arch/riscv/cpu/fu740/dram.c
@@ -20,7 +20,7 @@
return fdtdec_setup_memory_banksize();
}
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
#ifdef CONFIG_64BIT
/*
diff --git a/arch/riscv/cpu/generic/dram.c b/arch/riscv/cpu/generic/dram.c
index 1fdc783..44e11bd 100644
--- a/arch/riscv/cpu/generic/dram.c
+++ b/arch/riscv/cpu/generic/dram.c
@@ -21,7 +21,7 @@
return fdtdec_setup_memory_banksize();
}
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
/*
* Ensure that we run from first 4GB so that all
diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S
index b7f21ab..4687bca 100644
--- a/arch/riscv/cpu/start.S
+++ b/arch/riscv/cpu/start.S
@@ -122,7 +122,7 @@
call_harts_early_init:
jal harts_early_init
-#ifndef CONFIG_XIP
+#if !CONFIG_IS_ENABLED(XIP)
/*
* Pick hart to initialize global data and run U-Boot. The other harts
* wait for initialization to complete.
@@ -152,22 +152,24 @@
/* save the boot hart id to global_data */
SREG tp, GD_BOOT_HART(gp)
-#ifndef CONFIG_XIP
+#if !CONFIG_IS_ENABLED(XIP)
+#ifdef CONFIG_AVAILABLE_HARTS
la t0, available_harts_lock
amoswap.w.rl zero, zero, 0(t0)
+#endif
wait_for_gd_init:
- la t0, available_harts_lock
- li t1, 1
-1: amoswap.w.aq t1, t1, 0(t0)
- bnez t1, 1b
-
/*
* Set the global data pointer only when gd_t has been initialized.
* This was already set by arch_setup_gd on the boot hart, but all other
* harts' global data pointers gets set here.
*/
mv gp, s0
+#ifdef CONFIG_AVAILABLE_HARTS
+ la t0, available_harts_lock
+ li t1, 1
+1: amoswap.w.aq t1, t1, 0(t0)
+ bnez t1, 1b
/* register available harts in the available_harts mask */
li t1, 1
@@ -177,6 +179,7 @@
SREG t2, GD_AVAILABLE_HARTS(gp)
amoswap.w.rl zero, zero, 0(t0)
+#endif
/*
* Continue on hart lottery winner, others branch to
diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h
index 095484a..858594a 100644
--- a/arch/riscv/include/asm/global_data.h
+++ b/arch/riscv/include/asm/global_data.h
@@ -27,9 +27,11 @@
#if CONFIG_IS_ENABLED(SMP)
struct ipi_data ipi[CONFIG_NR_CPUS];
#endif
-#ifndef CONFIG_XIP
+#if !CONFIG_IS_ENABLED(XIP)
+#ifdef CONFIG_AVAILABLE_HARTS
ulong available_harts;
#endif
+#endif
};
#include <asm-generic/global_data.h>
diff --git a/arch/riscv/lib/asm-offsets.c b/arch/riscv/lib/asm-offsets.c
index f1fe089..452dfce 100644
--- a/arch/riscv/lib/asm-offsets.c
+++ b/arch/riscv/lib/asm-offsets.c
@@ -16,9 +16,11 @@
{
DEFINE(GD_BOOT_HART, offsetof(gd_t, arch.boot_hart));
DEFINE(GD_FIRMWARE_FDT_ADDR, offsetof(gd_t, arch.firmware_fdt_addr));
-#ifndef CONFIG_XIP
+#if !CONFIG_IS_ENABLED(XIP)
+#ifdef CONFIG_AVAILABLE_HARTS
DEFINE(GD_AVAILABLE_HARTS, offsetof(gd_t, arch.available_harts));
#endif
+#endif
return 0;
}
diff --git a/arch/riscv/lib/smp.c b/arch/riscv/lib/smp.c
index ba99210..c0f65af 100644
--- a/arch/riscv/lib/smp.c
+++ b/arch/riscv/lib/smp.c
@@ -45,11 +45,13 @@
continue;
}
-#ifndef CONFIG_XIP
+#if !CONFIG_IS_ENABLED(XIP)
+#ifdef CONFIG_AVAILABLE_HARTS
/* skip if hart is not available */
if (!(gd->arch.available_harts & (1 << reg)))
continue;
#endif
+#endif
gd->arch.ipi[reg].addr = ipi->addr;
gd->arch.ipi[reg].arg0 = ipi->arg0;
diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c
index f937991..d6170ad 100644
--- a/arch/sandbox/cpu/os.c
+++ b/arch/sandbox/cpu/os.c
@@ -669,6 +669,11 @@
os_putc(*str++);
}
+void os_flush(void)
+{
+ fflush(stdout);
+}
+
int os_write_ram_buf(const char *fname)
{
struct sandbox_state *state = state_get_current();
@@ -1012,8 +1017,24 @@
return base;
}
+/**
+ * os_unblock_signals() - unblock all signals
+ *
+ * If we are relaunching the sandbox in a signal handler, we have to unblock
+ * the respective signal before calling execv(). See signal(7) man-page.
+ */
+static void os_unblock_signals(void)
+{
+ sigset_t sigs;
+
+ sigfillset(&sigs);
+ sigprocmask(SIG_UNBLOCK, &sigs, NULL);
+}
+
void os_relaunch(char *argv[])
{
+ os_unblock_signals();
+
execv(argv[0], argv);
os_exit(1);
}
diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi
index 56e6b38..de7a218 100644
--- a/arch/sandbox/dts/sandbox.dtsi
+++ b/arch/sandbox/dts/sandbox.dtsi
@@ -245,6 +245,10 @@
compatible = "sandbox,sandbox-rng";
};
+ scsi {
+ compatible = "sandbox,scsi";
+ };
+
sound {
compatible = "sandbox,sound";
cpu {
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index c7fffa2..4ee4712 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -1158,6 +1158,11 @@
backlight = <&backlight 0 100>;
};
+ scsi {
+ compatible = "sandbox,scsi";
+ sandbox,filepath = "scsi.img";
+ };
+
smem@0 {
compatible = "sandbox,smem";
};
diff --git a/arch/x86/cpu/broadwell/sdram.c b/arch/x86/cpu/broadwell/sdram.c
index c104a84..1295121 100644
--- a/arch/x86/cpu/broadwell/sdram.c
+++ b/arch/x86/cpu/broadwell/sdram.c
@@ -25,7 +25,7 @@
#include <asm/arch/pei_data.h>
#include <asm/arch/pm.h>
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
return mrc_common_board_get_usable_ram_top(total_size);
}
diff --git a/arch/x86/cpu/coreboot/sdram.c b/arch/x86/cpu/coreboot/sdram.c
index 4a256ba..f4ee4cd 100644
--- a/arch/x86/cpu/coreboot/sdram.c
+++ b/arch/x86/cpu/coreboot/sdram.c
@@ -27,7 +27,7 @@
* address, and how far U-Boot is moved by relocation are set in the global
* data structure.
*/
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
uintptr_t dest_addr = 0;
int i;
diff --git a/arch/x86/cpu/efi/payload.c b/arch/x86/cpu/efi/payload.c
index b777856..1c28a43 100644
--- a/arch/x86/cpu/efi/payload.c
+++ b/arch/x86/cpu/efi/payload.c
@@ -27,7 +27,7 @@
* the relocation address, and how far U-Boot is moved by relocation are
* set in the global data structure.
*/
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
struct efi_mem_desc *desc, *end;
struct efi_entry_memmap *map;
diff --git a/arch/x86/cpu/efi/sdram.c b/arch/x86/cpu/efi/sdram.c
index af65982..f3086db 100644
--- a/arch/x86/cpu/efi/sdram.c
+++ b/arch/x86/cpu/efi/sdram.c
@@ -11,7 +11,7 @@
DECLARE_GLOBAL_DATA_PTR;
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
return (ulong)efi_get_ram_base() + gd->ram_size;
}
diff --git a/arch/x86/cpu/intel_common/mrc.c b/arch/x86/cpu/intel_common/mrc.c
index a97b0b7..a4918fb 100644
--- a/arch/x86/cpu/intel_common/mrc.c
+++ b/arch/x86/cpu/intel_common/mrc.c
@@ -25,7 +25,7 @@
"active"
};
-ulong mrc_common_board_get_usable_ram_top(ulong total_size)
+phys_size_t mrc_common_board_get_usable_ram_top(phys_size_t total_size)
{
struct memory_info *info = &gd->arch.meminfo;
uintptr_t dest_addr = 0;
@@ -50,7 +50,7 @@
dest_addr = largest->start + largest->size;
- return (ulong)dest_addr;
+ return (phys_size_t)dest_addr;
}
void mrc_common_dram_init_banksize(void)
diff --git a/arch/x86/cpu/ivybridge/sdram.c b/arch/x86/cpu/ivybridge/sdram.c
index dd6b875..1a0ec43 100644
--- a/arch/x86/cpu/ivybridge/sdram.c
+++ b/arch/x86/cpu/ivybridge/sdram.c
@@ -44,7 +44,7 @@
#define CMOS_OFFSET_MRC_SEED_S3 156
#define CMOS_OFFSET_MRC_SEED_CHK 160
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
return mrc_common_board_get_usable_ram_top(total_size);
}
diff --git a/arch/x86/cpu/qemu/dram.c b/arch/x86/cpu/qemu/dram.c
index c174550..595c397 100644
--- a/arch/x86/cpu/qemu/dram.c
+++ b/arch/x86/cpu/qemu/dram.c
@@ -71,7 +71,7 @@
* the relocation address, and how far U-Boot is moved by relocation are
* set in the global data structure.
*/
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
return qemu_get_low_memory_size();
}
diff --git a/arch/x86/cpu/quark/dram.c b/arch/x86/cpu/quark/dram.c
index 2287dce..8b1ee2d 100644
--- a/arch/x86/cpu/quark/dram.c
+++ b/arch/x86/cpu/quark/dram.c
@@ -184,7 +184,7 @@
* the relocation address, and how far U-Boot is moved by relocation are
* set in the global data structure.
*/
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
return gd->ram_size;
}
diff --git a/arch/x86/cpu/slimbootloader/sdram.c b/arch/x86/cpu/slimbootloader/sdram.c
index c6f10e2..d748d5c 100644
--- a/arch/x86/cpu/slimbootloader/sdram.c
+++ b/arch/x86/cpu/slimbootloader/sdram.c
@@ -48,7 +48,7 @@
* @total_size: The memory size that u-boot occupies
* Return: : The top available memory address lower than 4GB
*/
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
struct sbl_memory_map_info *data;
int i;
diff --git a/arch/x86/cpu/tangier/sdram.c b/arch/x86/cpu/tangier/sdram.c
index afb0847..8a4b1c5 100644
--- a/arch/x86/cpu/tangier/sdram.c
+++ b/arch/x86/cpu/tangier/sdram.c
@@ -204,7 +204,7 @@
* address, and how far U-Boot is moved by relocation are set in the global
* data structure.
*/
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
struct sfi_table_simple *sb;
struct sfi_mem_entry *mentry;
diff --git a/arch/x86/include/asm/mrc_common.h b/arch/x86/include/asm/mrc_common.h
index 3d7f00c..a7f260a 100644
--- a/arch/x86/include/asm/mrc_common.h
+++ b/arch/x86/include/asm/mrc_common.h
@@ -47,7 +47,7 @@
* the relocation address, and how far U-Boot is moved by relocation are
* set in the global data structure.
*/
-ulong mrc_common_board_get_usable_ram_top(ulong total_size);
+phys_size_t mrc_common_board_get_usable_ram_top(phys_size_t total_size);
void mrc_common_dram_init_banksize(void);
diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h
index a1655e1..4cf41e9 100644
--- a/arch/x86/include/asm/u-boot-x86.h
+++ b/arch/x86/include/asm/u-boot-x86.h
@@ -77,7 +77,7 @@
void x86_enable_caches(void);
void x86_disable_caches(void);
int x86_init_cache(void);
-ulong board_get_usable_ram_top(ulong total_size);
+phys_size_t board_get_usable_ram_top(phys_size_t total_size);
int default_print_cpuinfo(void);
/* Set up a UART which can be used with printch(), printhex8(), etc. */
diff --git a/arch/x86/lib/fsp1/fsp_dram.c b/arch/x86/lib/fsp1/fsp_dram.c
index cfd9b9f..5825221 100644
--- a/arch/x86/lib/fsp1/fsp_dram.c
+++ b/arch/x86/lib/fsp1/fsp_dram.c
@@ -34,7 +34,7 @@
* the relocation address, and how far U-Boot is moved by relocation are
* set in the global data structure.
*/
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
return fsp_get_usable_lowmem_top(gd->arch.hob_list);
}
diff --git a/arch/x86/lib/fsp2/fsp_dram.c b/arch/x86/lib/fsp2/fsp_dram.c
index 42d3892..f9ea1ab 100644
--- a/arch/x86/lib/fsp2/fsp_dram.c
+++ b/arch/x86/lib/fsp2/fsp_dram.c
@@ -77,7 +77,7 @@
return 0;
}
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
if (!ll_boot_init())
return gd->ram_size;
diff --git a/board/broadcom/bcmns3/ns3.c b/board/broadcom/bcmns3/ns3.c
index 88036c1..26652e8 100644
--- a/board/broadcom/bcmns3/ns3.c
+++ b/board/broadcom/bcmns3/ns3.c
@@ -183,7 +183,7 @@
}
/* Limit RAM used by U-Boot to the DDR first bank End region */
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
return BCM_NS3_MEM_END;
}
diff --git a/board/data_modul/imx8mm_edm_sbc/imx8mm_data_modul_edm_sbc.c b/board/data_modul/imx8mm_edm_sbc/imx8mm_data_modul_edm_sbc.c
index 6dc4e6a..dc08830 100644
--- a/board/data_modul/imx8mm_edm_sbc/imx8mm_data_modul_edm_sbc.c
+++ b/board/data_modul/imx8mm_edm_sbc/imx8mm_data_modul_edm_sbc.c
@@ -34,22 +34,6 @@
return 0;
}
-/* IMX8M SNVS registers needed for the bootcount functionality */
-#define SNVS_BASE_ADDR 0x30370000
-#define SNVS_LPSR 0x4c
-#define SNVS_LPLVDR 0x64
-#define SNVS_LPPGDR_INIT 0x41736166
-
-static void setup_snvs(void)
-{
- /* Enable SNVS clock */
- clock_enable(CCGR_SNVS, 1);
- /* Initialize glitch detect */
- writel(SNVS_LPPGDR_INIT, SNVS_BASE_ADDR + SNVS_LPLVDR);
- /* Clear interrupt status */
- writel(0xffffffff, SNVS_BASE_ADDR + SNVS_LPSR);
-}
-
static void setup_mac_address(void)
{
unsigned char enetaddr[6];
@@ -99,7 +83,6 @@
int board_init(void)
{
- setup_snvs();
return 0;
}
diff --git a/board/dhelectronics/dh_imx8mp/imx8mp_dhcom_pdk2.c b/board/dhelectronics/dh_imx8mp/imx8mp_dhcom_pdk2.c
index 6f06daf..9d8e19d 100644
--- a/board/dhelectronics/dh_imx8mp/imx8mp_dhcom_pdk2.c
+++ b/board/dhelectronics/dh_imx8mp/imx8mp_dhcom_pdk2.c
@@ -37,22 +37,6 @@
return 0;
}
-/* IMX8M SNVS registers needed for the bootcount functionality */
-#define SNVS_BASE_ADDR 0x30370000
-#define SNVS_LPSR 0x4c
-#define SNVS_LPLVDR 0x64
-#define SNVS_LPPGDR_INIT 0x41736166
-
-static void setup_snvs(void)
-{
- /* Enable SNVS clock */
- clock_enable(CCGR_SNVS, 1);
- /* Initialize glitch detect */
- writel(SNVS_LPPGDR_INIT, SNVS_BASE_ADDR + SNVS_LPLVDR);
- /* Clear interrupt status */
- writel(0xffffffff, SNVS_BASE_ADDR + SNVS_LPSR);
-}
-
static void setup_eqos(void)
{
struct iomuxc_gpr_base_regs *gpr =
@@ -145,7 +129,6 @@
{
setup_eqos();
setup_fec();
- setup_snvs();
return 0;
}
diff --git a/board/imgtec/boston/ddr.c b/board/imgtec/boston/ddr.c
index 182f79b..5b245cb 100644
--- a/board/imgtec/boston/ddr.c
+++ b/board/imgtec/boston/ddr.c
@@ -23,7 +23,7 @@
return 0;
}
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
DECLARE_GLOBAL_DATA_PTR;
diff --git a/board/mediatek/mt7981/MAINTAINERS b/board/mediatek/mt7981/MAINTAINERS
new file mode 100644
index 0000000..e7592a7
--- /dev/null
+++ b/board/mediatek/mt7981/MAINTAINERS
@@ -0,0 +1,10 @@
+MT7981
+M: Sam Shih <sam.shih@mediatek.com>
+S: Maintained
+F: board/mediatek/mt7981
+F: include/configs/mt7981.h
+F: configs/mt7981_emmc_rfb_defconfig
+F: configs/mt7981_rfb_defconfig
+F: configs/mt7981_sd_rfb_defconfig
+F: configs/mt7981_spim_nand_rfb_defconfig
+F: configs/mt7981_spim_nor_rfb_defconfig
diff --git a/board/mediatek/mt7981/Makefile b/board/mediatek/mt7981/Makefile
new file mode 100644
index 0000000..fa5990f
--- /dev/null
+++ b/board/mediatek/mt7981/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += mt7981_rfb.o
diff --git a/board/mediatek/mt7981/mt7981_rfb.c b/board/mediatek/mt7981/mt7981_rfb.c
new file mode 100644
index 0000000..846c715
--- /dev/null
+++ b/board/mediatek/mt7981/mt7981_rfb.c
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+int board_init(void)
+{
+ return 0;
+}
diff --git a/board/mediatek/mt7986/MAINTAINERS b/board/mediatek/mt7986/MAINTAINERS
new file mode 100644
index 0000000..ddc078a
--- /dev/null
+++ b/board/mediatek/mt7986/MAINTAINERS
@@ -0,0 +1,12 @@
+MT7986
+M: Sam Shih <sam.shih@mediatek.com>
+S: Maintained
+F: board/mediatek/mt7986
+F: include/configs/mt7986.h
+F: configs/mt7986_rfb_defconfig
+F: configs/mt7986a_bpir3_emmc_defconfig
+F: configs/mt7986a_bpir3_sd_defconfig
+F: configs/mt7986a_emmc_rfb_defconfig
+F: configs/mt7986a_sd_rfb_defconfig
+F: configs/mt7986b_emmc_rfb_defconfig
+F: configs/mt7986b_sd_rfb_defconfig
diff --git a/board/mediatek/mt7986/Makefile b/board/mediatek/mt7986/Makefile
new file mode 100644
index 0000000..7bb84fa
--- /dev/null
+++ b/board/mediatek/mt7986/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += mt7986_rfb.o
diff --git a/board/mediatek/mt7986/mt7986_rfb.c b/board/mediatek/mt7986/mt7986_rfb.c
new file mode 100644
index 0000000..846c715
--- /dev/null
+++ b/board/mediatek/mt7986/mt7986_rfb.c
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+int board_init(void)
+{
+ return 0;
+}
diff --git a/board/menlo/m53menlo/m53menlo.c b/board/menlo/m53menlo/m53menlo.c
index 61ab384..4afc5aa 100644
--- a/board/menlo/m53menlo/m53menlo.c
+++ b/board/menlo/m53menlo/m53menlo.c
@@ -42,7 +42,7 @@
static u32 mx53_dram_size[2];
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
/*
* WARNING: We must override get_effective_memsize() function here
diff --git a/board/menlo/mx8menlo/mx8menlo.c b/board/menlo/mx8menlo/mx8menlo.c
index 9d3708a..61fc4ec 100644
--- a/board/menlo/mx8menlo/mx8menlo.c
+++ b/board/menlo/mx8menlo/mx8menlo.c
@@ -12,24 +12,7 @@
#include <asm/mach-imx/iomux-v3.h>
#include <spl.h>
-#define SNVS_BASE_ADDR 0x30370000
-#define SNVS_LPSR 0x4c
-#define SNVS_LPLVDR 0x64
-#define SNVS_LPPGDR_INIT 0x41736166
-
-static void setup_snvs(void)
-{
- /* Enable SNVS clock */
- clock_enable(CCGR_SNVS, 1);
- /* Initialize glitch detect */
- writel(SNVS_LPPGDR_INIT, SNVS_BASE_ADDR + SNVS_LPLVDR);
- /* Clear interrupt status */
- writel(0xffffffff, SNVS_BASE_ADDR + SNVS_LPSR);
-}
-
void board_early_init(void)
{
init_uart_clk(1);
-
- setup_snvs();
}
diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c
index 17b8108..00afb35 100644
--- a/board/raspberrypi/rpi/rpi.c
+++ b/board/raspberrypi/rpi/rpi.c
@@ -335,7 +335,7 @@
/*
* Prevent relocation from stomping on a firmware provided FDT blob.
*/
-unsigned long board_get_usable_ram_top(unsigned long total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
if ((gd->ram_top - fw_dtb_pointer) > SZ_64M)
return gd->ram_top;
diff --git a/board/st/common/stm32mp_dfu.c b/board/st/common/stm32mp_dfu.c
index fa48b2a..0096f71 100644
--- a/board/st/common/stm32mp_dfu.c
+++ b/board/st/common/stm32mp_dfu.c
@@ -37,7 +37,7 @@
if (!desc)
return;
- name = blk_get_if_type_name(desc->if_type);
+ name = blk_get_uclass_name(desc->uclass_id);
devnum = desc->devnum;
len = strlen(buf);
diff --git a/board/ti/am65x/evm.c b/board/ti/am65x/evm.c
index 8a0a506..34ec391 100644
--- a/board/ti/am65x/evm.c
+++ b/board/ti/am65x/evm.c
@@ -61,7 +61,7 @@
return 0;
}
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
#ifdef CONFIG_PHYS_64BIT
/* Limit RAM used by U-Boot to the DDR low region */
diff --git a/board/ti/j721e/evm.c b/board/ti/j721e/evm.c
index 5d09004..d6e431e 100644
--- a/board/ti/j721e/evm.c
+++ b/board/ti/j721e/evm.c
@@ -57,7 +57,7 @@
return 0;
}
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
#ifdef CONFIG_PHYS_64BIT
/* Limit RAM used by U-Boot to the DDR low region */
diff --git a/board/ti/j721s2/evm.c b/board/ti/j721s2/evm.c
index 3c75ecf..e09adc8 100644
--- a/board/ti/j721s2/evm.c
+++ b/board/ti/j721s2/evm.c
@@ -46,7 +46,7 @@
return 0;
}
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
#ifdef CONFIG_PHYS_64BIT
/* Limit RAM used by U-Boot to the DDR low region */
diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c
index e1f7104..391ce4d 100644
--- a/board/xilinx/common/board.c
+++ b/board/xilinx/common/board.c
@@ -631,7 +631,7 @@
#endif
#if defined(CONFIG_LMB)
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
phys_size_t size;
phys_addr_t reg;
diff --git a/boot/bootm_os.c b/boot/bootm_os.c
index f31820c..079224c 100644
--- a/boot/bootm_os.c
+++ b/boot/bootm_os.c
@@ -303,6 +303,7 @@
#else
printf("## Starting vxWorks at 0x%08lx\n", (ulong)images->ep);
#endif
+ flush();
boot_jump_vxworks(images);
diff --git a/cmd/bcb.c b/cmd/bcb.c
index 8b87aa0..1622a90 100644
--- a/cmd/bcb.c
+++ b/cmd/bcb.c
@@ -122,7 +122,7 @@
char *endp;
int part, ret;
- desc = blk_get_devnum_by_type(UCLASS_MMC, devnum);
+ desc = blk_get_devnum_by_uclass_id(UCLASS_MMC, devnum);
if (!desc) {
ret = -ENODEV;
goto err_read_fail;
@@ -287,7 +287,7 @@
u64 cnt;
int ret;
- desc = blk_get_devnum_by_type(UCLASS_MMC, bcb_dev);
+ desc = blk_get_devnum_by_uclass_id(UCLASS_MMC, bcb_dev);
if (!desc) {
ret = -ENODEV;
goto err;
diff --git a/cmd/blk_common.c b/cmd/blk_common.c
index 369c5ae..75a072c 100644
--- a/cmd/blk_common.c
+++ b/cmd/blk_common.c
@@ -12,10 +12,10 @@
#include <blk.h>
#include <command.h>
-int blk_common_cmd(int argc, char *const argv[], enum uclass_id if_type,
+int blk_common_cmd(int argc, char *const argv[], enum uclass_id uclass_id,
int *cur_devnump)
{
- const char *if_name = blk_get_if_type_name(if_type);
+ const char *if_name = blk_get_uclass_name(uclass_id);
switch (argc) {
case 0:
@@ -23,16 +23,16 @@
return CMD_RET_USAGE;
case 2:
if (strncmp(argv[1], "inf", 3) == 0) {
- blk_list_devices(if_type);
+ blk_list_devices(uclass_id);
return 0;
} else if (strncmp(argv[1], "dev", 3) == 0) {
- if (blk_print_device_num(if_type, *cur_devnump)) {
+ if (blk_print_device_num(uclass_id, *cur_devnump)) {
printf("\nno %s devices available\n", if_name);
return CMD_RET_FAILURE;
}
return 0;
} else if (strncmp(argv[1], "part", 4) == 0) {
- if (blk_list_part(if_type))
+ if (blk_list_part(uclass_id))
printf("\nno %s partition table available\n",
if_name);
return 0;
@@ -42,7 +42,7 @@
if (strncmp(argv[1], "dev", 3) == 0) {
int dev = (int)dectoul(argv[2], NULL);
- if (!blk_show_device(if_type, dev)) {
+ if (!blk_show_device(uclass_id, dev)) {
*cur_devnump = dev;
printf("... is now current device\n");
} else {
@@ -52,7 +52,7 @@
} else if (strncmp(argv[1], "part", 4) == 0) {
int dev = (int)dectoul(argv[2], NULL);
- if (blk_print_part_devnum(if_type, dev)) {
+ if (blk_print_part_devnum(uclass_id, dev)) {
printf("\n%s device %d not available\n",
if_name, dev);
return CMD_RET_FAILURE;
@@ -71,7 +71,7 @@
printf("\n%s read: device %d block # "LBAFU", count %lu ... ",
if_name, *cur_devnump, blk, cnt);
- n = blk_read_devnum(if_type, *cur_devnump, blk, cnt,
+ n = blk_read_devnum(uclass_id, *cur_devnump, blk, cnt,
(ulong *)addr);
printf("%ld blocks read: %s\n", n,
@@ -86,7 +86,7 @@
printf("\n%s write: device %d block # "LBAFU", count %lu ... ",
if_name, *cur_devnump, blk, cnt);
- n = blk_write_devnum(if_type, *cur_devnump, blk, cnt,
+ n = blk_write_devnum(uclass_id, *cur_devnump, blk, cnt,
(ulong *)addr);
printf("%ld blocks written: %s\n", n,
diff --git a/cmd/boot.c b/cmd/boot.c
index be67a59..14839c1 100644
--- a/cmd/boot.c
+++ b/cmd/boot.c
@@ -32,6 +32,7 @@
addr = hextoul(argv[1], NULL);
printf ("## Starting application at 0x%08lX ...\n", addr);
+ flush();
/*
* pass address parameter as argv[0] (aka command name),
diff --git a/cmd/elf.c b/cmd/elf.c
index ce40d3f..b7b9f50 100644
--- a/cmd/elf.c
+++ b/cmd/elf.c
@@ -72,6 +72,7 @@
return rcode;
printf("## Starting application at 0x%08lx ...\n", addr);
+ flush();
/*
* pass address parameter as argv[0] (aka command name),
@@ -274,6 +275,7 @@
puts("## Not an ELF image, assuming binary\n");
printf("## Starting vxWorks at 0x%08lx ...\n", addr);
+ flush();
dcache_disable();
#if defined(CONFIG_ARM64) && defined(CONFIG_ARMV8_PSCI)
diff --git a/cmd/fdt.c b/cmd/fdt.c
index 842e6cb..6fbd920 100644
--- a/cmd/fdt.c
+++ b/cmd/fdt.c
@@ -48,11 +48,27 @@
/*
* Get a value from the fdt and format it to be set in the environment
*/
-static int fdt_value_env_set(const void *nodep, int len, const char *var)
+static int fdt_value_env_set(const void *nodep, int len,
+ const char *var, int index)
{
- if (is_printable_string(nodep, len))
- env_set(var, (void *)nodep);
- else if (len == 4) {
+ if (is_printable_string(nodep, len)) {
+ const char *nodec = (const char *)nodep;
+ int i;
+
+ /*
+ * Iterate over all members in stringlist and find the one at
+ * offset $index. If no such index exists, indicate failure.
+ */
+ for (i = 0; i < len; i += strlen(nodec) + 1) {
+ if (index-- > 0)
+ continue;
+
+ env_set(var, nodec + i);
+ return 0;
+ }
+
+ return 1;
+ } else if (len == 4) {
char buf[11];
sprintf(buf, "0x%08X", fdt32_to_cpu(*(fdt32_t *)nodep));
@@ -426,10 +442,14 @@
return 0;
} else if (nodep && len > 0) {
if (subcmd[0] == 'v') {
+ int index = 0;
int ret;
+ if (argc == 7)
+ index = simple_strtoul(argv[6], NULL, 10);
+
ret = fdt_value_env_set(nodep, len,
- var);
+ var, index);
if (ret != 0)
return ret;
} else if (subcmd[0] == 'a') {
@@ -1085,7 +1105,9 @@
"fdt resize [<extrasize>] - Resize fdt to size + padding to 4k addr + some optional <extrasize> if needed\n"
"fdt print <path> [<prop>] - Recursive print starting at <path>\n"
"fdt list <path> [<prop>] - Print one level starting at <path>\n"
- "fdt get value <var> <path> <prop> - Get <property> and store in <var>\n"
+ "fdt get value <var> <path> <prop> [<index>] - Get <property> and store in <var>\n"
+ " In case of stringlist property, use optional <index>\n"
+ " to select string within the stringlist. Default is 0.\n"
"fdt get name <var> <path> <index> - Get name of node <index> and store in <var>\n"
"fdt get addr <var> <path> <prop> - Get start address of <property> and store in <var>\n"
"fdt get size <var> <path> [<prop>] - Get size of [<property>] or num nodes and store in <var>\n"
diff --git a/cmd/load.c b/cmd/load.c
index e44ae0d..5c4f347 100644
--- a/cmd/load.c
+++ b/cmd/load.c
@@ -83,6 +83,7 @@
printf("## Switch baudrate to %d bps and press ENTER ...\n",
load_baudrate);
udelay(50000);
+ flush();
gd->baudrate = load_baudrate;
serial_setbrg();
udelay(50000);
@@ -126,6 +127,7 @@
printf("## Switch baudrate to %d bps and press ESC ...\n",
current_baudrate);
udelay(50000);
+ flush();
gd->baudrate = current_baudrate;
serial_setbrg();
udelay(50000);
@@ -317,6 +319,7 @@
printf("## Switch baudrate to %d bps and press ESC ...\n",
(int)current_baudrate);
udelay(50000);
+ flush();
gd->baudrate = current_baudrate;
serial_setbrg();
udelay(50000);
@@ -471,6 +474,7 @@
printf("## Switch baudrate to %d bps and press ENTER ...\n",
load_baudrate);
udelay(50000);
+ flush();
gd->baudrate = load_baudrate;
serial_setbrg();
udelay(50000);
@@ -533,6 +537,7 @@
printf("## Switch baudrate to %d bps and press ESC ...\n",
current_baudrate);
udelay(50000);
+ flush();
gd->baudrate = current_baudrate;
serial_setbrg();
udelay(50000);
diff --git a/cmd/lsblk.c b/cmd/lsblk.c
index 6a1c8f5..d214daf 100644
--- a/cmd/lsblk.c
+++ b/cmd/lsblk.c
@@ -36,7 +36,7 @@
continue;
desc = dev_get_uclass_plat(udev);
printf("%c %s %u", i ? ',' : ':',
- blk_get_if_type_name(desc->if_type),
+ blk_get_uclass_name(desc->uclass_id),
desc->devnum);
i++;
}
diff --git a/cmd/mmc.c b/cmd/mmc.c
index 0f1f4e0..c79d940 100644
--- a/cmd/mmc.c
+++ b/cmd/mmc.c
@@ -154,7 +154,7 @@
#ifdef CONFIG_BLOCK_CACHE
struct blk_desc *bd = mmc_get_blk_desc(mmc);
- blkcache_invalidate(bd->if_type, bd->devnum);
+ blkcache_invalidate(bd->uclass_id, bd->devnum);
#endif
return mmc;
@@ -530,7 +530,7 @@
if (!mmc)
return CMD_RET_FAILURE;
- mmc_dev = blk_get_devnum_by_type(UCLASS_MMC, curr_device);
+ mmc_dev = blk_get_devnum_by_uclass_id(UCLASS_MMC, curr_device);
if (mmc_dev != NULL && mmc_dev->type != DEV_TYPE_UNKNOWN) {
part_print(mmc_dev);
return CMD_RET_SUCCESS;
diff --git a/common/Kconfig b/common/Kconfig
index b776c5c..6591acd 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -186,6 +186,12 @@
We should consider removing this option and allocating the memory
in board_init_f_init_reserve() instead.
+config CONSOLE_FLUSH_SUPPORT
+ bool "Enable console flush support"
+ default y
+ help
+ This enables compilation of flush() function for console flush support.
+
config CONSOLE_MUX
bool "Enable console multiplexing"
default y if DM_VIDEO || VIDEO || LCD
diff --git a/common/board_f.c b/common/board_f.c
index f92d7b9..3df4efe 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -57,6 +57,7 @@
#include <asm/sections.h>
#include <dm/root.h>
#include <linux/errno.h>
+#include <linux/log2.h>
/*
* Pointer to initial global data area
@@ -216,6 +217,36 @@
return 0;
}
+/*
+ * From input size calculate its nearest rounded unit scale (multiply of 2^10)
+ * and value in calculated unit scale multiplied by 10 (as fractional fixed
+ * point number with one decimal digit), which is human natural format,
+ * same what uses print_size() function for displaying. Mathematically it is:
+ * round_nearest(val * 2^scale) = size * 10; where: 10 <= val < 10240.
+ *
+ * For example for size=87654321 we calculate scale=20 and val=836 which means
+ * that input has natural human format 83.6 M (mega = 2^20).
+ */
+#define compute_size_scale_val(size, scale, val) do { \
+ scale = ilog2(size) / 10 * 10; \
+ val = (10 * size + ((1ULL << scale) >> 1)) >> scale; \
+ if (val == 10240) { val = 10; scale += 10; } \
+} while (0)
+
+/*
+ * Check if the sizes in their natural units written in decimal format with
+ * one fraction number are same.
+ */
+static int sizes_near(unsigned long long size1, unsigned long long size2)
+{
+ unsigned int size1_scale, size1_val, size2_scale, size2_val;
+
+ compute_size_scale_val(size1, size1_scale, size1_val);
+ compute_size_scale_val(size2, size2_scale, size2_val);
+
+ return size1_scale == size2_scale && size1_val == size2_val;
+}
+
static int show_dram_config(void)
{
unsigned long long size;
@@ -232,7 +263,11 @@
}
debug("\nDRAM: ");
- print_size(size, "");
+ print_size(gd->ram_size, "");
+ if (!sizes_near(gd->ram_size, size)) {
+ printf(" (effective ");
+ print_size(size, ")");
+ }
board_add_ram_info(0);
putc('\n');
@@ -305,7 +340,7 @@
}
/* Get the top of usable RAM */
-__weak ulong board_get_usable_ram_top(ulong total_size)
+__weak phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
#if defined(CONFIG_SYS_SDRAM_BASE) && CONFIG_SYS_SDRAM_BASE > 0
/*
@@ -328,7 +363,7 @@
/*
* Ram is setup, size stored in gd !!
*/
- debug("Ram size: %08lX\n", (ulong)gd->ram_size);
+ debug("Ram size: %08llX\n", (unsigned long long)gd->ram_size);
#if CONFIG_VAL(SYS_MEM_TOP_HIDE)
/*
* Subtract specified amount of memory to hide so that it won't
@@ -348,7 +383,7 @@
gd->ram_top = gd->ram_base + get_effective_memsize();
gd->ram_top = board_get_usable_ram_top(gd->mon_len);
gd->relocaddr = gd->ram_top;
- debug("Ram top: %08lX\n", (ulong)gd->ram_top);
+ debug("Ram top: %08llX\n", (unsigned long long)gd->ram_top);
#if defined(CONFIG_MP) && (defined(CONFIG_MPC86xx) || defined(CONFIG_E500))
/*
* We need to make sure the location we intend to put secondary core
diff --git a/common/console.c b/common/console.c
index e5be6ff..0c9bf66 100644
--- a/common/console.c
+++ b/common/console.c
@@ -199,6 +199,7 @@
case stdout:
gd->jt->putc = putc;
gd->jt->puts = puts;
+ STDIO_DEV_ASSIGN_FLUSH(gd->jt, flush);
gd->jt->printf = printf;
break;
}
@@ -364,6 +365,19 @@
}
}
+#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
+static void console_flush(int file)
+{
+ int i;
+ struct stdio_dev *dev;
+
+ for_each_console_dev(i, file, dev) {
+ if (dev->flush != NULL)
+ dev->flush(dev);
+ }
+}
+#endif
+
#if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
static inline void console_doenv(int file, struct stdio_dev *dev)
{
@@ -413,6 +427,14 @@
stdio_devices[file]->puts(stdio_devices[file], s);
}
+#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
+static inline void console_flush(int file)
+{
+ if (stdio_devices[file]->flush)
+ stdio_devices[file]->flush(stdio_devices[file]);
+}
+#endif
+
#if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
static inline void console_doenv(int file, struct stdio_dev *dev)
{
@@ -525,6 +547,14 @@
if (file < MAX_FILES)
console_puts(file, s);
}
+
+#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
+void fflush(int file)
+{
+ if (file < MAX_FILES)
+ console_flush(file);
+}
+#endif
int fprintf(int file, const char *fmt, ...)
{
@@ -739,6 +769,40 @@
serial_puts(s);
}
}
+
+#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
+void flush(void)
+{
+ if (!gd)
+ return;
+
+ /* sandbox can send characters to stdout before it has a console */
+ if (IS_ENABLED(CONFIG_SANDBOX) && !(gd->flags & GD_FLG_SERIAL_READY)) {
+ os_flush();
+ return;
+ }
+
+ if (IS_ENABLED(CONFIG_DEBUG_UART) && !(gd->flags & GD_FLG_SERIAL_READY))
+ return;
+
+ if (IS_ENABLED(CONFIG_SILENT_CONSOLE) && (gd->flags & GD_FLG_SILENT))
+ return;
+
+ if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE))
+ return;
+
+ if (!gd->have_console)
+ return;
+
+ if (gd->flags & GD_FLG_DEVINIT) {
+ /* Send to the standard output */
+ fflush(stdout);
+ } else {
+ /* Send directly to the handler */
+ serial_flush();
+ }
+}
+#endif
#ifdef CONFIG_CONSOLE_RECORD
int console_record_init(void)
diff --git a/common/memsize.c b/common/memsize.c
index d5d13d5..3c80ad2 100644
--- a/common/memsize.c
+++ b/common/memsize.c
@@ -94,11 +94,23 @@
phys_size_t __weak get_effective_memsize(void)
{
-#ifndef CONFIG_VERY_BIG_RAM
- return gd->ram_size;
+ phys_size_t ram_size = gd->ram_size;
+
+ /*
+ * Check for overflow and limit ram size to some representable value.
+ * It is required that ram_base + ram_size must be representable by
+ * phys_size_t type and must be aligned by direct access, therefore
+ * calculate it from last 4kB sector which should work as alignment
+ * on any platform.
+ */
+ if (gd->ram_base + ram_size < gd->ram_base)
+ ram_size = ((phys_size_t)~0xfffULL) - gd->ram_base;
+
+#ifndef CONFIG_MAX_MEM_MAPPED
+ return ram_size;
#else
/* limit stack to what we can reasonable map */
- return ((gd->ram_size > CONFIG_MAX_MEM_MAPPED) ?
- CONFIG_MAX_MEM_MAPPED : gd->ram_size);
+ return ((ram_size > CONFIG_MAX_MEM_MAPPED) ?
+ CONFIG_MAX_MEM_MAPPED : ram_size);
#endif
}
diff --git a/common/spl/spl_sata.c b/common/spl/spl_sata.c
index ea9f175..6c36f2c 100644
--- a/common/spl/spl_sata.c
+++ b/common/spl/spl_sata.c
@@ -71,7 +71,7 @@
/* try to recognize storage devices immediately */
scsi_scan(false);
- stor_dev = blk_get_devnum_by_type(UCLASS_SCSI, 0);
+ stor_dev = blk_get_devnum_by_uclass_id(UCLASS_SCSI, 0);
if (!stor_dev)
return -ENODEV;
diff --git a/common/spl/spl_usb.c b/common/spl/spl_usb.c
index 63c00f8..479e2dc 100644
--- a/common/spl/spl_usb.c
+++ b/common/spl/spl_usb.c
@@ -41,7 +41,7 @@
/* try to recognize storage devices immediately */
usb_stor_curr_dev = usb_stor_scan(1);
- stor_dev = blk_get_devnum_by_type(UCLASS_USB, usb_stor_curr_dev);
+ stor_dev = blk_get_devnum_by_uclass_id(UCLASS_USB, usb_stor_curr_dev);
if (!stor_dev)
return -ENODEV;
diff --git a/common/stdio.c b/common/stdio.c
index 92161a0..1308384 100644
--- a/common/stdio.c
+++ b/common/stdio.c
@@ -87,6 +87,13 @@
serial_puts(s);
}
+#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
+static void stdio_serial_flush(struct stdio_dev *dev)
+{
+ serial_flush();
+}
+#endif
+
static int stdio_serial_getc(struct stdio_dev *dev)
{
return serial_getc();
@@ -112,6 +119,7 @@
dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT;
dev.putc = stdio_serial_putc;
dev.puts = stdio_serial_puts;
+ STDIO_DEV_ASSIGN_FLUSH(&dev, stdio_serial_flush);
dev.getc = stdio_serial_getc;
dev.tstc = stdio_serial_tstc;
stdio_register (&dev);
diff --git a/common/usb_storage.c b/common/usb_storage.c
index 7d42016..e59c819 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -279,7 +279,7 @@
blkdev = &usb_dev_desc[usb_max_devs];
memset(blkdev, '\0', sizeof(struct blk_desc));
- blkdev->if_type = UCLASS_USB;
+ blkdev->uclass_id = UCLASS_USB;
blkdev->devnum = usb_max_devs;
blkdev->part_type = PART_TYPE_UNKNOWN;
blkdev->target = 0xff;
@@ -1577,8 +1577,8 @@
};
#else
U_BOOT_LEGACY_BLK(usb) = {
- .if_typename = "usb",
- .if_type = UCLASS_USB,
+ .uclass_idname = "usb",
+ .uclass_id = UCLASS_USB,
.max_devs = USB_MAX_STOR_DEV,
.desc = usb_dev_desc,
};
diff --git a/configs/ae350_rv32_spl_defconfig b/configs/ae350_rv32_spl_defconfig
index 9b79cc4..1cc98a2 100644
--- a/configs/ae350_rv32_spl_defconfig
+++ b/configs/ae350_rv32_spl_defconfig
@@ -48,3 +48,4 @@
CONFIG_SPI=y
CONFIG_ATCSPI200_SPI=y
# CONFIG_BINMAN_FDT is not set
+# CONFIG_AVAILABLE_HARTS is not set
diff --git a/configs/ae350_rv32_spl_xip_defconfig b/configs/ae350_rv32_spl_xip_defconfig
index c7b6ea4..67c1e35 100644
--- a/configs/ae350_rv32_spl_xip_defconfig
+++ b/configs/ae350_rv32_spl_xip_defconfig
@@ -11,7 +11,7 @@
CONFIG_SYS_LOAD_ADDR=0x100000
CONFIG_TARGET_AX25_AE350=y
CONFIG_RISCV_SMODE=y
-CONFIG_XIP=y
+CONFIG_SPL_XIP=y
CONFIG_DISTRO_DEFAULTS=y
CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xffff00
diff --git a/configs/ae350_rv64_spl_defconfig b/configs/ae350_rv64_spl_defconfig
index 4c33ca2..4318300 100644
--- a/configs/ae350_rv64_spl_defconfig
+++ b/configs/ae350_rv64_spl_defconfig
@@ -49,3 +49,4 @@
CONFIG_SPI=y
CONFIG_ATCSPI200_SPI=y
# CONFIG_BINMAN_FDT is not set
+# CONFIG_AVAILABLE_HARTS is not set
diff --git a/configs/ae350_rv64_spl_xip_defconfig b/configs/ae350_rv64_spl_xip_defconfig
index a197c97..baee9bf 100644
--- a/configs/ae350_rv64_spl_xip_defconfig
+++ b/configs/ae350_rv64_spl_xip_defconfig
@@ -12,7 +12,7 @@
CONFIG_TARGET_AX25_AE350=y
CONFIG_ARCH_RV64I=y
CONFIG_RISCV_SMODE=y
-CONFIG_XIP=y
+CONFIG_SPL_XIP=y
CONFIG_DISTRO_DEFAULTS=y
CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xfffe70
diff --git a/configs/kontron-sl-mx8mm_defconfig b/configs/kontron-sl-mx8mm_defconfig
index 5387f65..f8589b0 100644
--- a/configs/kontron-sl-mx8mm_defconfig
+++ b/configs/kontron-sl-mx8mm_defconfig
@@ -39,7 +39,6 @@
CONFIG_SYS_SPL_MALLOC_SIZE=0x80000
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x300
-# CONFIG_SPL_FIT_IMAGE_TINY is not set
CONFIG_SPL_I2C=y
CONFIG_SPL_DM_SPI_FLASH=y
CONFIG_SPL_POWER=y
diff --git a/configs/mt7981_emmc_rfb_defconfig b/configs/mt7981_emmc_rfb_defconfig
new file mode 100644
index 0000000..5f9f6d8
--- /dev/null
+++ b/configs/mt7981_emmc_rfb_defconfig
@@ -0,0 +1,64 @@
+CONFIG_ARM=y
+CONFIG_POSITION_INDEPENDENT=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_SYS_TEXT_BASE=0x41e00000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x80000
+CONFIG_ENV_OFFSET=0x300000
+CONFIG_DEFAULT_DEVICE_TREE="mt7981-emmc-rfb"
+CONFIG_TARGET_MT7981=y
+CONFIG_DEBUG_UART_BASE=0x11002000
+CONFIG_DEBUG_UART_CLOCK=40000000
+CONFIG_SYS_LOAD_ADDR=0x46000000
+CONFIG_DEBUG_UART=y
+# CONFIG_AUTOBOOT is not set
+CONFIG_DEFAULT_FDT_FILE="mt7981-emmc-rfb"
+CONFIG_LOGLEVEL=7
+CONFIG_LOG=y
+CONFIG_SYS_PROMPT="MT7981> "
+CONFIG_SYS_CBSIZE=512
+CONFIG_SYS_PBSIZE=1049
+# CONFIG_BOOTM_NETBSD is not set
+# CONFIG_BOOTM_PLAN9 is not set
+# CONFIG_BOOTM_RTEMS is not set
+# CONFIG_BOOTM_VXWORKS is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_UNLZ4 is not set
+# CONFIG_CMD_UNZIP is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_GPT_RENAME=y
+CONFIG_CMD_LSBLK=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PART=y
+CONFIG_CMD_READ=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_SMC=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_PARTITION_TYPE_GUID=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_MMC_MTK=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_ETH=y
+CONFIG_MEDIATEK_ETH=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_MT7981=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_MTK_POWER_DOMAIN=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_SERIAL=y
+CONFIG_MTK_SERIAL=y
+CONFIG_FAT_WRITE=y
+CONFIG_HEXDUMP=y
+# CONFIG_EFI_LOADER is not set
diff --git a/configs/mt7981_rfb_defconfig b/configs/mt7981_rfb_defconfig
new file mode 100644
index 0000000..88299e3
--- /dev/null
+++ b/configs/mt7981_rfb_defconfig
@@ -0,0 +1,69 @@
+CONFIG_ARM=y
+CONFIG_POSITION_INDEPENDENT=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_SYS_TEXT_BASE=0x41e00000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_DEFAULT_DEVICE_TREE="mt7981-rfb"
+CONFIG_TARGET_MT7981=y
+CONFIG_DEBUG_UART_BASE=0x11002000
+CONFIG_DEBUG_UART_CLOCK=40000000
+CONFIG_SYS_LOAD_ADDR=0x46000000
+CONFIG_DEBUG_UART=y
+# CONFIG_AUTOBOOT is not set
+CONFIG_DEFAULT_FDT_FILE="mt7981-rfb"
+CONFIG_LOGLEVEL=7
+CONFIG_LOG=y
+CONFIG_SYS_PROMPT="MT7981> "
+CONFIG_SYS_CBSIZE=512
+CONFIG_SYS_PBSIZE=1049
+# CONFIG_BOOTM_NETBSD is not set
+# CONFIG_BOOTM_PLAN9 is not set
+# CONFIG_BOOTM_RTEMS is not set
+# CONFIG_BOOTM_VXWORKS is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_UNLZ4 is not set
+# CONFIG_CMD_UNZIP is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_MTD=y
+CONFIG_CMD_SF_TEST=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_SMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_BLK=y
+CONFIG_HAVE_BLOCK_DEVICE=y
+CONFIG_CLK=y
+# CONFIG_MMC is not set
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_MTD_SPI_NAND=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_EON=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_ISSI=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_XMC=y
+CONFIG_SPI_FLASH_XTX=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_ETH=y
+CONFIG_MEDIATEK_ETH=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_MT7981=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_MTK_POWER_DOMAIN=y
+CONFIG_DM_SERIAL=y
+CONFIG_MTK_SERIAL=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_MTK_SPIM=y
+CONFIG_HEXDUMP=y
+# CONFIG_EFI_LOADER is not set
diff --git a/configs/mt7981_sd_rfb_defconfig b/configs/mt7981_sd_rfb_defconfig
new file mode 100644
index 0000000..b5c765b
--- /dev/null
+++ b/configs/mt7981_sd_rfb_defconfig
@@ -0,0 +1,64 @@
+CONFIG_ARM=y
+CONFIG_POSITION_INDEPENDENT=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_SYS_TEXT_BASE=0x41e00000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x80000
+CONFIG_ENV_OFFSET=0x300000
+CONFIG_DEFAULT_DEVICE_TREE="mt7981-sd-rfb"
+CONFIG_TARGET_MT7981=y
+CONFIG_DEBUG_UART_BASE=0x11002000
+CONFIG_DEBUG_UART_CLOCK=40000000
+CONFIG_SYS_LOAD_ADDR=0x46000000
+CONFIG_DEBUG_UART=y
+# CONFIG_AUTOBOOT is not set
+CONFIG_DEFAULT_FDT_FILE="mt7981-sd-rfb"
+CONFIG_LOGLEVEL=7
+CONFIG_LOG=y
+CONFIG_SYS_PROMPT="MT7981> "
+CONFIG_SYS_CBSIZE=512
+CONFIG_SYS_PBSIZE=1049
+# CONFIG_BOOTM_NETBSD is not set
+# CONFIG_BOOTM_PLAN9 is not set
+# CONFIG_BOOTM_RTEMS is not set
+# CONFIG_BOOTM_VXWORKS is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_UNLZ4 is not set
+# CONFIG_CMD_UNZIP is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_GPT_RENAME=y
+CONFIG_CMD_LSBLK=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PART=y
+CONFIG_CMD_READ=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_SMC=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_PARTITION_TYPE_GUID=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_MMC_MTK=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_ETH=y
+CONFIG_MEDIATEK_ETH=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_MT7981=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_MTK_POWER_DOMAIN=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_SERIAL=y
+CONFIG_MTK_SERIAL=y
+CONFIG_FAT_WRITE=y
+CONFIG_HEXDUMP=y
+# CONFIG_EFI_LOADER is not set
diff --git a/configs/mt7986_rfb_defconfig b/configs/mt7986_rfb_defconfig
new file mode 100644
index 0000000..ff1e63b
--- /dev/null
+++ b/configs/mt7986_rfb_defconfig
@@ -0,0 +1,66 @@
+CONFIG_ARM=y
+CONFIG_POSITION_INDEPENDENT=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_SYS_TEXT_BASE=0x41e00000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_DEFAULT_DEVICE_TREE="mt7986a-rfb"
+CONFIG_TARGET_MT7986=y
+CONFIG_DEBUG_UART_BASE=0x11002000
+CONFIG_DEBUG_UART_CLOCK=40000000
+CONFIG_SYS_LOAD_ADDR=0x46000000
+CONFIG_DEBUG_UART=y
+# CONFIG_AUTOBOOT is not set
+CONFIG_DEFAULT_FDT_FILE="mt7986a-rfb"
+CONFIG_LOGLEVEL=7
+CONFIG_LOG=y
+CONFIG_SYS_PROMPT="MT7986> "
+CONFIG_SYS_CBSIZE=512
+CONFIG_SYS_PBSIZE=1049
+# CONFIG_BOOTM_NETBSD is not set
+# CONFIG_BOOTM_PLAN9 is not set
+# CONFIG_BOOTM_RTEMS is not set
+# CONFIG_BOOTM_VXWORKS is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_UNLZ4 is not set
+# CONFIG_CMD_UNZIP is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_MTD=y
+CONFIG_CMD_SF_TEST=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_SMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+# CONFIG_MMC is not set
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_MTD_SPI_NAND=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_EON=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_ISSI=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_XMC=y
+CONFIG_SPI_FLASH_XTX=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_ETH=y
+CONFIG_MEDIATEK_ETH=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_MT7986=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_MTK_POWER_DOMAIN=y
+CONFIG_DM_SERIAL=y
+CONFIG_MTK_SERIAL=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_MTK_SPIM=y
+CONFIG_HEXDUMP=y
diff --git a/configs/mt7986a_bpir3_emmc_defconfig b/configs/mt7986a_bpir3_emmc_defconfig
new file mode 100644
index 0000000..3e368b6
--- /dev/null
+++ b/configs/mt7986a_bpir3_emmc_defconfig
@@ -0,0 +1,64 @@
+CONFIG_ARM=y
+CONFIG_POSITION_INDEPENDENT=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_SYS_TEXT_BASE=0x41e00000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x80000
+CONFIG_ENV_OFFSET=0x300000
+CONFIG_DEFAULT_DEVICE_TREE="mt7986a-emmc-rfb"
+CONFIG_TARGET_MT7986=y
+CONFIG_DEBUG_UART_BASE=0x11002000
+CONFIG_DEBUG_UART_CLOCK=40000000
+CONFIG_SYS_LOAD_ADDR=0x46000000
+CONFIG_DEBUG_UART=y
+# CONFIG_AUTOBOOT is not set
+CONFIG_DEFAULT_FDT_FILE="mt7986a-emmc-rfb"
+CONFIG_LOGLEVEL=7
+CONFIG_LOG=y
+CONFIG_SYS_PROMPT="MT7986> "
+CONFIG_SYS_CBSIZE=512
+CONFIG_SYS_PBSIZE=1049
+# CONFIG_BOOTM_NETBSD is not set
+# CONFIG_BOOTM_PLAN9 is not set
+# CONFIG_BOOTM_RTEMS is not set
+# CONFIG_BOOTM_VXWORKS is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_UNLZ4 is not set
+# CONFIG_CMD_UNZIP is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_GPT_RENAME=y
+CONFIG_CMD_LSBLK=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PART=y
+CONFIG_CMD_READ=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_SMC=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_PARTITION_TYPE_GUID=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_MMC_MTK=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_ETH=y
+CONFIG_MEDIATEK_ETH=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_MT7986=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_MTK_POWER_DOMAIN=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_SERIAL=y
+CONFIG_MTK_SERIAL=y
+CONFIG_FAT_WRITE=y
+CONFIG_HEXDUMP=y
+# CONFIG_EFI_LOADER is not set
diff --git a/configs/mt7986a_bpir3_sd_defconfig b/configs/mt7986a_bpir3_sd_defconfig
new file mode 100644
index 0000000..b9a69a3
--- /dev/null
+++ b/configs/mt7986a_bpir3_sd_defconfig
@@ -0,0 +1,64 @@
+CONFIG_ARM=y
+CONFIG_POSITION_INDEPENDENT=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_SYS_TEXT_BASE=0x41e00000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x80000
+CONFIG_ENV_OFFSET=0x300000
+CONFIG_DEFAULT_DEVICE_TREE="mt7986a-sd-rfb"
+CONFIG_TARGET_MT7986=y
+CONFIG_DEBUG_UART_BASE=0x11002000
+CONFIG_DEBUG_UART_CLOCK=40000000
+CONFIG_SYS_LOAD_ADDR=0x46000000
+CONFIG_DEBUG_UART=y
+# CONFIG_AUTOBOOT is not set
+CONFIG_DEFAULT_FDT_FILE="mt7986a-sd-rfb"
+CONFIG_LOGLEVEL=7
+CONFIG_LOG=y
+CONFIG_SYS_PROMPT="MT7986> "
+CONFIG_SYS_CBSIZE=512
+CONFIG_SYS_PBSIZE=1049
+# CONFIG_BOOTM_NETBSD is not set
+# CONFIG_BOOTM_PLAN9 is not set
+# CONFIG_BOOTM_RTEMS is not set
+# CONFIG_BOOTM_VXWORKS is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_UNLZ4 is not set
+# CONFIG_CMD_UNZIP is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_GPT_RENAME=y
+CONFIG_CMD_LSBLK=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PART=y
+CONFIG_CMD_READ=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_SMC=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_PARTITION_TYPE_GUID=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_MMC_MTK=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_ETH=y
+CONFIG_MEDIATEK_ETH=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_MT7986=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_MTK_POWER_DOMAIN=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_SERIAL=y
+CONFIG_MTK_SERIAL=y
+CONFIG_FAT_WRITE=y
+CONFIG_HEXDUMP=y
+# CONFIG_EFI_LOADER is not set
diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig
index 9a1b6e4..b20b181 100644
--- a/configs/sandbox64_defconfig
+++ b/configs/sandbox64_defconfig
@@ -104,7 +104,6 @@
CONFIG_DEBUG_DEVRES=y
CONFIG_ADC=y
CONFIG_ADC_SANDBOX=y
-CONFIG_SYS_SATA_MAX_DEVICE=2
CONFIG_AXI=y
CONFIG_AXI_SANDBOX=y
CONFIG_SYS_IDE_MAXBUS=1
@@ -203,6 +202,8 @@
CONFIG_SANDBOX_RESET=y
CONFIG_DM_RTC=y
CONFIG_RTC_RV8803=y
+CONFIG_SCSI=y
+CONFIG_DM_SCSI=y
CONFIG_SANDBOX_SERIAL=y
CONFIG_SMEM=y
CONFIG_SANDBOX_SMEM=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index caecb50..df6a28e 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -137,7 +137,6 @@
CONFIG_SIMPLE_PM_BUS=y
CONFIG_ADC=y
CONFIG_ADC_SANDBOX=y
-CONFIG_SYS_SATA_MAX_DEVICE=2
CONFIG_AXI=y
CONFIG_AXI_SANDBOX=y
CONFIG_SYS_IDE_MAXBUS=1
@@ -264,9 +263,7 @@
CONFIG_DM_RTC=y
CONFIG_RTC_RV8803=y
CONFIG_SCSI=y
-CONFIG_SCSI_AHCI_PLAT=y
-CONFIG_SYS_SCSI_MAX_SCSI_ID=8
-CONFIG_SYS_SCSI_MAX_LUN=4
+CONFIG_DM_SCSI=y
CONFIG_SANDBOX_SERIAL=y
CONFIG_SMEM=y
CONFIG_SANDBOX_SMEM=y
diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig
index 4b18c24..a2eb7af 100644
--- a/configs/sandbox_flattree_defconfig
+++ b/configs/sandbox_flattree_defconfig
@@ -85,7 +85,6 @@
CONFIG_DEBUG_DEVRES=y
CONFIG_ADC=y
CONFIG_ADC_SANDBOX=y
-CONFIG_SYS_SATA_MAX_DEVICE=2
CONFIG_AXI=y
CONFIG_AXI_SANDBOX=y
CONFIG_CLK=y
@@ -174,6 +173,8 @@
CONFIG_DM_RESET=y
CONFIG_SANDBOX_RESET=y
CONFIG_DM_RTC=y
+CONFIG_SCSI=y
+CONFIG_DM_SCSI=y
CONFIG_SANDBOX_SERIAL=y
CONFIG_SOUND=y
CONFIG_SOUND_SANDBOX=y
diff --git a/configs/sandbox_noinst_defconfig b/configs/sandbox_noinst_defconfig
index 72c908f..8bf10bb 100644
--- a/configs/sandbox_noinst_defconfig
+++ b/configs/sandbox_noinst_defconfig
@@ -108,7 +108,6 @@
# CONFIG_SPL_SIMPLE_BUS is not set
CONFIG_ADC=y
CONFIG_ADC_SANDBOX=y
-CONFIG_SYS_SATA_MAX_DEVICE=2
CONFIG_AXI=y
CONFIG_AXI_SANDBOX=y
CONFIG_SYS_IDE_MAXBUS=1
@@ -200,6 +199,8 @@
CONFIG_SANDBOX_RESET=y
CONFIG_DM_RTC=y
CONFIG_SPL_DM_RTC=y
+CONFIG_SCSI=y
+CONFIG_DM_SCSI=y
CONFIG_SANDBOX_SERIAL=y
CONFIG_SOUND=y
CONFIG_SOUND_SANDBOX=y
diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig
index 11b9aa8..c33f171 100644
--- a/configs/sandbox_spl_defconfig
+++ b/configs/sandbox_spl_defconfig
@@ -109,7 +109,6 @@
# CONFIG_SPL_SIMPLE_BUS is not set
CONFIG_ADC=y
CONFIG_ADC_SANDBOX=y
-CONFIG_SYS_SATA_MAX_DEVICE=2
CONFIG_AXI=y
CONFIG_AXI_SANDBOX=y
CONFIG_SYS_IDE_MAXBUS=1
@@ -203,6 +202,8 @@
CONFIG_SANDBOX_RESET=y
CONFIG_DM_RTC=y
CONFIG_SPL_DM_RTC=y
+CONFIG_SCSI=y
+CONFIG_DM_SCSI=y
CONFIG_SANDBOX_SERIAL=y
CONFIG_SOUND=y
CONFIG_SOUND_SANDBOX=y
diff --git a/configs/sandbox_vpl_defconfig b/configs/sandbox_vpl_defconfig
index c3856a8..be8186e 100644
--- a/configs/sandbox_vpl_defconfig
+++ b/configs/sandbox_vpl_defconfig
@@ -124,7 +124,6 @@
# CONFIG_SPL_SIMPLE_BUS is not set
CONFIG_ADC=y
CONFIG_ADC_SANDBOX=y
-CONFIG_SYS_SATA_MAX_DEVICE=2
CONFIG_AXI=y
CONFIG_AXI_SANDBOX=y
CONFIG_CLK=y
@@ -209,6 +208,8 @@
CONFIG_DM_RTC=y
CONFIG_SPL_DM_RTC=y
CONFIG_TPL_DM_RTC=y
+CONFIG_SCSI=y
+CONFIG_DM_SCSI=y
CONFIG_SANDBOX_SERIAL=y
CONFIG_SOUND=y
CONFIG_SOUND_SANDBOX=y
diff --git a/configs/tools-only_defconfig b/configs/tools-only_defconfig
index 211acc7..2c418f5 100644
--- a/configs/tools-only_defconfig
+++ b/configs/tools-only_defconfig
@@ -18,7 +18,6 @@
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
# CONFIG_NET is not set
# CONFIG_ACPIGEN is not set
-CONFIG_SYS_SATA_MAX_DEVICE=2
CONFIG_AXI=y
CONFIG_AXI_SANDBOX=y
CONFIG_SANDBOX_GPIO=y
diff --git a/disk/disk-uclass.c b/disk/disk-uclass.c
index 9351a5c..551f8b1 100644
--- a/disk/disk-uclass.c
+++ b/disk/disk-uclass.c
@@ -191,12 +191,12 @@
start_in_disk += part->gpt_part_info.start;
}
- if (blkcache_read(block_dev->if_type, block_dev->devnum,
+ if (blkcache_read(block_dev->uclass_id, block_dev->devnum,
start_in_disk, blkcnt, block_dev->blksz, buffer))
return blkcnt;
blks_read = ops->read(dev, start, blkcnt, buffer);
if (blks_read == blkcnt)
- blkcache_fill(block_dev->if_type, block_dev->devnum,
+ blkcache_fill(block_dev->uclass_id, block_dev->devnum,
start_in_disk, blkcnt, block_dev->blksz, buffer);
return blks_read;
@@ -216,7 +216,7 @@
if (!ops->write)
return -ENOSYS;
- blkcache_invalidate(block_dev->if_type, block_dev->devnum);
+ blkcache_invalidate(block_dev->uclass_id, block_dev->devnum);
return ops->write(dev, start, blkcnt, buffer);
}
@@ -235,7 +235,7 @@
if (!ops->erase)
return -ENOSYS;
- blkcache_invalidate(block_dev->if_type, block_dev->devnum);
+ blkcache_invalidate(block_dev->uclass_id, block_dev->devnum);
return ops->erase(dev, start, blkcnt);
}
diff --git a/disk/part.c b/disk/part.c
index 47214c0..f982b30 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -61,7 +61,7 @@
if (!blk_enabled())
return NULL;
- dev_desc = blk_get_devnum_by_typename(ifname, dev);
+ dev_desc = blk_get_devnum_by_uclass_idname(ifname, dev);
if (!dev_desc) {
debug("%s: No device for iface '%s', dev %d\n", __func__,
ifname, dev);
@@ -120,7 +120,7 @@
return;
}
- switch (dev_desc->if_type) {
+ switch (dev_desc->uclass_id) {
case UCLASS_SCSI:
printf ("(%d:%d) Vendor: %s Prod.: %s Rev: %s\n",
dev_desc->target,dev_desc->lun,
@@ -155,7 +155,7 @@
puts("device type unknown\n");
return;
default:
- printf("Unhandled device type: %i\n", dev_desc->if_type);
+ printf("Unhandled device type: %i\n", dev_desc->uclass_id);
return;
}
puts (" Type: ");
@@ -225,7 +225,7 @@
const int n_ents = ll_entry_count(struct part_driver, part_driver);
struct part_driver *entry;
- blkcache_invalidate(dev_desc->if_type, dev_desc->devnum);
+ blkcache_invalidate(dev_desc->uclass_id, dev_desc->devnum);
dev_desc->part_type = PART_TYPE_UNKNOWN;
for (entry = drv; entry != drv + n_ents; entry++) {
@@ -248,7 +248,7 @@
CONFIG_IS_ENABLED(AMIGA_PARTITION) || \
CONFIG_IS_ENABLED(EFI_PARTITION)
puts ("\nPartition Map for ");
- switch (dev_desc->if_type) {
+ switch (dev_desc->uclass_id) {
case UCLASS_IDE:
puts ("IDE");
break;
@@ -408,7 +408,7 @@
* Always should be done, otherwise hw partition 0 will return
* stale data after displaying a non-zero hw partition.
*/
- if ((*dev_desc)->if_type == UCLASS_MMC)
+ if ((*dev_desc)->uclass_id == UCLASS_MMC)
part_init(*dev_desc);
}
@@ -762,7 +762,7 @@
{
char *devtype;
- switch (dev_desc->if_type) {
+ switch (dev_desc->uclass_id) {
case UCLASS_IDE:
case UCLASS_AHCI:
devtype = "hd";
diff --git a/doc/imx/habv4/csf_examples/mx8m/csf.sh b/doc/imx/habv4/csf_examples/mx8m/csf.sh
index 6898513..7d267a7 100644
--- a/doc/imx/habv4/csf_examples/mx8m/csf.sh
+++ b/doc/imx/habv4/csf_examples/mx8m/csf.sh
@@ -40,7 +40,7 @@
# fitImage tree
fit_block_base=$(printf "0x%x" $(( $(sed -n "/CONFIG_SYS_TEXT_BASE=/ s@.*=@@p" .config) - $(sed -n "/CONFIG_FIT_EXTERNAL_OFFSET=/ s@.*=@@p" .config) - 0x200 - 0x40)) )
fit_block_offset=$(printf "0x%s" $(fdtget -t x u-boot.dtb /binman/imx-boot/uboot offset))
-fit_block_size=$(printf "0x%x" $(( ( $(fdtdump u-boot.itb 2>/dev/null | sed -n "/^...totalsize:/ s@.*\(0x[0-9a-f]\+\).*@\1@p") + 0x1000 - 0x1 ) & ~(0x1000 - 0x1) + 0x20 )) )
+fit_block_size=$(printf "0x%x" $(( ( ($(fdtdump u-boot.itb 2>/dev/null | sed -n "/^...totalsize:/ s@.*\(0x[0-9a-f]\+\).*@\1@p") + 0x1000 - 0x1 ) & ~(0x1000 - 0x1)) + 0x20 )) )
sed -i "/Blocks = / s@.*@ Blocks = $fit_block_base $fit_block_offset $fit_block_size \"flash.bin\", \\\\@" csf_fit.tmp
# U-Boot
diff --git a/doc/usage/partitions.rst b/doc/usage/partitions.rst
index 2c1a12b..628469b 100644
--- a/doc/usage/partitions.rst
+++ b/doc/usage/partitions.rst
@@ -20,7 +20,7 @@
interface
The interface used to access the partition's device, like ``mmc`` or
``scsi``. For a full list of supported interfaces, consult the
- ``if_typename_str`` array in ``drivers/block/blk-uclass.c``
+ ``uclass_idname_str`` array in ``drivers/block/blk-uclass.c``
devnum
The device number. This defaults to 0.
diff --git a/drivers/ata/sata.c b/drivers/ata/sata.c
index 604c721..ce3e9b5 100644
--- a/drivers/ata/sata.c
+++ b/drivers/ata/sata.c
@@ -79,7 +79,7 @@
for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; i++) {
memset(&sata_dev_desc[i], 0, sizeof(struct blk_desc));
- sata_dev_desc[i].if_type = UCLASS_AHCI;
+ sata_dev_desc[i].uclass_id = UCLASS_AHCI;
sata_dev_desc[i].devnum = i;
sata_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
sata_dev_desc[i].type = DEV_TYPE_HARDDISK;
diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c
index a9a85aa..7d12d54 100644
--- a/drivers/block/blk-uclass.c
+++ b/drivers/block/blk-uclass.c
@@ -20,7 +20,7 @@
static struct {
enum uclass_id id;
const char *name;
-} if_typename_str[] = {
+} uclass_idname_str[] = {
{ UCLASS_IDE, "ide" },
{ UCLASS_SCSI, "scsi" },
{ UCLASS_USB, "usb" },
@@ -34,19 +34,19 @@
{ UCLASS_PVBLOCK, "pvblock" },
};
-static enum uclass_id if_typename_to_iftype(const char *if_typename)
+static enum uclass_id uclass_name_to_iftype(const char *uclass_idname)
{
int i;
- for (i = 0; i < ARRAY_SIZE(if_typename_str); i++) {
- if (!strcmp(if_typename, if_typename_str[i].name))
- return if_typename_str[i].id;
+ for (i = 0; i < ARRAY_SIZE(uclass_idname_str); i++) {
+ if (!strcmp(uclass_idname, uclass_idname_str[i].name))
+ return uclass_idname_str[i].id;
}
return UCLASS_INVALID;
}
-static enum uclass_id if_type_to_uclass_id(enum uclass_id if_type)
+static enum uclass_id conv_uclass_id(enum uclass_id uclass_id)
{
/*
* This strange adjustment is used because we use UCLASS_MASS_STORAGE
@@ -65,31 +65,30 @@
* - rename UCLASS_USB name to "usb_ctlr"
* - use UCLASS_MASS_STORAGE instead of UCLASS_USB in if_typename_str
*/
- if (if_type == UCLASS_USB)
+ if (uclass_id == UCLASS_USB)
return UCLASS_MASS_STORAGE;
-
- return if_type;
+ return uclass_id;
}
-const char *blk_get_if_type_name(enum uclass_id if_type)
+const char *blk_get_uclass_name(enum uclass_id uclass_id)
{
int i;
- for (i = 0; i < ARRAY_SIZE(if_typename_str); i++) {
- if (if_typename_str[i].id == if_type)
- return if_typename_str[i].name;
+ for (i = 0; i < ARRAY_SIZE(uclass_idname_str); i++) {
+ if (uclass_idname_str[i].id == uclass_id)
+ return uclass_idname_str[i].name;
}
return "(none)";
}
-struct blk_desc *blk_get_devnum_by_type(enum uclass_id if_type, int devnum)
+struct blk_desc *blk_get_devnum_by_uclass_id(enum uclass_id uclass_id, int devnum)
{
struct blk_desc *desc;
struct udevice *dev;
int ret;
- ret = blk_get_device(if_type, devnum, &dev);
+ ret = blk_get_device(uclass_id, devnum, &dev);
if (ret)
return NULL;
desc = dev_get_uclass_plat(dev);
@@ -102,7 +101,7 @@
* name in a local table. This gives us an interface type which we can match
* against the uclass of the block device's parent.
*/
-struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum)
+struct blk_desc *blk_get_devnum_by_uclass_idname(const char *uclass_idname, int devnum)
{
enum uclass_id uclass_id;
enum uclass_id type;
@@ -110,16 +109,16 @@
struct uclass *uc;
int ret;
- type = if_typename_to_iftype(if_typename);
+ type = uclass_name_to_iftype(uclass_idname);
if (type == UCLASS_INVALID) {
debug("%s: Unknown interface type '%s'\n", __func__,
- if_typename);
+ uclass_idname);
return NULL;
}
- uclass_id = if_type_to_uclass_id(type);
+ uclass_id = conv_uclass_id(type);
if (uclass_id == UCLASS_INVALID) {
debug("%s: Unknown uclass for interface type'\n",
- blk_get_if_type_name(type));
+ blk_get_uclass_name(type));
return NULL;
}
@@ -129,8 +128,8 @@
uclass_foreach_dev(dev, uc) {
struct blk_desc *desc = dev_get_uclass_plat(dev);
- debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__,
- type, devnum, dev->name, desc->if_type, desc->devnum);
+ debug("%s: uclass_id=%d, devnum=%d: %s, %d, %d\n", __func__,
+ type, devnum, dev->name, desc->uclass_id, desc->devnum);
if (desc->devnum != devnum)
continue;
@@ -178,14 +177,14 @@
/**
* get_desc() - Get the block device descriptor for the given device number
*
- * @if_type: Interface type
+ * @uclass_id: Interface type
* @devnum: Device number (0 = first)
* @descp: Returns block device descriptor on success
* Return: 0 on success, -ENODEV if there is no such device and no device
* with a higher device number, -ENOENT if there is no such device but there
* is one with a higher number, or other -ve on other error.
*/
-static int get_desc(enum uclass_id if_type, int devnum, struct blk_desc **descp)
+static int get_desc(enum uclass_id uclass_id, int devnum, struct blk_desc **descp)
{
bool found_more = false;
struct udevice *dev;
@@ -199,9 +198,9 @@
uclass_foreach_dev(dev, uc) {
struct blk_desc *desc = dev_get_uclass_plat(dev);
- debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__,
- if_type, devnum, dev->name, desc->if_type, desc->devnum);
- if (desc->if_type == if_type) {
+ debug("%s: uclass_id=%d, devnum=%d: %s, %d, %d\n", __func__,
+ uclass_id, devnum, dev->name, desc->uclass_id, desc->devnum);
+ if (desc->uclass_id == uclass_id) {
if (desc->devnum == devnum) {
ret = device_probe(dev);
if (ret)
@@ -218,26 +217,26 @@
return found_more ? -ENOENT : -ENODEV;
}
-int blk_select_hwpart_devnum(enum uclass_id if_type, int devnum, int hwpart)
+int blk_select_hwpart_devnum(enum uclass_id uclass_id, int devnum, int hwpart)
{
struct udevice *dev;
int ret;
- ret = blk_get_device(if_type, devnum, &dev);
+ ret = blk_get_device(uclass_id, devnum, &dev);
if (ret)
return ret;
return blk_select_hwpart(dev, hwpart);
}
-int blk_list_part(enum uclass_id if_type)
+int blk_list_part(enum uclass_id uclass_id)
{
struct blk_desc *desc;
int devnum, ok;
int ret;
for (ok = 0, devnum = 0;; ++devnum) {
- ret = get_desc(if_type, devnum, &desc);
+ ret = get_desc(uclass_id, devnum, &desc);
if (ret == -ENODEV)
break;
else if (ret)
@@ -255,12 +254,12 @@
return 0;
}
-int blk_print_part_devnum(enum uclass_id if_type, int devnum)
+int blk_print_part_devnum(enum uclass_id uclass_id, int devnum)
{
struct blk_desc *desc;
int ret;
- ret = get_desc(if_type, devnum, &desc);
+ ret = get_desc(uclass_id, devnum, &desc);
if (ret)
return ret;
if (desc->type == DEV_TYPE_UNKNOWN)
@@ -270,14 +269,14 @@
return 0;
}
-void blk_list_devices(enum uclass_id if_type)
+void blk_list_devices(enum uclass_id uclass_id)
{
struct blk_desc *desc;
int ret;
int i;
for (i = 0;; ++i) {
- ret = get_desc(if_type, i, &desc);
+ ret = get_desc(uclass_id, i, &desc);
if (ret == -ENODEV)
break;
else if (ret)
@@ -289,12 +288,12 @@
}
}
-int blk_print_device_num(enum uclass_id if_type, int devnum)
+int blk_print_device_num(enum uclass_id uclass_id, int devnum)
{
struct blk_desc *desc;
int ret;
- ret = get_desc(if_type, devnum, &desc);
+ ret = get_desc(uclass_id, devnum, &desc);
if (ret)
return ret;
printf("\nIDE device %d: ", devnum);
@@ -303,13 +302,13 @@
return 0;
}
-int blk_show_device(enum uclass_id if_type, int devnum)
+int blk_show_device(enum uclass_id uclass_id, int devnum)
{
struct blk_desc *desc;
int ret;
printf("\nDevice %d: ", devnum);
- ret = get_desc(if_type, devnum, &desc);
+ ret = get_desc(uclass_id, devnum, &desc);
if (ret == -ENODEV || ret == -ENOENT) {
printf("unknown device\n");
return -ENODEV;
@@ -324,14 +323,14 @@
return 0;
}
-ulong blk_read_devnum(enum uclass_id if_type, int devnum, lbaint_t start,
+ulong blk_read_devnum(enum uclass_id uclass_id, int devnum, lbaint_t start,
lbaint_t blkcnt, void *buffer)
{
struct blk_desc *desc;
ulong n;
int ret;
- ret = get_desc(if_type, devnum, &desc);
+ ret = get_desc(uclass_id, devnum, &desc);
if (ret)
return ret;
n = blk_dread(desc, start, blkcnt, buffer);
@@ -341,13 +340,13 @@
return n;
}
-ulong blk_write_devnum(enum uclass_id if_type, int devnum, lbaint_t start,
+ulong blk_write_devnum(enum uclass_id uclass_id, int devnum, lbaint_t start,
lbaint_t blkcnt, const void *buffer)
{
struct blk_desc *desc;
int ret;
- ret = get_desc(if_type, devnum, &desc);
+ ret = get_desc(uclass_id, devnum, &desc);
if (ret)
return ret;
return blk_dwrite(desc, start, blkcnt, buffer);
@@ -370,7 +369,7 @@
return blk_select_hwpart(desc->bdev, hwpart);
}
-int blk_first_device(int if_type, struct udevice **devp)
+int blk_first_device(int uclass_id, struct udevice **devp)
{
struct blk_desc *desc;
int ret;
@@ -382,7 +381,7 @@
return -ENODEV;
do {
desc = dev_get_uclass_plat(*devp);
- if (desc->if_type == if_type)
+ if (desc->uclass_id == uclass_id)
return 0;
ret = uclass_find_next_device(devp);
if (ret)
@@ -395,10 +394,10 @@
int blk_next_device(struct udevice **devp)
{
struct blk_desc *desc;
- int ret, if_type;
+ int ret, uclass_id;
desc = dev_get_uclass_plat(*devp);
- if_type = desc->if_type;
+ uclass_id = desc->uclass_id;
do {
ret = uclass_find_next_device(devp);
if (ret)
@@ -406,12 +405,12 @@
if (!*devp)
return -ENODEV;
desc = dev_get_uclass_plat(*devp);
- if (desc->if_type == if_type)
+ if (desc->uclass_id == uclass_id)
return 0;
} while (1);
}
-int blk_find_device(int if_type, int devnum, struct udevice **devp)
+int blk_find_device(int uclass_id, int devnum, struct udevice **devp)
{
struct uclass *uc;
struct udevice *dev;
@@ -423,9 +422,9 @@
uclass_foreach_dev(dev, uc) {
struct blk_desc *desc = dev_get_uclass_plat(dev);
- debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__,
- if_type, devnum, dev->name, desc->if_type, desc->devnum);
- if (desc->if_type == if_type && desc->devnum == devnum) {
+ debug("%s: uclass_id=%d, devnum=%d: %s, %d, %d\n", __func__,
+ uclass_id, devnum, dev->name, desc->uclass_id, desc->devnum);
+ if (desc->uclass_id == uclass_id && desc->devnum == devnum) {
*devp = dev;
return 0;
}
@@ -434,11 +433,11 @@
return -ENODEV;
}
-int blk_get_device(int if_type, int devnum, struct udevice **devp)
+int blk_get_device(int uclass_id, int devnum, struct udevice **devp)
{
int ret;
- ret = blk_find_device(if_type, devnum, devp);
+ ret = blk_find_device(uclass_id, devnum, devp);
if (ret)
return ret;
@@ -455,12 +454,12 @@
if (!ops->read)
return -ENOSYS;
- if (blkcache_read(block_dev->if_type, block_dev->devnum,
+ if (blkcache_read(block_dev->uclass_id, block_dev->devnum,
start, blkcnt, block_dev->blksz, buffer))
return blkcnt;
blks_read = ops->read(dev, start, blkcnt, buffer);
if (blks_read == blkcnt)
- blkcache_fill(block_dev->if_type, block_dev->devnum,
+ blkcache_fill(block_dev->uclass_id, block_dev->devnum,
start, blkcnt, block_dev->blksz, buffer);
return blks_read;
@@ -475,7 +474,7 @@
if (!ops->write)
return -ENOSYS;
- blkcache_invalidate(block_dev->if_type, block_dev->devnum);
+ blkcache_invalidate(block_dev->uclass_id, block_dev->devnum);
return ops->write(dev, start, blkcnt, buffer);
}
@@ -488,7 +487,7 @@
if (!ops->erase)
return -ENOSYS;
- blkcache_invalidate(block_dev->if_type, block_dev->devnum);
+ blkcache_invalidate(block_dev->uclass_id, block_dev->devnum);
return ops->erase(dev, start, blkcnt);
}
@@ -525,7 +524,7 @@
return uclass_get_name(device_get_uclass_id(parent));
};
-int blk_find_max_devnum(enum uclass_id if_type)
+int blk_find_max_devnum(enum uclass_id uclass_id)
{
struct udevice *dev;
int max_devnum = -ENODEV;
@@ -538,18 +537,18 @@
uclass_foreach_dev(dev, uc) {
struct blk_desc *desc = dev_get_uclass_plat(dev);
- if (desc->if_type == if_type && desc->devnum > max_devnum)
+ if (desc->uclass_id == uclass_id && desc->devnum > max_devnum)
max_devnum = desc->devnum;
}
return max_devnum;
}
-int blk_next_free_devnum(enum uclass_id if_type)
+int blk_next_free_devnum(enum uclass_id uclass_id)
{
int ret;
- ret = blk_find_max_devnum(if_type);
+ ret = blk_find_max_devnum(uclass_id);
if (ret == -ENODEV)
return 0;
if (ret < 0)
@@ -631,7 +630,7 @@
return count;
}
-static int blk_claim_devnum(enum uclass_id if_type, int devnum)
+static int blk_claim_devnum(enum uclass_id uclass_id, int devnum)
{
struct udevice *dev;
struct uclass *uc;
@@ -643,8 +642,8 @@
uclass_foreach_dev(dev, uc) {
struct blk_desc *desc = dev_get_uclass_plat(dev);
- if (desc->if_type == if_type && desc->devnum == devnum) {
- int next = blk_next_free_devnum(if_type);
+ if (desc->uclass_id == uclass_id && desc->devnum == devnum) {
+ int next = blk_next_free_devnum(uclass_id);
if (next < 0)
return next;
@@ -657,7 +656,7 @@
}
int blk_create_device(struct udevice *parent, const char *drv_name,
- const char *name, int if_type, int devnum, int blksz,
+ const char *name, int uclass_id, int devnum, int blksz,
lbaint_t lba, struct udevice **devp)
{
struct blk_desc *desc;
@@ -665,9 +664,9 @@
int ret;
if (devnum == -1) {
- devnum = blk_next_free_devnum(if_type);
+ devnum = blk_next_free_devnum(uclass_id);
} else {
- ret = blk_claim_devnum(if_type, devnum);
+ ret = blk_claim_devnum(uclass_id, devnum);
if (ret < 0 && ret != -ENOENT)
return ret;
}
@@ -677,7 +676,7 @@
if (ret)
return ret;
desc = dev_get_uclass_plat(dev);
- desc->if_type = if_type;
+ desc->uclass_id = uclass_id;
desc->blksz = blksz;
desc->log2blksz = LOG2(desc->blksz);
desc->lba = lba;
@@ -690,7 +689,7 @@
}
int blk_create_devicef(struct udevice *parent, const char *drv_name,
- const char *name, int if_type, int devnum, int blksz,
+ const char *name, int uclass_id, int devnum, int blksz,
lbaint_t lba, struct udevice **devp)
{
char dev_name[30], *str;
@@ -701,7 +700,7 @@
if (!str)
return -ENOMEM;
- ret = blk_create_device(parent, drv_name, str, if_type, devnum,
+ ret = blk_create_device(parent, drv_name, str, uclass_id, devnum,
blksz, lba, devp);
if (ret) {
free(str);
@@ -725,7 +724,7 @@
return ret;
}
-int blk_unbind_all(int if_type)
+int blk_unbind_all(int uclass_id)
{
struct uclass *uc;
struct udevice *dev, *next;
@@ -737,7 +736,7 @@
uclass_foreach_dev_safe(dev, next, uc) {
struct blk_desc *desc = dev_get_uclass_plat(dev);
- if (desc->if_type == if_type) {
+ if (desc->uclass_id == uclass_id) {
ret = device_remove(dev, DM_REMOVE_NORMAL);
if (ret)
return ret;
diff --git a/drivers/block/blk_legacy.c b/drivers/block/blk_legacy.c
index 8c6f9cb..5bf1d04 100644
--- a/drivers/block/blk_legacy.c
+++ b/drivers/block/blk_legacy.c
@@ -9,14 +9,14 @@
#include <part.h>
#include <linux/err.h>
-struct blk_driver *blk_driver_lookup_type(int if_type)
+struct blk_driver *blk_driver_lookup_type(int uclass_id)
{
struct blk_driver *drv = ll_entry_start(struct blk_driver, blk_driver);
const int n_ents = ll_entry_count(struct blk_driver, blk_driver);
struct blk_driver *entry;
for (entry = drv; entry != drv + n_ents; entry++) {
- if (if_type == entry->if_type)
+ if (uclass_id == entry->uclass_id)
return entry;
}
@@ -24,14 +24,14 @@
return NULL;
}
-static struct blk_driver *blk_driver_lookup_typename(const char *if_typename)
+static struct blk_driver *blk_driver_lookup_typename(const char *uclass_idname)
{
struct blk_driver *drv = ll_entry_start(struct blk_driver, blk_driver);
const int n_ents = ll_entry_count(struct blk_driver, blk_driver);
struct blk_driver *entry;
for (entry = drv; entry != drv + n_ents; entry++) {
- if (!strcmp(if_typename, entry->if_typename))
+ if (!strcmp(uclass_idname, entry->uclass_idname))
return entry;
}
@@ -39,11 +39,11 @@
return NULL;
}
-const char *blk_get_if_type_name(enum uclass_id if_type)
+const char *blk_get_uclass_name(enum uclass_id uclass_id)
{
- struct blk_driver *drv = blk_driver_lookup_type(if_type);
+ struct blk_driver *drv = blk_driver_lookup_type(uclass_id);
- return drv ? drv->if_typename : NULL;
+ return drv ? drv->uclass_idname : NULL;
}
/**
@@ -70,14 +70,14 @@
return drv->get_dev(devnum, descp);
}
-int blk_list_part(enum uclass_id if_type)
+int blk_list_part(enum uclass_id uclass_id)
{
struct blk_driver *drv;
struct blk_desc *desc;
int devnum, ok;
bool first = true;
- drv = blk_driver_lookup_type(if_type);
+ drv = blk_driver_lookup_type(uclass_id);
if (!drv)
return -ENOSYS;
for (ok = 0, devnum = 0; devnum < drv->max_devs; ++devnum) {
@@ -97,9 +97,9 @@
return 0;
}
-int blk_print_part_devnum(enum uclass_id if_type, int devnum)
+int blk_print_part_devnum(enum uclass_id uclass_id, int devnum)
{
- struct blk_driver *drv = blk_driver_lookup_type(if_type);
+ struct blk_driver *drv = blk_driver_lookup_type(uclass_id);
struct blk_desc *desc;
int ret;
@@ -115,9 +115,9 @@
return 0;
}
-void blk_list_devices(enum uclass_id if_type)
+void blk_list_devices(enum uclass_id uclass_id)
{
- struct blk_driver *drv = blk_driver_lookup_type(if_type);
+ struct blk_driver *drv = blk_driver_lookup_type(uclass_id);
struct blk_desc *desc;
int i;
@@ -133,9 +133,9 @@
}
}
-int blk_print_device_num(enum uclass_id if_type, int devnum)
+int blk_print_device_num(enum uclass_id uclass_id, int devnum)
{
- struct blk_driver *drv = blk_driver_lookup_type(if_type);
+ struct blk_driver *drv = blk_driver_lookup_type(uclass_id);
struct blk_desc *desc;
int ret;
@@ -144,15 +144,15 @@
ret = get_desc(drv, devnum, &desc);
if (ret)
return ret;
- printf("\n%s device %d: ", drv->if_typename, devnum);
+ printf("\n%s device %d: ", drv->uclass_idname, devnum);
dev_print(desc);
return 0;
}
-int blk_show_device(enum uclass_id if_type, int devnum)
+int blk_show_device(enum uclass_id uclass_id, int devnum)
{
- struct blk_driver *drv = blk_driver_lookup_type(if_type);
+ struct blk_driver *drv = blk_driver_lookup_type(uclass_id);
struct blk_desc *desc;
int ret;
@@ -174,9 +174,9 @@
return 0;
}
-struct blk_desc *blk_get_devnum_by_type(enum uclass_id if_type, int devnum)
+struct blk_desc *blk_get_devnum_by_uclass_id(enum uclass_id uclass_id, int devnum)
{
- struct blk_driver *drv = blk_driver_lookup_type(if_type);
+ struct blk_driver *drv = blk_driver_lookup_type(uclass_id);
struct blk_desc *desc;
if (!drv)
@@ -190,7 +190,7 @@
int blk_dselect_hwpart(struct blk_desc *desc, int hwpart)
{
- struct blk_driver *drv = blk_driver_lookup_type(desc->if_type);
+ struct blk_driver *drv = blk_driver_lookup_type(desc->uclass_id);
if (!drv)
return -ENOSYS;
@@ -200,9 +200,9 @@
return 0;
}
-struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum)
+struct blk_desc *blk_get_devnum_by_uclass_idname(const char *uclass_idname, int devnum)
{
- struct blk_driver *drv = blk_driver_lookup_typename(if_typename);
+ struct blk_driver *drv = blk_driver_lookup_typename(uclass_idname);
struct blk_desc *desc;
if (!drv)
@@ -214,10 +214,10 @@
return desc;
}
-ulong blk_read_devnum(enum uclass_id if_type, int devnum, lbaint_t start,
+ulong blk_read_devnum(enum uclass_id uclass_id, int devnum, lbaint_t start,
lbaint_t blkcnt, void *buffer)
{
- struct blk_driver *drv = blk_driver_lookup_type(if_type);
+ struct blk_driver *drv = blk_driver_lookup_type(uclass_id);
struct blk_desc *desc;
ulong n;
int ret;
@@ -234,10 +234,10 @@
return n;
}
-ulong blk_write_devnum(enum uclass_id if_type, int devnum, lbaint_t start,
+ulong blk_write_devnum(enum uclass_id uclass_id, int devnum, lbaint_t start,
lbaint_t blkcnt, const void *buffer)
{
- struct blk_driver *drv = blk_driver_lookup_type(if_type);
+ struct blk_driver *drv = blk_driver_lookup_type(uclass_id);
struct blk_desc *desc;
int ret;
@@ -249,9 +249,9 @@
return desc->block_write(desc, start, blkcnt, buffer);
}
-int blk_select_hwpart_devnum(enum uclass_id if_type, int devnum, int hwpart)
+int blk_select_hwpart_devnum(enum uclass_id uclass_id, int devnum, int hwpart)
{
- struct blk_driver *drv = blk_driver_lookup_type(if_type);
+ struct blk_driver *drv = blk_driver_lookup_type(uclass_id);
struct blk_desc *desc;
int ret;
diff --git a/drivers/block/ide.c b/drivers/block/ide.c
index b8840d2..eaa58d8 100644
--- a/drivers/block/ide.c
+++ b/drivers/block/ide.c
@@ -537,7 +537,7 @@
/* Select device
*/
ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
- dev_desc->if_type = UCLASS_IDE;
+ dev_desc->uclass_id = UCLASS_IDE;
#ifdef CONFIG_ATAPI
retries = 0;
@@ -752,7 +752,7 @@
for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; ++i) {
ide_dev_desc[i].type = DEV_TYPE_UNKNOWN;
- ide_dev_desc[i].if_type = UCLASS_IDE;
+ ide_dev_desc[i].uclass_id = UCLASS_IDE;
ide_dev_desc[i].devnum = i;
ide_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
ide_dev_desc[i].blksz = 0;
@@ -1143,8 +1143,8 @@
};
#else
U_BOOT_LEGACY_BLK(ide) = {
- .if_typename = "ide",
- .if_type = UCLASS_IDE,
+ .uclass_idname = "ide",
+ .uclass_id = UCLASS_IDE,
.max_devs = CONFIG_SYS_IDE_MAXDEVICE,
.desc = ide_dev_desc,
};
diff --git a/drivers/block/sandbox.c b/drivers/block/sandbox.c
index 2de12e0..f2aae89 100644
--- a/drivers/block/sandbox.c
+++ b/drivers/block/sandbox.c
@@ -150,7 +150,7 @@
goto err_file;
}
- desc = blk_get_devnum_by_type(UCLASS_ROOT, devnum);
+ desc = blk_get_devnum_by_uclass_id(UCLASS_ROOT, devnum);
desc->removable = removable;
snprintf(desc->vendor, BLK_VEN_SIZE, "U-Boot");
snprintf(desc->product, BLK_PRD_SIZE, "hostfile");
@@ -192,7 +192,7 @@
}
struct blk_desc *blk_dev = &host_dev->blk_dev;
- blk_dev->if_type = UCLASS_ROOT;
+ blk_dev->uclass_id = UCLASS_ROOT;
blk_dev->priv = host_dev;
blk_dev->blksz = 512;
blk_dev->lba = os_lseek(host_dev->fd, 0, OS_SEEK_END) / blk_dev->blksz;
@@ -262,8 +262,8 @@
};
#else
U_BOOT_LEGACY_BLK(sandbox_host) = {
- .if_typename = "host",
- .if_type = UCLASS_ROOT,
+ .uclass_idname = "host",
+ .uclass_id = UCLASS_ROOT,
.max_devs = SANDBOX_HOST_MAX_DEVICES,
.get_dev = host_get_dev_err,
};
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 522e724..1decf31 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -7,6 +7,8 @@
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 0000000..7fcb814
--- /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 <sam.shih@mediatek.com>
+ */
+
+#include <dm.h>
+#include <log.h>
+#include <asm/arch-mediatek/reset.h>
+#include <asm/io.h>
+#include <dt-bindings/clock/mt7981-clk.h>
+#include <linux/bitops.h>
+
+#include "clk-mtk.h"
+
+#define MT7981_CLK_PDN 0x250
+#define MT7981_CLK_PDN_EN_WRITE BIT(31)
+
+#define PLL_FACTOR(_id, _name, _parent, _mult, _div) \
+ FACTOR(_id, _parent, _mult, _div, CLK_PARENT_APMIXED)
+
+#define TOP_FACTOR(_id, _name, _parent, _mult, _div) \
+ FACTOR(_id, _parent, _mult, _div, CLK_PARENT_TOPCKGEN)
+
+#define INFRA_FACTOR(_id, _name, _parent, _mult, _div) \
+ FACTOR(_id, _parent, _mult, _div, CLK_PARENT_INFRASYS)
+
+/* FIXED PLLS */
+static const struct mtk_fixed_clk fixed_pll_clks[] = {
+ FIXED_CLK(CK_APMIXED_ARMPLL, CLK_XTAL, 1300000000),
+ FIXED_CLK(CK_APMIXED_NET2PLL, CLK_XTAL, 800000000),
+ FIXED_CLK(CK_APMIXED_MMPLL, CLK_XTAL, 720000000),
+ FIXED_CLK(CK_APMIXED_SGMPLL, CLK_XTAL, 325000000),
+ FIXED_CLK(CK_APMIXED_WEDMCUPLL, CLK_XTAL, 208000000),
+ FIXED_CLK(CK_APMIXED_NET1PLL, CLK_XTAL, 2500000000),
+ FIXED_CLK(CK_APMIXED_MPLL, CLK_XTAL, 416000000),
+ FIXED_CLK(CK_APMIXED_APLL2, CLK_XTAL, 196608000),
+};
+
+/* TOPCKGEN FIXED CLK */
+static const struct mtk_fixed_clk top_fixed_clks[] = {
+ FIXED_CLK(CK_TOP_CB_CKSQ_40M, CLK_XTAL, 40000000),
+};
+
+/* TOPCKGEN FIXED DIV */
+static const struct mtk_fixed_factor top_fixed_divs[] = {
+ PLL_FACTOR(CK_TOP_CB_M_416M, "cb_m_416m", CK_APMIXED_MPLL, 1, 1),
+ PLL_FACTOR(CK_TOP_CB_M_D2, "cb_m_d2", CK_APMIXED_MPLL, 1, 2),
+ PLL_FACTOR(CK_TOP_CB_M_D3, "cb_m_d3", CK_APMIXED_MPLL, 1, 3),
+ PLL_FACTOR(CK_TOP_M_D3_D2, "m_d3_d2", CK_APMIXED_MPLL, 1, 2),
+ PLL_FACTOR(CK_TOP_CB_M_D4, "cb_m_d4", CK_APMIXED_MPLL, 1, 4),
+ PLL_FACTOR(CK_TOP_CB_M_D8, "cb_m_d8", CK_APMIXED_MPLL, 1, 8),
+ PLL_FACTOR(CK_TOP_M_D8_D2, "m_d8_d2", CK_APMIXED_MPLL, 1, 16),
+ PLL_FACTOR(CK_TOP_CB_MM_720M, "cb_mm_720m", CK_APMIXED_MMPLL, 1, 1),
+ PLL_FACTOR(CK_TOP_CB_MM_D2, "cb_mm_d2", CK_APMIXED_MMPLL, 1, 2),
+ PLL_FACTOR(CK_TOP_CB_MM_D3, "cb_mm_d3", CK_APMIXED_MMPLL, 1, 3),
+ PLL_FACTOR(CK_TOP_CB_MM_D3_D5, "cb_mm_d3_d5", CK_APMIXED_MMPLL, 1, 15),
+ PLL_FACTOR(CK_TOP_CB_MM_D4, "cb_mm_d4", CK_APMIXED_MMPLL, 1, 4),
+ PLL_FACTOR(CK_TOP_CB_MM_D6, "cb_mm_d6", CK_APMIXED_MMPLL, 1, 6),
+ PLL_FACTOR(CK_TOP_MM_D6_D2, "mm_d6_d2", CK_APMIXED_MMPLL, 1, 12),
+ PLL_FACTOR(CK_TOP_CB_MM_D8, "cb_mm_d8", CK_APMIXED_MMPLL, 1, 8),
+ PLL_FACTOR(CK_TOP_CB_APLL2_196M, "cb_apll2_196m", CK_APMIXED_APLL2, 1,
+ 1),
+ PLL_FACTOR(CK_TOP_APLL2_D2, "apll2_d2", CK_APMIXED_APLL2, 1, 2),
+ PLL_FACTOR(CK_TOP_APLL2_D4, "apll2_d4", CK_APMIXED_APLL2, 1, 4),
+ PLL_FACTOR(CK_TOP_NET1_2500M, "net1_2500m", CK_APMIXED_NET1PLL, 1, 1),
+ PLL_FACTOR(CK_TOP_CB_NET1_D4, "cb_net1_d4", CK_APMIXED_NET1PLL, 1, 4),
+ PLL_FACTOR(CK_TOP_CB_NET1_D5, "cb_net1_d5", CK_APMIXED_NET1PLL, 1, 5),
+ PLL_FACTOR(CK_TOP_NET1_D5_D2, "net1_d5_d2", CK_APMIXED_NET1PLL, 1, 10),
+ PLL_FACTOR(CK_TOP_NET1_D5_D4, "net1_d5_d4", CK_APMIXED_NET1PLL, 1, 20),
+ PLL_FACTOR(CK_TOP_CB_NET1_D8, "cb_net1_d8", CK_APMIXED_NET1PLL, 1, 8),
+ PLL_FACTOR(CK_TOP_NET1_D8_D2, "net1_d8_d2", CK_APMIXED_NET1PLL, 1, 16),
+ PLL_FACTOR(CK_TOP_NET1_D8_D4, "net1_d8_d4", CK_APMIXED_NET1PLL, 1, 32),
+ PLL_FACTOR(CK_TOP_CB_NET2_800M, "cb_net2_800m", CK_APMIXED_NET2PLL, 1,
+ 1),
+ PLL_FACTOR(CK_TOP_CB_NET2_D2, "cb_net2_d2", CK_APMIXED_NET2PLL, 1, 2),
+ PLL_FACTOR(CK_TOP_CB_NET2_D4, "cb_net2_d4", CK_APMIXED_NET2PLL, 1, 4),
+ PLL_FACTOR(CK_TOP_NET2_D4_D2, "net2_d4_d2", CK_APMIXED_NET2PLL, 1, 8),
+ PLL_FACTOR(CK_TOP_NET2_D4_D4, "net2_d4_d4", CK_APMIXED_NET2PLL, 1, 16),
+ PLL_FACTOR(CK_TOP_CB_NET2_D6, "cb_net2_d6", CK_APMIXED_NET2PLL, 1, 6),
+ PLL_FACTOR(CK_TOP_CB_WEDMCU_208M, "cb_wedmcu_208m",
+ CK_APMIXED_WEDMCUPLL, 1, 1),
+ PLL_FACTOR(CK_TOP_CB_SGM_325M, "cb_sgm_325m", CK_APMIXED_SGMPLL, 1, 1),
+ TOP_FACTOR(CK_TOP_CKSQ_40M_D2, "cksq_40m_d2", CK_TOP_CB_CKSQ_40M, 1, 2),
+ TOP_FACTOR(CK_TOP_CB_RTC_32K, "cb_rtc_32k", CK_TOP_CB_CKSQ_40M, 1,
+ 1250),
+ TOP_FACTOR(CK_TOP_CB_RTC_32P7K, "cb_rtc_32p7k", CK_TOP_CB_CKSQ_40M, 1,
+ 1220),
+ TOP_FACTOR(CK_TOP_USB_TX250M, "usb_tx250m", CK_TOP_CB_CKSQ_40M, 1, 1),
+ TOP_FACTOR(CK_TOP_FAUD, "faud", CK_TOP_CB_CKSQ_40M, 1, 1),
+ TOP_FACTOR(CK_TOP_NFI1X, "nfi1x", CK_TOP_NFI1X_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_USB_EQ_RX250M, "usb_eq_rx250m", CK_TOP_CB_CKSQ_40M, 1,
+ 1),
+ TOP_FACTOR(CK_TOP_USB_CDR_CK, "usb_cdr", CK_TOP_CB_CKSQ_40M, 1, 1),
+ TOP_FACTOR(CK_TOP_USB_LN0_CK, "usb_ln0", CK_TOP_CB_CKSQ_40M, 1, 1),
+ TOP_FACTOR(CK_TOP_SPINFI_BCK, "spinfi_bck", CK_TOP_SPINFI_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_SPI, "spi", CK_TOP_SPI_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_SPIM_MST, "spim_mst", CK_TOP_SPIM_MST_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_UART_BCK, "uart_bck", CK_TOP_UART_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_PWM_BCK, "pwm_bck", CK_TOP_PWM_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_I2C_BCK, "i2c_bck", CK_TOP_I2C_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_PEXTP_TL, "pextp_tl", CK_TOP_PEXTP_TL_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_EMMC_208M, "emmc_208m", CK_TOP_EMMC_208M_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_EMMC_400M, "emmc_400m", CK_TOP_EMMC_400M_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_DRAMC_REF, "dramc_ref", CK_TOP_DRAMC_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_DRAMC_MD32, "dramc_md32", CK_TOP_DRAMC_MD32_SEL, 1,
+ 1),
+ TOP_FACTOR(CK_TOP_SYSAXI, "sysaxi", CK_TOP_SYSAXI_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_SYSAPB, "sysapb", CK_TOP_SYSAPB_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_ARM_DB_MAIN, "arm_db_main", CK_TOP_ARM_DB_MAIN_SEL, 1,
+ 1),
+ TOP_FACTOR(CK_TOP_AP2CNN_HOST, "ap2cnn_host", CK_TOP_AP2CNN_HOST_SEL, 1,
+ 1),
+ TOP_FACTOR(CK_TOP_NETSYS, "netsys", CK_TOP_NETSYS_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_NETSYS_500M, "netsys_500m", CK_TOP_NETSYS_500M_SEL, 1,
+ 1),
+ TOP_FACTOR(CK_TOP_NETSYS_WED_MCU, "netsys_wed_mcu",
+ CK_TOP_NETSYS_MCU_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_NETSYS_2X, "netsys_2x", CK_TOP_NETSYS_2X_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_SGM_325M, "sgm_325m", CK_TOP_SGM_325M_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_SGM_REG, "sgm_reg", CK_TOP_SGM_REG_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_F26M, "csw_f26m", CK_TOP_F26M_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_EIP97B, "eip97b", CK_TOP_EIP97B_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_USB3_PHY, "usb3_phy", CK_TOP_USB3_PHY_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_AUD, "aud", CK_TOP_FAUD, 1, 1),
+ TOP_FACTOR(CK_TOP_A1SYS, "a1sys", CK_TOP_A1SYS_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_AUD_L, "aud_l", CK_TOP_AUD_L_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_A_TUNER, "a_tuner", CK_TOP_A_TUNER_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_U2U3_REF, "u2u3_ref", CK_TOP_U2U3_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_U2U3_SYS, "u2u3_sys", CK_TOP_U2U3_SYS_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_U2U3_XHCI, "u2u3_xhci", CK_TOP_U2U3_XHCI_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_USB_FRMCNT, "usb_frmcnt", CK_TOP_USB_FRMCNT_SEL, 1,
+ 1),
+};
+
+/* TOPCKGEN MUX PARENTS */
+static const int nfi1x_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_MM_D4,
+ CK_TOP_NET1_D8_D2, CK_TOP_CB_NET2_D6,
+ CK_TOP_CB_M_D4, CK_TOP_CB_MM_D8,
+ CK_TOP_NET1_D8_D4, CK_TOP_CB_M_D8 };
+
+static const int spinfi_parents[] = { CK_TOP_CKSQ_40M_D2, CK_TOP_CB_CKSQ_40M,
+ CK_TOP_NET1_D5_D4, CK_TOP_CB_M_D4,
+ CK_TOP_CB_MM_D8, CK_TOP_NET1_D8_D4,
+ CK_TOP_MM_D6_D2, CK_TOP_CB_M_D8 };
+
+static const int spi_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D2,
+ CK_TOP_CB_MM_D4, CK_TOP_NET1_D8_D2,
+ CK_TOP_CB_NET2_D6, CK_TOP_NET1_D5_D4,
+ CK_TOP_CB_M_D4, CK_TOP_NET1_D8_D4 };
+
+static const int uart_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D8,
+ CK_TOP_M_D8_D2 };
+
+static const int pwm_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D8_D2,
+ CK_TOP_NET1_D5_D4, CK_TOP_CB_M_D4,
+ CK_TOP_M_D8_D2, CK_TOP_CB_RTC_32K };
+
+static const int i2c_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D5_D4,
+ CK_TOP_CB_M_D4, CK_TOP_NET1_D8_D4 };
+
+static const int pextp_tl_ck_parents[] = { CK_TOP_CB_CKSQ_40M,
+ CK_TOP_NET1_D5_D4, CK_TOP_CB_M_D4,
+ CK_TOP_CB_RTC_32K };
+
+static const int emmc_208m_parents[] = {
+ CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D2, CK_TOP_CB_NET2_D4,
+ CK_TOP_CB_APLL2_196M, CK_TOP_CB_MM_D4, CK_TOP_NET1_D8_D2,
+ CK_TOP_CB_MM_D6
+};
+
+static const int emmc_400m_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_NET2_D2,
+ CK_TOP_CB_MM_D2, CK_TOP_CB_NET2_D2 };
+
+static const int csw_f26m_parents[] = { CK_TOP_CKSQ_40M_D2, CK_TOP_M_D8_D2 };
+
+static const int dramc_md32_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D2,
+ CK_TOP_CB_WEDMCU_208M };
+
+static const int sysaxi_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D8_D2 };
+
+static const int sysapb_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_M_D3_D2 };
+
+static const int arm_db_main_parents[] = { CK_TOP_CB_CKSQ_40M,
+ CK_TOP_CB_NET2_D6 };
+
+static const int ap2cnn_host_parents[] = { CK_TOP_CB_CKSQ_40M,
+ CK_TOP_NET1_D8_D4 };
+
+static const int netsys_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_MM_D2 };
+
+static const int netsys_500m_parents[] = { CK_TOP_CB_CKSQ_40M,
+ CK_TOP_CB_NET1_D5 };
+
+static const int netsys_mcu_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_MM_720M,
+ CK_TOP_CB_NET1_D4, CK_TOP_CB_NET1_D5,
+ CK_TOP_CB_M_416M };
+
+static const int netsys_2x_parents[] = { CK_TOP_CB_CKSQ_40M,
+ CK_TOP_CB_NET2_800M,
+ CK_TOP_CB_MM_720M };
+
+static const int sgm_325m_parents[] = { CK_TOP_CB_CKSQ_40M,
+ CK_TOP_CB_SGM_325M };
+
+static const int sgm_reg_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_NET2_D4 };
+
+static const int eip97b_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_NET1_D5,
+ CK_TOP_CB_M_416M, CK_TOP_CB_MM_D2,
+ CK_TOP_NET1_D5_D2 };
+
+static const int aud_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_APLL2_196M };
+
+static const int a1sys_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_APLL2_D4 };
+
+static const int aud_l_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_APLL2_196M,
+ CK_TOP_M_D8_D2 };
+
+static const int a_tuner_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_APLL2_D4,
+ CK_TOP_M_D8_D2 };
+
+static const int u2u3_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_M_D8_D2 };
+
+static const int u2u3_sys_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D5_D4 };
+
+static const int usb_frmcnt_parents[] = { CK_TOP_CB_CKSQ_40M,
+ CK_TOP_CB_MM_D3_D5 };
+
+#define TOP_MUX(_id, _name, _parents, _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \
+ _shift, _width, _gate, _upd_ofs, _upd) \
+ { \
+ .id = _id, .mux_reg = _mux_ofs, .mux_set_reg = _mux_set_ofs, \
+ .mux_clr_reg = _mux_clr_ofs, .upd_reg = _upd_ofs, \
+ .upd_shift = _upd, .mux_shift = _shift, \
+ .mux_mask = BIT(_width) - 1, .gate_reg = _mux_ofs, \
+ .gate_shift = _gate, .parent = _parents, \
+ .num_parents = ARRAY_SIZE(_parents), \
+ .flags = CLK_MUX_SETCLR_UPD, \
+ }
+
+/* TOPCKGEN MUX_GATE */
+static const struct mtk_composite top_muxes[] = {
+ TOP_MUX(CK_TOP_NFI1X_SEL, "nfi1x_sel", nfi1x_parents, 0x0, 0x4, 0x8, 0,
+ 3, 7, 0x1c0, 0),
+ TOP_MUX(CK_TOP_SPINFI_SEL, "spinfi_sel", spinfi_parents, 0x0, 0x4, 0x8,
+ 8, 3, 15, 0x1c0, 1),
+ TOP_MUX(CK_TOP_SPI_SEL, "spi_sel", spi_parents, 0x0, 0x4, 0x8, 16, 3,
+ 23, 0x1c0, 2),
+ TOP_MUX(CK_TOP_SPIM_MST_SEL, "spim_mst_sel", spi_parents, 0x0, 0x4, 0x8,
+ 24, 3, 31, 0x1c0, 3),
+ TOP_MUX(CK_TOP_UART_SEL, "uart_sel", uart_parents, 0x10, 0x14, 0x18, 0,
+ 2, 7, 0x1c0, 4),
+ TOP_MUX(CK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x10, 0x14, 0x18, 8, 3,
+ 15, 0x1c0, 5),
+ TOP_MUX(CK_TOP_I2C_SEL, "i2c_sel", i2c_parents, 0x10, 0x14, 0x18, 16, 2,
+ 23, 0x1c0, 6),
+ TOP_MUX(CK_TOP_PEXTP_TL_SEL, "pextp_tl_ck_sel", pextp_tl_ck_parents,
+ 0x10, 0x14, 0x18, 24, 2, 31, 0x1c0, 7),
+ TOP_MUX(CK_TOP_EMMC_208M_SEL, "emmc_208m_sel", emmc_208m_parents, 0x20,
+ 0x24, 0x28, 0, 3, 7, 0x1c0, 8),
+ TOP_MUX(CK_TOP_EMMC_400M_SEL, "emmc_400m_sel", emmc_400m_parents, 0x20,
+ 0x24, 0x28, 8, 2, 15, 0x1c0, 9),
+ TOP_MUX(CK_TOP_F26M_SEL, "csw_f26m_sel", csw_f26m_parents, 0x20, 0x24,
+ 0x28, 16, 1, 23, 0x1c0, 10),
+ TOP_MUX(CK_TOP_DRAMC_SEL, "dramc_sel", csw_f26m_parents, 0x20, 0x24,
+ 0x28, 24, 1, 31, 0x1c0, 11),
+ TOP_MUX(CK_TOP_DRAMC_MD32_SEL, "dramc_md32_sel", dramc_md32_parents,
+ 0x30, 0x34, 0x38, 0, 2, 7, 0x1c0, 12),
+ TOP_MUX(CK_TOP_SYSAXI_SEL, "sysaxi_sel", sysaxi_parents, 0x30, 0x34,
+ 0x38, 8, 1, 15, 0x1c0, 13),
+ TOP_MUX(CK_TOP_SYSAPB_SEL, "sysapb_sel", sysapb_parents, 0x30, 0x34,
+ 0x38, 16, 1, 23, 0x1c0, 14),
+ TOP_MUX(CK_TOP_ARM_DB_MAIN_SEL, "arm_db_main_sel", arm_db_main_parents,
+ 0x30, 0x34, 0x38, 24, 1, 31, 0x1c0, 15),
+ TOP_MUX(CK_TOP_AP2CNN_HOST_SEL, "ap2cnn_host_sel", ap2cnn_host_parents,
+ 0x40, 0x44, 0x48, 0, 1, 7, 0x1c0, 16),
+ TOP_MUX(CK_TOP_NETSYS_SEL, "netsys_sel", netsys_parents, 0x40, 0x44,
+ 0x48, 8, 1, 15, 0x1c0, 17),
+ TOP_MUX(CK_TOP_NETSYS_500M_SEL, "netsys_500m_sel", netsys_500m_parents,
+ 0x40, 0x44, 0x48, 16, 1, 23, 0x1c0, 18),
+ TOP_MUX(CK_TOP_NETSYS_MCU_SEL, "netsys_mcu_sel", netsys_mcu_parents,
+ 0x40, 0x44, 0x48, 24, 3, 31, 0x1c0, 19),
+ TOP_MUX(CK_TOP_NETSYS_2X_SEL, "netsys_2x_sel", netsys_2x_parents, 0x50,
+ 0x54, 0x58, 0, 2, 7, 0x1c0, 20),
+ TOP_MUX(CK_TOP_SGM_325M_SEL, "sgm_325m_sel", sgm_325m_parents, 0x50,
+ 0x54, 0x58, 8, 1, 15, 0x1c0, 21),
+ TOP_MUX(CK_TOP_SGM_REG_SEL, "sgm_reg_sel", sgm_reg_parents, 0x50, 0x54,
+ 0x58, 16, 1, 23, 0x1c0, 22),
+ TOP_MUX(CK_TOP_EIP97B_SEL, "eip97b_sel", eip97b_parents, 0x50, 0x54,
+ 0x58, 24, 3, 31, 0x1c0, 23),
+ TOP_MUX(CK_TOP_USB3_PHY_SEL, "usb3_phy_sel", csw_f26m_parents, 0x60,
+ 0x64, 0x68, 0, 1, 7, 0x1c0, 24),
+ TOP_MUX(CK_TOP_AUD_SEL, "aud_sel", aud_parents, 0x60, 0x64, 0x68, 8, 1,
+ 15, 0x1c0, 25),
+ TOP_MUX(CK_TOP_A1SYS_SEL, "a1sys_sel", a1sys_parents, 0x60, 0x64, 0x68,
+ 16, 1, 23, 0x1c0, 26),
+ TOP_MUX(CK_TOP_AUD_L_SEL, "aud_l_sel", aud_l_parents, 0x60, 0x64, 0x68,
+ 24, 2, 31, 0x1c0, 27),
+ TOP_MUX(CK_TOP_A_TUNER_SEL, "a_tuner_sel", a_tuner_parents, 0x70, 0x74,
+ 0x78, 0, 2, 7, 0x1c0, 28),
+ TOP_MUX(CK_TOP_U2U3_SEL, "u2u3_sel", u2u3_parents, 0x70, 0x74, 0x78, 8,
+ 1, 15, 0x1c0, 29),
+ TOP_MUX(CK_TOP_U2U3_SYS_SEL, "u2u3_sys_sel", u2u3_sys_parents, 0x70,
+ 0x74, 0x78, 16, 1, 23, 0x1c0, 30),
+ TOP_MUX(CK_TOP_U2U3_XHCI_SEL, "u2u3_xhci_sel", u2u3_sys_parents, 0x70,
+ 0x74, 0x78, 24, 1, 31, 0x1c4, 0),
+ TOP_MUX(CK_TOP_USB_FRMCNT_SEL, "usb_frmcnt_sel", usb_frmcnt_parents,
+ 0x80, 0x84, 0x88, 0, 1, 7, 0x1c4, 1),
+};
+
+/* INFRA FIXED DIV */
+static const struct mtk_fixed_factor infra_fixed_divs[] = {
+ TOP_FACTOR(CK_INFRA_CK_F26M, "infra_ck_f26m", CK_TOP_F26M_SEL, 1, 1),
+ TOP_FACTOR(CK_INFRA_UART, "infra_uart", CK_TOP_UART_SEL, 1, 1),
+ TOP_FACTOR(CK_INFRA_ISPI0, "infra_ispi0", CK_TOP_SPI_SEL, 1, 1),
+ TOP_FACTOR(CK_INFRA_I2C, "infra_i2c", CK_TOP_I2C_SEL, 1, 1),
+ TOP_FACTOR(CK_INFRA_ISPI1, "infra_ispi1", CK_TOP_SPIM_MST_SEL, 1, 1),
+ TOP_FACTOR(CK_INFRA_PWM, "infra_pwm", CK_TOP_PWM_SEL, 1, 1),
+ TOP_FACTOR(CK_INFRA_66M_MCK, "infra_66m_mck", CK_TOP_SYSAXI_SEL, 1, 2),
+ TOP_FACTOR(CK_INFRA_CK_F32K, "infra_ck_f32k", CK_TOP_CB_RTC_32P7K, 1,
+ 1),
+ TOP_FACTOR(CK_INFRA_PCIE_CK, "infra_pcie", CK_TOP_PEXTP_TL_SEL, 1, 1),
+ INFRA_FACTOR(CK_INFRA_PWM_BCK, "infra_pwm_bck", CK_INFRA_PWM_BSEL, 1,
+ 1),
+ INFRA_FACTOR(CK_INFRA_PWM_CK1, "infra_pwm_ck1", CK_INFRA_PWM1_SEL, 1,
+ 1),
+ INFRA_FACTOR(CK_INFRA_PWM_CK2, "infra_pwm_ck2", CK_INFRA_PWM2_SEL, 1,
+ 1),
+ TOP_FACTOR(CK_INFRA_133M_HCK, "infra_133m_hck", CK_TOP_SYSAXI, 1, 1),
+ INFRA_FACTOR(CK_INFRA_66M_PHCK, "infra_66m_phck", CK_INFRA_133M_HCK, 1,
+ 1),
+ TOP_FACTOR(CK_INFRA_FAUD_L_CK, "infra_faud_l", CK_TOP_AUD_L, 1, 1),
+ TOP_FACTOR(CK_INFRA_FAUD_AUD_CK, "infra_faud_aud", CK_TOP_A1SYS, 1, 1),
+ TOP_FACTOR(CK_INFRA_FAUD_EG2_CK, "infra_faud_eg2", CK_TOP_A_TUNER, 1,
+ 1),
+ TOP_FACTOR(CK_INFRA_I2CS_CK, "infra_i2cs", CK_TOP_I2C_BCK, 1, 1),
+ INFRA_FACTOR(CK_INFRA_MUX_UART0, "infra_mux_uart0", CK_INFRA_UART0_SEL,
+ 1, 1),
+ INFRA_FACTOR(CK_INFRA_MUX_UART1, "infra_mux_uart1", CK_INFRA_UART1_SEL,
+ 1, 1),
+ INFRA_FACTOR(CK_INFRA_MUX_UART2, "infra_mux_uart2", CK_INFRA_UART2_SEL,
+ 1, 1),
+ TOP_FACTOR(CK_INFRA_NFI_CK, "infra_nfi", CK_TOP_NFI1X, 1, 1),
+ TOP_FACTOR(CK_INFRA_SPINFI_CK, "infra_spinfi", CK_TOP_SPINFI_BCK, 1, 1),
+ INFRA_FACTOR(CK_INFRA_MUX_SPI0, "infra_mux_spi0", CK_INFRA_SPI0_SEL, 1,
+ 1),
+ INFRA_FACTOR(CK_INFRA_MUX_SPI1, "infra_mux_spi1", CK_INFRA_SPI1_SEL, 1,
+ 1),
+ INFRA_FACTOR(CK_INFRA_MUX_SPI2, "infra_mux_spi2", CK_INFRA_SPI2_SEL, 1,
+ 1),
+ TOP_FACTOR(CK_INFRA_RTC_32K, "infra_rtc_32k", CK_TOP_CB_RTC_32K, 1, 1),
+ TOP_FACTOR(CK_INFRA_FMSDC_CK, "infra_fmsdc", CK_TOP_EMMC_400M, 1, 1),
+ TOP_FACTOR(CK_INFRA_FMSDC_HCK_CK, "infra_fmsdc_hck", CK_TOP_EMMC_208M,
+ 1, 1),
+ TOP_FACTOR(CK_INFRA_PERI_133M, "infra_peri_133m", CK_TOP_SYSAXI, 1, 1),
+ TOP_FACTOR(CK_INFRA_133M_PHCK, "infra_133m_phck", CK_TOP_SYSAXI, 1, 1),
+ TOP_FACTOR(CK_INFRA_USB_SYS_CK, "infra_usb_sys", CK_TOP_U2U3_SYS, 1, 1),
+ TOP_FACTOR(CK_INFRA_USB_CK, "infra_usb", CK_TOP_U2U3_REF, 1, 1),
+ TOP_FACTOR(CK_INFRA_USB_XHCI_CK, "infra_usb_xhci", CK_TOP_U2U3_XHCI, 1,
+ 1),
+ TOP_FACTOR(CK_INFRA_PCIE_GFMUX_TL_O_PRE, "infra_pcie_mux",
+ CK_TOP_PEXTP_TL, 1, 1),
+ TOP_FACTOR(CK_INFRA_F26M_CK0, "infra_f26m_ck0", CK_TOP_F26M, 1, 1),
+ TOP_FACTOR(CK_INFRA_133M_MCK, "infra_133m_mck", CK_TOP_SYSAXI, 1, 1),
+};
+
+/* INFRASYS MUX PARENTS */
+static const int infra_uart0_parents[] = { CK_INFRA_CK_F26M, CK_INFRA_UART };
+
+static const int infra_spi0_parents[] = { CK_INFRA_I2C, CK_INFRA_ISPI0 };
+
+static const int infra_spi1_parents[] = { CK_INFRA_I2C, CK_INFRA_ISPI1 };
+
+static const int infra_pwm1_parents[] = { -1, -1, -1, CK_INFRA_PWM };
+
+static const int infra_pwm_bsel_parents[] = { -1, -1, -1, CK_INFRA_PWM };
+
+static const int infra_pcie_parents[] = { CK_INFRA_CK_F32K, CK_INFRA_CK_F26M,
+ CK_TOP_CB_CKSQ_40M, CK_INFRA_PCIE_CK};
+
+#define INFRA_MUX(_id, _name, _parents, _reg, _shift, _width) \
+ { \
+ .id = _id, .mux_reg = (_reg) + 0x8, \
+ .mux_set_reg = (_reg) + 0x0, .mux_clr_reg = (_reg) + 0x4, \
+ .mux_shift = _shift, .mux_mask = BIT(_width) - 1, \
+ .parent = _parents, .num_parents = ARRAY_SIZE(_parents), \
+ .flags = CLK_MUX_SETCLR_UPD | CLK_PARENT_INFRASYS, \
+ }
+
+/* INFRA MUX */
+static const struct mtk_composite infra_muxes[] = {
+ INFRA_MUX(CK_INFRA_UART0_SEL, "infra_uart0_sel", infra_uart0_parents,
+ 0x10, 0, 1),
+ INFRA_MUX(CK_INFRA_UART1_SEL, "infra_uart1_sel", infra_uart0_parents,
+ 0x10, 1, 1),
+ INFRA_MUX(CK_INFRA_UART2_SEL, "infra_uart2_sel", infra_uart0_parents,
+ 0x10, 2, 1),
+ INFRA_MUX(CK_INFRA_SPI0_SEL, "infra_spi0_sel", infra_spi0_parents, 0x10,
+ 4, 1),
+ INFRA_MUX(CK_INFRA_SPI1_SEL, "infra_spi1_sel", infra_spi1_parents, 0x10,
+ 5, 1),
+ INFRA_MUX(CK_INFRA_SPI2_SEL, "infra_spi2_sel", infra_spi0_parents, 0x10,
+ 6, 1),
+ INFRA_MUX(CK_INFRA_PWM1_SEL, "infra_pwm1_sel", infra_pwm1_parents, 0x10,
+ 9, 2),
+ INFRA_MUX(CK_INFRA_PWM2_SEL, "infra_pwm2_sel", infra_pwm1_parents, 0x10,
+ 11, 2),
+ INFRA_MUX(CK_INFRA_PWM_BSEL, "infra_pwm_bsel", infra_pwm_bsel_parents,
+ 0x10, 13, 2),
+ INFRA_MUX(CK_INFRA_PCIE_SEL, "infra_pcie_sel", infra_pcie_parents, 0x20,
+ 0, 2),
+};
+
+static const struct mtk_gate_regs infra_0_cg_regs = {
+ .set_ofs = 0x40,
+ .clr_ofs = 0x44,
+ .sta_ofs = 0x48,
+};
+
+static const struct mtk_gate_regs infra_1_cg_regs = {
+ .set_ofs = 0x50,
+ .clr_ofs = 0x54,
+ .sta_ofs = 0x58,
+};
+
+static const struct mtk_gate_regs infra_2_cg_regs = {
+ .set_ofs = 0x60,
+ .clr_ofs = 0x64,
+ .sta_ofs = 0x68,
+};
+
+#define GATE_INFRA0(_id, _name, _parent, _shift) \
+ { \
+ .id = _id, .parent = _parent, .regs = &infra_0_cg_regs, \
+ .shift = _shift, \
+ .flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS, \
+ }
+
+#define GATE_INFRA1(_id, _name, _parent, _shift) \
+ { \
+ .id = _id, .parent = _parent, .regs = &infra_1_cg_regs, \
+ .shift = _shift, \
+ .flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS, \
+ }
+
+#define GATE_INFRA2(_id, _name, _parent, _shift) \
+ { \
+ .id = _id, .parent = _parent, .regs = &infra_2_cg_regs, \
+ .shift = _shift, \
+ .flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS, \
+ }
+
+/* INFRA GATE */
+static const struct mtk_gate infracfg_ao_gates[] = {
+ GATE_INFRA0(CK_INFRA_GPT_STA, "infra_gpt_sta", CK_INFRA_66M_MCK, 0),
+ GATE_INFRA0(CK_INFRA_PWM_HCK, "infra_pwm_hck", CK_INFRA_66M_MCK, 1),
+ GATE_INFRA0(CK_INFRA_PWM_STA, "infra_pwm_sta", CK_INFRA_PWM_BCK, 2),
+ GATE_INFRA0(CK_INFRA_PWM1_CK, "infra_pwm1", CK_INFRA_PWM_CK1, 3),
+ GATE_INFRA0(CK_INFRA_PWM2_CK, "infra_pwm2", CK_INFRA_PWM_CK2, 4),
+ GATE_INFRA0(CK_INFRA_CQ_DMA_CK, "infra_cq_dma", CK_INFRA_133M_HCK, 6),
+ GATE_INFRA0(CK_INFRA_AUD_BUS_CK, "infra_aud_bus", CK_INFRA_66M_PHCK, 8),
+ GATE_INFRA0(CK_INFRA_AUD_26M_CK, "infra_aud_26m", CK_INFRA_CK_F26M, 9),
+ GATE_INFRA0(CK_INFRA_AUD_L_CK, "infra_aud_l", CK_INFRA_FAUD_L_CK, 10),
+ GATE_INFRA0(CK_INFRA_AUD_AUD_CK, "infra_aud_aud", CK_INFRA_FAUD_AUD_CK,
+ 11),
+ GATE_INFRA0(CK_INFRA_AUD_EG2_CK, "infra_aud_eg2", CK_INFRA_FAUD_EG2_CK,
+ 13),
+ GATE_INFRA0(CK_INFRA_DRAMC_26M_CK, "infra_dramc_26m", CK_INFRA_CK_F26M,
+ 14),
+ GATE_INFRA0(CK_INFRA_DBG_CK, "infra_dbg", CK_INFRA_66M_MCK, 15),
+ GATE_INFRA0(CK_INFRA_AP_DMA_CK, "infra_ap_dma", CK_INFRA_66M_MCK, 16),
+ GATE_INFRA0(CK_INFRA_SEJ_CK, "infra_sej", CK_INFRA_66M_MCK, 24),
+ GATE_INFRA0(CK_INFRA_SEJ_13M_CK, "infra_sej_13m", CK_INFRA_CK_F26M, 25),
+ GATE_INFRA1(CK_INFRA_THERM_CK, "infra_therm", CK_INFRA_CK_F26M, 0),
+ GATE_INFRA1(CK_INFRA_I2CO_CK, "infra_i2co", CK_INFRA_I2CS_CK, 1),
+ GATE_INFRA1(CK_INFRA_UART0_CK, "infra_uart0", CK_INFRA_MUX_UART0, 2),
+ GATE_INFRA1(CK_INFRA_UART1_CK, "infra_uart1", CK_INFRA_MUX_UART1, 3),
+ GATE_INFRA1(CK_INFRA_UART2_CK, "infra_uart2", CK_INFRA_MUX_UART2, 4),
+ GATE_INFRA1(CK_INFRA_SPI2_CK, "infra_spi2", CK_INFRA_MUX_SPI2, 6),
+ GATE_INFRA1(CK_INFRA_SPI2_HCK_CK, "infra_spi2_hck", CK_INFRA_66M_MCK,
+ 7),
+ GATE_INFRA1(CK_INFRA_NFI1_CK, "infra_nfi1", CK_INFRA_NFI_CK, 8),
+ GATE_INFRA1(CK_INFRA_SPINFI1_CK, "infra_spinfi1", CK_INFRA_SPINFI_CK,
+ 9),
+ GATE_INFRA1(CK_INFRA_NFI_HCK_CK, "infra_nfi_hck", CK_INFRA_66M_MCK, 10),
+ GATE_INFRA1(CK_INFRA_SPI0_CK, "infra_spi0", CK_INFRA_MUX_SPI0, 11),
+ GATE_INFRA1(CK_INFRA_SPI1_CK, "infra_spi1", CK_INFRA_MUX_SPI1, 12),
+ GATE_INFRA1(CK_INFRA_SPI0_HCK_CK, "infra_spi0_hck", CK_INFRA_66M_MCK,
+ 13),
+ GATE_INFRA1(CK_INFRA_SPI1_HCK_CK, "infra_spi1_hck", CK_INFRA_66M_MCK,
+ 14),
+ GATE_INFRA1(CK_INFRA_FRTC_CK, "infra_frtc", CK_INFRA_RTC_32K, 15),
+ GATE_INFRA1(CK_INFRA_MSDC_CK, "infra_msdc", CK_INFRA_FMSDC_CK, 16),
+ GATE_INFRA1(CK_INFRA_MSDC_HCK_CK, "infra_msdc_hck",
+ CK_INFRA_FMSDC_HCK_CK, 17),
+ GATE_INFRA1(CK_INFRA_MSDC_133M_CK, "infra_msdc_133m",
+ CK_INFRA_PERI_133M, 18),
+ GATE_INFRA1(CK_INFRA_MSDC_66M_CK, "infra_msdc_66m", CK_INFRA_66M_PHCK,
+ 19),
+ GATE_INFRA1(CK_INFRA_ADC_26M_CK, "infra_adc_26m", CK_TOP_F26M, 20),
+ GATE_INFRA1(CK_INFRA_ADC_FRC_CK, "infra_adc_frc", CK_TOP_F26M, 21),
+ GATE_INFRA1(CK_INFRA_FBIST2FPC_CK, "infra_fbist2fpc", CK_INFRA_NFI_CK,
+ 23),
+ GATE_INFRA1(CK_INFRA_I2C_MCK_CK, "infra_i2c_mck", CK_INFRA_133M_MCK,
+ 25),
+ GATE_INFRA1(CK_INFRA_I2C_PCK_CK, "infra_i2c_pck", CK_INFRA_66M_MCK, 26),
+ GATE_INFRA2(CK_INFRA_IUSB_133_CK, "infra_iusb_133", CK_INFRA_133M_PHCK,
+ 0),
+ GATE_INFRA2(CK_INFRA_IUSB_66M_CK, "infra_iusb_66m", CK_INFRA_66M_PHCK,
+ 1),
+ GATE_INFRA2(CK_INFRA_IUSB_SYS_CK, "infra_iusb_sys", CK_INFRA_USB_SYS_CK,
+ 2),
+ GATE_INFRA2(CK_INFRA_IUSB_CK, "infra_iusb", CK_INFRA_USB_CK, 3),
+ GATE_INFRA2(CK_INFRA_IPCIE_CK, "infra_ipcie",
+ CK_INFRA_PCIE_GFMUX_TL_O_PRE, 12),
+ GATE_INFRA2(CK_INFRA_IPCIER_CK, "infra_ipcier", CK_INFRA_F26M_CK0, 14),
+ GATE_INFRA2(CK_INFRA_IPCIEB_CK, "infra_ipcieb", CK_INFRA_133M_PHCK, 15),
+};
+
+static const struct mtk_clk_tree mt7981_fixed_pll_clk_tree = {
+ .fdivs_offs = CLK_APMIXED_NR_CLK,
+ .xtal_rate = 40 * MHZ,
+ .fclks = fixed_pll_clks,
+};
+
+static const struct mtk_clk_tree mt7981_topckgen_clk_tree = {
+ .fdivs_offs = CK_TOP_CB_M_416M,
+ .muxes_offs = CK_TOP_NFI1X_SEL,
+ .fclks = top_fixed_clks,
+ .fdivs = top_fixed_divs,
+ .muxes = top_muxes,
+ .flags = CLK_BYPASS_XTAL,
+};
+
+static const struct mtk_clk_tree mt7981_infracfg_clk_tree = {
+ .fdivs_offs = CK_INFRA_CK_F26M,
+ .muxes_offs = CK_INFRA_UART0_SEL,
+ .fdivs = infra_fixed_divs,
+ .muxes = infra_muxes,
+};
+
+static const struct udevice_id mt7981_fixed_pll_compat[] = {
+ { .compatible = "mediatek,mt7981-fixed-plls" },
+ {}
+};
+
+static const struct udevice_id mt7981_topckgen_compat[] = {
+ { .compatible = "mediatek,mt7981-topckgen" },
+ {}
+};
+
+static int mt7981_fixed_pll_probe(struct udevice *dev)
+{
+ return mtk_common_clk_init(dev, &mt7981_fixed_pll_clk_tree);
+}
+
+static int mt7981_topckgen_probe(struct udevice *dev)
+{
+ struct mtk_clk_priv *priv = dev_get_priv(dev);
+
+ priv->base = dev_read_addr_ptr(dev);
+ writel(MT7981_CLK_PDN_EN_WRITE, priv->base + MT7981_CLK_PDN);
+
+ return mtk_common_clk_init(dev, &mt7981_topckgen_clk_tree);
+}
+
+U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
+ .name = "mt7981-clock-fixed-pll",
+ .id = UCLASS_CLK,
+ .of_match = mt7981_fixed_pll_compat,
+ .probe = mt7981_fixed_pll_probe,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_topckgen_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(mtk_clk_topckgen) = {
+ .name = "mt7981-clock-topckgen",
+ .id = UCLASS_CLK,
+ .of_match = mt7981_topckgen_compat,
+ .probe = mt7981_topckgen_probe,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_topckgen_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+static const struct udevice_id mt7981_infracfg_compat[] = {
+ { .compatible = "mediatek,mt7981-infracfg" },
+ {}
+};
+
+static const struct udevice_id mt7981_infracfg_ao_compat[] = {
+ { .compatible = "mediatek,mt7981-infracfg_ao" },
+ {}
+};
+
+static int mt7981_infracfg_probe(struct udevice *dev)
+{
+ return mtk_common_clk_init(dev, &mt7981_infracfg_clk_tree);
+}
+
+static int mt7981_infracfg_ao_probe(struct udevice *dev)
+{
+ return mtk_common_clk_gate_init(dev, &mt7981_infracfg_clk_tree,
+ infracfg_ao_gates);
+}
+
+U_BOOT_DRIVER(mtk_clk_infracfg) = {
+ .name = "mt7981-clock-infracfg",
+ .id = UCLASS_CLK,
+ .of_match = mt7981_infracfg_compat,
+ .probe = mt7981_infracfg_probe,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_infrasys_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(mtk_clk_infracfg_ao) = {
+ .name = "mt7981-clock-infracfg-ao",
+ .id = UCLASS_CLK,
+ .of_match = mt7981_infracfg_ao_compat,
+ .probe = mt7981_infracfg_ao_probe,
+ .priv_auto = sizeof(struct mtk_cg_priv),
+ .ops = &mtk_clk_gate_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+/* ethsys */
+static const struct mtk_gate_regs eth_cg_regs = {
+ .set_ofs = 0x30,
+ .clr_ofs = 0x30,
+ .sta_ofs = 0x30,
+};
+
+#define GATE_ETH(_id, _name, _parent, _shift) \
+ { \
+ .id = _id, .parent = _parent, .regs = ð_cg_regs, \
+ .shift = _shift, \
+ .flags = CLK_GATE_NO_SETCLR_INV | CLK_PARENT_TOPCKGEN, \
+ }
+
+static const struct mtk_gate eth_cgs[] = {
+ GATE_ETH(CK_ETH_FE_EN, "eth_fe_en", CK_TOP_NETSYS_2X, 6),
+ GATE_ETH(CK_ETH_GP2_EN, "eth_gp2_en", CK_TOP_SGM_325M, 7),
+ GATE_ETH(CK_ETH_GP1_EN, "eth_gp1_en", CK_TOP_SGM_325M, 8),
+ GATE_ETH(CK_ETH_WOCPU0_EN, "eth_wocpu0_en", CK_TOP_NETSYS_WED_MCU, 15),
+};
+
+static int mt7981_ethsys_probe(struct udevice *dev)
+{
+ return mtk_common_clk_gate_init(dev, &mt7981_topckgen_clk_tree,
+ eth_cgs);
+}
+
+static int mt7981_ethsys_bind(struct udevice *dev)
+{
+ int ret = 0;
+
+ if (CONFIG_IS_ENABLED(RESET_MEDIATEK)) {
+ ret = mediatek_reset_bind(dev, ETHSYS_HIFSYS_RST_CTRL_OFS, 1);
+ if (ret)
+ debug("Warning: failed to bind reset controller\n");
+ }
+
+ return ret;
+}
+
+static const struct udevice_id mt7981_ethsys_compat[] = {
+ { .compatible = "mediatek,mt7981-ethsys", },
+ {}
+};
+
+U_BOOT_DRIVER(mtk_clk_ethsys) = {
+ .name = "mt7981-clock-ethsys",
+ .id = UCLASS_CLK,
+ .of_match = mt7981_ethsys_compat,
+ .probe = mt7981_ethsys_probe,
+ .bind = mt7981_ethsys_bind,
+ .priv_auto = sizeof(struct mtk_cg_priv),
+ .ops = &mtk_clk_gate_ops,
+};
diff --git a/drivers/clk/mediatek/clk-mt7986.c b/drivers/clk/mediatek/clk-mt7986.c
new file mode 100644
index 0000000..b3fa63f
--- /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 <sam.shih@mediatek.com>
+ */
+
+#include <dm.h>
+#include <log.h>
+#include <asm/arch-mediatek/reset.h>
+#include <asm/io.h>
+#include <dt-bindings/clock/mt7986-clk.h>
+#include <linux/bitops.h>
+
+#include "clk-mtk.h"
+
+#define MT7986_CLK_PDN 0x250
+#define MT7986_CLK_PDN_EN_WRITE BIT(31)
+
+#define PLL_FACTOR(_id, _name, _parent, _mult, _div) \
+ FACTOR(_id, _parent, _mult, _div, CLK_PARENT_APMIXED)
+
+#define TOP_FACTOR(_id, _name, _parent, _mult, _div) \
+ FACTOR(_id, _parent, _mult, _div, CLK_PARENT_TOPCKGEN)
+
+#define INFRA_FACTOR(_id, _name, _parent, _mult, _div) \
+ FACTOR(_id, _parent, _mult, _div, CLK_PARENT_INFRASYS)
+
+/* FIXED PLLS */
+static const struct mtk_fixed_clk fixed_pll_clks[] = {
+ FIXED_CLK(CK_APMIXED_ARMPLL, CLK_XTAL, 2000000000),
+ FIXED_CLK(CK_APMIXED_NET2PLL, CLK_XTAL, 800000000),
+ FIXED_CLK(CK_APMIXED_MMPLL, CLK_XTAL, 1440000000),
+ FIXED_CLK(CK_APMIXED_SGMPLL, CLK_XTAL, 325000000),
+ FIXED_CLK(CK_APMIXED_WEDMCUPLL, CLK_XTAL, 760000000),
+ FIXED_CLK(CK_APMIXED_NET1PLL, CLK_XTAL, 2500000000),
+ FIXED_CLK(CK_APMIXED_MPLL, CLK_XTAL, 416000000),
+ FIXED_CLK(CK_APMIXED_APLL2, CLK_XTAL, 196608000),
+};
+
+/* TOPCKGEN FIXED CLK */
+static const struct mtk_fixed_clk top_fixed_clks[] = {
+ FIXED_CLK(CK_TOP_CB_CKSQ_40M, CLK_XTAL, 40000000),
+};
+
+/* TOPCKGEN FIXED DIV */
+static const struct mtk_fixed_factor top_fixed_divs[] = {
+ PLL_FACTOR(CK_TOP_CB_M_416M, "cb_m_416m", CK_APMIXED_MPLL, 1, 1),
+ PLL_FACTOR(CK_TOP_CB_M_D2, "cb_m_d2", CK_APMIXED_MPLL, 1, 2),
+ PLL_FACTOR(CK_TOP_CB_M_D4, "cb_m_d4", CK_APMIXED_MPLL, 1, 4),
+ PLL_FACTOR(CK_TOP_CB_M_D8, "cb_m_d8", CK_APMIXED_MPLL, 1, 8),
+ PLL_FACTOR(CK_TOP_M_D8_D2, "m_d8_d2", CK_APMIXED_MPLL, 1, 16),
+ PLL_FACTOR(CK_TOP_M_D3_D2, "m_d3_d2", CK_APMIXED_MPLL, 1, 2),
+ PLL_FACTOR(CK_TOP_CB_MM_D2, "cb_mm_d2", CK_APMIXED_MMPLL, 1, 2),
+ PLL_FACTOR(CK_TOP_CB_MM_D4, "cb_mm_d4", CK_APMIXED_MMPLL, 1, 4),
+ PLL_FACTOR(CK_TOP_CB_MM_D8, "cb_mm_d8", CK_APMIXED_MMPLL, 1, 8),
+ PLL_FACTOR(CK_TOP_MM_D8_D2, "mm_d8_d2", CK_APMIXED_MMPLL, 1, 16),
+ PLL_FACTOR(CK_TOP_MM_D3_D8, "mm_d3_d8", CK_APMIXED_MMPLL, 1, 8),
+ PLL_FACTOR(CK_TOP_CB_U2_PHYD_CK, "cb_u2_phyd", CK_APMIXED_MMPLL, 1, 30),
+ PLL_FACTOR(CK_TOP_CB_APLL2_196M, "cb_apll2_196m", CK_APMIXED_APLL2, 1,
+ 1),
+ PLL_FACTOR(CK_TOP_APLL2_D4, "apll2_d4", CK_APMIXED_APLL2, 1, 4),
+ PLL_FACTOR(CK_TOP_CB_NET1_D4, "cb_net1_d4", CK_APMIXED_NET1PLL, 1, 4),
+ PLL_FACTOR(CK_TOP_CB_NET1_D5, "cb_net1_d5", CK_APMIXED_NET1PLL, 1, 5),
+ PLL_FACTOR(CK_TOP_NET1_D5_D2, "net1_d5_d2", CK_APMIXED_NET1PLL, 1, 10),
+ PLL_FACTOR(CK_TOP_NET1_D5_D4, "net1_d5_d4", CK_APMIXED_NET1PLL, 1, 20),
+ PLL_FACTOR(CK_TOP_NET1_D8_D2, "net1_d8_d2", CK_APMIXED_NET1PLL, 1, 16),
+ PLL_FACTOR(CK_TOP_NET1_D8_D4, "net1_d8_d4", CK_APMIXED_NET1PLL, 1, 32),
+ PLL_FACTOR(CK_TOP_CB_NET2_800M, "cb_net2_800m", CK_APMIXED_NET2PLL, 1,
+ 1),
+ PLL_FACTOR(CK_TOP_CB_NET2_D4, "cb_net2_d4", CK_APMIXED_NET2PLL, 1, 4),
+ PLL_FACTOR(CK_TOP_NET2_D4_D2, "net2_d4_d2", CK_APMIXED_NET2PLL, 1, 8),
+ PLL_FACTOR(CK_TOP_NET2_D3_D2, "net2_d3_d2", CK_APMIXED_NET2PLL, 1, 2),
+ PLL_FACTOR(CK_TOP_CB_WEDMCU_760M, "cb_wedmcu_760m",
+ CK_APMIXED_WEDMCUPLL, 1, 1),
+ PLL_FACTOR(CK_TOP_WEDMCU_D5_D2, "wedmcu_d5_d2", CK_APMIXED_WEDMCUPLL, 1,
+ 10),
+ PLL_FACTOR(CK_TOP_CB_SGM_325M, "cb_sgm_325m", CK_APMIXED_SGMPLL, 1, 1),
+ TOP_FACTOR(CK_TOP_CB_CKSQ_40M_D2, "cb_cksq_40m_d2", CK_TOP_CB_CKSQ_40M,
+ 1, 2),
+ TOP_FACTOR(CK_TOP_CB_RTC_32K, "cb_rtc_32k", CK_TOP_CB_CKSQ_40M, 1,
+ 1250),
+ TOP_FACTOR(CK_TOP_CB_RTC_32P7K, "cb_rtc_32p7k", CK_TOP_CB_CKSQ_40M, 1,
+ 1220),
+ TOP_FACTOR(CK_TOP_NFI1X, "nfi1x", CK_TOP_NFI1X_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_USB_EQ_RX250M, "usb_eq_rx250m", CK_TOP_CB_CKSQ_40M, 1,
+ 1),
+ TOP_FACTOR(CK_TOP_USB_TX250M, "usb_tx250m", CK_TOP_CB_CKSQ_40M, 1, 1),
+ TOP_FACTOR(CK_TOP_USB_LN0_CK, "usb_ln0", CK_TOP_CB_CKSQ_40M, 1, 1),
+ TOP_FACTOR(CK_TOP_USB_CDR_CK, "usb_cdr", CK_TOP_CB_CKSQ_40M, 1, 1),
+ TOP_FACTOR(CK_TOP_SPINFI_BCK, "spinfi_bck", CK_TOP_SPINFI_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_I2C_BCK, "i2c_bck", CK_TOP_I2C_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_PEXTP_TL, "pextp_tl", CK_TOP_PEXTP_TL_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_EMMC_250M, "emmc_250m", CK_TOP_EMMC_250M_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_EMMC_416M, "emmc_416m", CK_TOP_EMMC_416M_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_F_26M_ADC_CK, "f_26m_adc", CK_TOP_F_26M_ADC_SEL, 1,
+ 1),
+ TOP_FACTOR(CK_TOP_SYSAXI, "sysaxi", CK_TOP_SYSAXI_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_NETSYS_WED_MCU, "netsys_wed_mcu",
+ CK_TOP_NETSYS_MCU_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_NETSYS_2X, "netsys_2x", CK_TOP_NETSYS_2X_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_SGM_325M, "sgm_325m", CK_TOP_SGM_325M_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_A1SYS, "a1sys", CK_TOP_A1SYS_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_EIP_B, "eip_b", CK_TOP_EIP_B_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_F26M, "csw_f26m", CK_TOP_F26M_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_AUD_L, "aud_l", CK_TOP_AUD_L_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_A_TUNER, "a_tuner", CK_TOP_A_TUNER_SEL, 2, 1),
+ TOP_FACTOR(CK_TOP_U2U3_REF, "u2u3_ref", CK_TOP_U2U3_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_U2U3_SYS, "u2u3_sys", CK_TOP_U2U3_SYS_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_U2U3_XHCI, "u2u3_xhci", CK_TOP_U2U3_XHCI_SEL, 1, 1),
+ TOP_FACTOR(CK_TOP_AP2CNN_HOST, "ap2cnn_host", CK_TOP_AP2CNN_HOST_SEL, 1,
+ 1),
+};
+
+/* TOPCKGEN MUX PARENTS */
+static const int nfi1x_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_MM_D8,
+ CK_TOP_NET1_D8_D2, CK_TOP_NET2_D3_D2,
+ CK_TOP_CB_M_D4, CK_TOP_MM_D8_D2,
+ CK_TOP_WEDMCU_D5_D2, CK_TOP_CB_M_D8 };
+
+static const int spinfi_parents[] = {
+ CK_TOP_CB_CKSQ_40M_D2, CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D5_D4,
+ CK_TOP_CB_M_D4, CK_TOP_MM_D8_D2, CK_TOP_WEDMCU_D5_D2,
+ CK_TOP_MM_D3_D8, CK_TOP_CB_M_D8
+};
+
+static const int spi_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D2,
+ CK_TOP_CB_MM_D8, CK_TOP_NET1_D8_D2,
+ CK_TOP_NET2_D3_D2, CK_TOP_NET1_D5_D4,
+ CK_TOP_CB_M_D4, CK_TOP_WEDMCU_D5_D2 };
+
+static const int uart_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D8,
+ CK_TOP_M_D8_D2 };
+
+static const int pwm_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D8_D2,
+ CK_TOP_NET1_D5_D4, CK_TOP_CB_M_D4 };
+
+static const int i2c_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D5_D4,
+ CK_TOP_CB_M_D4, CK_TOP_NET1_D8_D4 };
+
+static const int pextp_tl_ck_parents[] = { CK_TOP_CB_CKSQ_40M,
+ CK_TOP_NET1_D5_D4, CK_TOP_NET2_D4_D2,
+ CK_TOP_CB_RTC_32K };
+
+static const int emmc_250m_parents[] = { CK_TOP_CB_CKSQ_40M,
+ CK_TOP_NET1_D5_D2 };
+
+static const int emmc_416m_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_416M };
+
+static const int f_26m_adc_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_M_D8_D2 };
+
+static const int dramc_md32_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D2 };
+
+static const int sysaxi_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D8_D2,
+ CK_TOP_CB_NET2_D4 };
+
+static const int sysapb_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_M_D3_D2,
+ CK_TOP_NET2_D4_D2 };
+
+static const int arm_db_main_parents[] = { CK_TOP_CB_CKSQ_40M,
+ CK_TOP_NET2_D3_D2 };
+
+static const int arm_db_jtsel_parents[] = { -1, CK_TOP_CB_CKSQ_40M };
+
+static const int netsys_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_MM_D4 };
+
+static const int netsys_500m_parents[] = { CK_TOP_CB_CKSQ_40M,
+ CK_TOP_CB_NET1_D5 };
+
+static const int netsys_mcu_parents[] = { CK_TOP_CB_CKSQ_40M,
+ CK_TOP_CB_WEDMCU_760M,
+ CK_TOP_CB_MM_D2, CK_TOP_CB_NET1_D4,
+ CK_TOP_CB_NET1_D5 };
+
+static const int netsys_2x_parents[] = { CK_TOP_CB_CKSQ_40M,
+ CK_TOP_CB_NET2_800M,
+ CK_TOP_CB_WEDMCU_760M,
+ CK_TOP_CB_MM_D2 };
+
+static const int sgm_325m_parents[] = { CK_TOP_CB_CKSQ_40M,
+ CK_TOP_CB_SGM_325M };
+
+static const int sgm_reg_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D8_D4 };
+
+static const int a1sys_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_APLL2_D4 };
+
+static const int conn_mcusys_parents[] = { CK_TOP_CB_CKSQ_40M,
+ CK_TOP_CB_MM_D2 };
+
+static const int eip_b_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_NET2_800M };
+
+static const int aud_l_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_APLL2_196M,
+ CK_TOP_M_D8_D2 };
+
+static const int a_tuner_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_APLL2_D4,
+ CK_TOP_M_D8_D2 };
+
+static const int u2u3_sys_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D5_D4 };
+
+static const int da_u2_refsel_parents[] = { CK_TOP_CB_CKSQ_40M,
+ CK_TOP_CB_U2_PHYD_CK };
+
+#define TOP_MUX(_id, _name, _parents, _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \
+ _shift, _width, _gate, _upd_ofs, _upd) \
+ { \
+ .id = _id, .mux_reg = _mux_ofs, .mux_set_reg = _mux_set_ofs, \
+ .mux_clr_reg = _mux_clr_ofs, .upd_reg = _upd_ofs, \
+ .upd_shift = _upd, .mux_shift = _shift, \
+ .mux_mask = BIT(_width) - 1, .gate_reg = _mux_ofs, \
+ .gate_shift = _gate, .parent = _parents, \
+ .num_parents = ARRAY_SIZE(_parents), \
+ .flags = CLK_MUX_SETCLR_UPD, \
+ }
+
+/* TOPCKGEN MUX_GATE */
+static const struct mtk_composite top_muxes[] = {
+ /* CLK_CFG_0 */
+ TOP_MUX(CK_TOP_NFI1X_SEL, "nfi1x_sel", nfi1x_parents, 0x000, 0x004,
+ 0x008, 0, 3, 7, 0x1C0, 0),
+ TOP_MUX(CK_TOP_SPINFI_SEL, "spinfi_sel", spinfi_parents, 0x000, 0x004,
+ 0x008, 8, 3, 15, 0x1C0, 1),
+ TOP_MUX(CK_TOP_SPI_SEL, "spi_sel", spi_parents, 0x000, 0x004, 0x008, 16,
+ 3, 23, 0x1C0, 2),
+ TOP_MUX(CK_TOP_SPIM_MST_SEL, "spim_mst_sel", spi_parents, 0x000, 0x004,
+ 0x008, 24, 3, 31, 0x1C0, 3),
+ /* CLK_CFG_1 */
+ TOP_MUX(CK_TOP_UART_SEL, "uart_sel", uart_parents, 0x010, 0x014, 0x018,
+ 0, 2, 7, 0x1C0, 4),
+ TOP_MUX(CK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x010, 0x014, 0x018, 8,
+ 2, 15, 0x1C0, 5),
+ TOP_MUX(CK_TOP_I2C_SEL, "i2c_sel", i2c_parents, 0x010, 0x014, 0x018, 16,
+ 2, 23, 0x1C0, 6),
+ TOP_MUX(CK_TOP_PEXTP_TL_SEL, "pextp_tl_ck_sel", pextp_tl_ck_parents,
+ 0x010, 0x014, 0x018, 24, 2, 31, 0x1C0, 7),
+ /* CLK_CFG_2 */
+ TOP_MUX(CK_TOP_EMMC_250M_SEL, "emmc_250m_sel", emmc_250m_parents, 0x020,
+ 0x024, 0x028, 0, 1, 7, 0x1C0, 8),
+ TOP_MUX(CK_TOP_EMMC_416M_SEL, "emmc_416m_sel", emmc_416m_parents, 0x020,
+ 0x024, 0x028, 8, 1, 15, 0x1C0, 9),
+ TOP_MUX(CK_TOP_F_26M_ADC_SEL, "f_26m_adc_sel", f_26m_adc_parents, 0x020,
+ 0x024, 0x028, 16, 1, 23, 0x1C0, 10),
+ TOP_MUX(CK_TOP_DRAMC_SEL, "dramc_sel", f_26m_adc_parents, 0x020, 0x024,
+ 0x028, 24, 1, 31, 0x1C0, 11),
+ /* CLK_CFG_3 */
+ TOP_MUX(CK_TOP_DRAMC_MD32_SEL, "dramc_md32_sel", dramc_md32_parents,
+ 0x030, 0x034, 0x038, 0, 1, 7, 0x1C0, 12),
+ TOP_MUX(CK_TOP_SYSAXI_SEL, "sysaxi_sel", sysaxi_parents, 0x030, 0x034,
+ 0x038, 8, 2, 15, 0x1C0, 13),
+ TOP_MUX(CK_TOP_SYSAPB_SEL, "sysapb_sel", sysapb_parents, 0x030, 0x034,
+ 0x038, 16, 2, 23, 0x1C0, 14),
+ TOP_MUX(CK_TOP_ARM_DB_MAIN_SEL, "arm_db_main_sel", arm_db_main_parents,
+ 0x030, 0x034, 0x038, 24, 1, 31, 0x1C0, 15),
+ /* CLK_CFG_4 */
+ TOP_MUX(CK_TOP_ARM_DB_JTSEL, "arm_db_jtsel", arm_db_jtsel_parents,
+ 0x040, 0x044, 0x048, 0, 1, 7, 0x1C0, 16),
+ TOP_MUX(CK_TOP_NETSYS_SEL, "netsys_sel", netsys_parents, 0x040, 0x044,
+ 0x048, 8, 1, 15, 0x1C0, 17),
+ TOP_MUX(CK_TOP_NETSYS_500M_SEL, "netsys_500m_sel", netsys_500m_parents,
+ 0x040, 0x044, 0x048, 16, 1, 23, 0x1C0, 18),
+ TOP_MUX(CK_TOP_NETSYS_MCU_SEL, "netsys_mcu_sel", netsys_mcu_parents,
+ 0x040, 0x044, 0x048, 24, 3, 31, 0x1C0, 19),
+ /* CLK_CFG_5 */
+ TOP_MUX(CK_TOP_NETSYS_2X_SEL, "netsys_2x_sel", netsys_2x_parents, 0x050,
+ 0x054, 0x058, 0, 2, 7, 0x1C0, 20),
+ TOP_MUX(CK_TOP_SGM_325M_SEL, "sgm_325m_sel", sgm_325m_parents, 0x050,
+ 0x054, 0x058, 8, 1, 15, 0x1C0, 21),
+ TOP_MUX(CK_TOP_SGM_REG_SEL, "sgm_reg_sel", sgm_reg_parents, 0x050,
+ 0x054, 0x058, 16, 1, 23, 0x1C0, 22),
+ TOP_MUX(CK_TOP_A1SYS_SEL, "a1sys_sel", a1sys_parents, 0x050, 0x054,
+ 0x058, 24, 1, 31, 0x1C0, 23),
+ /* CLK_CFG_6 */
+ TOP_MUX(CK_TOP_CONN_MCUSYS_SEL, "conn_mcusys_sel", conn_mcusys_parents,
+ 0x060, 0x064, 0x068, 0, 1, 7, 0x1C0, 24),
+ TOP_MUX(CK_TOP_EIP_B_SEL, "eip_b_sel", eip_b_parents, 0x060, 0x064,
+ 0x068, 8, 1, 15, 0x1C0, 25),
+ TOP_MUX(CK_TOP_PCIE_PHY_SEL, "pcie_phy_sel", f_26m_adc_parents, 0x060,
+ 0x064, 0x068, 16, 1, 23, 0x1C0, 26),
+ TOP_MUX(CK_TOP_USB3_PHY_SEL, "usb3_phy_sel", f_26m_adc_parents, 0x060,
+ 0x064, 0x068, 24, 1, 31, 0x1C0, 27),
+ /* CLK_CFG_7 */
+ TOP_MUX(CK_TOP_F26M_SEL, "csw_f26m_sel", f_26m_adc_parents, 0x070,
+ 0x074, 0x078, 0, 1, 7, 0x1C0, 28),
+ TOP_MUX(CK_TOP_AUD_L_SEL, "aud_l_sel", aud_l_parents, 0x070, 0x074,
+ 0x078, 8, 2, 15, 0x1C0, 29),
+ TOP_MUX(CK_TOP_A_TUNER_SEL, "a_tuner_sel", a_tuner_parents, 0x070,
+ 0x074, 0x078, 16, 2, 23, 0x1C0, 30),
+ TOP_MUX(CK_TOP_U2U3_SEL, "u2u3_sel", f_26m_adc_parents, 0x070, 0x074,
+ 0x078, 24, 1, 31, 0x1C4, 0),
+ /* CLK_CFG_8 */
+ TOP_MUX(CK_TOP_U2U3_SYS_SEL, "u2u3_sys_sel", u2u3_sys_parents, 0x080,
+ 0x084, 0x088, 0, 1, 7, 0x1C4, 1),
+ TOP_MUX(CK_TOP_U2U3_XHCI_SEL, "u2u3_xhci_sel", u2u3_sys_parents, 0x080,
+ 0x084, 0x088, 8, 1, 15, 0x1C4, 2),
+ TOP_MUX(CK_TOP_DA_U2_REFSEL, "da_u2_refsel", da_u2_refsel_parents,
+ 0x080, 0x084, 0x088, 16, 1, 23, 0x1C4, 3),
+ TOP_MUX(CK_TOP_DA_U2_CK_1P_SEL, "da_u2_ck_1p_sel", da_u2_refsel_parents,
+ 0x080, 0x084, 0x088, 24, 1, 31, 0x1C4, 4),
+ /* CLK_CFG_9 */
+ TOP_MUX(CK_TOP_AP2CNN_HOST_SEL, "ap2cnn_host_sel", sgm_reg_parents,
+ 0x090, 0x094, 0x098, 0, 1, 7, 0x1C4, 5),
+};
+
+/* INFRA FIXED DIV */
+static const struct mtk_fixed_factor infra_fixed_divs[] = {
+ TOP_FACTOR(CK_INFRA_CK_F26M, "infra_ck_f26m", CK_TOP_F26M_SEL, 1, 1),
+ TOP_FACTOR(CK_INFRA_UART, "infra_uart", CK_TOP_UART_SEL, 1, 1),
+ TOP_FACTOR(CK_INFRA_ISPI0, "infra_ispi0", CK_TOP_SPI_SEL, 1, 1),
+ TOP_FACTOR(CK_INFRA_I2C, "infra_i2c", CK_TOP_I2C_SEL, 1, 1),
+ TOP_FACTOR(CK_INFRA_ISPI1, "infra_ispi1", CK_TOP_SPINFI_SEL, 1, 1),
+ TOP_FACTOR(CK_INFRA_PWM, "infra_pwm", CK_TOP_PWM_SEL, 1, 1),
+ TOP_FACTOR(CK_INFRA_66M_MCK, "infra_66m_mck", CK_TOP_SYSAXI_SEL, 1, 2),
+ TOP_FACTOR(CK_INFRA_CK_F32K, "infra_ck_f32k", CK_TOP_CB_RTC_32P7K, 1,
+ 1),
+ TOP_FACTOR(CK_INFRA_PCIE_CK, "infra_pcie", CK_TOP_PEXTP_TL_SEL, 1, 1),
+ INFRA_FACTOR(CK_INFRA_PWM_BCK, "infra_pwm_bck", CK_INFRA_PWM_BSEL, 1,
+ 1),
+ INFRA_FACTOR(CK_INFRA_PWM_CK1, "infra_pwm_ck1", CK_INFRA_PWM1_SEL, 1,
+ 1),
+ INFRA_FACTOR(CK_INFRA_PWM_CK2, "infra_pwm_ck2", CK_INFRA_PWM2_SEL, 1,
+ 1),
+ TOP_FACTOR(CK_INFRA_133M_HCK, "infra_133m_hck", CK_TOP_SYSAXI, 1, 1),
+ TOP_FACTOR(CK_INFRA_EIP_CK, "infra_eip", CK_TOP_EIP_B, 1, 1),
+ INFRA_FACTOR(CK_INFRA_66M_PHCK, "infra_66m_phck", CK_INFRA_133M_HCK, 1,
+ 1),
+ TOP_FACTOR(CK_INFRA_FAUD_L_CK, "infra_faud_l", CK_TOP_AUD_L, 1, 1),
+ TOP_FACTOR(CK_INFRA_FAUD_AUD_CK, "infra_faud_aud", CK_TOP_A1SYS, 1, 1),
+ TOP_FACTOR(CK_INFRA_FAUD_EG2_CK, "infra_faud_eg2", CK_TOP_A_TUNER, 1,
+ 1),
+ TOP_FACTOR(CK_INFRA_I2CS_CK, "infra_i2cs", CK_TOP_I2C_BCK, 1, 1),
+ INFRA_FACTOR(CK_INFRA_MUX_UART0, "infra_mux_uart0", CK_INFRA_UART0_SEL,
+ 1, 1),
+ INFRA_FACTOR(CK_INFRA_MUX_UART1, "infra_mux_uart1", CK_INFRA_UART1_SEL,
+ 1, 1),
+ INFRA_FACTOR(CK_INFRA_MUX_UART2, "infra_mux_uart2", CK_INFRA_UART2_SEL,
+ 1, 1),
+ TOP_FACTOR(CK_INFRA_NFI_CK, "infra_nfi", CK_TOP_NFI1X, 1, 1),
+ TOP_FACTOR(CK_INFRA_SPINFI_CK, "infra_spinfi", CK_TOP_SPINFI_BCK, 1, 1),
+ INFRA_FACTOR(CK_INFRA_MUX_SPI0, "infra_mux_spi0", CK_INFRA_SPI0_SEL, 1,
+ 1),
+ INFRA_FACTOR(CK_INFRA_MUX_SPI1, "infra_mux_spi1", CK_INFRA_SPI1_SEL, 1,
+ 1),
+ TOP_FACTOR(CK_INFRA_RTC_32K, "infra_rtc_32k", CK_TOP_CB_RTC_32K, 1, 1),
+ TOP_FACTOR(CK_INFRA_FMSDC_CK, "infra_fmsdc", CK_TOP_EMMC_416M, 1, 1),
+ TOP_FACTOR(CK_INFRA_FMSDC_HCK_CK, "infra_fmsdc_hck", CK_TOP_EMMC_250M,
+ 1, 1),
+ TOP_FACTOR(CK_INFRA_PERI_133M, "infra_peri_133m", CK_TOP_SYSAXI, 1, 1),
+ TOP_FACTOR(CK_INFRA_133M_PHCK, "infra_133m_phck", CK_TOP_SYSAXI, 1, 1),
+ TOP_FACTOR(CK_INFRA_USB_SYS_CK, "infra_usb_sys", CK_TOP_U2U3_SYS, 1, 1),
+ TOP_FACTOR(CK_INFRA_USB_CK, "infra_usb", CK_TOP_U2U3_REF, 1, 1),
+ TOP_FACTOR(CK_INFRA_USB_XHCI_CK, "infra_usb_xhci", CK_TOP_U2U3_XHCI, 1,
+ 1),
+ TOP_FACTOR(CK_INFRA_PCIE_GFMUX_TL_O_PRE, "infra_pcie_mux",
+ CK_TOP_PEXTP_TL, 1, 1),
+ TOP_FACTOR(CK_INFRA_F26M_CK0, "infra_f26m_ck0", CK_TOP_F26M, 1, 1),
+ TOP_FACTOR(CK_INFRA_HD_133M, "infra_hd_133m", CK_TOP_SYSAXI, 1, 1),
+};
+
+/* INFRASYS MUX PARENTS */
+static const int infra_uart0_parents[] = { CK_INFRA_CK_F26M, CK_INFRA_UART };
+
+static const int infra_spi0_parents[] = { CK_INFRA_I2C, CK_INFRA_ISPI0 };
+
+static const int infra_spi1_parents[] = { CK_INFRA_I2C, CK_INFRA_ISPI1 };
+
+static const int infra_pwm_bsel_parents[] = { CK_INFRA_CK_F32K,
+ CK_INFRA_CK_F26M,
+ CK_INFRA_66M_MCK, CK_INFRA_PWM };
+
+static const int infra_pcie_parents[] = { CK_INFRA_CK_F32K, CK_INFRA_CK_F26M,
+ -1, CK_INFRA_PCIE_CK };
+
+#define INFRA_MUX(_id, _name, _parents, _reg, _shift, _width) \
+ { \
+ .id = _id, .mux_reg = (_reg) + 0x8, \
+ .mux_set_reg = (_reg) + 0x0, .mux_clr_reg = (_reg) + 0x4, \
+ .mux_shift = _shift, .mux_mask = BIT(_width) - 1, \
+ .parent = _parents, .num_parents = ARRAY_SIZE(_parents), \
+ .flags = CLK_MUX_SETCLR_UPD | CLK_PARENT_INFRASYS, \
+ }
+
+/* INFRA MUX */
+
+static const struct mtk_composite infra_muxes[] = {
+ /* MODULE_CLK_SEL_0 */
+ INFRA_MUX(CK_INFRA_UART0_SEL, "infra_uart0_sel", infra_uart0_parents,
+ 0x10, 0, 1),
+ INFRA_MUX(CK_INFRA_UART1_SEL, "infra_uart1_sel", infra_uart0_parents,
+ 0x10, 1, 1),
+ INFRA_MUX(CK_INFRA_UART2_SEL, "infra_uart2_sel", infra_uart0_parents,
+ 0x10, 2, 1),
+ INFRA_MUX(CK_INFRA_SPI0_SEL, "infra_spi0_sel", infra_spi0_parents, 0x10,
+ 4, 1),
+ INFRA_MUX(CK_INFRA_SPI1_SEL, "infra_spi1_sel", infra_spi1_parents, 0x10,
+ 5, 1),
+ INFRA_MUX(CK_INFRA_PWM1_SEL, "infra_pwm1_sel", infra_pwm_bsel_parents,
+ 0x10, 9, 2),
+ INFRA_MUX(CK_INFRA_PWM2_SEL, "infra_pwm2_sel", infra_pwm_bsel_parents,
+ 0x10, 11, 2),
+ INFRA_MUX(CK_INFRA_PWM_BSEL, "infra_pwm_bsel", infra_pwm_bsel_parents,
+ 0x10, 13, 2),
+ /* MODULE_CLK_SEL_1 */
+ INFRA_MUX(CK_INFRA_PCIE_SEL, "infra_pcie_sel", infra_pcie_parents, 0x20,
+ 0, 2),
+};
+
+static const struct mtk_gate_regs infra_0_cg_regs = {
+ .set_ofs = 0x40,
+ .clr_ofs = 0x44,
+ .sta_ofs = 0x48,
+};
+
+static const struct mtk_gate_regs infra_1_cg_regs = {
+ .set_ofs = 0x50,
+ .clr_ofs = 0x54,
+ .sta_ofs = 0x58,
+};
+
+static const struct mtk_gate_regs infra_2_cg_regs = {
+ .set_ofs = 0x60,
+ .clr_ofs = 0x64,
+ .sta_ofs = 0x68,
+};
+
+#define GATE_INFRA0(_id, _name, _parent, _shift) \
+ { \
+ .id = _id, .parent = _parent, .regs = &infra_0_cg_regs, \
+ .shift = _shift, \
+ .flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS, \
+ }
+
+#define GATE_INFRA1(_id, _name, _parent, _shift) \
+ { \
+ .id = _id, .parent = _parent, .regs = &infra_1_cg_regs, \
+ .shift = _shift, \
+ .flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS, \
+ }
+
+#define GATE_INFRA2(_id, _name, _parent, _shift) \
+ { \
+ .id = _id, .parent = _parent, .regs = &infra_2_cg_regs, \
+ .shift = _shift, \
+ .flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS, \
+ }
+
+/* INFRA GATE */
+
+static const struct mtk_gate infracfg_ao_gates[] = {
+ /* INFRA0 */
+ GATE_INFRA0(CK_INFRA_GPT_STA, "infra_gpt_sta", CK_INFRA_66M_MCK, 0),
+ GATE_INFRA0(CK_INFRA_PWM_HCK, "infra_pwm_hck", CK_INFRA_66M_MCK, 1),
+ GATE_INFRA0(CK_INFRA_PWM_STA, "infra_pwm_sta", CK_INFRA_PWM_BCK, 2),
+ GATE_INFRA0(CK_INFRA_PWM1_CK, "infra_pwm1", CK_INFRA_PWM_CK1, 3),
+ GATE_INFRA0(CK_INFRA_PWM2_CK, "infra_pwm2", CK_INFRA_PWM_CK2, 4),
+ GATE_INFRA0(CK_INFRA_CQ_DMA_CK, "infra_cq_dma", CK_INFRA_133M_HCK, 6),
+ GATE_INFRA0(CK_INFRA_EIP97_CK, "infra_eip97", CK_INFRA_EIP_CK, 7),
+ GATE_INFRA0(CK_INFRA_AUD_BUS_CK, "infra_aud_bus", CK_INFRA_66M_PHCK, 8),
+ GATE_INFRA0(CK_INFRA_AUD_26M_CK, "infra_aud_26m", CK_INFRA_CK_F26M, 9),
+ GATE_INFRA0(CK_INFRA_AUD_L_CK, "infra_aud_l", CK_INFRA_FAUD_L_CK, 10),
+ GATE_INFRA0(CK_INFRA_AUD_AUD_CK, "infra_aud_aud", CK_INFRA_FAUD_AUD_CK,
+ 11),
+ GATE_INFRA0(CK_INFRA_AUD_EG2_CK, "infra_aud_eg2", CK_INFRA_FAUD_EG2_CK,
+ 13),
+ GATE_INFRA0(CK_INFRA_DRAMC_26M_CK, "infra_dramc_26m", CK_INFRA_CK_F26M,
+ 14),
+ GATE_INFRA0(CK_INFRA_DBG_CK, "infra_dbg", CK_INFRA_66M_MCK, 15),
+ GATE_INFRA0(CK_INFRA_AP_DMA_CK, "infra_ap_dma", CK_INFRA_66M_MCK, 16),
+ GATE_INFRA0(CK_INFRA_SEJ_CK, "infra_sej", CK_INFRA_66M_MCK, 24),
+ GATE_INFRA0(CK_INFRA_SEJ_13M_CK, "infra_sej_13m", CK_INFRA_CK_F26M, 25),
+ GATE_INFRA0(CK_INFRA_TRNG_CK, "infra_trng", CK_INFRA_HD_133M, 26),
+ /* INFRA1 */
+ GATE_INFRA1(CK_INFRA_THERM_CK, "infra_therm", CK_INFRA_CK_F26M, 0),
+ GATE_INFRA1(CK_INFRA_I2CO_CK, "infra_i2co", CK_INFRA_I2CS_CK, 1),
+ GATE_INFRA1(CK_INFRA_UART0_CK, "infra_uart0", CK_INFRA_MUX_UART0, 2),
+ GATE_INFRA1(CK_INFRA_UART1_CK, "infra_uart1", CK_INFRA_MUX_UART1, 3),
+ GATE_INFRA1(CK_INFRA_UART2_CK, "infra_uart2", CK_INFRA_MUX_UART2, 4),
+ GATE_INFRA1(CK_INFRA_NFI1_CK, "infra_nfi1", CK_INFRA_NFI_CK, 8),
+ GATE_INFRA1(CK_INFRA_SPINFI1_CK, "infra_spinfi1", CK_INFRA_SPINFI_CK,
+ 9),
+ GATE_INFRA1(CK_INFRA_NFI_HCK_CK, "infra_nfi_hck", CK_INFRA_66M_MCK, 10),
+ GATE_INFRA1(CK_INFRA_SPI0_CK, "infra_spi0", CK_INFRA_MUX_SPI0, 11),
+ GATE_INFRA1(CK_INFRA_SPI1_CK, "infra_spi1", CK_INFRA_MUX_SPI1, 12),
+ GATE_INFRA1(CK_INFRA_SPI0_HCK_CK, "infra_spi0_hck", CK_INFRA_66M_MCK,
+ 13),
+ GATE_INFRA1(CK_INFRA_SPI1_HCK_CK, "infra_spi1_hck", CK_INFRA_66M_MCK,
+ 14),
+ GATE_INFRA1(CK_INFRA_FRTC_CK, "infra_frtc", CK_INFRA_RTC_32K, 15),
+ GATE_INFRA1(CK_INFRA_MSDC_CK, "infra_msdc", CK_INFRA_FMSDC_CK, 16),
+ GATE_INFRA1(CK_INFRA_MSDC_HCK_CK, "infra_msdc_hck",
+ CK_INFRA_FMSDC_HCK_CK, 17),
+ GATE_INFRA1(CK_INFRA_MSDC_133M_CK, "infra_msdc_133m",
+ CK_INFRA_PERI_133M, 18),
+ GATE_INFRA1(CK_INFRA_MSDC_66M_CK, "infra_msdc_66m", CK_INFRA_66M_PHCK,
+ 19),
+ GATE_INFRA1(CK_INFRA_ADC_26M_CK, "infra_adc_26m", CK_INFRA_CK_F26M, 20),
+ GATE_INFRA1(CK_INFRA_ADC_FRC_CK, "infra_adc_frc", CK_INFRA_CK_F26M, 21),
+ GATE_INFRA1(CK_INFRA_FBIST2FPC_CK, "infra_fbist2fpc", CK_INFRA_NFI_CK,
+ 23),
+ /* INFRA2 */
+ GATE_INFRA2(CK_INFRA_IUSB_133_CK, "infra_iusb_133", CK_INFRA_133M_PHCK,
+ 0),
+ GATE_INFRA2(CK_INFRA_IUSB_66M_CK, "infra_iusb_66m", CK_INFRA_66M_PHCK,
+ 1),
+ GATE_INFRA2(CK_INFRA_IUSB_SYS_CK, "infra_iusb_sys", CK_INFRA_USB_SYS_CK,
+ 2),
+ GATE_INFRA2(CK_INFRA_IUSB_CK, "infra_iusb", CK_INFRA_USB_CK, 3),
+ GATE_INFRA2(CK_INFRA_IPCIE_CK, "infra_ipcie", CK_INFRA_PCIE_CK, 13),
+ GATE_INFRA2(CK_INFRA_IPCIER_CK, "infra_ipcier", CK_INFRA_F26M_CK0, 15),
+ GATE_INFRA2(CK_INFRA_IPCIEB_CK, "infra_ipcieb", CK_INFRA_133M_PHCK, 15),
+};
+
+static const struct mtk_clk_tree mt7986_fixed_pll_clk_tree = {
+ .fdivs_offs = CLK_APMIXED_NR_CLK,
+ .xtal_rate = 40 * MHZ,
+ .fclks = fixed_pll_clks,
+};
+
+static const struct mtk_clk_tree mt7986_topckgen_clk_tree = {
+ .fdivs_offs = CK_TOP_CB_M_416M,
+ .muxes_offs = CK_TOP_NFI1X_SEL,
+ .fclks = top_fixed_clks,
+ .fdivs = top_fixed_divs,
+ .muxes = top_muxes,
+ .flags = CLK_BYPASS_XTAL,
+};
+
+static const struct mtk_clk_tree mt7986_infracfg_clk_tree = {
+ .fdivs_offs = CK_INFRA_CK_F26M,
+ .muxes_offs = CK_INFRA_UART0_SEL,
+ .fdivs = infra_fixed_divs,
+ .muxes = infra_muxes,
+};
+
+static const struct udevice_id mt7986_fixed_pll_compat[] = {
+ { .compatible = "mediatek,mt7986-fixed-plls" },
+ {}
+};
+
+static const struct udevice_id mt7986_topckgen_compat[] = {
+ { .compatible = "mediatek,mt7986-topckgen" },
+ {}
+};
+
+static int mt7986_fixed_pll_probe(struct udevice *dev)
+{
+ return mtk_common_clk_init(dev, &mt7986_fixed_pll_clk_tree);
+}
+
+static int mt7986_topckgen_probe(struct udevice *dev)
+{
+ struct mtk_clk_priv *priv = dev_get_priv(dev);
+
+ priv->base = dev_read_addr_ptr(dev);
+ writel(MT7986_CLK_PDN_EN_WRITE, priv->base + MT7986_CLK_PDN);
+
+ return mtk_common_clk_init(dev, &mt7986_topckgen_clk_tree);
+}
+
+U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
+ .name = "mt7986-clock-fixed-pll",
+ .id = UCLASS_CLK,
+ .of_match = mt7986_fixed_pll_compat,
+ .probe = mt7986_fixed_pll_probe,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_topckgen_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(mtk_clk_topckgen) = {
+ .name = "mt7986-clock-topckgen",
+ .id = UCLASS_CLK,
+ .of_match = mt7986_topckgen_compat,
+ .probe = mt7986_topckgen_probe,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_topckgen_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+static const struct udevice_id mt7986_infracfg_compat[] = {
+ { .compatible = "mediatek,mt7986-infracfg" },
+ {}
+};
+
+static const struct udevice_id mt7986_infracfg_ao_compat[] = {
+ { .compatible = "mediatek,mt7986-infracfg_ao" },
+ {}
+};
+
+static int mt7986_infracfg_probe(struct udevice *dev)
+{
+ return mtk_common_clk_init(dev, &mt7986_infracfg_clk_tree);
+}
+
+static int mt7986_infracfg_ao_probe(struct udevice *dev)
+{
+ return mtk_common_clk_gate_init(dev, &mt7986_infracfg_clk_tree,
+ infracfg_ao_gates);
+}
+
+U_BOOT_DRIVER(mtk_clk_infracfg) = {
+ .name = "mt7986-clock-infracfg",
+ .id = UCLASS_CLK,
+ .of_match = mt7986_infracfg_compat,
+ .probe = mt7986_infracfg_probe,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_infrasys_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(mtk_clk_infracfg_ao) = {
+ .name = "mt7986-clock-infracfg-ao",
+ .id = UCLASS_CLK,
+ .of_match = mt7986_infracfg_ao_compat,
+ .probe = mt7986_infracfg_ao_probe,
+ .priv_auto = sizeof(struct mtk_cg_priv),
+ .ops = &mtk_clk_gate_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+/* ethsys */
+static const struct mtk_gate_regs eth_cg_regs = {
+ .sta_ofs = 0x30,
+};
+
+#define GATE_ETH(_id, _name, _parent, _shift) \
+ { \
+ .id = _id, .parent = _parent, .regs = ð_cg_regs, \
+ .shift = _shift, \
+ .flags = CLK_GATE_NO_SETCLR_INV | CLK_PARENT_TOPCKGEN, \
+ }
+
+static const struct mtk_gate eth_cgs[] = {
+ GATE_ETH(CK_ETH_FE_EN, "eth_fe_en", CK_TOP_NETSYS_2X, 7),
+ GATE_ETH(CK_ETH_GP2_EN, "eth_gp2_en", CK_TOP_SGM_325M, 8),
+ GATE_ETH(CK_ETH_GP1_EN, "eth_gp1_en", CK_TOP_SGM_325M, 8),
+ GATE_ETH(CK_ETH_WOCPU1_EN, "eth_wocpu1_en", CK_TOP_NETSYS_WED_MCU, 14),
+ GATE_ETH(CK_ETH_WOCPU0_EN, "eth_wocpu0_en", CK_TOP_NETSYS_WED_MCU, 15),
+};
+
+static int mt7986_ethsys_probe(struct udevice *dev)
+{
+ return mtk_common_clk_gate_init(dev, &mt7986_topckgen_clk_tree,
+ eth_cgs);
+}
+
+static int mt7986_ethsys_bind(struct udevice *dev)
+{
+ int ret = 0;
+
+ if (CONFIG_IS_ENABLED(RESET_MEDIATEK)) {
+ ret = mediatek_reset_bind(dev, ETHSYS_HIFSYS_RST_CTRL_OFS, 1);
+ if (ret)
+ debug("Warning: failed to bind reset controller\n");
+ }
+
+ return ret;
+}
+
+static const struct udevice_id mt7986_ethsys_compat[] = {
+ { .compatible = "mediatek,mt7986-ethsys" },
+ { }
+};
+
+U_BOOT_DRIVER(mtk_clk_ethsys) = {
+ .name = "mt7986-clock-ethsys",
+ .id = UCLASS_CLK,
+ .of_match = mt7986_ethsys_compat,
+ .probe = mt7986_ethsys_probe,
+ .bind = mt7986_ethsys_bind,
+ .priv_auto = sizeof(struct mtk_cg_priv),
+ .ops = &mtk_clk_gate_ops,
+};
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index d43b8a0..4303300 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -42,20 +42,14 @@
* the accurate frequency.
*/
static ulong mtk_clk_find_parent_rate(struct clk *clk, int id,
- const struct driver *drv)
+ struct udevice *pdev)
{
struct clk parent = { .id = id, };
- if (drv) {
- struct udevice *dev;
-
- if (uclass_get_device_by_driver(UCLASS_CLK, drv, &dev))
- return -ENODEV;
-
- parent.dev = dev;
- } else {
+ if (pdev)
+ parent.dev = pdev;
+ else
parent.dev = clk->dev;
- }
return clk_get_rate(&parent);
}
@@ -296,14 +290,36 @@
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);
break;
+ case CLK_PARENT_XTAL:
default:
rate = priv->tree->xtal_rate;
+ }
+
+ return mtk_factor_recalc_rate(fdiv, rate);
+}
+
+static ulong mtk_infrasys_get_factor_rate(struct clk *clk, u32 off)
+{
+ struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+ const struct mtk_fixed_factor *fdiv = &priv->tree->fdivs[off];
+ ulong rate;
+
+ switch (fdiv->flags & CLK_PARENT_MASK) {
+ case CLK_PARENT_TOPCKGEN:
+ rate = mtk_clk_find_parent_rate(clk, fdiv->parent,
+ priv->parent);
+ break;
+ case CLK_PARENT_XTAL:
+ rate = priv->tree->xtal_rate;
+ break;
+ default:
+ rate = mtk_clk_find_parent_rate(clk, fdiv->parent, NULL);
}
return mtk_factor_recalc_rate(fdiv, rate);
@@ -319,13 +335,51 @@
index &= mux->mux_mask << mux->mux_shift;
index = index >> mux->mux_shift;
- if (mux->parent[index])
- return mtk_clk_find_parent_rate(clk, mux->parent[index],
- NULL);
+ 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_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;
}
+static ulong mtk_infrasys_get_mux_rate(struct clk *clk, u32 off)
+{
+ struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+ const struct mtk_composite *mux = &priv->tree->muxes[off];
+ u32 index;
+
+ 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);
@@ -340,9 +394,28 @@
priv->tree->muxes_offs);
}
-static int mtk_topckgen_enable(struct clk *clk)
+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);
const struct mtk_composite *mux;
u32 val;
@@ -373,7 +446,7 @@
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;
@@ -399,7 +472,7 @@
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);
@@ -471,19 +544,7 @@
struct mtk_cg_priv *priv = dev_get_priv(clk->dev);
const struct mtk_gate *gate = &priv->gates[clk->id];
- switch (gate->flags & CLK_PARENT_MASK) {
- case CLK_PARENT_APMIXED:
- return mtk_clk_find_parent_rate(clk, gate->parent,
- DM_DRIVER_GET(mtk_clk_apmixedsys));
- break;
- case CLK_PARENT_TOPCKGEN:
- return mtk_clk_find_parent_rate(clk, gate->parent,
- DM_DRIVER_GET(mtk_clk_topckgen));
- break;
-
- default:
- return priv->tree->xtal_rate;
- }
+ return mtk_clk_find_parent_rate(clk, gate->parent, priv->parent);
}
const struct clk_ops mtk_clk_apmixedsys_ops = {
@@ -494,10 +555,17 @@
};
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_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 = {
@@ -510,11 +578,22 @@
const struct mtk_clk_tree *tree)
{
struct mtk_clk_priv *priv = dev_get_priv(dev);
+ struct udevice *parent;
+ int ret;
priv->base = dev_read_addr_ptr(dev);
if (!priv->base)
return -ENOENT;
+ ret = uclass_get_device_by_phandle(UCLASS_CLK, dev, "clock-parent", &parent);
+ if (ret || !parent) {
+ ret = uclass_get_device_by_driver(UCLASS_CLK,
+ DM_DRIVER_GET(mtk_clk_apmixedsys), &parent);
+ if (ret || !parent)
+ return -ENOENT;
+ }
+
+ priv->parent = parent;
priv->tree = tree;
return 0;
@@ -525,11 +604,22 @@
const struct mtk_gate *gates)
{
struct mtk_cg_priv *priv = dev_get_priv(dev);
+ struct udevice *parent;
+ int ret;
priv->base = dev_read_addr_ptr(dev);
if (!priv->base)
return -ENOENT;
+ ret = uclass_get_device_by_phandle(UCLASS_CLK, dev, "clock-parent", &parent);
+ if (ret || !parent) {
+ ret = uclass_get_device_by_driver(UCLASS_CLK,
+ DM_DRIVER_GET(mtk_clk_topckgen), &parent);
+ if (ret || !parent)
+ return -ENOENT;
+ }
+
+ priv->parent = parent;
priv->tree = tree;
priv->gates = gates;
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index 95a23d1..48ce164 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_XTAL BIT(0)
+
#define HAVE_RST_BAR BIT(0)
#define CLK_DOMAIN_SCPSYS BIT(0)
#define CLK_MUX_SETCLR_UPD BIT(1)
@@ -23,7 +28,9 @@
#define CLK_PARENT_APMIXED BIT(4)
#define CLK_PARENT_TOPCKGEN BIT(5)
-#define CLK_PARENT_MASK GENMASK(5, 4)
+#define CLK_PARENT_INFRASYS BIT(6)
+#define CLK_PARENT_XTAL BIT(7)
+#define CLK_PARENT_MASK GENMASK(7, 4)
#define ETHSYS_HIFSYS_RST_CTRL_OFS 0x34
@@ -197,14 +204,17 @@
const struct mtk_fixed_clk *fclks;
const struct mtk_fixed_factor *fdivs;
const struct mtk_composite *muxes;
+ u32 flags;
};
struct mtk_clk_priv {
+ struct udevice *parent;
void __iomem *base;
const struct mtk_clk_tree *tree;
};
struct mtk_cg_priv {
+ struct udevice *parent;
void __iomem *base;
const struct mtk_clk_tree *tree;
const struct mtk_gate *gates;
@@ -212,6 +222,7 @@
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,
diff --git a/drivers/cpu/Makefile b/drivers/cpu/Makefile
index 20884b1..3b38ba9 100644
--- a/drivers/cpu/Makefile
+++ b/drivers/cpu/Makefile
@@ -9,6 +9,7 @@
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 0000000..2a08be9
--- /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 <weijie.gao@mediatek.com>
+ */
+
+#include <linux/types.h>
+#include <cpu.h>
+#include <dm.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <asm/global_data.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+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, &val);
+
+ 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,
+ &args);
+ 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 = &mtk_cpu_ops,
+ .probe = mtk_cpu_probe,
+ .plat_auto = sizeof(struct mtk_cpu_plat),
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/ddr/fsl/lc_common_dimm_params.c b/drivers/ddr/fsl/lc_common_dimm_params.c
index d738ae3..5e4ad56 100644
--- a/drivers/ddr/fsl/lc_common_dimm_params.c
+++ b/drivers/ddr/fsl/lc_common_dimm_params.c
@@ -422,6 +422,9 @@
dimm_params[i].mpart);
#endif
}
+#ifndef CONFIG_SPL_BUILD
+ puts(" ");
+#endif
}
}
diff --git a/drivers/ddr/fsl/main.c b/drivers/ddr/fsl/main.c
index 1903562..ed3313a 100644
--- a/drivers/ddr/fsl/main.c
+++ b/drivers/ddr/fsl/main.c
@@ -857,17 +857,32 @@
debug("total_memory by %s = %llu\n", __func__, total_memory);
#if !defined(CONFIG_PHYS_64BIT)
- /* Check for 4G or more. Bad. */
- if ((first_ctrl == 0) && (total_memory >= (1ull << 32))) {
+ /*
+ * Show warning about big DDR moodules. But avoid warning for 4 GB DDR
+ * modules when U-Boot supports RAM of maximal size 4 GB - 1 byte.
+ */
+ if ((first_ctrl == 0) && (total_memory - 1 > (phys_size_t)~0ULL)) {
puts("Detected ");
print_size(total_memory, " of memory\n");
- printf(" This U-Boot only supports < 4G of DDR\n");
- printf(" You could rebuild it with CONFIG_PHYS_64BIT\n");
- printf(" "); /* re-align to match init_dram print */
- total_memory = CONFIG_MAX_MEM_MAPPED;
+#ifndef CONFIG_SPL_BUILD
+ puts(" "); /* re-align to match init_dram print */
+#endif
+ puts("This U-Boot only supports <= ");
+ print_size((unsigned long long)((phys_size_t)~0ULL)+1, " of DDR\n");
+#ifndef CONFIG_SPL_BUILD
+ puts(" "); /* re-align to match init_dram print */
+#endif
+ puts("You could rebuild it with CONFIG_PHYS_64BIT\n");
+#ifndef CONFIG_SPL_BUILD
+ puts(" "); /* re-align to match init_dram print */
+#endif
}
#endif
+ /* Ensure that total_memory does not overflow on return */
+ if (total_memory > (phys_size_t)~0ULL)
+ total_memory = (phys_size_t)~0ULL;
+
return total_memory;
}
@@ -941,5 +956,9 @@
/* Compute it once normally. */
total_memory = fsl_ddr_compute(&info, STEP_GET_SPD, 1);
+ /* Ensure that total_memory does not overflow on return */
+ if (total_memory > (phys_size_t)~0ULL)
+ total_memory = (phys_size_t)~0ULL;
+
return total_memory;
}
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index be4724b..08b6c7b 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -261,6 +261,15 @@
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 7e046f8..920aafb 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -32,6 +32,7 @@
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 0000000..5528bcd
--- /dev/null
+++ b/drivers/i2c/mtk_i2c.c
@@ -0,0 +1,822 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2022 MediaTek Inc. All Rights Reserved.
+ *
+ * Author: Mingming Lee <Mingming.Lee@mediatek.com>
+ *
+ * MediaTek I2C Interface driver
+ */
+
+#include <clk.h>
+#include <cpu_func.h>
+#include <dm.h>
+#include <i2c.h>
+#include <log.h>
+#include <asm/cache.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+
+#define I2C_RS_TRANSFER BIT(4)
+#define I2C_HS_NACKERR BIT(2)
+#define I2C_ACKERR BIT(1)
+#define I2C_TRANSAC_COMP BIT(0)
+#define I2C_TRANSAC_START BIT(0)
+#define I2C_RS_MUL_CNFG BIT(15)
+#define I2C_RS_MUL_TRIG BIT(14)
+#define I2C_DCM_DISABLE 0x0000
+#define I2C_IO_CONFIG_OPEN_DRAIN 0x0003
+#define I2C_IO_CONFIG_PUSH_PULL 0x0000
+#define I2C_SOFT_RST 0x0001
+#define I2C_FIFO_ADDR_CLR 0x0001
+#define I2C_DELAY_LEN 0x0002
+#define I2C_ST_START_CON 0x8001
+#define I2C_FS_START_CON 0x1800
+#define I2C_TIME_CLR_VALUE 0x0000
+#define I2C_TIME_DEFAULT_VALUE 0x0003
+#define I2C_WRRD_TRANAC_VALUE 0x0002
+#define I2C_RD_TRANAC_VALUE 0x0001
+
+#define I2C_DMA_CON_TX 0x0000
+#define I2C_DMA_CON_RX 0x0001
+#define I2C_DMA_START_EN 0x0001
+#define I2C_DMA_INT_FLAG_NONE 0x0000
+#define I2C_DMA_CLR_FLAG 0x0000
+#define I2C_DMA_TX_RX 0x0000
+#define I2C_DMA_HARD_RST 0x0002
+
+#define MAX_ST_MODE_SPEED 100000
+#define MAX_FS_MODE_SPEED 400000
+#define MAX_HS_MODE_SPEED 3400000
+#define MAX_SAMPLE_CNT_DIV 8
+#define MAX_STEP_CNT_DIV 64
+#define MAX_HS_STEP_CNT_DIV 8
+#define I2C_DEFAULT_CLK_DIV 4
+
+#define MAX_I2C_ADDR 0x7f
+#define MAX_I2C_LEN 0xff
+#define TRANS_ADDR_ONLY BIT(8)
+#define TRANSFER_TIMEOUT 50000 /* us */
+#define I2C_FIFO_STAT1_MASK 0x001f
+#define TIMING_SAMPLE_OFFSET 8
+#define HS_SAMPLE_OFFSET 12
+#define HS_STEP_OFFSET 8
+
+#define I2C_CONTROL_WRAPPER BIT(0)
+#define I2C_CONTROL_RS BIT(1)
+#define I2C_CONTROL_DMA_EN BIT(2)
+#define I2C_CONTROL_CLK_EXT_EN BIT(3)
+#define I2C_CONTROL_DIR_CHANGE BIT(4)
+#define I2C_CONTROL_ACKERR_DET_EN BIT(5)
+#define I2C_CONTROL_TRANSFER_LEN_CHANGE BIT(6)
+#define I2C_CONTROL_DMAACK BIT(8)
+#define I2C_CONTROL_ASYNC BIT(9)
+
+#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,
+ REG_FIFO_STAT1,
+ REG_LTIMING,
+ REG_FIFO_STAT,
+ REG_FIFO_THRESH,
+ REG_FIFO_ADDR_CLR,
+ REG_IO_CONFIG,
+ REG_RSV_DEBUG,
+ REG_HS,
+ REG_SOFTRESET,
+ REG_DCM_EN,
+ REG_PATH_DIR,
+ REG_DEBUGSTAT,
+ REG_DEBUGCTRL,
+ REG_TRANSFER_LEN_AUX,
+ REG_CLOCK_DIV,
+ REG_SCL_HL_RATIO,
+ REG_SCL_HS_HL_RATIO,
+ REG_SCL_MIS_COMP_POINT,
+ REG_STA_STOP_AC_TIME,
+ REG_HS_STA_STOP_AC_TIME,
+ REG_DATA_TIME,
+};
+
+enum DMA_REGS_OFFSET {
+ REG_INT_FLAG = 0x0,
+ REG_INT_EN = 0x04,
+ REG_EN = 0x08,
+ REG_RST = 0x0c,
+ REG_CON = 0x18,
+ REG_TX_MEM_ADDR = 0x1c,
+ REG_RX_MEM_ADDR = 0x20,
+ REG_TX_LEN = 0x24,
+ REG_RX_LEN = 0x28,
+};
+
+static const uint mt_i2c_regs_v1[] = {
+ [REG_PORT] = 0x0,
+ [REG_SLAVE_ADDR] = 0x4,
+ [REG_INTR_MASK] = 0x8,
+ [REG_INTR_STAT] = 0xc,
+ [REG_CONTROL] = 0x10,
+ [REG_TRANSFER_LEN] = 0x14,
+ [REG_TRANSAC_LEN] = 0x18,
+ [REG_DELAY_LEN] = 0x1c,
+ [REG_TIMING] = 0x20,
+ [REG_START] = 0x24,
+ [REG_EXT_CONF] = 0x28,
+ [REG_FIFO_STAT1] = 0x2c,
+ [REG_FIFO_STAT] = 0x30,
+ [REG_FIFO_THRESH] = 0x34,
+ [REG_FIFO_ADDR_CLR] = 0x38,
+ [REG_IO_CONFIG] = 0x40,
+ [REG_RSV_DEBUG] = 0x44,
+ [REG_HS] = 0x48,
+ [REG_SOFTRESET] = 0x50,
+ [REG_SOFTRESET] = 0x50,
+ [REG_DCM_EN] = 0x54,
+ [REG_DEBUGSTAT] = 0x64,
+ [REG_DEBUGCTRL] = 0x68,
+ [REG_TRANSFER_LEN_AUX] = 0x6c,
+ [REG_CLOCK_DIV] = 0x70,
+ [REG_SCL_HL_RATIO] = 0x74,
+ [REG_SCL_HS_HL_RATIO] = 0x78,
+ [REG_SCL_MIS_COMP_POINT] = 0x7c,
+ [REG_STA_STOP_AC_TIME] = 0x80,
+ [REG_HS_STA_STOP_AC_TIME] = 0x84,
+ [REG_DATA_TIME] = 0x88,
+};
+
+static const uint mt_i2c_regs_v2[] = {
+ [REG_PORT] = 0x0,
+ [REG_SLAVE_ADDR] = 0x4,
+ [REG_INTR_MASK] = 0x8,
+ [REG_INTR_STAT] = 0xc,
+ [REG_CONTROL] = 0x10,
+ [REG_TRANSFER_LEN] = 0x14,
+ [REG_TRANSAC_LEN] = 0x18,
+ [REG_DELAY_LEN] = 0x1c,
+ [REG_TIMING] = 0x20,
+ [REG_START] = 0x24,
+ [REG_EXT_CONF] = 0x28,
+ [REG_LTIMING] = 0x2c,
+ [REG_HS] = 0x30,
+ [REG_IO_CONFIG] = 0x34,
+ [REG_FIFO_ADDR_CLR] = 0x38,
+ [REG_TRANSFER_LEN_AUX] = 0x44,
+ [REG_CLOCK_DIV] = 0x48,
+ [REG_SOFTRESET] = 0x50,
+ [REG_DEBUGSTAT] = 0xe0,
+ [REG_DEBUGCTRL] = 0xe8,
+ [REG_FIFO_STAT] = 0xf4,
+ [REG_FIFO_THRESH] = 0xf8,
+ [REG_DCM_EN] = 0xf88,
+};
+
+struct mtk_i2c_soc_data {
+ const uint *regs;
+ uint dma_sync: 1;
+};
+
+struct mtk_i2c_priv {
+ /* set in i2c probe */
+ void __iomem *base; /* i2c base addr */
+ void __iomem *pdmabase; /* dma base address*/
+ struct clk clk_main; /* main clock for i2c bus */
+ struct clk clk_dma; /* DMA clock for i2c via DMA */
+ const struct mtk_i2c_soc_data *soc_data; /* Compatible data for different IC */
+ int op; /* operation mode */
+ bool zero_len; /* Only transfer slave address, no data */
+ bool pushpull; /* push pull mode or open drain mode */
+ bool filter_msg; /* filter msg error log */
+ bool auto_restart; /* restart mode */
+ bool ignore_restart_irq; /* ignore restart IRQ */
+ uint speed; /* i2c speed, unit: hz */
+};
+
+static inline void i2c_writel(struct mtk_i2c_priv *priv, uint reg, uint value)
+{
+ u32 offset = priv->soc_data->regs[reg];
+
+ writel(value, priv->base + offset);
+}
+
+static inline uint i2c_readl(struct mtk_i2c_priv *priv, uint offset)
+{
+ return readl(priv->base + priv->soc_data->regs[offset]);
+}
+
+static int mtk_i2c_clk_enable(struct mtk_i2c_priv *priv)
+{
+ int ret;
+
+ ret = clk_enable(&priv->clk_main);
+ if (ret)
+ return log_msg_ret("enable clk_main", ret);
+
+ ret = clk_enable(&priv->clk_dma);
+ if (ret)
+ return log_msg_ret("enable clk_dma", ret);
+
+ return 0;
+}
+
+static int mtk_i2c_clk_disable(struct mtk_i2c_priv *priv)
+{
+ int ret;
+
+ ret = clk_disable(&priv->clk_dma);
+ if (ret)
+ return log_msg_ret("disable clk_dma", ret);
+
+ ret = clk_disable(&priv->clk_main);
+ if (ret)
+ return log_msg_ret("disable clk_main", ret);
+
+ return 0;
+}
+
+static void mtk_i2c_init_hw(struct mtk_i2c_priv *priv)
+{
+ uint control_reg;
+
+ writel(I2C_DMA_HARD_RST, priv->pdmabase + REG_RST);
+ writel(I2C_DMA_CLR_FLAG, priv->pdmabase + REG_RST);
+ i2c_writel(priv, REG_SOFTRESET, I2C_SOFT_RST);
+ /* set ioconfig */
+ if (priv->pushpull)
+ i2c_writel(priv, REG_IO_CONFIG, I2C_IO_CONFIG_PUSH_PULL);
+ else
+ i2c_writel(priv, REG_IO_CONFIG, I2C_IO_CONFIG_OPEN_DRAIN);
+
+ i2c_writel(priv, REG_DCM_EN, I2C_DCM_DISABLE);
+ control_reg = I2C_CONTROL_ACKERR_DET_EN | I2C_CONTROL_CLK_EXT_EN;
+ if (priv->soc_data->dma_sync)
+ control_reg |= I2C_CONTROL_DMAACK | I2C_CONTROL_ASYNC;
+ i2c_writel(priv, REG_CONTROL, control_reg);
+ i2c_writel(priv, REG_DELAY_LEN, I2C_DELAY_LEN);
+}
+
+/*
+ * Calculate i2c port speed
+ *
+ * Hardware design:
+ * i2c_bus_freq = parent_clk / (clock_div * 2 * sample_cnt * step_cnt)
+ * clock_div: fixed in hardware, but may be various in different SoCs
+ *
+ * The calculation want to pick the highest bus frequency that is still
+ * less than or equal to target_speed. The calculation try to get
+ * sample_cnt and step_cn
+ * @param[in]
+ * clk_src: i2c clock source
+ * @param[out]
+ * timing_step_cnt: step cnt calculate result
+ * @param[out]
+ * timing_sample_cnt: sample cnt calculate result
+ * @return
+ * 0, set speed successfully.
+ * -EINVAL, Unsupported speed.
+ */
+static int mtk_i2c_calculate_speed(uint clk_src,
+ uint target_speed,
+ uint *timing_step_cnt,
+ uint *timing_sample_cnt)
+{
+ uint base_sample_cnt = MAX_SAMPLE_CNT_DIV;
+ uint base_step_cnt;
+ uint max_step_cnt;
+ uint sample_cnt;
+ uint step_cnt;
+ uint opt_div;
+ uint best_mul;
+ uint cnt_mul;
+
+ if (target_speed > MAX_HS_MODE_SPEED)
+ target_speed = MAX_HS_MODE_SPEED;
+
+ if (target_speed > MAX_FS_MODE_SPEED)
+ max_step_cnt = MAX_HS_STEP_CNT_DIV;
+ else
+ max_step_cnt = MAX_STEP_CNT_DIV;
+
+ base_step_cnt = max_step_cnt;
+ /* Find the best combination */
+ opt_div = DIV_ROUND_UP(clk_src >> 1, target_speed);
+ best_mul = MAX_SAMPLE_CNT_DIV * max_step_cnt;
+
+ /*
+ * Search for the best pair (sample_cnt, step_cnt) with
+ * 0 < sample_cnt < MAX_SAMPLE_CNT_DIV
+ * 0 < step_cnt < max_step_cnt
+ * sample_cnt * step_cnt >= opt_div
+ * optimizing for sample_cnt * step_cnt being minimal
+ */
+ for (sample_cnt = 1; sample_cnt <= MAX_SAMPLE_CNT_DIV; sample_cnt++) {
+ step_cnt = DIV_ROUND_UP(opt_div, sample_cnt);
+ cnt_mul = step_cnt * sample_cnt;
+ if (step_cnt > max_step_cnt)
+ continue;
+
+ if (cnt_mul < best_mul) {
+ best_mul = cnt_mul;
+ base_sample_cnt = sample_cnt;
+ base_step_cnt = step_cnt;
+ if (best_mul == opt_div)
+ break;
+ }
+ }
+
+ sample_cnt = base_sample_cnt;
+ step_cnt = base_step_cnt;
+
+ if ((clk_src / (2 * sample_cnt * step_cnt)) > target_speed) {
+ /*
+ * In this case, hardware can't support such
+ * low i2c_bus_freq
+ */
+ debug("Unsupported speed(%uhz)\n", target_speed);
+ return log_msg_ret("calculate speed", -EINVAL);
+ }
+
+ *timing_step_cnt = step_cnt - 1;
+ *timing_sample_cnt = sample_cnt - 1;
+
+ return 0;
+}
+
+/*
+ * mtk_i2c_set_speed
+ *
+ * @par Description
+ * Calculate i2c speed and write sample_cnt, step_cnt to TIMING register.
+ * @param[in]
+ * dev: udevice pointer, struct udevice contains i2c source clock,
+ * clock divide and speed.
+ * @return
+ * 0, set speed successfully.\n
+ * error code from mtk_i2c_calculate_speed().
+ */
+static int mtk_i2c_set_speed(struct udevice *dev, uint speed)
+{
+ struct mtk_i2c_priv *priv = dev_get_priv(dev);
+ uint high_speed_reg;
+ uint sample_cnt;
+ uint timing_reg;
+ uint step_cnt;
+ uint clk_src;
+ int ret = 0;
+
+ priv->speed = speed;
+ if (mtk_i2c_clk_enable(priv))
+ return log_msg_ret("set_speed enable clk", -1);
+
+ clk_src = clk_get_rate(&priv->clk_main) / I2C_DEFAULT_CLK_DIV;
+ i2c_writel(priv, REG_CLOCK_DIV, (I2C_DEFAULT_CLK_DIV - 1));
+ if (priv->speed > MAX_FS_MODE_SPEED) {
+ /* Set master code speed register */
+ ret = mtk_i2c_calculate_speed(clk_src, MAX_FS_MODE_SPEED,
+ &step_cnt, &sample_cnt);
+ if (ret < 0)
+ goto exit;
+
+ timing_reg = (sample_cnt << TIMING_SAMPLE_OFFSET) | step_cnt;
+ i2c_writel(priv, REG_TIMING, timing_reg);
+ /* Set the high speed mode register */
+ ret = mtk_i2c_calculate_speed(clk_src, priv->speed,
+ &step_cnt, &sample_cnt);
+ if (ret < 0)
+ goto exit;
+
+ high_speed_reg = I2C_TIME_DEFAULT_VALUE |
+ (sample_cnt << HS_SAMPLE_OFFSET) |
+ (step_cnt << HS_STEP_OFFSET);
+ i2c_writel(priv, REG_HS, high_speed_reg);
+ } else {
+ ret = mtk_i2c_calculate_speed(clk_src, priv->speed,
+ &step_cnt, &sample_cnt);
+ if (ret < 0)
+ goto exit;
+
+ timing_reg = (sample_cnt << TIMING_SAMPLE_OFFSET) | step_cnt;
+ /* Disable the high speed transaction */
+ high_speed_reg = I2C_TIME_CLR_VALUE;
+ i2c_writel(priv, REG_TIMING, timing_reg);
+ i2c_writel(priv, REG_HS, high_speed_reg);
+ }
+exit:
+ if (mtk_i2c_clk_disable(priv))
+ return log_msg_ret("set_speed disable clk", -1);
+
+ return ret;
+}
+
+/*
+ * mtk_i2c_do_transfer
+ *
+ * @par Description
+ * Configure i2c register and trigger transfer.
+ * @param[in]
+ * priv: mtk_i2cmtk_i2c_priv pointer, struct mtk_i2c_priv contains register base\n
+ * address, operation mode, interrupt status and i2c driver data.
+ * @param[in]
+ * msgs: i2c_msg pointer, struct i2c_msg contains slave\n
+ * address, operation mode, msg length and data buffer.
+ * @param[in]
+ * num: i2c_msg number.
+ * @param[in]
+ * left_num: left i2c_msg number.
+ * @return
+ * 0, i2c transfer successfully.\n
+ * -ETIMEDOUT, i2c transfer timeout.\n
+ * -EREMOTEIO, i2c transfer ack error.
+ */
+static int mtk_i2c_do_transfer(struct mtk_i2c_priv *priv,
+ struct i2c_msg *msgs,
+ int num, int left_num)
+{
+ struct i2c_msg *msg_rx = NULL;
+ uint restart_flag = 0;
+ uint trans_error = 0;
+ uint irq_stat = 0;
+ uint tmo_poll = 0;
+ uint control_reg;
+ bool tmo = false;
+ uint start_reg;
+ uint addr_reg;
+ int ret = 0;
+
+ if (priv->auto_restart)
+ restart_flag = I2C_RS_TRANSFER;
+
+ control_reg = i2c_readl(priv, REG_CONTROL) &
+ ~(I2C_CONTROL_DIR_CHANGE | I2C_CONTROL_RS);
+
+ if (priv->speed > MAX_FS_MODE_SPEED || num > 1)
+ control_reg |= I2C_CONTROL_RS;
+
+ if (priv->op == I2C_MASTER_WRRD)
+ control_reg |= I2C_CONTROL_DIR_CHANGE | I2C_CONTROL_RS;
+
+ control_reg |= I2C_CONTROL_DMA_EN;
+ i2c_writel(priv, REG_CONTROL, control_reg);
+
+ /* set start condition */
+ if (priv->speed <= MAX_ST_MODE_SPEED)
+ i2c_writel(priv, REG_EXT_CONF, I2C_ST_START_CON);
+ else
+ i2c_writel(priv, REG_EXT_CONF, I2C_FS_START_CON);
+
+ addr_reg = msgs->addr << 1;
+ if (priv->op == I2C_MASTER_RD)
+ addr_reg |= I2C_M_RD;
+ if (priv->zero_len)
+ i2c_writel(priv, REG_SLAVE_ADDR, addr_reg | TRANS_ADDR_ONLY);
+ else
+ i2c_writel(priv, REG_SLAVE_ADDR, addr_reg);
+
+ /* clear interrupt status */
+ i2c_writel(priv, REG_INTR_STAT, restart_flag | I2C_HS_NACKERR |
+ I2C_ACKERR | I2C_TRANSAC_COMP);
+ i2c_writel(priv, REG_FIFO_ADDR_CLR, I2C_FIFO_ADDR_CLR);
+
+ /* enable interrupt */
+ i2c_writel(priv, REG_INTR_MASK, restart_flag | I2C_HS_NACKERR |
+ I2C_ACKERR | I2C_TRANSAC_COMP);
+
+ /* set transfer and transaction len */
+ if (priv->op == I2C_MASTER_WRRD) {
+ i2c_writel(priv, REG_TRANSFER_LEN, msgs->len);
+ i2c_writel(priv, REG_TRANSFER_LEN_AUX, (msgs + 1)->len);
+ i2c_writel(priv, REG_TRANSAC_LEN, I2C_WRRD_TRANAC_VALUE);
+ } else {
+ i2c_writel(priv, REG_TRANSFER_LEN, msgs->len);
+ i2c_writel(priv, REG_TRANSAC_LEN, num);
+ }
+
+ /* Clear DMA interrupt flag */
+ writel(I2C_DMA_INT_FLAG_NONE, priv->pdmabase + REG_INT_FLAG);
+
+ /* Flush cache for first msg */
+ flush_cache((ulong)msgs->buf, msgs->len);
+
+ /*
+ * prepare buffer data to start transfer
+ * three cases here: read, write, write then read
+ */
+ if (priv->op & I2C_MASTER_WR) {
+ /* Set DMA direction TX (w/ or w/o RX) */
+ writel(I2C_DMA_CON_TX, priv->pdmabase + REG_CON);
+
+ /* Write the tx buffer address to dma register */
+ writel((ulong)msgs->buf, priv->pdmabase + REG_TX_MEM_ADDR);
+ /* Write the tx length to dma register */
+ writel(msgs->len, priv->pdmabase + REG_TX_LEN);
+
+ if (priv->op & I2C_MASTER_RD) {
+ /* write then read */
+ msg_rx = msgs + 1;
+
+ /* Flush cache for second msg */
+ flush_cache((ulong)msg_rx->buf, msg_rx->len);
+ }
+ }
+
+ if (priv->op & I2C_MASTER_RD) {
+ if (!msg_rx) {
+ /* Set DMA direction RX */
+ writel(I2C_DMA_CON_RX, priv->pdmabase + REG_CON);
+
+ msg_rx = msgs;
+ }
+
+ /* Write the rx buffer address to dma register */
+ writel((ulong)msg_rx->buf, priv->pdmabase + REG_RX_MEM_ADDR);
+ /* Write the rx length to dma register */
+ writel(msg_rx->len, priv->pdmabase + REG_RX_LEN);
+ }
+
+ writel(I2C_DMA_START_EN, priv->pdmabase + REG_EN);
+
+ if (!priv->auto_restart) {
+ start_reg = I2C_TRANSAC_START;
+ } else {
+ start_reg = I2C_TRANSAC_START | I2C_RS_MUL_TRIG;
+ if (left_num >= 1)
+ start_reg |= I2C_RS_MUL_CNFG;
+ }
+ i2c_writel(priv, REG_START, start_reg);
+
+ for (;;) {
+ irq_stat = i2c_readl(priv, REG_INTR_STAT);
+
+ /* ignore the first restart irq after the master code */
+ if (priv->ignore_restart_irq && (irq_stat & restart_flag)) {
+ priv->ignore_restart_irq = false;
+ irq_stat = 0;
+ i2c_writel(priv, REG_START, I2C_RS_MUL_CNFG |
+ I2C_RS_MUL_TRIG | I2C_TRANSAC_START);
+ }
+
+ if (irq_stat & (I2C_TRANSAC_COMP | restart_flag)) {
+ tmo = false;
+ if (irq_stat & (I2C_HS_NACKERR | I2C_ACKERR))
+ trans_error = 1;
+
+ break;
+ }
+ udelay(1);
+ if (tmo_poll++ >= TRANSFER_TIMEOUT) {
+ tmo = true;
+ break;
+ }
+ }
+
+ /* clear interrupt mask */
+ i2c_writel(priv, REG_INTR_MASK, ~(restart_flag | I2C_HS_NACKERR |
+ I2C_ACKERR | I2C_TRANSAC_COMP));
+
+ if (!tmo && trans_error != 0) {
+ if (tmo) {
+ ret = -ETIMEDOUT;
+ if (!priv->filter_msg)
+ debug("I2C timeout! addr: 0x%x,\n", msgs->addr);
+ } else {
+ ret = -EREMOTEIO;
+ if (!priv->filter_msg)
+ debug("I2C ACKERR! addr: 0x%x,IRQ:0x%x\n",
+ msgs->addr, irq_stat);
+ }
+ mtk_i2c_init_hw(priv);
+ }
+
+ return ret;
+}
+
+/*
+ * mtk_i2c_transfer
+ *
+ * @par Description
+ * Common i2c transfer API. Set i2c transfer mode according to i2c_msg\n
+ * information, then call mtk_i2c_do_transfer() to configure i2c register\n
+ * and trigger transfer.
+ * @param[in]
+ * dev: udevice pointer, struct udevice contains struct mtk_i2c_priv, \n
+ * struct mtk_i2c_priv contains register base\n
+ * address, operation mode, interrupt status and i2c driver data.
+ * @param[in]
+ * msgs: i2c_msg pointer, struct i2c_msg contains slave\n
+ * address, operation mode, msg length and data buffer.
+ * @param[in]
+ * num: i2c_msg number.
+ * @return
+ * i2c_msg number, i2c transfer successfully.\n
+ * -EINVAL, msg length is more than 16\n
+ * use DMA MODE or slave address more than 0x7f.\n
+ * error code from mtk_i2c_init_base().\n
+ * error code from mtk_i2c_set_speed().\n
+ * error code from mtk_i2c_do_transfer().
+ */
+static int mtk_i2c_transfer(struct udevice *dev, struct i2c_msg *msg,
+ int nmsgs)
+{
+ struct mtk_i2c_priv *priv = dev_get_priv(dev);
+ int left_num;
+ uint num_cnt;
+ int ret;
+
+ priv->auto_restart = true;
+ left_num = nmsgs;
+ if (mtk_i2c_clk_enable(priv))
+ return log_msg_ret("transfer enable clk", -1);
+
+ for (num_cnt = 0; num_cnt < nmsgs; num_cnt++) {
+ if (((msg + num_cnt)->addr) > MAX_I2C_ADDR) {
+ ret = -EINVAL;
+ goto err_exit;
+ }
+ if ((msg + num_cnt)->len > MAX_I2C_LEN) {
+ ret = -EINVAL;
+ goto err_exit;
+ }
+ }
+
+ /* check if we can skip restart and optimize using WRRD mode */
+ if (priv->auto_restart && nmsgs == 2) {
+ if (!(msg[0].flags & I2C_M_RD) && (msg[1].flags & I2C_M_RD) &&
+ msg[0].addr == msg[1].addr) {
+ priv->auto_restart = false;
+ }
+ }
+
+ if (priv->auto_restart && nmsgs >= 2 && priv->speed > MAX_FS_MODE_SPEED)
+ /* ignore the first restart irq after the master code,
+ * otherwise the first transfer will be discarded.
+ */
+ priv->ignore_restart_irq = true;
+ else
+ priv->ignore_restart_irq = false;
+
+ while (left_num--) {
+ /* transfer slave address only to support devices detect */
+ if (!msg->buf)
+ priv->zero_len = true;
+ else
+ priv->zero_len = false;
+
+ if (msg->flags & I2C_M_RD)
+ priv->op = I2C_MASTER_RD;
+ else
+ priv->op = I2C_MASTER_WR;
+
+ if (!priv->auto_restart) {
+ if (nmsgs > 1) {
+ /* combined two messages into one transaction */
+ priv->op = I2C_MASTER_WRRD;
+ left_num--;
+ }
+ }
+ ret = mtk_i2c_do_transfer(priv, msg, nmsgs, left_num);
+ if (ret < 0)
+ goto err_exit;
+ msg++;
+ }
+ ret = 0;
+
+err_exit:
+ if (mtk_i2c_clk_disable(priv))
+ return log_msg_ret("transfer disable clk", -1);
+
+ return ret;
+}
+
+static int mtk_i2c_of_to_plat(struct udevice *dev)
+{
+ struct mtk_i2c_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ priv->base = dev_remap_addr_index(dev, 0);
+ priv->pdmabase = dev_remap_addr_index(dev, 1);
+ ret = clk_get_by_index(dev, 0, &priv->clk_main);
+ if (ret)
+ return log_msg_ret("clk_get_by_index 0", ret);
+
+ ret = clk_get_by_index(dev, 1, &priv->clk_dma);
+
+ return ret;
+}
+
+static int mtk_i2c_probe(struct udevice *dev)
+{
+ struct mtk_i2c_priv *priv = dev_get_priv(dev);
+
+ priv->soc_data = (struct mtk_i2c_soc_data *)dev_get_driver_data(dev);
+
+ if (mtk_i2c_clk_enable(priv))
+ return log_msg_ret("probe enable clk", -1);
+
+ mtk_i2c_init_hw(priv);
+
+ if (mtk_i2c_clk_disable(priv))
+ return log_msg_ret("probe disable clk", -1);
+
+ return 0;
+}
+
+static int mtk_i2c_deblock(struct udevice *dev)
+{
+ struct mtk_i2c_priv *priv = dev_get_priv(dev);
+
+ if (mtk_i2c_clk_enable(priv))
+ return log_msg_ret("deblock enable clk", -1);
+
+ mtk_i2c_init_hw(priv);
+
+ if (mtk_i2c_clk_disable(priv))
+ return log_msg_ret("deblock disable clk", -1);
+
+ return 0;
+}
+
+static const struct mtk_i2c_soc_data mt76xx_soc_data = {
+ .regs = mt_i2c_regs_v1,
+ .dma_sync = 0,
+};
+
+static const struct mtk_i2c_soc_data mt7981_soc_data = {
+ .regs = mt_i2c_regs_v1,
+ .dma_sync = 1,
+};
+
+static const struct mtk_i2c_soc_data mt7986_soc_data = {
+ .regs = mt_i2c_regs_v1,
+ .dma_sync = 1,
+};
+
+static const struct mtk_i2c_soc_data mt8183_soc_data = {
+ .regs = mt_i2c_regs_v2,
+ .dma_sync = 1,
+};
+
+static const struct mtk_i2c_soc_data mt8518_soc_data = {
+ .regs = mt_i2c_regs_v1,
+ .dma_sync = 0,
+};
+
+static const struct mtk_i2c_soc_data mt8512_soc_data = {
+ .regs = mt_i2c_regs_v1,
+ .dma_sync = 1,
+};
+
+static const struct dm_i2c_ops mtk_i2c_ops = {
+ .xfer = mtk_i2c_transfer,
+ .set_bus_speed = mtk_i2c_set_speed,
+ .deblock = mtk_i2c_deblock,
+};
+
+static const struct udevice_id mtk_i2c_ids[] = {
+ {
+ .compatible = "mediatek,mt7622-i2c",
+ .data = (ulong)&mt76xx_soc_data,
+ }, {
+ .compatible = "mediatek,mt7623-i2c",
+ .data = (ulong)&mt76xx_soc_data,
+ }, {
+ .compatible = "mediatek,mt7629-i2c",
+ .data = (ulong)&mt76xx_soc_data,
+ }, {
+ .compatible = "mediatek,mt7981-i2c",
+ .data = (ulong)&mt7981_soc_data,
+ }, {
+ .compatible = "mediatek,mt7986-i2c",
+ .data = (ulong)&mt7986_soc_data,
+ }, {
+ .compatible = "mediatek,mt8183-i2c",
+ .data = (ulong)&mt8183_soc_data,
+ }, {
+ .compatible = "mediatek,mt8512-i2c",
+ .data = (ulong)&mt8512_soc_data,
+ }, {
+ .compatible = "mediatek,mt8518-i2c",
+ .data = (ulong)&mt8518_soc_data,
+ }
+};
+
+U_BOOT_DRIVER(mtk_i2c) = {
+ .name = "mtk_i2c",
+ .id = UCLASS_I2C,
+ .of_match = mtk_i2c_ids,
+ .of_to_plat = mtk_i2c_of_to_plat,
+ .probe = mtk_i2c_probe,
+ .priv_auto = sizeof(struct mtk_i2c_priv),
+ .ops = &mtk_i2c_ops,
+};
diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c
index b1bd4ae..759a6b7 100644
--- a/drivers/mmc/mmc-uclass.c
+++ b/drivers/mmc/mmc-uclass.c
@@ -472,7 +472,7 @@
ret = mmc_switch_part(mmc, hwpart);
if (!ret)
- blkcache_invalidate(desc->if_type, desc->devnum);
+ blkcache_invalidate(desc->uclass_id, desc->devnum);
return ret;
}
diff --git a/drivers/mmc/mmc_legacy.c b/drivers/mmc/mmc_legacy.c
index 4e0891e..a101ee4 100644
--- a/drivers/mmc/mmc_legacy.c
+++ b/drivers/mmc/mmc_legacy.c
@@ -132,7 +132,7 @@
.dsr_imp = 0,
.dsr = 0xffffffff,
.block_dev = {
- .if_type = UCLASS_MMC,
+ .uclass_id = UCLASS_MMC,
.removable = 1,
.devnum = 0,
.block_read = mmc_bread,
@@ -194,7 +194,7 @@
mmc->dsr = 0xffffffff;
/* Setup the universal parts of the block interface just once */
bdesc = mmc_get_blk_desc(mmc);
- bdesc->if_type = UCLASS_MMC;
+ bdesc->uclass_id = UCLASS_MMC;
bdesc->removable = 1;
bdesc->devnum = mmc_get_next_devnum();
bdesc->block_read = mmc_bread;
@@ -253,8 +253,8 @@
}
U_BOOT_LEGACY_BLK(mmc) = {
- .if_typename = "mmc",
- .if_type = UCLASS_MMC,
+ .uclass_idname = "mmc",
+ .uclass_id = UCLASS_MMC,
.max_devs = -1,
.get_dev = mmc_get_dev,
.select_hwpart = mmc_select_hwpartp,
diff --git a/drivers/mmc/mtk-sd.c b/drivers/mmc/mtk-sd.c
index e61e8cf..b206b0a 100644
--- a/drivers/mmc/mtk-sd.c
+++ b/drivers/mmc/mtk-sd.c
@@ -1496,7 +1496,12 @@
/* Enable data & cmd interrupts */
writel(DATA_INTS_MASK | CMD_INTS_MASK, &host->base->msdc_inten);
- writel(0, tune_reg);
+ if (host->top_base) {
+ writel(0, &host->top_base->emmc_top_control);
+ writel(0, &host->top_base->emmc_top_cmd);
+ } else {
+ writel(0, tune_reg);
+ }
writel(0, &host->base->msdc_iocon);
if (host->r_smpl)
@@ -1507,9 +1512,14 @@
writel(0x403c0046, &host->base->patch_bit0);
writel(0xffff4089, &host->base->patch_bit1);
- if (host->dev_comp->stop_clk_fix)
+ if (host->dev_comp->stop_clk_fix) {
clrsetbits_le32(&host->base->patch_bit1, MSDC_PB1_STOP_DLY_M,
3 << MSDC_PB1_STOP_DLY_S);
+ clrbits_le32(&host->base->sdc_fifo_cfg,
+ SDC_FIFO_CFG_WRVALIDSEL);
+ clrbits_le32(&host->base->sdc_fifo_cfg,
+ SDC_FIFO_CFG_RDVALIDSEL);
+ }
if (host->dev_comp->busy_check)
clrbits_le32(&host->base->patch_bit1, (1 << 7));
@@ -1544,15 +1554,28 @@
}
if (host->dev_comp->data_tune) {
- setbits_le32(tune_reg,
- MSDC_PAD_TUNE_RD_SEL | MSDC_PAD_TUNE_CMD_SEL);
- clrsetbits_le32(&host->base->patch_bit0,
- MSDC_INT_DAT_LATCH_CK_SEL_M,
- host->latch_ck <<
- MSDC_INT_DAT_LATCH_CK_SEL_S);
+ if (host->top_base) {
+ setbits_le32(&host->top_base->emmc_top_control,
+ PAD_DAT_RD_RXDLY_SEL);
+ clrbits_le32(&host->top_base->emmc_top_control,
+ DATA_K_VALUE_SEL);
+ setbits_le32(&host->top_base->emmc_top_cmd,
+ PAD_CMD_RD_RXDLY_SEL);
+ } else {
+ setbits_le32(tune_reg,
+ MSDC_PAD_TUNE_RD_SEL | MSDC_PAD_TUNE_CMD_SEL);
+ clrsetbits_le32(&host->base->patch_bit0,
+ MSDC_INT_DAT_LATCH_CK_SEL_M,
+ host->latch_ck <<
+ MSDC_INT_DAT_LATCH_CK_SEL_S);
+ }
} else {
/* choose clock tune */
- setbits_le32(tune_reg, MSDC_PAD_TUNE_RXDLYSEL);
+ if (host->top_base)
+ setbits_le32(&host->top_base->emmc_top_control,
+ PAD_RXDLY_SEL);
+ else
+ setbits_le32(tune_reg, MSDC_PAD_TUNE_RXDLYSEL);
}
if (host->dev_comp->builtin_pad_ctrl) {
@@ -1604,12 +1627,6 @@
clrsetbits_le32(&host->base->sdc_cfg, SDC_CFG_DTOC_M,
3 << SDC_CFG_DTOC_S);
- if (host->dev_comp->stop_clk_fix) {
- clrbits_le32(&host->base->sdc_fifo_cfg,
- SDC_FIFO_CFG_WRVALIDSEL);
- clrbits_le32(&host->base->sdc_fifo_cfg,
- SDC_FIFO_CFG_RDVALIDSEL);
- }
host->def_tune_para.iocon = readl(&host->base->msdc_iocon);
host->def_tune_para.pad_tune = readl(&host->base->pad_tune);
@@ -1792,6 +1809,25 @@
.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 @@
{ .compatible = "mediatek,mt7621-mmc", .data = (ulong)&mt7621_compat },
{ .compatible = "mediatek,mt7622-mmc", .data = (ulong)&mt7622_compat },
{ .compatible = "mediatek,mt7623-mmc", .data = (ulong)&mt7623_compat },
+ { .compatible = "mediatek,mt7986-mmc", .data = (ulong)&mt7986_compat },
+ { .compatible = "mediatek,mt7981-mmc", .data = (ulong)&mt7981_compat },
{ .compatible = "mediatek,mt8512-mmc", .data = (ulong)&mt8512_compat },
{ .compatible = "mediatek,mt8516-mmc", .data = (ulong)&mt8516_compat },
{ .compatible = "mediatek,mt8183-mmc", .data = (ulong)&mt8183_compat },
diff --git a/drivers/net/fsl_enetc.c b/drivers/net/fsl_enetc.c
index 835e5bd..d43a85b 100644
--- a/drivers/net/fsl_enetc.c
+++ b/drivers/net/fsl_enetc.c
@@ -146,7 +146,7 @@
if (!enetc_has_imdio(dev))
return 0;
- if (priv->if_type == PHY_INTERFACE_MODE_2500BASEX)
+ if (priv->uclass_id == PHY_INTERFACE_MODE_2500BASEX)
is2500 = true;
/*
@@ -221,7 +221,7 @@
struct enetc_priv *priv = dev_get_priv(dev);
u32 if_mode;
- switch (priv->if_type) {
+ switch (priv->uclass_id) {
case PHY_INTERFACE_MODE_RGMII:
case PHY_INTERFACE_MODE_RGMII_ID:
case PHY_INTERFACE_MODE_RGMII_RXID:
@@ -278,14 +278,14 @@
return;
}
- priv->if_type = dev_read_phy_mode(dev);
- if (priv->if_type == PHY_INTERFACE_MODE_NA) {
+ priv->uclass_id = dev_read_phy_mode(dev);
+ if (priv->uclass_id == PHY_INTERFACE_MODE_NA) {
enetc_dbg(dev,
"phy-mode property not found, defaulting to SGMII\n");
- priv->if_type = PHY_INTERFACE_MODE_SGMII;
+ priv->uclass_id = PHY_INTERFACE_MODE_SGMII;
}
- switch (priv->if_type) {
+ switch (priv->uclass_id) {
case PHY_INTERFACE_MODE_SGMII:
case PHY_INTERFACE_MODE_2500BASEX:
enetc_init_sgmii(dev);
diff --git a/drivers/net/fsl_enetc.h b/drivers/net/fsl_enetc.h
index 69f2f4a..f2acf36 100644
--- a/drivers/net/fsl_enetc.h
+++ b/drivers/net/fsl_enetc.h
@@ -158,7 +158,7 @@
struct bd_ring tx_bdr;
struct bd_ring rx_bdr;
- int if_type;
+ int uclass_id;
struct mii_dev imdio;
struct phy_device *phy;
};
diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c
index 4fe7ee0..4c9fb26 100644
--- a/drivers/net/mtk_eth.c
+++ b/drivers/net/mtk_eth.c
@@ -65,95 +65,34 @@
(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,
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
+ * @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;
};
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;
@@ -171,11 +110,12 @@
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;
int duplex;
+ bool pn_swap;
struct phy_device *phydev;
int phy_interface;
@@ -195,13 +135,13 @@
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,
@@ -679,7 +619,7 @@
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 +1048,8 @@
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,
@@ -1119,6 +1058,12 @@
/* 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);
@@ -1182,7 +1127,8 @@
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),
@@ -1198,14 +1144,16 @@
static void mtk_eth_fifo_init(struct mtk_eth_priv *priv)
{
char *pkt_base = priv->pkt_pool;
+ struct mtk_tx_dma_v2 *txd;
+ struct mtk_rx_dma_v2 *rxd;
int i;
mtk_pdma_rmw(priv, PDMA_GLO_CFG_REG, 0xffff0000, 0);
udelay(500);
- memset(priv->tx_ring_noc, 0, NUM_TX_DESC * sizeof(struct pdma_txdesc));
- memset(priv->rx_ring_noc, 0, NUM_RX_DESC * sizeof(struct pdma_rxdesc));
- memset(priv->pkt_pool, 0, TOTAL_PKT_BUF_SIZE);
+ memset(priv->tx_ring_noc, 0, NUM_TX_DESC * priv->soc->txd_size);
+ memset(priv->rx_ring_noc, 0, NUM_RX_DESC * priv->soc->rxd_size);
+ memset(priv->pkt_pool, 0xff, TOTAL_PKT_BUF_SIZE);
flush_dcache_range((ulong)pkt_base,
(ulong)(pkt_base + TOTAL_PKT_BUF_SIZE));
@@ -1214,17 +1162,29 @@
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;
- priv->tx_ring_noc[i].txd_info1.SDP0 = virt_to_phys(pkt_base);
+ 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;
}
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);
+
+ 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;
}
@@ -1252,6 +1212,9 @@
reset_deassert(&priv->rst_fe);
mdelay(10);
+ if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2))
+ setbits_le32(priv->fe_base + FE_GLO_MISC_REG, PDMA_VER_V2);
+
/* Packets forward to PDMA */
mtk_gdma_write(priv, priv->gmac_id, GDMA_IG_CTRL_REG, GDMA_FWD_TO_CPU);
@@ -1286,7 +1249,7 @@
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);
}
@@ -1311,20 +1274,25 @@
{
struct mtk_eth_priv *priv = dev_get_priv(dev);
u32 idx = priv->tx_cpu_owner_idx0;
+ struct mtk_tx_dma_v2 *txd;
void *pkt_base;
- if (!priv->tx_ring_noc[idx].txd_info2.DDONE) {
+ txd = priv->tx_ring_noc + idx * priv->soc->txd_size;
+
+ if (!(txd->txd2 & PDMA_TXD2_DDONE)) {
debug("mtk-eth: TX DMA descriptor ring is full\n");
return -EPERM;
}
- pkt_base = (void *)phys_to_virt(priv->tx_ring_noc[idx].txd_info1.SDP0);
+ pkt_base = (void *)phys_to_virt(txd->txd1);
memcpy(pkt_base, packet, length);
flush_dcache_range((ulong)pkt_base, (ulong)pkt_base +
roundup(length, ARCH_DMA_MINALIGN));
- priv->tx_ring_noc[idx].txd_info2.SDL0 = length;
- priv->tx_ring_noc[idx].txd_info2.DDONE = 0;
+ if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2))
+ txd->txd2 = PDMA_TXD2_LS0 | PDMA_V2_TXD2_SDL0_SET(length);
+ else
+ txd->txd2 = PDMA_TXD2_LS0 | PDMA_V1_TXD2_SDL0_SET(length);
priv->tx_cpu_owner_idx0 = (priv->tx_cpu_owner_idx0 + 1) % NUM_TX_DESC;
mtk_pdma_write(priv, TX_CTX_IDX_REG(0), priv->tx_cpu_owner_idx0);
@@ -1336,16 +1304,23 @@
{
struct mtk_eth_priv *priv = dev_get_priv(dev);
u32 idx = priv->rx_dma_owner_idx0;
+ struct mtk_rx_dma_v2 *rxd;
uchar *pkt_base;
u32 length;
- if (!priv->rx_ring_noc[idx].rxd_info2.DDONE) {
+ rxd = priv->rx_ring_noc + idx * priv->soc->rxd_size;
+
+ if (!(rxd->rxd2 & PDMA_RXD2_DDONE)) {
debug("mtk-eth: RX DMA descriptor ring is empty\n");
return -EAGAIN;
}
- length = priv->rx_ring_noc[idx].rxd_info2.PLEN0;
- pkt_base = (void *)phys_to_virt(priv->rx_ring_noc[idx].rxd_info1.PDP0);
+ if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2))
+ length = PDMA_V2_RXD2_PLEN0_GET(rxd->rxd2);
+ else
+ length = PDMA_V1_RXD2_PLEN0_GET(rxd->rxd2);
+
+ pkt_base = (void *)phys_to_virt(rxd->rxd1);
invalidate_dcache_range((ulong)pkt_base, (ulong)pkt_base +
roundup(length, ARCH_DMA_MINALIGN));
@@ -1359,10 +1334,14 @@
{
struct mtk_eth_priv *priv = dev_get_priv(dev);
u32 idx = priv->rx_dma_owner_idx0;
+ struct mtk_rx_dma_v2 *rxd;
+
+ rxd = priv->rx_ring_noc + idx * priv->soc->rxd_size;
- priv->rx_ring_noc[idx].rxd_info2.DDONE = 0;
- priv->rx_ring_noc[idx].rxd_info2.LS0 = 0;
- priv->rx_ring_noc[idx].rxd_info2.PLEN0 = PKTSIZE_ALIGN;
+ if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2))
+ rxd->rxd2 = PDMA_V2_RXD2_PLEN0_SET(PKTSIZE_ALIGN);
+ else
+ rxd->rxd2 = PDMA_V1_RXD2_PLEN0_SET(PKTSIZE_ALIGN);
mtk_pdma_write(priv, RX_CRX_IDX_REG(0), idx);
priv->rx_dma_owner_idx0 = (priv->rx_dma_owner_idx0 + 1) % NUM_RX_DESC;
@@ -1389,11 +1368,11 @@
return ret;
/* Prepare for tx/rx rings */
- priv->tx_ring_noc = (struct pdma_txdesc *)
- noncached_alloc(sizeof(struct pdma_txdesc) * NUM_TX_DESC,
+ priv->tx_ring_noc = (void *)
+ noncached_alloc(priv->soc->txd_size * NUM_TX_DESC,
ARCH_DMA_MINALIGN);
- priv->rx_ring_noc = (struct pdma_rxdesc *)
- noncached_alloc(sizeof(struct pdma_rxdesc) * NUM_RX_DESC,
+ priv->rx_ring_noc = (void *)
+ noncached_alloc(priv->soc->rxd_size * NUM_RX_DESC,
ARCH_DMA_MINALIGN);
/* Set MAC mode */
@@ -1431,7 +1410,11 @@
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);
@@ -1494,6 +1477,8 @@
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 */
@@ -1544,11 +1529,57 @@
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,
+ .txd_size = sizeof(struct mtk_tx_dma),
+ .rxd_size = sizeof(struct mtk_rx_dma),
+};
+
+static const struct mtk_soc_data mt7623_data = {
+ .caps = MT7623_CAPS,
+ .pdma_base = PDMA_V1_BASE,
+ .txd_size = sizeof(struct mtk_tx_dma),
+ .rxd_size = sizeof(struct mtk_rx_dma),
+};
+
+static const struct mtk_soc_data mt7622_data = {
+ .ana_rgc3 = 0x2028,
+ .pdma_base = PDMA_V1_BASE,
+ .txd_size = sizeof(struct mtk_tx_dma),
+ .rxd_size = sizeof(struct mtk_rx_dma),
+};
+
+static const struct mtk_soc_data mt7621_data = {
+ .caps = MT7621_CAPS,
+ .pdma_base = PDMA_V1_BASE,
+ .txd_size = sizeof(struct mtk_tx_dma),
+ .rxd_size = sizeof(struct mtk_rx_dma),
+};
+
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,mt7986-eth", .data = (ulong)&mt7986_data },
+ { .compatible = "mediatek,mt7981-eth", .data = (ulong)&mt7981_data },
+ { .compatible = "mediatek,mt7629-eth", .data = (ulong)&mt7629_data },
+ { .compatible = "mediatek,mt7623-eth", .data = (ulong)&mt7623_data },
+ { .compatible = "mediatek,mt7622-eth", .data = (ulong)&mt7622_data },
+ { .compatible = "mediatek,mt7621-eth", .data = (ulong)&mt7621_data },
{}
};
diff --git a/drivers/net/mtk_eth.h b/drivers/net/mtk_eth.h
index 057ecfa..1382ccb 100644
--- a/drivers/net/mtk_eth.h
+++ b/drivers/net/mtk_eth.h
@@ -9,9 +9,38 @@
#ifndef _MTK_ETH_H_
#define _MTK_ETH_H_
-/* Frame Engine Register Bases */
#include <linux/bitops.h>
-#define PDMA_BASE 0x0800
+#include <linux/bitfield.h>
+
+enum mkt_eth_capabilities {
+ MTK_TRGMII_BIT,
+ MTK_TRGMII_MT7621_CLK_BIT,
+ MTK_NETSYS_V2_BIT,
+
+ /* PATH BITS */
+ MTK_ETH_PATH_GMAC1_TRGMII_BIT,
+};
+
+#define MTK_TRGMII BIT(MTK_TRGMII_BIT)
+#define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT)
+#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_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII)
+
+#define MTK_HAS_CAPS(caps, _x) (((caps) & (_x)) == (_x))
+
+#define MT7621_CAPS (MTK_GMAC1_TRGMII | MTK_TRGMII_MT7621_CLK)
+
+#define MT7623_CAPS (MTK_GMAC1_TRGMII)
+
+#define MT7986_CAPS (MTK_NETSYS_V2)
+
+/* Frame Engine Register Bases */
+#define PDMA_V1_BASE 0x0800
+#define PDMA_V2_BASE 0x6000
#define GDMA1_BASE 0x0500
#define GDMA2_BASE 0x1500
#define GMAC_BASE 0x10000
@@ -45,11 +74,16 @@
#define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8
#define SGMII_PHYA_PWD BIT(4)
+#define SGMSYS_QPHY_WRAP_CTRL 0xec
+#define SGMII_PN_SWAP_TX_RX 0x03
+
#define SGMSYS_GEN2_SPEED 0x2028
#define SGMSYS_GEN2_SPEED_V2 0x128
#define SGMSYS_SPEED_2500 BIT(2)
/* Frame Engine Registers */
+#define FE_GLO_MISC_REG 0x124
+#define PDMA_VER_V2 BIT(4)
/* PDMA */
#define TX_BASE_PTR_REG(n) (0x000 + (n) * 0x10)
@@ -412,4 +446,67 @@
#define PHY_POWER_SAVING_M 0x300
#define PHY_POWER_SAVING_TX 0x0
+/* PDMA descriptors */
+struct mtk_rx_dma {
+ unsigned int rxd1;
+ unsigned int rxd2;
+ unsigned int rxd3;
+ unsigned int rxd4;
+} __packed __aligned(4);
+
+struct mtk_rx_dma_v2 {
+ unsigned int rxd1;
+ unsigned int rxd2;
+ unsigned int rxd3;
+ unsigned int rxd4;
+ unsigned int rxd5;
+ unsigned int rxd6;
+ unsigned int rxd7;
+ unsigned int rxd8;
+} __packed __aligned(4);
+
+struct mtk_tx_dma {
+ unsigned int txd1;
+ unsigned int txd2;
+ unsigned int txd3;
+ unsigned int txd4;
+} __packed __aligned(4);
+
+struct mtk_tx_dma_v2 {
+ unsigned int txd1;
+ unsigned int txd2;
+ unsigned int txd3;
+ unsigned int txd4;
+ unsigned int txd5;
+ unsigned int txd6;
+ unsigned int txd7;
+ unsigned int txd8;
+} __packed __aligned(4);
+
+/* PDMA TXD fields */
+#define PDMA_TXD2_DDONE BIT(31)
+#define PDMA_TXD2_LS0 BIT(30)
+#define PDMA_V1_TXD2_SDL0_M GENMASK(29, 16)
+#define PDMA_V1_TXD2_SDL0_SET(_v) FIELD_PREP(PDMA_V1_TXD2_SDL0_M, (_v))
+#define PDMA_V2_TXD2_SDL0_M GENMASK(23, 8)
+#define PDMA_V2_TXD2_SDL0_SET(_v) FIELD_PREP(PDMA_V2_TXD2_SDL0_M, (_v))
+
+#define PDMA_V1_TXD4_FPORT_M GENMASK(27, 25)
+#define PDMA_V1_TXD4_FPORT_SET(_v) FIELD_PREP(PDMA_V1_TXD4_FPORT_M, (_v))
+#define PDMA_V2_TXD4_FPORT_M GENMASK(27, 24)
+#define PDMA_V2_TXD4_FPORT_SET(_v) FIELD_PREP(PDMA_V2_TXD4_FPORT_M, (_v))
+
+#define PDMA_V2_TXD5_FPORT_M GENMASK(19, 16)
+#define PDMA_V2_TXD5_FPORT_SET(_v) FIELD_PREP(PDMA_V2_TXD5_FPORT_M, (_v))
+
+/* PDMA RXD fields */
+#define PDMA_RXD2_DDONE BIT(31)
+#define PDMA_RXD2_LS0 BIT(30)
+#define PDMA_V1_RXD2_PLEN0_M GENMASK(29, 16)
+#define PDMA_V1_RXD2_PLEN0_GET(_v) FIELD_GET(PDMA_V1_RXD2_PLEN0_M, (_v))
+#define PDMA_V1_RXD2_PLEN0_SET(_v) FIELD_PREP(PDMA_V1_RXD2_PLEN0_M, (_v))
+#define PDMA_V2_RXD2_PLEN0_M GENMASK(23, 8)
+#define PDMA_V2_RXD2_PLEN0_GET(_v) FIELD_GET(PDMA_V2_RXD2_PLEN0_M, (_v))
+#define PDMA_V2_RXD2_PLEN0_SET(_v) FIELD_PREP(PDMA_V2_RXD2_PLEN0_M, (_v))
+
#endif /* _MTK_ETH_H_ */
diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
index 58df508..27e8998 100644
--- a/drivers/pinctrl/mediatek/Kconfig
+++ b/drivers/pinctrl/mediatek/Kconfig
@@ -16,6 +16,14 @@
bool "MT7629 SoC pinctrl driver"
select PINCTRL_MTK
+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 d7e8cf1..6e73375 100644
--- a/drivers/pinctrl/mediatek/Makefile
+++ b/drivers/pinctrl/mediatek/Makefile
@@ -6,6 +6,8 @@
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-mt7981.c b/drivers/pinctrl/mediatek/pinctrl-mt7981.c
new file mode 100644
index 0000000..d887524
--- /dev/null
+++ b/drivers/pinctrl/mediatek/pinctrl-mt7981.c
@@ -0,0 +1,1049 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The MT7981 driver based on Linux generic pinctrl binding.
+ *
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+#include <dm.h>
+#include "pinctrl-mtk-common.h"
+
+#define MT7981_TYPE0_PIN(_number, _name) \
+ MTK_TYPED_PIN(_number, _name, DRV_GRP4, IO_TYPE_GRP0)
+
+#define MT7981_TYPE1_PIN(_number, _name) \
+ MTK_TYPED_PIN(_number, _name, DRV_GRP4, IO_TYPE_GRP1)
+
+#define PIN_FIELD_GPIO(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits) \
+ PIN_FIELD_BASE_CALC(_s_pin, _e_pin, GPIO_BASE, _s_addr, _x_addrs, \
+ _s_bit, _x_bits, 32, 0)
+
+#define PIN_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \
+ _x_bits) \
+ PIN_FIELD_BASE_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \
+ _x_bits, 32, 0)
+
+/**
+ * enum - Locking variants of the iocfg bases
+ *
+ * MT7981 have multiple bases to program pin configuration listed as the below:
+ * iocfg_rt:0x11c00000, iocfg_rm:0x11c10000, iocfg_rb:0x11d20000,
+ * iocfg_lb:0x11e00000, iocfg_bl:0x11e20000, iocfg_tm:0x11f00000,
+ * iocfg_tl:0x11f10000,
+ * _i_based could be used to indicate what base the pin should be mapped into.
+ *
+ * Each iocfg register base control different group of pads on the SoC
+ *
+ *
+ * chip carrier
+ *
+ * A B C D E F G H
+ * +------------------------+
+ * 8 | o o o o o o o o |
+ * 7 | o o o o o o o o |
+ * 6 | o o o o o o o o |
+ * 5 | o o o o o o o o |
+ * 4 | o o o o o o o o |
+ * 3 | o o o o o o o o |
+ * 2 | o o o o o o o o |
+ * 1 | o o o o o o o o |
+ * +------------------------+
+ *
+ * inside Chip carrier
+ *
+ * A B C D E F G H
+ * +------------------------+
+ * 8 | |
+ * 7 | TL TM |
+ * 6 | +---------+ |
+ * 5 | | | RT |
+ * 4 | | | RM |
+ * 3 | LB | | RB |
+ * 2 | +---------+ |
+ * 1 | BL |
+ * +------------------------+
+ *
+ */
+
+enum {
+ GPIO_BASE,
+ IOCFG_RT_BASE,
+ IOCFG_RM_BASE,
+ IOCFG_RB_BASE,
+ IOCFG_LB_BASE,
+ IOCFG_BL_BASE,
+ IOCFG_TM_BASE,
+ IOCFG_TL_BASE,
+};
+
+static const struct mtk_pin_field_calc mt7981_pin_mode_range[] = {
+ PIN_FIELD_GPIO(0, 56, 0x300, 0x10, 0, 4),
+};
+
+static const struct mtk_pin_field_calc mt7981_pin_dir_range[] = {
+ PIN_FIELD_GPIO(0, 56, 0x0, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7981_pin_di_range[] = {
+ PIN_FIELD_GPIO(0, 56, 0x200, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7981_pin_do_range[] = {
+ PIN_FIELD_GPIO(0, 56, 0x100, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7981_pin_ies_range[] = {
+ PIN_FIELD_BASE(0, 0, 1, 0x10, 0x10, 1, 1),
+ PIN_FIELD_BASE(1, 1, 1, 0x10, 0x10, 0, 1),
+ PIN_FIELD_BASE(2, 2, 5, 0x20, 0x10, 6, 1),
+ PIN_FIELD_BASE(3, 3, 4, 0x20, 0x10, 6, 1),
+ PIN_FIELD_BASE(4, 4, 4, 0x20, 0x10, 2, 1),
+ PIN_FIELD_BASE(5, 5, 4, 0x20, 0x10, 1, 1),
+ PIN_FIELD_BASE(6, 6, 4, 0x20, 0x10, 3, 1),
+ PIN_FIELD_BASE(7, 7, 4, 0x20, 0x10, 0, 1),
+ PIN_FIELD_BASE(8, 8, 4, 0x20, 0x10, 4, 1),
+ PIN_FIELD_BASE(9, 9, 4, 0x20, 0x10, 9, 1),
+
+ PIN_FIELD_BASE(10, 10, 5, 0x20, 0x10, 8, 1),
+ PIN_FIELD_BASE(11, 11, 5, 0x40, 0x10, 10, 1),
+ PIN_FIELD_BASE(12, 12, 5, 0x20, 0x10, 7, 1),
+ PIN_FIELD_BASE(13, 13, 5, 0x20, 0x10, 11, 1),
+
+ PIN_FIELD_BASE(14, 14, 4, 0x20, 0x10, 8, 1),
+
+ PIN_FIELD_BASE(15, 15, 2, 0x20, 0x10, 0, 1),
+ PIN_FIELD_BASE(16, 16, 2, 0x20, 0x10, 1, 1),
+ PIN_FIELD_BASE(17, 17, 2, 0x20, 0x10, 5, 1),
+ PIN_FIELD_BASE(18, 18, 2, 0x20, 0x10, 4, 1),
+ PIN_FIELD_BASE(19, 19, 2, 0x20, 0x10, 2, 1),
+ PIN_FIELD_BASE(20, 20, 2, 0x20, 0x10, 3, 1),
+ PIN_FIELD_BASE(21, 21, 2, 0x20, 0x10, 6, 1),
+ PIN_FIELD_BASE(22, 22, 2, 0x20, 0x10, 7, 1),
+ PIN_FIELD_BASE(23, 23, 2, 0x20, 0x10, 10, 1),
+ PIN_FIELD_BASE(24, 24, 2, 0x20, 0x10, 9, 1),
+ PIN_FIELD_BASE(25, 25, 2, 0x20, 0x10, 8, 1),
+
+ PIN_FIELD_BASE(26, 26, 5, 0x20, 0x10, 0, 1),
+ PIN_FIELD_BASE(27, 27, 5, 0x20, 0x10, 4, 1),
+ PIN_FIELD_BASE(28, 28, 5, 0x20, 0x10, 3, 1),
+ PIN_FIELD_BASE(29, 29, 5, 0x20, 0x10, 1, 1),
+ PIN_FIELD_BASE(30, 30, 5, 0x20, 0x10, 2, 1),
+ PIN_FIELD_BASE(31, 31, 5, 0x20, 0x10, 5, 1),
+
+ PIN_FIELD_BASE(32, 32, 1, 0x10, 0x10, 2, 1),
+ PIN_FIELD_BASE(33, 33, 1, 0x10, 0x10, 3, 1),
+
+ PIN_FIELD_BASE(34, 34, 4, 0x20, 0x10, 5, 1),
+ PIN_FIELD_BASE(35, 35, 4, 0x20, 0x10, 7, 1),
+
+ PIN_FIELD_BASE(36, 36, 3, 0x10, 0x10, 2, 1),
+ PIN_FIELD_BASE(37, 37, 3, 0x10, 0x10, 3, 1),
+ PIN_FIELD_BASE(38, 38, 3, 0x10, 0x10, 0, 1),
+ PIN_FIELD_BASE(39, 39, 3, 0x10, 0x10, 1, 1),
+
+ PIN_FIELD_BASE(40, 40, 7, 0x30, 0x10, 1, 1),
+ PIN_FIELD_BASE(41, 41, 7, 0x30, 0x10, 0, 1),
+ PIN_FIELD_BASE(42, 42, 7, 0x30, 0x10, 9, 1),
+ PIN_FIELD_BASE(43, 43, 7, 0x30, 0x10, 7, 1),
+ PIN_FIELD_BASE(44, 44, 7, 0x30, 0x10, 8, 1),
+ PIN_FIELD_BASE(45, 45, 7, 0x30, 0x10, 3, 1),
+ PIN_FIELD_BASE(46, 46, 7, 0x30, 0x10, 4, 1),
+ PIN_FIELD_BASE(47, 47, 7, 0x30, 0x10, 5, 1),
+ PIN_FIELD_BASE(48, 48, 7, 0x30, 0x10, 6, 1),
+ PIN_FIELD_BASE(49, 49, 7, 0x30, 0x10, 2, 1),
+
+ PIN_FIELD_BASE(50, 50, 6, 0x10, 0x10, 0, 1),
+ PIN_FIELD_BASE(51, 51, 6, 0x10, 0x10, 2, 1),
+ PIN_FIELD_BASE(52, 52, 6, 0x10, 0x10, 3, 1),
+ PIN_FIELD_BASE(53, 53, 6, 0x10, 0x10, 4, 1),
+ PIN_FIELD_BASE(54, 54, 6, 0x10, 0x10, 5, 1),
+ PIN_FIELD_BASE(55, 55, 6, 0x10, 0x10, 6, 1),
+ PIN_FIELD_BASE(56, 56, 6, 0x10, 0x10, 1, 1),
+};
+
+static const struct mtk_pin_field_calc mt7981_pin_smt_range[] = {
+ PIN_FIELD_BASE(0, 0, 1, 0x60, 0x10, 1, 1),
+ PIN_FIELD_BASE(1, 1, 1, 0x60, 0x10, 0, 1),
+ PIN_FIELD_BASE(2, 2, 5, 0x90, 0x10, 6, 1),
+ PIN_FIELD_BASE(3, 3, 4, 0x80, 0x10, 6, 1),
+ PIN_FIELD_BASE(4, 4, 4, 0x80, 0x10, 2, 1),
+ PIN_FIELD_BASE(5, 5, 4, 0x80, 0x10, 1, 1),
+ PIN_FIELD_BASE(6, 6, 4, 0x80, 0x10, 3, 1),
+ PIN_FIELD_BASE(7, 7, 4, 0x80, 0x10, 0, 1),
+ PIN_FIELD_BASE(8, 8, 4, 0x80, 0x10, 4, 1),
+ PIN_FIELD_BASE(9, 9, 4, 0x80, 0x10, 9, 1),
+
+ PIN_FIELD_BASE(10, 10, 5, 0x90, 0x10, 8, 1),
+ PIN_FIELD_BASE(11, 11, 5, 0x90, 0x10, 10, 1),
+ PIN_FIELD_BASE(12, 12, 5, 0x90, 0x10, 7, 1),
+ PIN_FIELD_BASE(13, 13, 5, 0x90, 0x10, 11, 1),
+
+ PIN_FIELD_BASE(14, 14, 4, 0x80, 0x10, 8, 1),
+
+ PIN_FIELD_BASE(15, 15, 2, 0x90, 0x10, 0, 1),
+ PIN_FIELD_BASE(16, 16, 2, 0x90, 0x10, 1, 1),
+ PIN_FIELD_BASE(17, 17, 2, 0x90, 0x10, 5, 1),
+ PIN_FIELD_BASE(18, 18, 2, 0x90, 0x10, 4, 1),
+ PIN_FIELD_BASE(19, 19, 2, 0x90, 0x10, 2, 1),
+ PIN_FIELD_BASE(20, 20, 2, 0x90, 0x10, 3, 1),
+ PIN_FIELD_BASE(21, 21, 2, 0x90, 0x10, 6, 1),
+ PIN_FIELD_BASE(22, 22, 2, 0x90, 0x10, 7, 1),
+ PIN_FIELD_BASE(23, 23, 2, 0x90, 0x10, 10, 1),
+ PIN_FIELD_BASE(24, 24, 2, 0x90, 0x10, 9, 1),
+ PIN_FIELD_BASE(25, 25, 2, 0x90, 0x10, 8, 1),
+
+ PIN_FIELD_BASE(26, 26, 5, 0x90, 0x10, 0, 1),
+ PIN_FIELD_BASE(27, 27, 5, 0x90, 0x10, 4, 1),
+ PIN_FIELD_BASE(28, 28, 5, 0x90, 0x10, 3, 1),
+ PIN_FIELD_BASE(29, 29, 5, 0x90, 0x10, 1, 1),
+ PIN_FIELD_BASE(30, 30, 5, 0x90, 0x10, 2, 1),
+ PIN_FIELD_BASE(31, 31, 5, 0x90, 0x10, 5, 1),
+
+ PIN_FIELD_BASE(32, 32, 1, 0x60, 0x10, 2, 1),
+ PIN_FIELD_BASE(33, 33, 1, 0x60, 0x10, 3, 1),
+
+ PIN_FIELD_BASE(34, 34, 4, 0x80, 0x10, 5, 1),
+ PIN_FIELD_BASE(35, 35, 4, 0x80, 0x10, 7, 1),
+
+ PIN_FIELD_BASE(36, 36, 3, 0x60, 0x10, 2, 1),
+ PIN_FIELD_BASE(37, 37, 3, 0x60, 0x10, 3, 1),
+ PIN_FIELD_BASE(38, 38, 3, 0x60, 0x10, 0, 1),
+ PIN_FIELD_BASE(39, 39, 3, 0x60, 0x10, 1, 1),
+
+ PIN_FIELD_BASE(40, 40, 7, 0x70, 0x10, 1, 1),
+ PIN_FIELD_BASE(41, 41, 7, 0x70, 0x10, 0, 1),
+ PIN_FIELD_BASE(42, 42, 7, 0x70, 0x10, 9, 1),
+ PIN_FIELD_BASE(43, 43, 7, 0x70, 0x10, 7, 1),
+ PIN_FIELD_BASE(44, 44, 7, 0x30, 0x10, 8, 1),
+ PIN_FIELD_BASE(45, 45, 7, 0x70, 0x10, 3, 1),
+ PIN_FIELD_BASE(46, 46, 7, 0x70, 0x10, 4, 1),
+ PIN_FIELD_BASE(47, 47, 7, 0x70, 0x10, 5, 1),
+ PIN_FIELD_BASE(48, 48, 7, 0x70, 0x10, 6, 1),
+ PIN_FIELD_BASE(49, 49, 7, 0x70, 0x10, 2, 1),
+
+ PIN_FIELD_BASE(50, 50, 6, 0x50, 0x10, 0, 1),
+ PIN_FIELD_BASE(51, 51, 6, 0x50, 0x10, 2, 1),
+ PIN_FIELD_BASE(52, 52, 6, 0x50, 0x10, 3, 1),
+ PIN_FIELD_BASE(53, 53, 6, 0x50, 0x10, 4, 1),
+ PIN_FIELD_BASE(54, 54, 6, 0x50, 0x10, 5, 1),
+ PIN_FIELD_BASE(55, 55, 6, 0x50, 0x10, 6, 1),
+ PIN_FIELD_BASE(56, 56, 6, 0x50, 0x10, 1, 1),
+};
+
+static const struct mtk_pin_field_calc mt7981_pin_pu_range[] = {
+ PIN_FIELD_BASE(40, 40, 7, 0x50, 0x10, 1, 1),
+ PIN_FIELD_BASE(41, 41, 7, 0x50, 0x10, 0, 1),
+ PIN_FIELD_BASE(42, 42, 7, 0x50, 0x10, 9, 1),
+ PIN_FIELD_BASE(43, 43, 7, 0x50, 0x10, 7, 1),
+ PIN_FIELD_BASE(44, 44, 7, 0x50, 0x10, 8, 1),
+ PIN_FIELD_BASE(45, 45, 7, 0x50, 0x10, 3, 1),
+ PIN_FIELD_BASE(46, 46, 7, 0x50, 0x10, 4, 1),
+ PIN_FIELD_BASE(47, 47, 7, 0x50, 0x10, 5, 1),
+ PIN_FIELD_BASE(48, 48, 7, 0x50, 0x10, 6, 1),
+ PIN_FIELD_BASE(49, 49, 7, 0x50, 0x10, 2, 1),
+
+ PIN_FIELD_BASE(50, 50, 6, 0x30, 0x10, 0, 1),
+ PIN_FIELD_BASE(51, 51, 6, 0x30, 0x10, 2, 1),
+ PIN_FIELD_BASE(52, 52, 6, 0x30, 0x10, 3, 1),
+ PIN_FIELD_BASE(53, 53, 6, 0x30, 0x10, 4, 1),
+ PIN_FIELD_BASE(54, 54, 6, 0x30, 0x10, 5, 1),
+ PIN_FIELD_BASE(55, 55, 6, 0x30, 0x10, 6, 1),
+ PIN_FIELD_BASE(56, 56, 6, 0x30, 0x10, 1, 1),
+};
+
+static const struct mtk_pin_field_calc mt7981_pin_pd_range[] = {
+ PIN_FIELD_BASE(40, 40, 7, 0x40, 0x10, 1, 1),
+ PIN_FIELD_BASE(41, 41, 7, 0x40, 0x10, 0, 1),
+ PIN_FIELD_BASE(42, 42, 7, 0x40, 0x10, 9, 1),
+ PIN_FIELD_BASE(43, 43, 7, 0x40, 0x10, 7, 1),
+ PIN_FIELD_BASE(44, 44, 7, 0x40, 0x10, 8, 1),
+ PIN_FIELD_BASE(45, 45, 7, 0x40, 0x10, 3, 1),
+ PIN_FIELD_BASE(46, 46, 7, 0x40, 0x10, 4, 1),
+ PIN_FIELD_BASE(47, 47, 7, 0x40, 0x10, 5, 1),
+ PIN_FIELD_BASE(48, 48, 7, 0x40, 0x10, 6, 1),
+ PIN_FIELD_BASE(49, 49, 7, 0x40, 0x10, 2, 1),
+
+ PIN_FIELD_BASE(50, 50, 6, 0x20, 0x10, 0, 1),
+ PIN_FIELD_BASE(51, 51, 6, 0x20, 0x10, 2, 1),
+ PIN_FIELD_BASE(52, 52, 6, 0x20, 0x10, 3, 1),
+ PIN_FIELD_BASE(53, 53, 6, 0x20, 0x10, 4, 1),
+ PIN_FIELD_BASE(54, 54, 6, 0x20, 0x10, 5, 1),
+ PIN_FIELD_BASE(55, 55, 6, 0x20, 0x10, 6, 1),
+ PIN_FIELD_BASE(56, 56, 6, 0x20, 0x10, 1, 1),
+};
+
+static const struct mtk_pin_field_calc mt7981_pin_drv_range[] = {
+ PIN_FIELD_BASE(0, 0, 1, 0x00, 0x10, 3, 3),
+ PIN_FIELD_BASE(1, 1, 1, 0x00, 0x10, 0, 3),
+
+ PIN_FIELD_BASE(2, 2, 5, 0x00, 0x10, 18, 3),
+
+ PIN_FIELD_BASE(3, 3, 4, 0x00, 0x10, 18, 1),
+ PIN_FIELD_BASE(4, 4, 4, 0x00, 0x10, 6, 1),
+ PIN_FIELD_BASE(5, 5, 4, 0x00, 0x10, 3, 3),
+ PIN_FIELD_BASE(6, 6, 4, 0x00, 0x10, 9, 3),
+ PIN_FIELD_BASE(7, 7, 4, 0x00, 0x10, 0, 3),
+ PIN_FIELD_BASE(8, 8, 4, 0x00, 0x10, 12, 3),
+ PIN_FIELD_BASE(9, 9, 4, 0x00, 0x10, 27, 3),
+
+ PIN_FIELD_BASE(10, 10, 5, 0x00, 0x10, 24, 3),
+ PIN_FIELD_BASE(11, 11, 5, 0x00, 0x10, 0, 3),
+ PIN_FIELD_BASE(12, 12, 5, 0x00, 0x10, 21, 3),
+ PIN_FIELD_BASE(13, 13, 5, 0x00, 0x10, 3, 3),
+
+ PIN_FIELD_BASE(14, 14, 4, 0x00, 0x10, 27, 3),
+
+ PIN_FIELD_BASE(15, 15, 2, 0x00, 0x10, 0, 3),
+ PIN_FIELD_BASE(16, 16, 2, 0x00, 0x10, 3, 3),
+ PIN_FIELD_BASE(17, 17, 2, 0x00, 0x10, 15, 3),
+ PIN_FIELD_BASE(18, 18, 2, 0x00, 0x10, 12, 3),
+ PIN_FIELD_BASE(19, 19, 2, 0x00, 0x10, 6, 3),
+ PIN_FIELD_BASE(20, 20, 2, 0x00, 0x10, 9, 3),
+ PIN_FIELD_BASE(21, 21, 2, 0x00, 0x10, 18, 3),
+ PIN_FIELD_BASE(22, 22, 2, 0x00, 0x10, 21, 3),
+ PIN_FIELD_BASE(23, 23, 2, 0x00, 0x10, 0, 3),
+ PIN_FIELD_BASE(24, 24, 2, 0x00, 0x10, 27, 3),
+ PIN_FIELD_BASE(25, 25, 2, 0x00, 0x10, 24, 3),
+
+ PIN_FIELD_BASE(26, 26, 5, 0x00, 0x10, 0, 3),
+ PIN_FIELD_BASE(27, 27, 5, 0x00, 0x10, 12, 3),
+ PIN_FIELD_BASE(28, 28, 5, 0x00, 0x10, 9, 3),
+ PIN_FIELD_BASE(29, 29, 5, 0x00, 0x10, 3, 3),
+ PIN_FIELD_BASE(30, 30, 5, 0x00, 0x10, 6, 3),
+ PIN_FIELD_BASE(31, 31, 5, 0x00, 0x10, 15, 3),
+
+ PIN_FIELD_BASE(32, 32, 1, 0x00, 0x10, 9, 3),
+ PIN_FIELD_BASE(33, 33, 1, 0x00, 0x10, 12, 3),
+
+ PIN_FIELD_BASE(34, 34, 4, 0x00, 0x10, 15, 3),
+ PIN_FIELD_BASE(35, 35, 4, 0x00, 0x10, 21, 3),
+
+ PIN_FIELD_BASE(36, 36, 3, 0x00, 0x10, 6, 3),
+ PIN_FIELD_BASE(37, 37, 3, 0x00, 0x10, 9, 3),
+ PIN_FIELD_BASE(38, 38, 3, 0x00, 0x10, 0, 3),
+ PIN_FIELD_BASE(39, 39, 3, 0x00, 0x10, 3, 3),
+
+ PIN_FIELD_BASE(40, 40, 7, 0x00, 0x10, 3, 3),
+ PIN_FIELD_BASE(41, 41, 7, 0x00, 0x10, 0, 3),
+ PIN_FIELD_BASE(42, 42, 7, 0x00, 0x10, 27, 3),
+ PIN_FIELD_BASE(43, 43, 7, 0x00, 0x10, 21, 3),
+ PIN_FIELD_BASE(44, 44, 7, 0x00, 0x10, 24, 3),
+ PIN_FIELD_BASE(45, 45, 7, 0x00, 0x10, 9, 3),
+ PIN_FIELD_BASE(46, 46, 7, 0x00, 0x10, 12, 3),
+ PIN_FIELD_BASE(47, 47, 7, 0x00, 0x10, 15, 3),
+ PIN_FIELD_BASE(48, 48, 7, 0x00, 0x10, 18, 3),
+ PIN_FIELD_BASE(49, 49, 7, 0x00, 0x10, 6, 3),
+
+ PIN_FIELD_BASE(50, 50, 6, 0x00, 0x10, 0, 3),
+ PIN_FIELD_BASE(51, 51, 6, 0x00, 0x10, 6, 3),
+ PIN_FIELD_BASE(52, 52, 6, 0x00, 0x10, 9, 3),
+ PIN_FIELD_BASE(53, 53, 6, 0x00, 0x10, 12, 3),
+ PIN_FIELD_BASE(54, 54, 6, 0x00, 0x10, 15, 3),
+ PIN_FIELD_BASE(55, 55, 6, 0x00, 0x10, 18, 3),
+ PIN_FIELD_BASE(56, 56, 6, 0x00, 0x10, 3, 3),
+};
+
+static const struct mtk_pin_field_calc mt7981_pin_pupd_range[] = {
+ PIN_FIELD_BASE(0, 0, 1, 0x20, 0x10, 1, 1),
+ PIN_FIELD_BASE(1, 1, 1, 0x20, 0x10, 0, 1),
+ PIN_FIELD_BASE(2, 2, 5, 0x30, 0x10, 6, 1),
+ PIN_FIELD_BASE(3, 3, 4, 0x30, 0x10, 6, 1),
+ PIN_FIELD_BASE(4, 4, 4, 0x30, 0x10, 2, 1),
+ PIN_FIELD_BASE(5, 5, 4, 0x30, 0x10, 1, 1),
+ PIN_FIELD_BASE(6, 6, 4, 0x30, 0x10, 3, 1),
+ PIN_FIELD_BASE(7, 7, 4, 0x30, 0x10, 0, 1),
+ PIN_FIELD_BASE(8, 8, 4, 0x30, 0x10, 4, 1),
+ PIN_FIELD_BASE(9, 9, 4, 0x30, 0x10, 9, 1),
+
+ PIN_FIELD_BASE(10, 10, 5, 0x30, 0x10, 8, 1),
+ PIN_FIELD_BASE(11, 11, 5, 0x30, 0x10, 10, 1),
+ PIN_FIELD_BASE(12, 12, 5, 0x30, 0x10, 7, 1),
+ PIN_FIELD_BASE(13, 13, 5, 0x30, 0x10, 11, 1),
+
+ PIN_FIELD_BASE(14, 14, 4, 0x30, 0x10, 8, 1),
+
+ PIN_FIELD_BASE(15, 15, 2, 0x30, 0x10, 0, 1),
+ PIN_FIELD_BASE(16, 16, 2, 0x30, 0x10, 1, 1),
+ PIN_FIELD_BASE(17, 17, 2, 0x30, 0x10, 5, 1),
+ PIN_FIELD_BASE(18, 18, 2, 0x30, 0x10, 4, 1),
+ PIN_FIELD_BASE(19, 19, 2, 0x30, 0x10, 2, 1),
+ PIN_FIELD_BASE(20, 20, 2, 0x90, 0x10, 3, 1),
+ PIN_FIELD_BASE(21, 21, 2, 0x30, 0x10, 6, 1),
+ PIN_FIELD_BASE(22, 22, 2, 0x30, 0x10, 7, 1),
+ PIN_FIELD_BASE(23, 23, 2, 0x30, 0x10, 10, 1),
+ PIN_FIELD_BASE(24, 24, 2, 0x30, 0x10, 9, 1),
+ PIN_FIELD_BASE(25, 25, 2, 0x30, 0x10, 8, 1),
+
+ PIN_FIELD_BASE(26, 26, 5, 0x30, 0x10, 0, 1),
+ PIN_FIELD_BASE(27, 27, 5, 0x30, 0x10, 4, 1),
+ PIN_FIELD_BASE(28, 28, 5, 0x30, 0x10, 3, 1),
+ PIN_FIELD_BASE(29, 29, 5, 0x30, 0x10, 1, 1),
+ PIN_FIELD_BASE(30, 30, 5, 0x30, 0x10, 2, 1),
+ PIN_FIELD_BASE(31, 31, 5, 0x30, 0x10, 5, 1),
+
+ PIN_FIELD_BASE(32, 32, 1, 0x20, 0x10, 2, 1),
+ PIN_FIELD_BASE(33, 33, 1, 0x20, 0x10, 3, 1),
+
+ PIN_FIELD_BASE(34, 34, 4, 0x30, 0x10, 5, 1),
+ PIN_FIELD_BASE(35, 35, 4, 0x30, 0x10, 7, 1),
+
+ PIN_FIELD_BASE(36, 36, 3, 0x20, 0x10, 2, 1),
+ PIN_FIELD_BASE(37, 37, 3, 0x20, 0x10, 3, 1),
+ PIN_FIELD_BASE(38, 38, 3, 0x20, 0x10, 0, 1),
+ PIN_FIELD_BASE(39, 39, 3, 0x20, 0x10, 1, 1),
+};
+
+static const struct mtk_pin_field_calc mt7981_pin_r0_range[] = {
+ PIN_FIELD_BASE(0, 0, 1, 0x30, 0x10, 1, 1),
+ PIN_FIELD_BASE(1, 1, 1, 0x30, 0x10, 0, 1),
+ PIN_FIELD_BASE(2, 2, 5, 0x40, 0x10, 6, 1),
+ PIN_FIELD_BASE(3, 3, 4, 0x40, 0x10, 6, 1),
+ PIN_FIELD_BASE(4, 4, 4, 0x40, 0x10, 2, 1),
+ PIN_FIELD_BASE(5, 5, 4, 0x40, 0x10, 1, 1),
+ PIN_FIELD_BASE(6, 6, 4, 0x40, 0x10, 3, 1),
+ PIN_FIELD_BASE(7, 7, 4, 0x40, 0x10, 0, 1),
+ PIN_FIELD_BASE(8, 8, 4, 0x40, 0x10, 4, 1),
+ PIN_FIELD_BASE(9, 9, 4, 0x40, 0x10, 9, 1),
+
+ PIN_FIELD_BASE(10, 10, 5, 0x40, 0x10, 8, 1),
+ PIN_FIELD_BASE(11, 11, 5, 0x40, 0x10, 10, 1),
+ PIN_FIELD_BASE(12, 12, 5, 0x40, 0x10, 7, 1),
+ PIN_FIELD_BASE(13, 13, 5, 0x40, 0x10, 11, 1),
+
+ PIN_FIELD_BASE(14, 14, 4, 0x40, 0x10, 8, 1),
+
+ PIN_FIELD_BASE(15, 15, 2, 0x40, 0x10, 0, 1),
+ PIN_FIELD_BASE(16, 16, 2, 0x40, 0x10, 1, 1),
+ PIN_FIELD_BASE(17, 17, 2, 0x40, 0x10, 5, 1),
+ PIN_FIELD_BASE(18, 18, 2, 0x40, 0x10, 4, 1),
+ PIN_FIELD_BASE(19, 19, 2, 0x40, 0x10, 2, 1),
+ PIN_FIELD_BASE(20, 20, 2, 0x40, 0x10, 3, 1),
+ PIN_FIELD_BASE(21, 21, 2, 0x40, 0x10, 6, 1),
+ PIN_FIELD_BASE(22, 22, 2, 0x40, 0x10, 7, 1),
+ PIN_FIELD_BASE(23, 23, 2, 0x40, 0x10, 10, 1),
+ PIN_FIELD_BASE(24, 24, 2, 0x40, 0x10, 9, 1),
+ PIN_FIELD_BASE(25, 25, 2, 0x40, 0x10, 8, 1),
+
+ PIN_FIELD_BASE(26, 26, 5, 0x40, 0x10, 0, 1),
+ PIN_FIELD_BASE(27, 27, 5, 0x40, 0x10, 4, 1),
+ PIN_FIELD_BASE(28, 28, 5, 0x40, 0x10, 3, 1),
+ PIN_FIELD_BASE(29, 29, 5, 0x40, 0x10, 1, 1),
+ PIN_FIELD_BASE(30, 30, 5, 0x40, 0x10, 2, 1),
+ PIN_FIELD_BASE(31, 31, 5, 0x40, 0x10, 5, 1),
+
+ PIN_FIELD_BASE(32, 32, 1, 0x30, 0x10, 2, 1),
+ PIN_FIELD_BASE(33, 33, 1, 0x30, 0x10, 3, 1),
+
+ PIN_FIELD_BASE(34, 34, 4, 0x40, 0x10, 5, 1),
+ PIN_FIELD_BASE(35, 35, 4, 0x40, 0x10, 7, 1),
+
+ PIN_FIELD_BASE(36, 36, 3, 0x30, 0x10, 2, 1),
+ PIN_FIELD_BASE(37, 37, 3, 0x30, 0x10, 3, 1),
+ PIN_FIELD_BASE(38, 38, 3, 0x30, 0x10, 0, 1),
+ PIN_FIELD_BASE(39, 39, 3, 0x30, 0x10, 1, 1),
+};
+
+static const struct mtk_pin_field_calc mt7981_pin_r1_range[] = {
+ PIN_FIELD_BASE(0, 0, 1, 0x40, 0x10, 1, 1),
+ PIN_FIELD_BASE(1, 1, 1, 0x40, 0x10, 0, 1),
+ PIN_FIELD_BASE(2, 2, 5, 0x50, 0x10, 6, 1),
+ PIN_FIELD_BASE(3, 3, 4, 0x50, 0x10, 6, 1),
+ PIN_FIELD_BASE(4, 4, 4, 0x50, 0x10, 2, 1),
+ PIN_FIELD_BASE(5, 5, 4, 0x50, 0x10, 1, 1),
+ PIN_FIELD_BASE(6, 6, 4, 0x50, 0x10, 3, 1),
+ PIN_FIELD_BASE(7, 7, 4, 0x50, 0x10, 0, 1),
+ PIN_FIELD_BASE(8, 8, 4, 0x50, 0x10, 4, 1),
+ PIN_FIELD_BASE(9, 9, 4, 0x50, 0x10, 9, 1),
+
+ PIN_FIELD_BASE(10, 10, 5, 0x50, 0x10, 8, 1),
+ PIN_FIELD_BASE(11, 11, 5, 0x50, 0x10, 10, 1),
+ PIN_FIELD_BASE(12, 12, 5, 0x50, 0x10, 7, 1),
+ PIN_FIELD_BASE(13, 13, 5, 0x50, 0x10, 11, 1),
+
+ PIN_FIELD_BASE(14, 14, 4, 0x50, 0x10, 8, 1),
+
+ PIN_FIELD_BASE(15, 15, 2, 0x50, 0x10, 0, 1),
+ PIN_FIELD_BASE(16, 16, 2, 0x50, 0x10, 1, 1),
+ PIN_FIELD_BASE(17, 17, 2, 0x50, 0x10, 5, 1),
+ PIN_FIELD_BASE(18, 18, 2, 0x50, 0x10, 4, 1),
+ PIN_FIELD_BASE(19, 19, 2, 0x50, 0x10, 2, 1),
+ PIN_FIELD_BASE(20, 20, 2, 0x50, 0x10, 3, 1),
+ PIN_FIELD_BASE(21, 21, 2, 0x50, 0x10, 6, 1),
+ PIN_FIELD_BASE(22, 22, 2, 0x50, 0x10, 7, 1),
+ PIN_FIELD_BASE(23, 23, 2, 0x50, 0x10, 10, 1),
+ PIN_FIELD_BASE(24, 24, 2, 0x50, 0x10, 9, 1),
+ PIN_FIELD_BASE(25, 25, 2, 0x50, 0x10, 8, 1),
+
+ PIN_FIELD_BASE(26, 26, 5, 0x50, 0x10, 0, 1),
+ PIN_FIELD_BASE(27, 27, 5, 0x50, 0x10, 4, 1),
+ PIN_FIELD_BASE(28, 28, 5, 0x50, 0x10, 3, 1),
+ PIN_FIELD_BASE(29, 29, 5, 0x50, 0x10, 1, 1),
+ PIN_FIELD_BASE(30, 30, 5, 0x50, 0x10, 2, 1),
+ PIN_FIELD_BASE(31, 31, 5, 0x50, 0x10, 5, 1),
+
+ PIN_FIELD_BASE(32, 32, 1, 0x40, 0x10, 2, 1),
+ PIN_FIELD_BASE(33, 33, 1, 0x40, 0x10, 3, 1),
+
+ PIN_FIELD_BASE(34, 34, 4, 0x50, 0x10, 5, 1),
+ PIN_FIELD_BASE(35, 35, 4, 0x50, 0x10, 7, 1),
+
+ PIN_FIELD_BASE(36, 36, 3, 0x40, 0x10, 2, 1),
+ PIN_FIELD_BASE(37, 37, 3, 0x40, 0x10, 3, 1),
+ PIN_FIELD_BASE(38, 38, 3, 0x40, 0x10, 0, 1),
+ PIN_FIELD_BASE(39, 39, 3, 0x40, 0x10, 1, 1),
+};
+
+static const struct mtk_pin_reg_calc mt7981_reg_cals[] = {
+ [PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7981_pin_mode_range),
+ [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7981_pin_dir_range),
+ [PINCTRL_PIN_REG_DI] = MTK_RANGE(mt7981_pin_di_range),
+ [PINCTRL_PIN_REG_DO] = MTK_RANGE(mt7981_pin_do_range),
+ [PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt7981_pin_smt_range),
+ [PINCTRL_PIN_REG_IES] = MTK_RANGE(mt7981_pin_ies_range),
+ [PINCTRL_PIN_REG_PU] = MTK_RANGE(mt7981_pin_pu_range),
+ [PINCTRL_PIN_REG_PD] = MTK_RANGE(mt7981_pin_pd_range),
+ [PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt7981_pin_drv_range),
+ [PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt7981_pin_pupd_range),
+ [PINCTRL_PIN_REG_R0] = MTK_RANGE(mt7981_pin_r0_range),
+ [PINCTRL_PIN_REG_R1] = MTK_RANGE(mt7981_pin_r1_range),
+};
+
+static const struct mtk_pin_desc mt7981_pins[] = {
+ MT7981_TYPE0_PIN(0, "GPIO_WPS"),
+ MT7981_TYPE0_PIN(1, "GPIO_RESET"),
+ MT7981_TYPE0_PIN(2, "SYS_WATCHDOG"),
+ MT7981_TYPE0_PIN(3, "PCIE_PERESET_N"),
+ MT7981_TYPE0_PIN(4, "JTAG_JTDO"),
+ MT7981_TYPE0_PIN(5, "JTAG_JTDI"),
+ MT7981_TYPE0_PIN(6, "JTAG_JTMS"),
+ MT7981_TYPE0_PIN(7, "JTAG_JTCLK"),
+ MT7981_TYPE0_PIN(8, "JTAG_JTRST_N"),
+ MT7981_TYPE0_PIN(9, "WO_JTAG_JTDO"),
+ MT7981_TYPE0_PIN(10, "WO_JTAG_JTDI"),
+ MT7981_TYPE0_PIN(11, "WO_JTAG_JTMS"),
+ MT7981_TYPE0_PIN(12, "WO_JTAG_JTCLK"),
+ MT7981_TYPE0_PIN(13, "WO_JTAG_JTRST_N"),
+ MT7981_TYPE0_PIN(14, "USB_VBUS"),
+ MT7981_TYPE0_PIN(15, "PWM0"),
+ MT7981_TYPE0_PIN(16, "SPI0_CLK"),
+ MT7981_TYPE0_PIN(17, "SPI0_MOSI"),
+ MT7981_TYPE0_PIN(18, "SPI0_MISO"),
+ MT7981_TYPE0_PIN(19, "SPI0_CS"),
+ MT7981_TYPE0_PIN(20, "SPI0_HOLD"),
+ MT7981_TYPE0_PIN(21, "SPI0_WP"),
+ MT7981_TYPE0_PIN(22, "SPI1_CLK"),
+ MT7981_TYPE0_PIN(23, "SPI1_MOSI"),
+ MT7981_TYPE0_PIN(24, "SPI1_MISO"),
+ MT7981_TYPE0_PIN(25, "SPI1_CS"),
+ MT7981_TYPE0_PIN(26, "SPI2_CLK"),
+ MT7981_TYPE0_PIN(27, "SPI2_MOSI"),
+ MT7981_TYPE0_PIN(28, "SPI2_MISO"),
+ MT7981_TYPE0_PIN(29, "SPI2_CS"),
+ MT7981_TYPE0_PIN(30, "SPI2_HOLD"),
+ MT7981_TYPE0_PIN(31, "SPI2_WP"),
+ MT7981_TYPE0_PIN(32, "UART0_RXD"),
+ MT7981_TYPE0_PIN(33, "UART0_TXD"),
+ MT7981_TYPE0_PIN(34, "PCIE_CLK_REQ"),
+ MT7981_TYPE0_PIN(35, "PCIE_WAKE_N"),
+ MT7981_TYPE0_PIN(36, "SMI_MDC"),
+ MT7981_TYPE0_PIN(37, "SMI_MDIO"),
+ MT7981_TYPE0_PIN(38, "GBE_INT"),
+ MT7981_TYPE0_PIN(39, "GBE_RESET"),
+ MT7981_TYPE1_PIN(40, "WF_DIG_RESETB"),
+ MT7981_TYPE1_PIN(41, "WF_CBA_RESETB"),
+ MT7981_TYPE1_PIN(42, "WF_XO_REQ"),
+ MT7981_TYPE1_PIN(43, "WF_TOP_CLK"),
+ MT7981_TYPE1_PIN(44, "WF_TOP_DATA"),
+ MT7981_TYPE1_PIN(45, "WF_HB1"),
+ MT7981_TYPE1_PIN(46, "WF_HB2"),
+ MT7981_TYPE1_PIN(47, "WF_HB3"),
+ MT7981_TYPE1_PIN(48, "WF_HB4"),
+ MT7981_TYPE1_PIN(49, "WF_HB0"),
+ MT7981_TYPE1_PIN(50, "WF_HB0_B"),
+ MT7981_TYPE1_PIN(51, "WF_HB5"),
+ MT7981_TYPE1_PIN(52, "WF_HB6"),
+ MT7981_TYPE1_PIN(53, "WF_HB7"),
+ MT7981_TYPE1_PIN(54, "WF_HB8"),
+ MT7981_TYPE1_PIN(55, "WF_HB9"),
+ MT7981_TYPE1_PIN(56, "WF_HB10"),
+};
+
+/* WA_AICE */
+static int mt7981_wa_aice1_pins[] = { 0, 1, };
+static int mt7981_wa_aice1_funcs[] = { 2, 2, };
+
+static int mt7981_wa_aice2_pins[] = { 0, 1, };
+static int mt7981_wa_aice2_funcs[] = { 3, 3, };
+
+static int mt7981_wa_aice3_pins[] = { 28, 29, };
+static int mt7981_wa_aice3_funcs[] = { 3, 3, };
+
+static int mt7981_wm_aice1_pins[] = { 9, 10, };
+static int mt7981_wm_aice1_funcs[] = { 2, 2, };
+
+static int mt7981_wm_aice2_pins[] = { 30, 31, };
+static int mt7981_wm_aice2_funcs[] = { 5, 5, };
+
+/* WM_UART */
+static int mt7981_wm_uart_0_pins[] = { 0, 1, };
+static int mt7981_wm_uart_0_funcs[] = { 5, 5, };
+
+static int mt7981_wm_uart_1_pins[] = { 20, 21, };
+static int mt7981_wm_uart_1_funcs[] = { 4, 4, };
+
+static int mt7981_wm_uart_2_pins[] = { 30, 31, };
+static int mt7981_wm_uart_2_funcs[] = { 3, 3, };
+
+/* DFD */
+static int mt7981_dfd_pins[] = { 0, 1, 4, 5, };
+static int mt7981_dfd_funcs[] = { 5, 5, 6, 6, };
+
+/* SYS_WATCHDOG */
+static int mt7981_watchdog_pins[] = { 2, };
+static int mt7981_watchdog_funcs[] = { 1, };
+
+static int mt7981_watchdog1_pins[] = { 13, };
+static int mt7981_watchdog1_funcs[] = { 5, };
+
+/* PCIE_PERESET_N */
+static int mt7981_pcie_pereset_pins[] = { 3, };
+static int mt7981_pcie_pereset_funcs[] = { 1, };
+
+/* JTAG */
+static int mt7981_jtag_pins[] = { 4, 5, 6, 7, 8, };
+static int mt7981_jtag_funcs[] = { 1, 1, 1, 1, 1, };
+
+/* WM_JTAG */
+static int mt7981_wm_jtag_0_pins[] = { 4, 5, 6, 7, 8, };
+static int mt7981_wm_jtag_0_funcs[] = { 2, 2, 2, 2, 2, };
+
+static int mt7981_wm_jtag_1_pins[] = { 20, 21, 22, 23, 24, };
+static int mt7981_wm_jtag_1_funcs[] = { 5, 5, 5, 5, 5, };
+
+/* WO0_JTAG */
+static int mt7981_wo0_jtag_0_pins[] = { 9, 10, 11, 12, 13, };
+static int mt7981_wo0_jtag_0_funcs[] = { 1, 1, 1, 1, 1, };
+
+static int mt7981_wo0_jtag_1_pins[] = { 25, 26, 27, 28, 29, };
+static int mt7981_wo0_jtag_1_funcs[] = { 5, 5, 5, 5, 5, };
+
+/* UART2 */
+static int mt7981_uart2_0_pins[] = { 4, 5, 6, 7, };
+static int mt7981_uart2_0_funcs[] = { 3, 3, 3, 3, };
+
+/* GBE_LED0 */
+static int mt7981_gbe_led0_pins[] = { 8, };
+static int mt7981_gbe_led0_funcs[] = { 3, };
+
+/* PTA_EXT */
+static int mt7981_pta_ext_0_pins[] = { 4, 5, 6, };
+static int mt7981_pta_ext_0_funcs[] = { 4, 4, 4, };
+
+static int mt7981_pta_ext_1_pins[] = { 22, 23, 24, };
+static int mt7981_pta_ext_1_funcs[] = { 4, 4, 4, };
+
+/* PWM2 */
+static int mt7981_pwm2_pins[] = { 7, };
+static int mt7981_pwm2_funcs[] = { 4, };
+
+/* NET_WO0_UART_TXD */
+static int mt7981_net_wo0_uart_txd_0_pins[] = { 8, };
+static int mt7981_net_wo0_uart_txd_0_funcs[] = { 4, };
+
+static int mt7981_net_wo0_uart_txd_1_pins[] = { 14, };
+static int mt7981_net_wo0_uart_txd_1_funcs[] = { 3, };
+
+static int mt7981_net_wo0_uart_txd_2_pins[] = { 15, };
+static int mt7981_net_wo0_uart_txd_2_funcs[] = { 4, };
+
+/* SPI1 */
+static int mt7981_spi1_0_pins[] = { 4, 5, 6, 7, };
+static int mt7981_spi1_0_funcs[] = { 5, 5, 5, 5, };
+
+/* I2C */
+static int mt7981_i2c0_0_pins[] = { 6, 7, };
+static int mt7981_i2c0_0_funcs[] = { 6, 6, };
+
+static int mt7981_i2c0_1_pins[] = { 30, 31, };
+static int mt7981_i2c0_1_funcs[] = { 4, 4, };
+
+static int mt7981_i2c0_2_pins[] = { 36, 37, };
+static int mt7981_i2c0_2_funcs[] = { 2, 2, };
+
+static int mt7981_u2_phy_i2c_pins[] = { 30, 31, };
+static int mt7981_u2_phy_i2c_funcs[] = { 6, 6, };
+
+static int mt7981_u3_phy_i2c_pins[] = { 32, 33, };
+static int mt7981_u3_phy_i2c_funcs[] = { 3, 3, };
+
+static int mt7981_sgmii1_phy_i2c_pins[] = { 32, 33, };
+static int mt7981_sgmii1_phy_i2c_funcs[] = { 2, 2, };
+
+static int mt7981_sgmii0_phy_i2c_pins[] = { 32, 33, };
+static int mt7981_sgmii0_phy_i2c_funcs[] = { 5, 5, };
+
+/* DFD_NTRST */
+static int mt7981_dfd_ntrst_pins[] = { 8, };
+static int mt7981_dfd_ntrst_funcs[] = { 6, };
+
+/* PWM0 */
+static int mt7981_pwm0_0_pins[] = { 13, };
+static int mt7981_pwm0_0_funcs[] = { 2, };
+
+static int mt7981_pwm0_1_pins[] = { 15, };
+static int mt7981_pwm0_1_funcs[] = { 1, };
+
+/* PWM1 */
+static int mt7981_pwm1_0_pins[] = { 14, };
+static int mt7981_pwm1_0_funcs[] = { 2, };
+
+static int mt7981_pwm1_1_pins[] = { 15, };
+static int mt7981_pwm1_1_funcs[] = { 3, };
+
+/* GBE_LED1 */
+static int mt7981_gbe_led1_pins[] = { 13, };
+static int mt7981_gbe_led1_funcs[] = { 3, };
+
+/* PCM */
+static int mt7981_pcm_pins[] = { 9, 10, 11, 12, 13, 25 };
+static int mt7981_pcm_funcs[] = { 4, 4, 4, 4, 4, 4, };
+
+/* UDI */
+static int mt7981_udi_pins[] = { 9, 10, 11, 12, 13, };
+static int mt7981_udi_funcs[] = { 6, 6, 6, 6, 6, };
+
+/* DRV_VBUS */
+static int mt7981_drv_vbus_pins[] = { 14, };
+static int mt7981_drv_vbus_funcs[] = { 1, };
+
+/* EMMC */
+static int mt7981_emmc_45_pins[] = { 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, };
+static int mt7981_emmc_45_funcs[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, };
+
+/* SNFI */
+static int mt7981_snfi_pins[] = { 16, 17, 18, 19, 20, 21, };
+static int mt7981_snfi_funcs[] = { 3, 3, 3, 3, 3, 3, };
+
+/* SPI0 */
+static int mt7981_spi0_pins[] = { 16, 17, 18, 19, };
+static int mt7981_spi0_funcs[] = { 1, 1, 1, 1, };
+
+/* SPI0 */
+static int mt7981_spi0_wp_hold_pins[] = { 20, 21, };
+static int mt7981_spi0_wp_hold_funcs[] = { 1, 1, };
+
+/* SPI1 */
+static int mt7981_spi1_1_pins[] = { 22, 23, 24, 25, };
+static int mt7981_spi1_1_funcs[] = { 1, 1, 1, 1, };
+
+/* SPI2 */
+static int mt7981_spi2_pins[] = { 26, 27, 28, 29, };
+static int mt7981_spi2_funcs[] = { 1, 1, 1, 1, };
+
+/* SPI2 */
+static int mt7981_spi2_wp_hold_pins[] = { 30, 31, };
+static int mt7981_spi2_wp_hold_funcs[] = { 1, 1, };
+
+/* UART1 */
+static int mt7981_uart1_0_pins[] = { 16, 17, 18, 19, };
+static int mt7981_uart1_0_funcs[] = { 4, 4, 4, 4, };
+
+static int mt7981_uart1_1_pins[] = { 26, 27, 28, 29, };
+static int mt7981_uart1_1_funcs[] = { 2, 2, 2, 2, };
+
+/* UART2 */
+static int mt7981_uart2_1_pins[] = { 22, 23, 24, 25, };
+static int mt7981_uart2_1_funcs[] = { 3, 3, 3, 3, };
+
+/* UART0 */
+static int mt7981_uart0_pins[] = { 32, 33, };
+static int mt7981_uart0_funcs[] = { 1, 1, };
+
+/* PCIE_CLK_REQ */
+static int mt7981_pcie_clk_pins[] = { 34, };
+static int mt7981_pcie_clk_funcs[] = { 2, };
+
+/* PCIE_WAKE_N */
+static int mt7981_pcie_wake_pins[] = { 35, };
+static int mt7981_pcie_wake_funcs[] = { 2, };
+
+/* MDC_MDIO */
+static int mt7981_smi_mdc_mdio_pins[] = { 36, 37, };
+static int mt7981_smi_mdc_mdio_funcs[] = { 1, 1, };
+
+static int mt7981_gbe_ext_mdc_mdio_pins[] = { 36, 37, };
+static int mt7981_gbe_ext_mdc_mdio_funcs[] = { 3, 3, };
+
+/* WF0_MODE1 */
+static int mt7981_wf0_mode1_pins[] = { 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56 };
+static int mt7981_wf0_mode1_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1 };
+
+/* WF0_MODE3 */
+static int mt7981_wf0_mode3_pins[] = { 45, 46, 47, 48, 49, 51 };
+static int mt7981_wf0_mode3_funcs[] = { 2, 2, 2, 2, 2, 2 };
+
+/* WF2G_LED */
+static int mt7981_wf2g_led0_pins[] = { 30, };
+static int mt7981_wf2g_led0_funcs[] = { 2, };
+
+static int mt7981_wf2g_led1_pins[] = { 34, };
+static int mt7981_wf2g_led1_funcs[] = { 1, };
+
+/* WF5G_LED */
+static int mt7981_wf5g_led0_pins[] = { 31, };
+static int mt7981_wf5g_led0_funcs[] = { 2, };
+
+static int mt7981_wf5g_led1_pins[] = { 35, };
+static int mt7981_wf5g_led1_funcs[] = { 1, };
+
+/* MT7531_INT */
+static int mt7981_mt7531_int_pins[] = { 38, };
+static int mt7981_mt7531_int_funcs[] = { 1, };
+
+/* ANT_SEL */
+static int mt7981_ant_sel_pins[] = { 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 34, 35 };
+static int mt7981_ant_sel_funcs[] = { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 };
+
+static const struct mtk_group_desc mt7981_groups[] = {
+ /* @GPIO(0,1): WA_AICE(2) */
+ PINCTRL_PIN_GROUP("wa_aice1", mt7981_wa_aice1),
+ /* @GPIO(0,1): WA_AICE(3) */
+ PINCTRL_PIN_GROUP("wa_aice2", mt7981_wa_aice2),
+ /* @GPIO(0,1): WM_UART(5) */
+ PINCTRL_PIN_GROUP("wm_uart_0", mt7981_wm_uart_0),
+ /* @GPIO(0,1,4,5): DFD(6) */
+ PINCTRL_PIN_GROUP("dfd", mt7981_dfd),
+ /* @GPIO(2): SYS_WATCHDOG(1) */
+ PINCTRL_PIN_GROUP("watchdog", mt7981_watchdog),
+ /* @GPIO(3): PCIE_PERESET_N(1) */
+ PINCTRL_PIN_GROUP("pcie_pereset", mt7981_pcie_pereset),
+ /* @GPIO(4,8) JTAG(1) */
+ PINCTRL_PIN_GROUP("jtag", mt7981_jtag),
+ /* @GPIO(4,8) WM_JTAG(2) */
+ PINCTRL_PIN_GROUP("wm_jtag_0", mt7981_wm_jtag_0),
+ /* @GPIO(9,13) WO0_JTAG(1) */
+ PINCTRL_PIN_GROUP("wo0_jtag_0", mt7981_wo0_jtag_0),
+ /* @GPIO(4,7) WM_JTAG(3) */
+ PINCTRL_PIN_GROUP("uart2_0", mt7981_uart2_0),
+ /* @GPIO(8) GBE_LED0(3) */
+ PINCTRL_PIN_GROUP("gbe_led0", mt7981_gbe_led0),
+ /* @GPIO(4,6) PTA_EXT(4) */
+ PINCTRL_PIN_GROUP("pta_ext_0", mt7981_pta_ext_0),
+ /* @GPIO(7) PWM2(4) */
+ PINCTRL_PIN_GROUP("pwm2", mt7981_pwm2),
+ /* @GPIO(8) NET_WO0_UART_TXD(4) */
+ PINCTRL_PIN_GROUP("net_wo0_uart_txd_0", mt7981_net_wo0_uart_txd_0),
+ /* @GPIO(4,7) SPI1(5) */
+ PINCTRL_PIN_GROUP("spi1_0", mt7981_spi1_0),
+ /* @GPIO(6,7) I2C(5) */
+ PINCTRL_PIN_GROUP("i2c0_0", mt7981_i2c0_0),
+ /* @GPIO(8): DFD_NTRST(6) */
+ PINCTRL_PIN_GROUP("dfd_ntrst", mt7981_dfd_ntrst),
+ /* @GPIO(9,10): WM_AICE(2) */
+ PINCTRL_PIN_GROUP("wm_aice1", mt7981_wm_aice1),
+ /* @GPIO(13): PWM0(2) */
+ PINCTRL_PIN_GROUP("pwm0_0", mt7981_pwm0_0),
+ /* @GPIO(15): PWM0(1) */
+ PINCTRL_PIN_GROUP("pwm0_1", mt7981_pwm0_1),
+ /* @GPIO(14): PWM1(2) */
+ PINCTRL_PIN_GROUP("pwm1_0", mt7981_pwm1_0),
+ /* @GPIO(15): PWM1(3) */
+ PINCTRL_PIN_GROUP("pwm1_1", mt7981_pwm1_1),
+ /* @GPIO(14) NET_WO0_UART_TXD(3) */
+ PINCTRL_PIN_GROUP("net_wo0_uart_txd_1", mt7981_net_wo0_uart_txd_1),
+ /* @GPIO(15) NET_WO0_UART_TXD(4) */
+ PINCTRL_PIN_GROUP("net_wo0_uart_txd_2", mt7981_net_wo0_uart_txd_2),
+ /* @GPIO(13) GBE_LED0(3) */
+ PINCTRL_PIN_GROUP("gbe_led1", mt7981_gbe_led1),
+ /* @GPIO(9,13) PCM(4) */
+ PINCTRL_PIN_GROUP("pcm", mt7981_pcm),
+ /* @GPIO(13): SYS_WATCHDOG1(5) */
+ PINCTRL_PIN_GROUP("watchdog1", mt7981_watchdog1),
+ /* @GPIO(9,13) UDI(4) */
+ PINCTRL_PIN_GROUP("udi", mt7981_udi),
+ /* @GPIO(14) DRV_VBUS(1) */
+ PINCTRL_PIN_GROUP("drv_vbus", mt7981_drv_vbus),
+ /* @GPIO(15,25): EMMC(2) */
+ PINCTRL_PIN_GROUP("emmc_45", mt7981_emmc_45),
+ /* @GPIO(16,21): SNFI(3) */
+ PINCTRL_PIN_GROUP("snfi", mt7981_snfi),
+ /* @GPIO(16,19): SPI0(1) */
+ PINCTRL_PIN_GROUP("spi0", mt7981_spi0),
+ /* @GPIO(20,21): SPI0(1) */
+ PINCTRL_PIN_GROUP("spi0_wp_hold", mt7981_spi0_wp_hold),
+ /* @GPIO(22,25) SPI1(1) */
+ PINCTRL_PIN_GROUP("spi1_1", mt7981_spi1_1),
+ /* @GPIO(26,29): SPI2(1) */
+ PINCTRL_PIN_GROUP("spi2", mt7981_spi2),
+ /* @GPIO(30,31): SPI2(1) */
+ PINCTRL_PIN_GROUP("spi2_wp_hold", mt7981_spi2_wp_hold),
+ /* @GPIO(16,19): UART1(4) */
+ PINCTRL_PIN_GROUP("uart1_0", mt7981_uart1_0),
+ /* @GPIO(26,29): UART1(2) */
+ PINCTRL_PIN_GROUP("uart1_1", mt7981_uart1_1),
+ /* @GPIO(22,25): UART2(3) */
+ PINCTRL_PIN_GROUP("uart2_0", mt7981_uart2_1),
+ /* @GPIO(22,24) PTA_EXT(4) */
+ PINCTRL_PIN_GROUP("pta_ext_1", mt7981_pta_ext_1),
+ /* @GPIO(20,21): WM_UART(4) */
+ PINCTRL_PIN_GROUP("wm_aurt_1", mt7981_wm_uart_1),
+ /* @GPIO(30,31): WM_UART(3) */
+ PINCTRL_PIN_GROUP("wm_aurt_2", mt7981_wm_uart_2),
+ /* @GPIO(20,24) WM_JTAG(5) */
+ PINCTRL_PIN_GROUP("wm_jtag_1", mt7981_wm_jtag_1),
+ /* @GPIO(25,29) WO0_JTAG(5) */
+ PINCTRL_PIN_GROUP("wo0_jtag_1", mt7981_wo0_jtag_1),
+ /* @GPIO(28,29): WA_AICE(3) */
+ PINCTRL_PIN_GROUP("wa_aice3", mt7981_wa_aice3),
+ /* @GPIO(30,31): WM_AICE(5) */
+ PINCTRL_PIN_GROUP("wm_aice2", mt7981_wm_aice2),
+ /* @GPIO(30,31): I2C(4) */
+ PINCTRL_PIN_GROUP("i2c0_1", mt7981_i2c0_1),
+ /* @GPIO(30,31): I2C(6) */
+ PINCTRL_PIN_GROUP("u2_phy_i2c", mt7981_u2_phy_i2c),
+ /* @GPIO(32,33): I2C(1) */
+ PINCTRL_PIN_GROUP("uart0", mt7981_uart0),
+ /* @GPIO(32,33): I2C(2) */
+ PINCTRL_PIN_GROUP("sgmii1_phy_i2c", mt7981_sgmii1_phy_i2c),
+ /* @GPIO(32,33): I2C(3) */
+ PINCTRL_PIN_GROUP("u3_phy_i2c", mt7981_u3_phy_i2c),
+ /* @GPIO(32,33): I2C(5) */
+ PINCTRL_PIN_GROUP("sgmii0_phy_i2c", mt7981_sgmii0_phy_i2c),
+ /* @GPIO(34): PCIE_CLK_REQ(2) */
+ PINCTRL_PIN_GROUP("pcie_clk", mt7981_pcie_clk),
+ /* @GPIO(35): PCIE_WAKE_N(2) */
+ PINCTRL_PIN_GROUP("pcie_wake", mt7981_pcie_wake),
+ /* @GPIO(36,37): I2C(2) */
+ PINCTRL_PIN_GROUP("i2c0_2", mt7981_i2c0_2),
+ /* @GPIO(36,37): MDC_MDIO(1) */
+ PINCTRL_PIN_GROUP("smi_mdc_mdio", mt7981_smi_mdc_mdio),
+ /* @GPIO(36,37): MDC_MDIO(3) */
+ PINCTRL_PIN_GROUP("gbe_ext_mdc_mdio", mt7981_gbe_ext_mdc_mdio),
+ /* @GPIO(40,56): WF0_MODE1(1) */
+ PINCTRL_PIN_GROUP("wf0_mode1", mt7981_wf0_mode1),
+ /* @GPIO(45,46,47,48,49,51): WF0_MODE3(3) */
+ PINCTRL_PIN_GROUP("wf0_mode3", mt7981_wf0_mode3),
+ /* @GPIO(30): WF2G_LED(2) */
+ PINCTRL_PIN_GROUP("wf2g_led0", mt7981_wf2g_led0),
+ /* @GPIO(34): WF2G_LED(1) */
+ PINCTRL_PIN_GROUP("wf2g_led1", mt7981_wf2g_led1),
+ /* @GPIO(31): WF5G_LED(2) */
+ PINCTRL_PIN_GROUP("wf5g_led0", mt7981_wf5g_led0),
+ /* @GPIO(35): WF5G_LED(1) */
+ PINCTRL_PIN_GROUP("wf5g_led1", mt7981_wf5g_led1),
+ /* @GPIO(38): MT7531_INT(1) */
+ PINCTRL_PIN_GROUP("mt7531_int", mt7981_mt7531_int),
+ /* @GPIO(14,15,26,17,18,19,20,21,22,23,24,25,34,35): ANT_SEL(1) */
+ PINCTRL_PIN_GROUP("ant_sel", mt7981_ant_sel),
+};
+
+static const struct mtk_io_type_desc mt7981_io_type_desc[] = {
+ [IO_TYPE_GRP0] = {
+ .name = "18OD33",
+ .bias_set = mtk_pinconf_bias_set_pupd_r1_r0,
+ .drive_set = mtk_pinconf_drive_set_v1,
+ .input_enable = mtk_pinconf_input_enable_v1,
+ },
+ [IO_TYPE_GRP1] = {
+ .name = "18A01",
+ .bias_set = mtk_pinconf_bias_set_pu_pd,
+ .drive_set = mtk_pinconf_drive_set_v1,
+ .input_enable = mtk_pinconf_input_enable_v1,
+ },
+};
+
+/* Joint those groups owning the same capability in user point of view which
+ * allows that people tend to use through the device tree.
+ */
+static const char *const mt7981_wa_aice_groups[] = { "wa_aice1", "wa_aice2",
+ "wm_aice1_1", "wa_aice3", "wm_aice1_2", };
+static const char *const mt7981_uart_groups[] = { "wm_uart_0", "uart2_0",
+ "net_wo0_uart_txd_0", "net_wo0_uart_txd_1", "net_wo0_uart_txd_2",
+ "uart1_0", "uart1_1", "uart2_0", "wm_aurt_1", "wm_aurt_2", "uart0", };
+static const char *const mt7981_dfd_groups[] = { "dfd", "dfd_ntrst", };
+static const char *const mt7981_wdt_groups[] = { "watchdog", "watchdog1", };
+static const char *const mt7981_pcie_groups[] = { "pcie_pereset", "pcie_clk",
+ "pcie_wake", };
+static const char *const mt7981_jtag_groups[] = { "jtag", "wm_jtag_0",
+ "wo0_jtag_0", "wo0_jtag_1", "wm_jtag_1", };
+static const char *const mt7981_led_groups[] = { "gbe_led0", "gbe_led1",
+ "wf2g_led0", "wf2g_led1", "wf5g_led0", "wf5g_led1", };
+static const char *const mt7981_pta_groups[] = { "pta_ext_0", "pta_ext_1", };
+static const char *const mt7981_pwm_groups[] = { "pwm2", "pwm0_0", "pwm0_1",
+ "pwm1_0", "pwm1_1", };
+static const char *const mt7981_spi_groups[] = { "spi1_0", "spi0",
+ "spi0_wp_hold", "spi1_1", "spi2", "spi2_wp_hold", };
+static const char *const mt7981_i2c_groups[] = { "i2c0_0", "i2c0_1",
+ "u2_phy_i2c", "sgmii1_phy_i2c", "u3_phy_i2c", "sgmii0_phy_i2c",
+ "i2c0_2", };
+static const char *const mt7981_pcm_groups[] = { "pcm", };
+static const char *const mt7981_udi_groups[] = { "udi", };
+static const char *const mt7981_usb_groups[] = { "drv_vbus", };
+static const char *const mt7981_flash_groups[] = { "emmc_45", "snfi", };
+static const char *const mt7981_ethernet_groups[] = { "smi_mdc_mdio",
+ "gbe_ext_mdc_mdio", "wf0_mode1", "wf0_mode3", "mt7531_int", };
+static const char *const mt7981_ant_groups[] = { "ant_sel", };
+
+static const struct mtk_function_desc mt7981_functions[] = {
+ {"wa_aice", mt7981_wa_aice_groups, ARRAY_SIZE(mt7981_wa_aice_groups)},
+ {"dfd", mt7981_dfd_groups, ARRAY_SIZE(mt7981_dfd_groups)},
+ {"jtag", mt7981_jtag_groups, ARRAY_SIZE(mt7981_jtag_groups)},
+ {"pta", mt7981_pta_groups, ARRAY_SIZE(mt7981_pta_groups)},
+ {"pcm", mt7981_pcm_groups, ARRAY_SIZE(mt7981_pcm_groups)},
+ {"udi", mt7981_udi_groups, ARRAY_SIZE(mt7981_udi_groups)},
+ {"usb", mt7981_usb_groups, ARRAY_SIZE(mt7981_usb_groups)},
+ {"ant", mt7981_ant_groups, ARRAY_SIZE(mt7981_ant_groups)},
+ {"eth", mt7981_ethernet_groups, ARRAY_SIZE(mt7981_ethernet_groups)},
+ {"i2c", mt7981_i2c_groups, ARRAY_SIZE(mt7981_i2c_groups)},
+ {"led", mt7981_led_groups, ARRAY_SIZE(mt7981_led_groups)},
+ {"pwm", mt7981_pwm_groups, ARRAY_SIZE(mt7981_pwm_groups)},
+ {"spi", mt7981_spi_groups, ARRAY_SIZE(mt7981_spi_groups)},
+ {"uart", mt7981_uart_groups, ARRAY_SIZE(mt7981_uart_groups)},
+ {"watchdog", mt7981_wdt_groups, ARRAY_SIZE(mt7981_wdt_groups)},
+ {"flash", mt7981_flash_groups, ARRAY_SIZE(mt7981_flash_groups)},
+ {"pcie", mt7981_pcie_groups, ARRAY_SIZE(mt7981_pcie_groups)},
+};
+
+static const char *const mt7981_pinctrl_register_base_names[] = {
+ "gpio_base", "iocfg_rt_base", "iocfg_rm_base", "iocfg_rb_base",
+ "iocfg_lb_base", "iocfg_bl_base", "iocfg_tm_base", "iocfg_tl_base",
+};
+
+static struct mtk_pinctrl_soc mt7981_data = {
+ .name = "mt7981_pinctrl",
+ .reg_cal = mt7981_reg_cals,
+ .pins = mt7981_pins,
+ .npins = ARRAY_SIZE(mt7981_pins),
+ .grps = mt7981_groups,
+ .ngrps = ARRAY_SIZE(mt7981_groups),
+ .funcs = mt7981_functions,
+ .nfuncs = ARRAY_SIZE(mt7981_functions),
+ .io_type = mt7981_io_type_desc,
+ .ntype = ARRAY_SIZE(mt7981_io_type_desc),
+ .gpio_mode = 0,
+ .base_names = mt7981_pinctrl_register_base_names,
+ .nbase_names = ARRAY_SIZE(mt7981_pinctrl_register_base_names),
+ .base_calc = 1,
+};
+
+static int mtk_pinctrl_mt7981_probe(struct udevice *dev)
+{
+ return mtk_pinctrl_common_probe(dev, &mt7981_data);
+}
+
+static const struct udevice_id mt7981_pctrl_match[] = {
+ {.compatible = "mediatek,mt7981-pinctrl"},
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(mt7981_pinctrl) = {
+ .name = "mt7981_pinctrl",
+ .id = UCLASS_PINCTRL,
+ .of_match = mt7981_pctrl_match,
+ .ops = &mtk_pinctrl_ops,
+ .probe = mtk_pinctrl_mt7981_probe,
+ .priv_auto = sizeof(struct mtk_pinctrl_priv),
+};
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7986.c b/drivers/pinctrl/mediatek/pinctrl-mt7986.c
new file mode 100644
index 0000000..449e5ad
--- /dev/null
+++ b/drivers/pinctrl/mediatek/pinctrl-mt7986.c
@@ -0,0 +1,775 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The MT7986 driver based on Linux generic pinctrl binding.
+ *
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+#include <dm.h>
+#include "pinctrl-mtk-common.h"
+
+#define MT7986_TYPE0_PIN(_number, _name) \
+ MTK_TYPED_PIN(_number, _name, DRV_GRP4, IO_TYPE_GRP0)
+
+#define MT7986_TYPE1_PIN(_number, _name) \
+ MTK_TYPED_PIN(_number, _name, DRV_GRP4, IO_TYPE_GRP1)
+
+#define PIN_FIELD_GPIO(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits) \
+ PIN_FIELD_BASE_CALC(_s_pin, _e_pin, GPIO_BASE, _s_addr, _x_addrs, \
+ _s_bit, _x_bits, 32, 0)
+
+#define PIN_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \
+ _x_bits) \
+ PIN_FIELD_BASE_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \
+ _x_bits, 32, 0)
+
+/**
+ * enum - Locking variants of the iocfg bases
+ *
+ * MT7986 have multiple bases to program pin configuration listed as the below:
+ * iocfg_rt:0x11c30000, iocfg_rb:0x11c40000, iocfg_lt:0x11e20000,
+ * iocfg_lb:0x11e30000, iocfg_tr:0x11f00000, iocfg_tl:0x11f10000,
+ * _i_based could be used to indicate what base the pin should be mapped into.
+ *
+ * Each iocfg register base control different group of pads on the SoC
+ *
+ *
+ * chip carrier
+ *
+ * A B C D E F G H
+ * +------------------------+
+ * 8 | o o o o o o o o |
+ * 7 | o o o o o o o o |
+ * 6 | o o o o o o o o |
+ * 5 | o o o o o o o o |
+ * 4 | o o o o o o o o |
+ * 3 | o o o o o o o o |
+ * 2 | o o o o o o o o |
+ * 1 | o o o o o o o o |
+ * +------------------------+
+ *
+ * inside Chip carrier
+ *
+ * A B C D E F G H
+ * +------------------------+
+ * 8 | |
+ * 7 | TL TR |
+ * 6 | +---------+ |
+ * 5 | LT | | RT |
+ * 4 | | | |
+ * 3 | LB | | RB |
+ * 2 | +---------+ |
+ * 1 | |
+ * +------------------------+
+ *
+ */
+
+enum {
+ GPIO_BASE,
+ IOCFG_RT_BASE,
+ IOCFG_RB_BASE,
+ IOCFG_LT_BASE,
+ IOCFG_LB_BASE,
+ IOCFG_TR_BASE,
+ IOCFG_TL_BASE,
+};
+
+static const char *const mt7986_pinctrl_register_base_names[] = {
+ "gpio", "iocfg_rt", "iocfg_rb", "iocfg_lt", "iocfg_lb", "iocfg_tr",
+ "iocfg_tl",
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_mode_range[] = {
+ PIN_FIELD_GPIO(0, 100, 0x300, 0x10, 0, 4),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_dir_range[] = {
+ PIN_FIELD_GPIO(0, 100, 0x0, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_di_range[] = {
+ PIN_FIELD_GPIO(0, 100, 0x200, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_do_range[] = {
+ PIN_FIELD_GPIO(0, 100, 0x100, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_ies_range[] = {
+ PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x40, 0x10, 17, 1),
+ PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x20, 0x10, 10, 1),
+ PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x20, 0x10, 0, 1),
+ PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0x40, 0x10, 0, 1),
+ PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x20, 0x10, 0, 1),
+ PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0x40, 0x10, 8, 1),
+ PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x40, 0x10, 2, 1),
+ PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x30, 0x10, 12, 1),
+ PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x30, 0x10, 18, 1),
+ PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x30, 0x10, 17, 1),
+ PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x30, 0x10, 15, 1),
+ PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0x30, 0x10, 19, 1),
+ PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x30, 0x10, 23, 1),
+ PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x30, 0x10, 22, 1),
+ PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x30, 0x10, 21, 1),
+ PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x20, 0x10, 4, 1),
+ PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x20, 0x10, 8, 1),
+ PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x20, 0x10, 7, 1),
+ PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x20, 0x10, 5, 1),
+ PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x20, 0x10, 9, 1),
+ PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x40, 0x10, 18, 1),
+ PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x40, 0x10, 12, 1),
+ PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x40, 0x10, 22, 1),
+ PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x40, 0x10, 20, 1),
+ PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x40, 0x10, 26, 1),
+ PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x40, 0x10, 24, 1),
+ PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x30, 0x10, 2, 1),
+ PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x30, 0x10, 1, 1),
+ PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x30, 0x10, 0, 1),
+ PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x30, 0x10, 10, 1),
+ PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x40, 0x10, 15, 1),
+ PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x40, 0x10, 14, 1),
+ PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x40, 0x10, 13, 1),
+ PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x40, 0x10, 16, 1),
+ PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x20, 0x10, 2, 1),
+ PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x30, 0x10, 1, 1),
+ PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x30, 0x10, 0, 1),
+ PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x30, 0x10, 16, 1),
+ PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x30, 0x10, 14, 1),
+ PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x30, 0x10, 4, 1),
+ PIN_FIELD_BASE(75, 77, IOCFG_TR_BASE, 0x30, 0x10, 6, 1),
+ PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x30, 0x10, 2, 1),
+ PIN_FIELD_BASE(80, 84, IOCFG_TR_BASE, 0x30, 0x10, 9, 1),
+ PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x30, 0x10, 5, 1),
+ PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x30, 0x10, 1, 1),
+ PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x30, 0x10, 0, 1),
+ PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x30, 0x10, 14, 1),
+ PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x30, 0x10, 12, 1),
+ PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x30, 0x10, 4, 1),
+ PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x30, 0x10, 2, 1),
+ PIN_FIELD_BASE(97, 100, IOCFG_TL_BASE, 0x30, 0x10, 8, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_smt_range[] = {
+ PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0xf0, 0x10, 17, 1),
+ PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x90, 0x10, 10, 1),
+ PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x90, 0x10, 0, 1),
+ PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0xf0, 0x10, 0, 1),
+ PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x90, 0x10, 0, 1),
+ PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0xf0, 0x10, 8, 1),
+ PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0xf0, 0x10, 2, 1),
+ PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0xc0, 0x10, 12, 1),
+ PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0xc0, 0x10, 18, 1),
+ PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0xc0, 0x10, 17, 1),
+ PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0xc0, 0x10, 15, 1),
+ PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0xc0, 0x10, 19, 1),
+ PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0xc0, 0x10, 23, 1),
+ PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0xc0, 0x10, 22, 1),
+ PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0xc0, 0x10, 21, 1),
+ PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x90, 0x10, 4, 1),
+ PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x90, 0x10, 8, 1),
+ PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x90, 0x10, 7, 1),
+ PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x90, 0x10, 5, 1),
+ PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x90, 0x10, 9, 1),
+ PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0xf0, 0x10, 18, 1),
+ PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0xf0, 0x10, 12, 1),
+ PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0xf0, 0x10, 22, 1),
+ PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0xf0, 0x10, 20, 1),
+ PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0xf0, 0x10, 26, 1),
+ PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0xf0, 0x10, 24, 1),
+ PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0xc0, 0x10, 2, 1),
+ PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0xc0, 0x10, 1, 1),
+ PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0xc0, 0x10, 0, 1),
+ PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0xc0, 0x10, 10, 1),
+ PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0xf0, 0x10, 15, 1),
+ PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0xf0, 0x10, 14, 1),
+ PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0xf0, 0x10, 13, 1),
+ PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0xf0, 0x10, 16, 1),
+ PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x90, 0x10, 2, 1),
+ PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x80, 0x10, 1, 1),
+ PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x80, 0x10, 0, 1),
+ PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x80, 0x10, 16, 1),
+ PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x80, 0x10, 14, 1),
+ PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x80, 0x10, 4, 1),
+ PIN_FIELD_BASE(75, 77, IOCFG_TR_BASE, 0x80, 0x10, 6, 1),
+ PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x80, 0x10, 2, 1),
+ PIN_FIELD_BASE(80, 84, IOCFG_TR_BASE, 0x80, 0x10, 9, 1),
+ PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x80, 0x10, 5, 1),
+ PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x70, 0x10, 1, 1),
+ PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x70, 0x10, 0, 1),
+ PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x70, 0x10, 14, 1),
+ PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x70, 0x10, 12, 1),
+ PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x70, 0x10, 4, 1),
+ PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x70, 0x10, 2, 1),
+ PIN_FIELD_BASE(97, 100, IOCFG_TL_BASE, 0x70, 0x10, 8, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_pu_range[] = {
+ PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x50, 0x10, 1, 1),
+ PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x50, 0x10, 0, 1),
+ PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x50, 0x10, 16, 1),
+ PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x50, 0x10, 14, 1),
+ PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x50, 0x10, 4, 1),
+ PIN_FIELD_BASE(75, 77, IOCFG_TR_BASE, 0x50, 0x10, 6, 1),
+ PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x50, 0x10, 2, 1),
+ PIN_FIELD_BASE(80, 84, IOCFG_TR_BASE, 0x50, 0x10, 9, 1),
+ PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x50, 0x10, 5, 1),
+ PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x50, 0x10, 1, 1),
+ PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x50, 0x10, 0, 1),
+ PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x50, 0x10, 14, 1),
+ PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x50, 0x10, 12, 1),
+ PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x50, 0x10, 4, 1),
+ PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x50, 0x10, 2, 1),
+ PIN_FIELD_BASE(97, 100, IOCFG_TL_BASE, 0x50, 0x10, 8, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_pd_range[] = {
+ PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x40, 0x10, 1, 1),
+ PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x40, 0x10, 0, 1),
+ PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x40, 0x10, 16, 1),
+ PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x40, 0x10, 14, 1),
+ PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x40, 0x10, 4, 1),
+ PIN_FIELD_BASE(75, 77, IOCFG_TR_BASE, 0x40, 0x10, 6, 1),
+ PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x40, 0x10, 2, 1),
+ PIN_FIELD_BASE(80, 84, IOCFG_TR_BASE, 0x40, 0x10, 9, 1),
+ PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x40, 0x10, 5, 1),
+ PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x40, 0x10, 1, 1),
+ PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x40, 0x10, 0, 1),
+ PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x40, 0x10, 14, 1),
+ PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x40, 0x10, 12, 1),
+ PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x40, 0x10, 4, 1),
+ PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x40, 0x10, 2, 1),
+ PIN_FIELD_BASE(97, 100, IOCFG_TL_BASE, 0x40, 0x10, 8, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_drv_range[] = {
+ PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x10, 0x10, 21, 3),
+ PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x10, 0x10, 0, 3),
+ PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x00, 0x10, 0, 1),
+ PIN_FIELD_BASE(5, 5, IOCFG_RB_BASE, 0x00, 0x10, 0, 3),
+ PIN_FIELD_BASE(6, 6, IOCFG_RB_BASE, 0x00, 0x10, 21, 3),
+ PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x00, 0x10, 0, 3),
+ PIN_FIELD_BASE(11, 12, IOCFG_RB_BASE, 0x00, 0x10, 24, 3),
+ PIN_FIELD_BASE(13, 14, IOCFG_RB_BASE, 0x10, 0x10, 0, 3),
+ PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x00, 0x10, 3, 3),
+ PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x10, 0x10, 6, 3),
+ PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x10, 0x10, 24, 3),
+ PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x10, 0x10, 21, 3),
+ PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x10, 0x10, 15, 3),
+ PIN_FIELD_BASE(28, 28, IOCFG_RT_BASE, 0x10, 0x10, 27, 3),
+ PIN_FIELD_BASE(29, 29, IOCFG_RT_BASE, 0x20, 0x10, 0, 3),
+ PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x20, 0x10, 9, 3),
+ PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x20, 0x10, 6, 3),
+ PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x20, 0x10, 3, 3),
+ PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x00, 0x10, 12, 3),
+ PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x00, 0x10, 24, 3),
+ PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x00, 0x10, 21, 3),
+ PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x00, 0x10, 15, 3),
+ PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x00, 0x10, 27, 3),
+ PIN_FIELD_BASE(39, 39, IOCFG_RB_BASE, 0x10, 0x10, 27, 3),
+ PIN_FIELD_BASE(40, 40, IOCFG_RB_BASE, 0x20, 0x10, 0, 3),
+ PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x10, 0x10, 6, 3),
+ PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x20, 0x10, 9, 3),
+ PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x20, 0x10, 3, 3),
+ PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x20, 0x10, 21, 3),
+ PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x20, 0x10, 15, 3),
+ PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x00, 0x10, 6, 3),
+ PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x00, 0x10, 3, 3),
+ PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x00, 0x10, 0, 3),
+ PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x10, 0x10, 0, 3),
+ PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x10, 0x10, 15, 3),
+ PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x10, 0x10, 12, 3),
+ PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x10, 0x10, 9, 3),
+ PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x10, 0x10, 18, 3),
+ PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x00, 0x10, 2, 3),
+ PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x00, 0x10, 3, 3),
+ PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x00, 0x10, 0, 3),
+ PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x10, 0x10, 18, 3),
+ PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x10, 0x10, 12, 3),
+ PIN_FIELD_BASE(74, 77, IOCFG_TR_BASE, 0x00, 0x10, 15, 3),
+ PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x00, 0x10, 6, 3),
+ PIN_FIELD_BASE(80, 80, IOCFG_TR_BASE, 0x00, 0x10, 27, 3),
+ PIN_FIELD_BASE(81, 84, IOCFG_TR_BASE, 0x10, 0x10, 0, 3),
+ PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x00, 0x10, 12, 3),
+ PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x00, 0x10, 3, 3),
+ PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x00, 0x10, 0, 3),
+ PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x10, 0x10, 12, 3),
+ PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x10, 0x10, 6, 3),
+ PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x00, 0x10, 12, 3),
+ PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x00, 0x10, 6, 3),
+ PIN_FIELD_BASE(97, 98, IOCFG_TL_BASE, 0x00, 0x10, 24, 3),
+ PIN_FIELD_BASE(99, 100, IOCFG_TL_BASE, 0x10, 0x10, 2, 3),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_pupd_range[] = {
+ PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x60, 0x10, 17, 1),
+ PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x30, 0x10, 10, 1),
+ PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x40, 0x10, 0, 1),
+ PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0x60, 0x10, 0, 1),
+ PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x30, 0x10, 0, 1),
+ PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0x60, 0x10, 8, 1),
+ PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x60, 0x10, 2, 1),
+ PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x40, 0x10, 12, 1),
+ PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x40, 0x10, 18, 1),
+ PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x40, 0x10, 17, 1),
+ PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x40, 0x10, 15, 1),
+ PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0x40, 0x10, 19, 1),
+ PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x40, 0x10, 23, 1),
+ PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x40, 0x10, 22, 1),
+ PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x40, 0x10, 21, 1),
+ PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x30, 0x10, 4, 1),
+ PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x30, 0x10, 8, 1),
+ PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x30, 0x10, 7, 1),
+ PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x30, 0x10, 5, 1),
+ PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x30, 0x10, 9, 1),
+ PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x60, 0x10, 18, 1),
+ PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x60, 0x10, 12, 1),
+ PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x60, 0x10, 23, 1),
+ PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x60, 0x10, 21, 1),
+ PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x60, 0x10, 27, 1),
+ PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x60, 0x10, 25, 1),
+ PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x40, 0x10, 2, 1),
+ PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x40, 0x10, 1, 1),
+ PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x40, 0x10, 0, 1),
+ PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x40, 0x10, 10, 1),
+ PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x60, 0x10, 15, 1),
+ PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x60, 0x10, 14, 1),
+ PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x60, 0x10, 13, 1),
+ PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x60, 0x10, 16, 1),
+ PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x40, 0x10, 2, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_r0_range[] = {
+ PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x70, 0x10, 17, 1),
+ PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x40, 0x10, 10, 1),
+ PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x50, 0x10, 0, 1),
+ PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0x70, 0x10, 0, 1),
+ PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x40, 0x10, 0, 1),
+ PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0x70, 0x10, 8, 1),
+ PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x70, 0x10, 2, 1),
+ PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x50, 0x10, 12, 1),
+ PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x50, 0x10, 18, 1),
+ PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x50, 0x10, 17, 1),
+ PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x50, 0x10, 15, 1),
+ PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0x50, 0x10, 19, 1),
+ PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x50, 0x10, 23, 1),
+ PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x50, 0x10, 22, 1),
+ PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x50, 0x10, 21, 1),
+ PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x40, 0x10, 4, 1),
+ PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x40, 0x10, 8, 1),
+ PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x40, 0x10, 7, 1),
+ PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x40, 0x10, 5, 1),
+ PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x40, 0x10, 9, 1),
+ PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x70, 0x10, 18, 1),
+ PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x70, 0x10, 12, 1),
+ PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x70, 0x10, 23, 1),
+ PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x70, 0x10, 21, 1),
+ PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x70, 0x10, 27, 1),
+ PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x70, 0x10, 25, 1),
+ PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x50, 0x10, 2, 1),
+ PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x50, 0x10, 1, 1),
+ PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x50, 0x10, 0, 1),
+ PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x50, 0x10, 10, 1),
+ PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x70, 0x10, 15, 1),
+ PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x70, 0x10, 14, 1),
+ PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x70, 0x10, 13, 1),
+ PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x70, 0x10, 16, 1),
+ PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x50, 0x10, 2, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_r1_range[] = {
+ PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x80, 0x10, 17, 1),
+ PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x50, 0x10, 10, 1),
+ PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x60, 0x10, 0, 1),
+ PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0x80, 0x10, 0, 1),
+ PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x50, 0x10, 0, 1),
+ PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0x80, 0x10, 8, 1),
+ PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x80, 0x10, 2, 1),
+ PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x60, 0x10, 12, 1),
+ PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x60, 0x10, 18, 1),
+ PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x60, 0x10, 17, 1),
+ PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x60, 0x10, 15, 1),
+ PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0x60, 0x10, 19, 1),
+ PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x60, 0x10, 23, 1),
+ PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x60, 0x10, 22, 1),
+ PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x60, 0x10, 21, 1),
+ PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x50, 0x10, 4, 1),
+ PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x50, 0x10, 8, 1),
+ PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x50, 0x10, 7, 1),
+ PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x50, 0x10, 5, 1),
+ PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x50, 0x10, 9, 1),
+ PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x80, 0x10, 18, 1),
+ PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x80, 0x10, 12, 1),
+ PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x80, 0x10, 23, 1),
+ PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x80, 0x10, 21, 1),
+ PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x80, 0x10, 27, 1),
+ PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x80, 0x10, 25, 1),
+ PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x60, 0x10, 2, 1),
+ PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x60, 0x10, 1, 1),
+ PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x60, 0x10, 0, 1),
+ PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x60, 0x10, 10, 1),
+ PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x80, 0x10, 15, 1),
+ PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x80, 0x10, 14, 1),
+ PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x80, 0x10, 13, 1),
+ PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x80, 0x10, 16, 1),
+ PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x60, 0x10, 2, 1),
+};
+
+static const struct mtk_pin_reg_calc mt7986_reg_cals[] = {
+ [PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7986_pin_mode_range),
+ [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7986_pin_dir_range),
+ [PINCTRL_PIN_REG_DI] = MTK_RANGE(mt7986_pin_di_range),
+ [PINCTRL_PIN_REG_DO] = MTK_RANGE(mt7986_pin_do_range),
+ [PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt7986_pin_smt_range),
+ [PINCTRL_PIN_REG_IES] = MTK_RANGE(mt7986_pin_ies_range),
+ [PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt7986_pin_drv_range),
+ [PINCTRL_PIN_REG_PU] = MTK_RANGE(mt7986_pin_pu_range),
+ [PINCTRL_PIN_REG_PD] = MTK_RANGE(mt7986_pin_pd_range),
+ [PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt7986_pin_pupd_range),
+ [PINCTRL_PIN_REG_R0] = MTK_RANGE(mt7986_pin_r0_range),
+ [PINCTRL_PIN_REG_R1] = MTK_RANGE(mt7986_pin_r1_range),
+};
+
+static const struct mtk_pin_desc mt7986_pins[] = {
+ MT7986_TYPE0_PIN(0, "SYS_WATCHDOG"),
+ MT7986_TYPE0_PIN(1, "WF2G_LED"),
+ MT7986_TYPE0_PIN(2, "WF5G_LED"),
+ MT7986_TYPE0_PIN(3, "I2C_SCL"),
+ MT7986_TYPE0_PIN(4, "I2C_SDA"),
+ MT7986_TYPE0_PIN(5, "GPIO_0"),
+ MT7986_TYPE0_PIN(6, "GPIO_1"),
+ MT7986_TYPE0_PIN(7, "GPIO_2"),
+ MT7986_TYPE0_PIN(8, "GPIO_3"),
+ MT7986_TYPE0_PIN(9, "GPIO_4"),
+ MT7986_TYPE0_PIN(10, "GPIO_5"),
+ MT7986_TYPE0_PIN(11, "GPIO_6"),
+ MT7986_TYPE0_PIN(12, "GPIO_7"),
+ MT7986_TYPE0_PIN(13, "GPIO_8"),
+ MT7986_TYPE0_PIN(14, "GPIO_9"),
+ MT7986_TYPE0_PIN(15, "GPIO_10"),
+ MT7986_TYPE0_PIN(16, "GPIO_11"),
+ MT7986_TYPE0_PIN(17, "GPIO_12"),
+ MT7986_TYPE0_PIN(18, "GPIO_13"),
+ MT7986_TYPE0_PIN(19, "GPIO_14"),
+ MT7986_TYPE0_PIN(20, "GPIO_15"),
+ MT7986_TYPE0_PIN(21, "PWM0"),
+ MT7986_TYPE0_PIN(22, "PWM1"),
+ MT7986_TYPE0_PIN(23, "SPI0_CLK"),
+ MT7986_TYPE0_PIN(24, "SPI0_MOSI"),
+ MT7986_TYPE0_PIN(25, "SPI0_MISO"),
+ MT7986_TYPE0_PIN(26, "SPI0_CS"),
+ MT7986_TYPE0_PIN(27, "SPI0_HOLD"),
+ MT7986_TYPE0_PIN(28, "SPI0_WP"),
+ MT7986_TYPE0_PIN(29, "SPI1_CLK"),
+ MT7986_TYPE0_PIN(30, "SPI1_MOSI"),
+ MT7986_TYPE0_PIN(31, "SPI1_MISO"),
+ MT7986_TYPE0_PIN(32, "SPI1_CS"),
+ MT7986_TYPE0_PIN(33, "SPI2_CLK"),
+ MT7986_TYPE0_PIN(34, "SPI2_MOSI"),
+ MT7986_TYPE0_PIN(35, "SPI2_MISO"),
+ MT7986_TYPE0_PIN(36, "SPI2_CS"),
+ MT7986_TYPE0_PIN(37, "SPI2_HOLD"),
+ MT7986_TYPE0_PIN(38, "SPI2_WP"),
+ MT7986_TYPE0_PIN(39, "UART0_RXD"),
+ MT7986_TYPE0_PIN(40, "UART0_TXD"),
+ MT7986_TYPE0_PIN(41, "PCIE_PERESET_N"),
+ MT7986_TYPE0_PIN(42, "UART1_RXD"),
+ MT7986_TYPE0_PIN(43, "UART1_TXD"),
+ MT7986_TYPE0_PIN(44, "UART1_CTS"),
+ MT7986_TYPE0_PIN(45, "UART1_RTS"),
+ MT7986_TYPE0_PIN(46, "UART2_RXD"),
+ MT7986_TYPE0_PIN(47, "UART2_TXD"),
+ MT7986_TYPE0_PIN(48, "UART2_CTS"),
+ MT7986_TYPE0_PIN(49, "UART2_RTS"),
+ MT7986_TYPE0_PIN(50, "EMMC_DATA_0"),
+ MT7986_TYPE0_PIN(51, "EMMC_DATA_1"),
+ MT7986_TYPE0_PIN(52, "EMMC_DATA_2"),
+ MT7986_TYPE0_PIN(53, "EMMC_DATA_3"),
+ MT7986_TYPE0_PIN(54, "EMMC_DATA_4"),
+ MT7986_TYPE0_PIN(55, "EMMC_DATA_5"),
+ MT7986_TYPE0_PIN(56, "EMMC_DATA_6"),
+ MT7986_TYPE0_PIN(57, "EMMC_DATA_7"),
+ MT7986_TYPE0_PIN(58, "EMMC_CMD"),
+ MT7986_TYPE0_PIN(59, "EMMC_CK"),
+ MT7986_TYPE0_PIN(60, "EMMC_DSL"),
+ MT7986_TYPE0_PIN(61, "EMMC_RSTB"),
+ MT7986_TYPE0_PIN(62, "PCM_DTX"),
+ MT7986_TYPE0_PIN(63, "PCM_DRX"),
+ MT7986_TYPE0_PIN(64, "PCM_CLK"),
+ MT7986_TYPE0_PIN(65, "PCM_FS"),
+ MT7986_TYPE0_PIN(66, "MT7531_INT"),
+ MT7986_TYPE0_PIN(67, "SMI_MDC"),
+ MT7986_TYPE0_PIN(68, "SMI_MDIO"),
+ MT7986_TYPE1_PIN(69, "WF0_DIG_RESETB"),
+ MT7986_TYPE1_PIN(70, "WF0_CBA_RESETB"),
+ MT7986_TYPE1_PIN(71, "WF0_XO_REQ"),
+ MT7986_TYPE1_PIN(72, "WF0_TOP_CLK"),
+ MT7986_TYPE1_PIN(73, "WF0_TOP_DATA"),
+ MT7986_TYPE1_PIN(74, "WF0_HB1"),
+ MT7986_TYPE1_PIN(75, "WF0_HB2"),
+ MT7986_TYPE1_PIN(76, "WF0_HB3"),
+ MT7986_TYPE1_PIN(77, "WF0_HB4"),
+ MT7986_TYPE1_PIN(78, "WF0_HB0"),
+ MT7986_TYPE1_PIN(79, "WF0_HB0_B"),
+ MT7986_TYPE1_PIN(80, "WF0_HB5"),
+ MT7986_TYPE1_PIN(81, "WF0_HB6"),
+ MT7986_TYPE1_PIN(82, "WF0_HB7"),
+ MT7986_TYPE1_PIN(83, "WF0_HB8"),
+ MT7986_TYPE1_PIN(84, "WF0_HB9"),
+ MT7986_TYPE1_PIN(85, "WF0_HB10"),
+ MT7986_TYPE1_PIN(86, "WF1_DIG_RESETB"),
+ MT7986_TYPE1_PIN(87, "WF1_CBA_RESETB"),
+ MT7986_TYPE1_PIN(88, "WF1_XO_REQ"),
+ MT7986_TYPE1_PIN(89, "WF1_TOP_CLK"),
+ MT7986_TYPE1_PIN(90, "WF1_TOP_DATA"),
+ MT7986_TYPE1_PIN(91, "WF1_HB1"),
+ MT7986_TYPE1_PIN(92, "WF1_HB2"),
+ MT7986_TYPE1_PIN(93, "WF1_HB3"),
+ MT7986_TYPE1_PIN(94, "WF1_HB4"),
+ MT7986_TYPE1_PIN(95, "WF1_HB0"),
+ MT7986_TYPE1_PIN(96, "WF1_HB0_B"),
+ MT7986_TYPE1_PIN(97, "WF1_HB5"),
+ MT7986_TYPE1_PIN(98, "WF1_HB6"),
+ MT7986_TYPE1_PIN(99, "WF1_HB7"),
+ MT7986_TYPE1_PIN(100, "WF1_HB8"),
+};
+
+static const struct mtk_io_type_desc mt7986_io_type_desc[] = {
+ [IO_TYPE_GRP0] = {
+ .name = "18OD33",
+ .bias_set = mtk_pinconf_bias_set_pupd_r1_r0,
+ .drive_set = mtk_pinconf_drive_set_v1,
+ .input_enable = mtk_pinconf_input_enable_v1,
+ },
+ [IO_TYPE_GRP1] = {
+ .name = "18A01",
+ .bias_set = mtk_pinconf_bias_set_pu_pd,
+ .drive_set = mtk_pinconf_drive_set_v1,
+ .input_enable = mtk_pinconf_input_enable_v1,
+ },
+};
+
+/* List all groups consisting of these pins dedicated to the enablement of
+ * certain hardware block and the corresponding mode for all of the pins.
+ * The hardware probably has multiple combinations of these pinouts.
+ */
+
+static int mt7986_watchdog_pins[] = { 0, };
+static int mt7986_watchdog_funcs[] = { 1, };
+
+static int mt7986_wifi_led_pins[] = { 1, 2, };
+static int mt7986_wifi_led_funcs[] = { 1, 1, };
+
+static int mt7986_i2c_pins[] = { 3, 4, };
+static int mt7986_i2c_funcs[] = { 1, 1, };
+
+static int mt7986_uart1_0_pins[] = { 7, 8, 9, 10, };
+static int mt7986_uart1_0_funcs[] = { 3, 3, 3, 3, };
+
+static int mt7986_spi1_0_pins[] = { 11, 12, 13, 14, };
+static int mt7986_spi1_0_funcs[] = { 3, 3, 3, 3, };
+
+static int mt7986_pwm1_1_pins[] = { 20, };
+static int mt7986_pwm1_1_funcs[] = { 2, };
+
+static int mt7986_pwm0_pins[] = { 21, };
+static int mt7986_pwm0_funcs[] = { 1, };
+
+static int mt7986_pwm1_0_pins[] = { 22, };
+static int mt7986_pwm1_0_funcs[] = { 1, };
+
+static int mt7986_emmc_45_pins[] = {
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, };
+static int mt7986_emmc_45_funcs[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, };
+
+static int mt7986_snfi_pins[] = { 23, 24, 25, 26, 27, 28, };
+static int mt7986_snfi_funcs[] = { 1, 1, 1, 1, 1, 1, };
+
+static int mt7986_spi1_1_pins[] = { 23, 24, 25, 26, };
+static int mt7986_spi1_1_funcs[] = { 3, 3, 3, 3, };
+
+static int mt7986_uart1_1_pins[] = { 23, 24, 25, 26, };
+static int mt7986_uart1_1_funcs[] = { 4, 4, 4, 4, };
+
+static int mt7986_spi1_2_pins[] = { 29, 30, 31, 32, };
+static int mt7986_spi1_2_funcs[] = { 1, 1, 1, 1, };
+
+static int mt7986_uart1_2_pins[] = { 29, 30, 31, 32, };
+static int mt7986_uart1_2_funcs[] = { 3, 3, 3, 3, };
+
+static int mt7986_uart2_0_pins[] = { 29, 30, 31, 32, };
+static int mt7986_uart2_0_funcs[] = { 4, 4, 4, 4, };
+
+static int mt7986_spi0_pins[] = { 33, 34, 35, 36, };
+static int mt7986_spi0_funcs[] = { 1, 1, 1, 1, };
+
+static int mt7986_spi0_wp_hold_pins[] = { 37, 38, };
+static int mt7986_spi0_wp_hold_funcs[] = { 1, 1, };
+
+static int mt7986_uart2_1_pins[] = { 33, 34, 35, 36, };
+static int mt7986_uart2_1_funcs[] = { 3, 3, 3, 3, };
+
+static int mt7986_uart1_3_rx_tx_pins[] = { 35, 36, };
+static int mt7986_uart1_3_rx_tx_funcs[] = { 2, 2, };
+
+static int mt7986_uart1_3_cts_rts_pins[] = { 37, 38, };
+static int mt7986_uart1_3_cts_rts_funcs[] = { 2, 2, };
+
+static int mt7986_spi1_3_pins[] = { 33, 34, 35, 36, };
+static int mt7986_spi1_3_funcs[] = { 4, 4, 4, 4, };
+
+static int mt7986_uart0_pins[] = { 39, 40, };
+static int mt7986_uart0_funcs[] = { 1, 1, };
+
+static int mt7986_pcie_reset_pins[] = { 41, };
+static int mt7986_pcie_reset_funcs[] = { 1, };
+
+static int mt7986_uart1_pins[] = { 42, 43, 44, 45, };
+static int mt7986_uart1_funcs[] = { 1, 1, 1, 1, };
+
+static int mt7986_uart2_pins[] = { 46, 47, 48, 49, };
+static int mt7986_uart2_funcs[] = { 1, 1, 1, 1, };
+
+static int mt7986_emmc_51_pins[] = {
+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, };
+static int mt7986_emmc_51_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, };
+
+static int mt7986_pcm_pins[] = { 62, 63, 64, 65, };
+static int mt7986_pcm_funcs[] = { 1, 1, 1, 1, };
+
+static int mt7986_i2s_pins[] = { 62, 63, 64, 65, };
+static int mt7986_i2s_funcs[] = { 1, 1, 1, 1, };
+
+static int mt7986_switch_int_pins[] = { 66, };
+static int mt7986_switch_int_funcs[] = { 1, };
+
+static int mt7986_mdc_mdio_pins[] = { 67, 68, };
+static int mt7986_mdc_mdio_funcs[] = { 1, 1, };
+
+static int mt7986_wf_2g_pins[] = {74, 75, 76, 77, 78, 79, 80, 81, 82, 83, };
+static int mt7986_wf_2g_funcs[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, };
+
+static int mt7986_wf_5g_pins[] = {91, 92, 93, 94, 95, 96, 97, 98, 99, 100, };
+static int mt7986_wf_5g_funcs[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, };
+
+static int mt7986_wf_dbdc_pins[] = {
+ 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, };
+static int mt7986_wf_dbdc_funcs[] = {
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, };
+
+static int mt7986_pcie_clk_pins[] = { 9, };
+static int mt7986_pcie_clk_funcs[] = { 1, };
+
+static int mt7986_pcie_wake_pins[] = { 10, };
+static int mt7986_pcie_wake_funcs[] = { 1, };
+
+static const struct mtk_group_desc mt7986_groups[] = {
+ PINCTRL_PIN_GROUP("watchdog", mt7986_watchdog),
+ PINCTRL_PIN_GROUP("wifi_led", mt7986_wifi_led),
+ PINCTRL_PIN_GROUP("i2c", mt7986_i2c),
+ PINCTRL_PIN_GROUP("uart1_0", mt7986_uart1_0),
+ PINCTRL_PIN_GROUP("pcie_clk", mt7986_pcie_clk),
+ PINCTRL_PIN_GROUP("pcie_wake", mt7986_pcie_wake),
+ PINCTRL_PIN_GROUP("spi1_0", mt7986_spi1_0),
+ PINCTRL_PIN_GROUP("pwm1_1", mt7986_pwm1_1),
+ PINCTRL_PIN_GROUP("pwm0", mt7986_pwm0),
+ PINCTRL_PIN_GROUP("pwm1_0", mt7986_pwm1_0),
+ PINCTRL_PIN_GROUP("emmc_45", mt7986_emmc_45),
+ PINCTRL_PIN_GROUP("snfi", mt7986_snfi),
+ PINCTRL_PIN_GROUP("spi1_1", mt7986_spi1_1),
+ PINCTRL_PIN_GROUP("uart1_1", mt7986_uart1_1),
+ PINCTRL_PIN_GROUP("spi1_2", mt7986_spi1_2),
+ PINCTRL_PIN_GROUP("uart1_2", mt7986_uart1_2),
+ PINCTRL_PIN_GROUP("uart2_0", mt7986_uart2_0),
+ PINCTRL_PIN_GROUP("spi0", mt7986_spi0),
+ PINCTRL_PIN_GROUP("spi0_wp_hold", mt7986_spi0_wp_hold),
+ PINCTRL_PIN_GROUP("uart2_1", mt7986_uart2_1),
+ PINCTRL_PIN_GROUP("uart1_3_rx_tx", mt7986_uart1_3_rx_tx),
+ PINCTRL_PIN_GROUP("uart1_3_cts_rts", mt7986_uart1_3_cts_rts),
+ PINCTRL_PIN_GROUP("spi1_3", mt7986_spi1_3),
+ PINCTRL_PIN_GROUP("uart0", mt7986_uart0),
+ PINCTRL_PIN_GROUP("switch_int", mt7986_switch_int),
+ PINCTRL_PIN_GROUP("mdc_mdio", mt7986_mdc_mdio),
+ PINCTRL_PIN_GROUP("pcie_pereset", mt7986_pcie_reset),
+ PINCTRL_PIN_GROUP("uart1", mt7986_uart1),
+ PINCTRL_PIN_GROUP("uart2", mt7986_uart2),
+ PINCTRL_PIN_GROUP("emmc_51", mt7986_emmc_51),
+ PINCTRL_PIN_GROUP("pcm", mt7986_pcm),
+ PINCTRL_PIN_GROUP("i2s", mt7986_i2s),
+ PINCTRL_PIN_GROUP("wf_2g", mt7986_wf_2g),
+ PINCTRL_PIN_GROUP("wf_5g", mt7986_wf_5g),
+ PINCTRL_PIN_GROUP("wf_dbdc", mt7986_wf_dbdc),
+};
+
+/* Joint those groups owning the same capability in user point of view which
+ * allows that people tend to use through the device tree.
+ */
+
+static const char *const mt7986_audio_groups[] = { "pcm", "i2s" };
+static const char *const mt7986_emmc_groups[] = { "emmc_45", "emmc_51", };
+static const char *const mt7986_ethernet_groups[] = { "switch_int",
+ "mdc_mdio", };
+static const char *const mt7986_i2c_groups[] = { "i2c", };
+static const char *const mt7986_led_groups[] = { "wifi_led", };
+static const char *const mt7986_flash_groups[] = { "snfi", };
+static const char *const mt7986_pcie_groups[] = { "pcie_clk", "pcie_wake",
+ "pcie_pereset" };
+static const char *const mt7986_pwm_groups[] = { "pwm0", "pwm1_0", "pwm1_1", };
+static const char *const mt7986_spi_groups[] = { "spi0", "spi0_wp_hold",
+ "spi1_0", "spi1_1", "spi1_2", "spi1_3", };
+static const char *const mt7986_uart_groups[] = { "uart1_0", "uart1_1",
+ "uart1_2", "uart1_3_rx_tx", "uart1_3_cts_rts", "uart2_0", "uart2_1",
+ "uart0", "uart1", "uart2", };
+static const char *const mt7986_wdt_groups[] = { "watchdog", };
+static const char *const mt7986_wf_groups[] = { "wf_2g", "wf_5g", "wf_dbdc", };
+
+static const struct mtk_function_desc mt7986_functions[] = {
+ {"audio", mt7986_audio_groups, ARRAY_SIZE(mt7986_audio_groups)},
+ {"emmc", mt7986_emmc_groups, ARRAY_SIZE(mt7986_emmc_groups)},
+ {"eth", mt7986_ethernet_groups, ARRAY_SIZE(mt7986_ethernet_groups)},
+ {"i2c", mt7986_i2c_groups, ARRAY_SIZE(mt7986_i2c_groups)},
+ {"led", mt7986_led_groups, ARRAY_SIZE(mt7986_led_groups)},
+ {"flash", mt7986_flash_groups, ARRAY_SIZE(mt7986_flash_groups)},
+ {"pcie", mt7986_pcie_groups, ARRAY_SIZE(mt7986_pcie_groups)},
+ {"pwm", mt7986_pwm_groups, ARRAY_SIZE(mt7986_pwm_groups)},
+ {"spi", mt7986_spi_groups, ARRAY_SIZE(mt7986_spi_groups)},
+ {"uart", mt7986_uart_groups, ARRAY_SIZE(mt7986_uart_groups)},
+ {"watchdog", mt7986_wdt_groups, ARRAY_SIZE(mt7986_wdt_groups)},
+ {"wifi", mt7986_wf_groups, ARRAY_SIZE(mt7986_wf_groups)},
+};
+
+static struct mtk_pinctrl_soc mt7986_data = {
+ .name = "mt7986_pinctrl",
+ .reg_cal = mt7986_reg_cals,
+ .pins = mt7986_pins,
+ .npins = ARRAY_SIZE(mt7986_pins),
+ .grps = mt7986_groups,
+ .ngrps = ARRAY_SIZE(mt7986_groups),
+ .funcs = mt7986_functions,
+ .nfuncs = ARRAY_SIZE(mt7986_functions),
+ .io_type = mt7986_io_type_desc,
+ .ntype = ARRAY_SIZE(mt7986_io_type_desc),
+ .gpio_mode = 0,
+ .base_names = mt7986_pinctrl_register_base_names,
+ .nbase_names = ARRAY_SIZE(mt7986_pinctrl_register_base_names),
+ .base_calc = 1,
+};
+
+static int mtk_pinctrl_mt7986_probe(struct udevice *dev)
+{
+ return mtk_pinctrl_common_probe(dev, &mt7986_data);
+}
+
+static const struct udevice_id mt7986_pctrl_match[] = {
+ {.compatible = "mediatek,mt7986-pinctrl"},
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(mt7986_pinctrl) = {
+ .name = "mt7986_pinctrl",
+ .id = UCLASS_PINCTRL,
+ .of_match = mt7986_pctrl_match,
+ .ops = &mtk_pinctrl_ops,
+ .probe = mtk_pinctrl_mt7986_probe,
+ .priv_auto = sizeof(struct mtk_pinctrl_priv),
+};
diff --git a/drivers/pwm/pwm-mtk.c b/drivers/pwm/pwm-mtk.c
index aee1d82..605142e 100644
--- a/drivers/pwm/pwm-mtk.c
+++ b/drivers/pwm/pwm-mtk.c
@@ -29,13 +29,23 @@
#define NSEC_PER_SEC 1000000000L
-static const unsigned int mtk_pwm_reg_offset[] = {
+enum mtk_pwm_reg_ver {
+ PWM_REG_V1,
+ PWM_REG_V2,
+};
+
+static const unsigned int mtk_pwm_reg_offset_v1[] = {
0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220
};
+static const unsigned int mtk_pwm_reg_offset_v2[] = {
+ 0x0080, 0x00c0, 0x0100, 0x0140, 0x0180, 0x01c0, 0x0200, 0x0240
+};
+
struct mtk_pwm_soc {
unsigned int num_pwms;
bool pwm45_fixup;
+ enum mtk_pwm_reg_ver reg_ver;
};
struct mtk_pwm_priv {
@@ -49,7 +59,16 @@
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,22 +178,39 @@
static const struct mtk_pwm_soc mt7622_data = {
.num_pwms = 6,
.pwm45_fixup = false,
+ .reg_ver = PWM_REG_V1,
};
static const struct mtk_pwm_soc mt7623_data = {
.num_pwms = 5,
.pwm45_fixup = true,
+ .reg_ver = PWM_REG_V1,
};
static const struct mtk_pwm_soc mt7629_data = {
.num_pwms = 1,
.pwm45_fixup = false,
+ .reg_ver = PWM_REG_V1,
};
+static const struct mtk_pwm_soc mt7981_data = {
+ .num_pwms = 2,
+ .pwm45_fixup = false,
+ .reg_ver = PWM_REG_V2,
+};
+
+static const struct mtk_pwm_soc mt7986_data = {
+ .num_pwms = 2,
+ .pwm45_fixup = false,
+ .reg_ver = PWM_REG_V1,
+};
+
static const struct udevice_id mtk_pwm_ids[] = {
{ .compatible = "mediatek,mt7622-pwm", .data = (ulong)&mt7622_data },
{ .compatible = "mediatek,mt7623-pwm", .data = (ulong)&mt7623_data },
{ .compatible = "mediatek,mt7629-pwm", .data = (ulong)&mt7629_data },
+ { .compatible = "mediatek,mt7981-pwm", .data = (ulong)&mt7981_data },
+ { .compatible = "mediatek,mt7986-pwm", .data = (ulong)&mt7986_data },
{ }
};
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 25194ee..d1b40c6 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -17,4 +17,5 @@
ifdef CONFIG_SCSI
obj-$(CONFIG_SANDBOX) += sandbox_scsi.o
+obj-$(CONFIG_SANDBOX) += scsi_emul.o
endif
diff --git a/drivers/scsi/sandbox_scsi.c b/drivers/scsi/sandbox_scsi.c
index 39b969a..a7ac33c 100644
--- a/drivers/scsi/sandbox_scsi.c
+++ b/drivers/scsi/sandbox_scsi.c
@@ -7,19 +7,145 @@
* that CONFIG_SCSI can be enabled for sandbox.
*/
+#define LOG_CATEGORY UCLASS_SCSI
+
#include <common.h>
+#include <dm.h>
+#include <os.h>
+#include <malloc.h>
#include <scsi.h>
+#include <scsi_emul.h>
+
+enum {
+ SANDBOX_SCSI_BLOCK_LEN = 512,
+ SANDBOX_SCSI_BUF_SIZE = 512,
+};
-int scsi_bus_reset(struct udevice *dev)
+/**
+ * struct sandbox_scsi_priv
+ *
+ * @eminfo: emulator state
+ * @pathanme: Path to the backing file, e.g. 'scsi.img'
+ * @fd: File descriptor of backing file
+ */
+struct sandbox_scsi_priv {
+ struct scsi_emul_info eminfo;
+ const char *pathname;
+ int fd;
+};
+
+static int sandbox_scsi_exec(struct udevice *dev, struct scsi_cmd *req)
{
+ struct sandbox_scsi_priv *priv = dev_get_priv(dev);
+ struct scsi_emul_info *info = &priv->eminfo;
+ int ret;
+
+ if (req->lun || req->target)
+ return -EIO;
+ ret = sb_scsi_emul_command(info, req, req->cmdlen);
+ if (ret < 0) {
+ log_debug("SCSI command 0x%02x ret errno %d\n", req->cmd[0],
+ ret);
+ return ret;
+ } else if (ret == SCSI_EMUL_DO_READ && priv->fd != -1) {
+ long bytes_read;
+
+ log_debug("read %x %x\n", info->seek_block, info->read_len);
+ os_lseek(priv->fd, info->seek_block * info->block_size,
+ OS_SEEK_SET);
+ bytes_read = os_read(priv->fd, req->pdata, info->buff_used);
+ if (bytes_read < 0)
+ return bytes_read;
+ if (bytes_read != info->buff_used)
+ return -EIO;
+ } else if (!ret) {
+ req->pdata = info->buff;
+ info->phase = SCSIPH_STATUS;
+ log_debug("sending buf\n");
+ } else {
+ log_debug("error\n");
+ return -EIO;
+ }
+
return 0;
}
-void scsi_init(void)
+static int sandbox_scsi_bus_reset(struct udevice *dev)
{
+ /* Not implemented */
+
+ return 0;
}
-int scsi_exec(struct udevice *dev, struct scsi_cmd *pccb)
+static int sandbox_scsi_of_to_plat(struct udevice *dev)
{
+ struct sandbox_scsi_priv *priv = dev_get_priv(dev);
+
+ priv->pathname = dev_read_string(dev, "sandbox,filepath");
+
return 0;
}
+
+static int sandbox_scsi_probe(struct udevice *dev)
+{
+ struct scsi_plat *scsi_plat = dev_get_uclass_plat(dev);
+ struct sandbox_scsi_priv *priv = dev_get_priv(dev);
+ struct scsi_emul_info *info = &priv->eminfo;
+ int ret;
+
+ scsi_plat->max_id = 2;
+ scsi_plat->max_lun = 3;
+ scsi_plat->max_bytes_per_req = 1 << 20;
+
+ info->vendor = "SANDBOX";
+ info->product = "FAKE DISK";
+ info->buff = malloc(SANDBOX_SCSI_BUF_SIZE);
+ if (!info->buff)
+ return log_ret(-ENOMEM);
+ info->block_size = SANDBOX_SCSI_BLOCK_LEN;
+
+ if (priv->pathname) {
+ priv->fd = os_open(priv->pathname, OS_O_RDONLY);
+ if (priv->fd != -1) {
+ ret = os_get_filesize(priv->pathname, &info->file_size);
+ if (ret)
+ return log_msg_ret("sz", ret);
+ }
+ } else {
+ priv->fd = -1;
+ }
+ log_debug("filename: %s, fd %d\n", priv->pathname, priv->fd);
+
+ return 0;
+}
+
+static int sandbox_scsi_remove(struct udevice *dev)
+{
+ struct sandbox_scsi_priv *priv = dev_get_priv(dev);
+ struct scsi_emul_info *info = &priv->eminfo;
+
+ free(info->buff);
+
+ return 0;
+}
+
+struct scsi_ops sandbox_scsi_ops = {
+ .exec = sandbox_scsi_exec,
+ .bus_reset = sandbox_scsi_bus_reset,
+};
+
+static const struct udevice_id sanbox_scsi_ids[] = {
+ { .compatible = "sandbox,scsi" },
+ { }
+};
+
+U_BOOT_DRIVER(sandbox_scsi) = {
+ .name = "sandbox_scsi",
+ .id = UCLASS_SCSI,
+ .ops = &sandbox_scsi_ops,
+ .of_match = sanbox_scsi_ids,
+ .of_to_plat = sandbox_scsi_of_to_plat,
+ .probe = sandbox_scsi_probe,
+ .remove = sandbox_scsi_remove,
+ .priv_auto = sizeof(struct sandbox_scsi_priv),
+};
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 99be5ae..3e769b0 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -456,7 +456,7 @@
{
dev_desc->lba = 0;
dev_desc->blksz = 0;
- dev_desc->if_type = UCLASS_SCSI;
+ dev_desc->uclass_id = UCLASS_SCSI;
dev_desc->devnum = devnum;
dev_desc->part_type = PART_TYPE_UNKNOWN;
@@ -706,8 +706,8 @@
};
#else
U_BOOT_LEGACY_BLK(scsi) = {
- .if_typename = "scsi",
- .if_type = UCLASS_SCSI,
+ .uclass_idname = "scsi",
+ .uclass_id = UCLASS_SCSI,
.max_devs = SCSI_MAX_DEVICE,
.desc = scsi_dev_desc,
};
diff --git a/drivers/scsi/scsi_emul.c b/drivers/scsi/scsi_emul.c
new file mode 100644
index 0000000..5ba364b
--- /dev/null
+++ b/drivers/scsi/scsi_emul.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Emulation of enough SCSI commands to find and read from a unit
+ *
+ * Copyright 2022 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * implementation of SCSI functions required so that CONFIG_SCSI can be enabled
+ * for sandbox.
+ */
+
+#define LOG_CATEGORY UCLASS_SCSI
+
+#include <common.h>
+#include <dm.h>
+#include <log.h>
+#include <scsi.h>
+#include <scsi_emul.h>
+
+int sb_scsi_emul_command(struct scsi_emul_info *info,
+ const struct scsi_cmd *req, int len)
+{
+ int ret = 0;
+
+ info->buff_used = 0;
+ log_debug("emul %x\n", *req->cmd);
+ switch (*req->cmd) {
+ case SCSI_INQUIRY: {
+ struct scsi_inquiry_resp *resp = (void *)info->buff;
+
+ info->alloc_len = req->cmd[4];
+ memset(resp, '\0', sizeof(*resp));
+ resp->data_format = 1;
+ resp->additional_len = 0x1f;
+ strncpy(resp->vendor, info->vendor, sizeof(resp->vendor));
+ strncpy(resp->product, info->product, sizeof(resp->product));
+ strncpy(resp->revision, "1.0", sizeof(resp->revision));
+ info->buff_used = sizeof(*resp);
+ break;
+ }
+ case SCSI_TST_U_RDY:
+ break;
+ case SCSI_RD_CAPAC: {
+ struct scsi_read_capacity_resp *resp = (void *)info->buff;
+ uint blocks;
+
+ if (info->file_size)
+ blocks = info->file_size / info->block_size - 1;
+ else
+ blocks = 0;
+ resp->last_block_addr = cpu_to_be32(blocks);
+ resp->block_len = cpu_to_be32(info->block_size);
+ info->buff_used = sizeof(*resp);
+ break;
+ }
+ case SCSI_READ10: {
+ const struct scsi_read10_req *read_req = (void *)req;
+
+ info->seek_block = be32_to_cpu(read_req->lba);
+ info->read_len = be16_to_cpu(read_req->xfer_len);
+ info->buff_used = info->read_len * info->block_size;
+ ret = SCSI_EMUL_DO_READ;
+ break;
+ }
+ default:
+ debug("Command not supported: %x\n", req->cmd[0]);
+ ret = -EPROTONOSUPPORT;
+ }
+ if (ret >= 0)
+ info->phase = info->transfer_len ? SCSIPH_DATA : SCSIPH_STATUS;
+ log_debug(" - done %x: ret=%d\n", *req->cmd, ret);
+
+ return ret;
+}
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index 0d43e9b..da3e1eb 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -238,6 +238,18 @@
} while (*str);
}
+#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
+static void _serial_flush(struct udevice *dev)
+{
+ struct dm_serial_ops *ops = serial_get_ops(dev);
+
+ if (!ops->pending)
+ return;
+ while (ops->pending(dev, false) > 0)
+ ;
+}
+#endif
+
static int __serial_getc(struct udevice *dev)
{
struct dm_serial_ops *ops = serial_get_ops(dev);
@@ -314,6 +326,16 @@
if (gd->cur_serial_dev)
_serial_puts(gd->cur_serial_dev, str);
}
+
+#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
+void serial_flush(void)
+{
+ if (!gd->cur_serial_dev)
+ return;
+
+ _serial_flush(gd->cur_serial_dev);
+}
+#endif
int serial_getc(void)
{
@@ -398,6 +420,13 @@
_serial_puts(sdev->priv, str);
}
+#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
+static void serial_stub_flush(struct stdio_dev *sdev)
+{
+ _serial_flush(sdev->priv);
+}
+#endif
+
static int serial_stub_getc(struct stdio_dev *sdev)
{
return _serial_getc(sdev->priv);
@@ -447,6 +476,7 @@
printf("## Switch baudrate to %d bps and press ENTER ...\n",
baudrate);
udelay(50000);
+ flush();
}
gd->baudrate = baudrate;
@@ -520,6 +550,7 @@
sdev.priv = dev;
sdev.putc = serial_stub_putc;
sdev.puts = serial_stub_puts;
+ STDIO_DEV_ASSIGN_FLUSH(&sdev, serial_stub_flush);
sdev.getc = serial_stub_getc;
sdev.tstc = serial_stub_tstc;
diff --git a/drivers/serial/serial_mtk.c b/drivers/serial/serial_mtk.c
index 22251c5..03b9e86 100644
--- a/drivers/serial/serial_mtk.c
+++ b/drivers/serial/serial_mtk.c
@@ -10,6 +10,7 @@
#include <common.h>
#include <div64.h>
#include <dm.h>
+#include <dm/device_compat.h>
#include <errno.h>
#include <log.h>
#include <serial.h>
@@ -70,27 +71,37 @@
#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 <= 12000000) {
+ if (baud <= 115200 && clk_rate == 12000000) {
writel(3, &priv->regs->highspeed);
- quot = DIV_ROUND_CLOSEST(priv->clock, 256 * baud);
+ quot = DIV_ROUND_CLOSEST(clk_rate, 256 * baud);
if (quot == 0)
quot = 1;
- samplecount = DIV_ROUND_CLOSEST(priv->clock, quot * baud);
+ samplecount = DIV_ROUND_CLOSEST(clk_rate, quot * baud);
- realbaud = priv->clock / samplecount / quot;
+ realbaud = clk_rate / samplecount / quot;
if (realbaud > BAUD_ALLOW_MAX(baud) ||
realbaud < BAUD_ALLOW_MIX(baud)) {
pr_info("baud %d can't be handled\n", baud);
@@ -104,7 +115,7 @@
if (baud <= 115200) {
writel(0, &priv->regs->highspeed);
- quot = DIV_ROUND_CLOSEST(priv->clock, 16 * baud);
+ quot = DIV_ROUND_CLOSEST(clk_rate, 16 * baud);
} else if (baud <= 576000) {
writel(2, &priv->regs->highspeed);
@@ -112,13 +123,13 @@
if ((baud == 500000) || (baud == 576000))
baud = 460800;
- quot = DIV_ROUND_UP(priv->clock, 4 * baud);
+ quot = DIV_ROUND_UP(clk_rate, 4 * baud);
} else {
use_hs3:
writel(3, &priv->regs->highspeed);
- quot = DIV_ROUND_UP(priv->clock, 256 * baud);
- samplecount = DIV_ROUND_CLOSEST(priv->clock, quot * baud);
+ quot = DIV_ROUND_UP(clk_rate, 256 * baud);
+ samplecount = DIV_ROUND_CLOSEST(clk_rate, quot * baud);
}
set_baud:
@@ -167,8 +178,13 @@
static int mtk_serial_setbrg(struct udevice *dev, int baudrate)
{
struct mtk_serial_priv *priv = dev_get_priv(dev);
+ u32 clk_rate;
- _mtk_serial_setbrg(priv, baudrate);
+ clk_rate = clk_get_rate(&priv->clk);
+ if (IS_ERR_VALUE(clk_rate) || clk_rate == 0)
+ clk_rate = priv->fixed_clk_rate;
+
+ _mtk_serial_setbrg(priv, baudrate, clk_rate);
return 0;
}
@@ -211,7 +227,6 @@
{
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 @@
priv->regs = map_physmem(addr, 0, MAP_NOCACHE);
- err = clk_get_by_index(dev, 0, &clk);
- if (!err) {
- err = clk_get_rate(&clk);
- if (!IS_ERR_VALUE(err))
- priv->clock = err;
- } else if (err != -ENOENT && err != -ENODEV && err != -ENOSYS) {
- debug("mtk_serial: failed to get clock\n");
- return err;
- }
-
- if (!priv->clock)
- priv->clock = dev_read_u32_default(dev, "clock-frequency", 0);
-
- if (!priv->clock) {
- debug("mtk_serial: clock not defined\n");
- return -EINVAL;
+ err = clk_get_by_index(dev, 0, &priv->clk);
+ if (err) {
+ err = dev_read_u32(dev, "clock-frequency", &priv->fixed_clk_rate);
+ if (err) {
+ dev_err(dev, "baud clock not defined\n");
+ return -EINVAL;
+ }
+ } else {
+ err = clk_get_rate(&priv->clk);
+ if (IS_ERR_VALUE(err)) {
+ dev_err(dev, "invalid baud clock\n");
+ return -EINVAL;
+ }
}
priv->force_highspeed = dev_read_bool(dev, "mediatek,force-highspeed");
@@ -273,7 +285,7 @@
#define DECLARE_HSUART_PRIV(port) \
static struct mtk_serial_priv mtk_hsuart##port = { \
.regs = (struct mtk_serial_regs *)CONFIG_SYS_NS16550_COM##port, \
- .clock = CONFIG_SYS_NS16550_CLK \
+ .fixed_clk_rate = CONFIG_SYS_NS16550_CLK \
};
#define DECLARE_HSUART_FUNCTIONS(port) \
@@ -282,12 +294,14 @@
writel(0, &mtk_hsuart##port.regs->ier); \
writel(UART_MCRVAL, &mtk_hsuart##port.regs->mcr); \
writel(UART_FCRVAL, &mtk_hsuart##port.regs->fcr); \
- _mtk_serial_setbrg(&mtk_hsuart##port, gd->baudrate); \
+ _mtk_serial_setbrg(&mtk_hsuart##port, gd->baudrate, \
+ mtk_hsuart##port.fixed_clk_rate); \
return 0 ; \
} \
static void mtk_serial##port##_setbrg(void) \
{ \
- _mtk_serial_setbrg(&mtk_hsuart##port, gd->baudrate); \
+ _mtk_serial_setbrg(&mtk_hsuart##port, gd->baudrate, \
+ mtk_hsuart##port.fixed_clk_rate); \
} \
static int mtk_serial##port##_getc(void) \
{ \
@@ -427,13 +441,13 @@
struct mtk_serial_priv priv;
priv.regs = (void *) CONFIG_VAL(DEBUG_UART_BASE);
- priv.clock = CONFIG_DEBUG_UART_CLOCK;
+ priv.fixed_clk_rate = CONFIG_DEBUG_UART_CLOCK;
writel(0, &priv.regs->ier);
writel(UART_MCRVAL, &priv.regs->mcr);
writel(UART_FCRVAL, &priv.regs->fcr);
- _mtk_serial_setbrg(&priv, CONFIG_BAUDRATE);
+ _mtk_serial_setbrg(&priv, CONFIG_BAUDRATE, priv.fixed_clk_rate);
}
static inline void _debug_uart_putc(int ch)
diff --git a/drivers/serial/usbtty.h b/drivers/serial/usbtty.h
index 0d89fc0..e27aa36 100644
--- a/drivers/serial/usbtty.h
+++ b/drivers/serial/usbtty.h
@@ -13,8 +13,6 @@
#include <usbdevice.h>
#if defined(CONFIG_PPC)
#include <usb/mpc8xx_udc.h>
-#elif defined(CONFIG_DW_UDC)
-#include <usb/designware_udc.h>
#elif defined(CONFIG_CI_UDC)
#include <usb/ci_udc.h>
#endif
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 240ff21..2f12081 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -286,6 +286,14 @@
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 7ba953d..50ba435 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -44,6 +44,7 @@
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 0000000..b45ef52
--- /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 <skylake.huang@mediatek.com>
+ */
+
+#include <clk.h>
+#include <cpu_func.h>
+#include <div64.h>
+#include <dm.h>
+#include <spi.h>
+#include <spi-mem.h>
+#include <stdbool.h>
+#include <watchdog.h>
+#include <dm/device.h>
+#include <dm/device_compat.h>
+#include <dm/devres.h>
+#include <dm/pinctrl.h>
+#include <linux/bitops.h>
+#include <linux/completion.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+
+#define SPI_CFG0_REG 0x0000
+#define SPI_CFG1_REG 0x0004
+#define SPI_TX_SRC_REG 0x0008
+#define SPI_RX_DST_REG 0x000c
+#define SPI_TX_DATA_REG 0x0010
+#define SPI_RX_DATA_REG 0x0014
+#define SPI_CMD_REG 0x0018
+#define SPI_IRQ_REG 0x001c
+#define SPI_STATUS_REG 0x0020
+#define SPI_PAD_SEL_REG 0x0024
+#define SPI_CFG2_REG 0x0028
+#define SPI_TX_SRC_REG_64 0x002c
+#define SPI_RX_DST_REG_64 0x0030
+#define SPI_CFG3_IPM_REG 0x0040
+
+#define SPI_CFG0_SCK_HIGH_OFFSET 0
+#define SPI_CFG0_SCK_LOW_OFFSET 8
+#define SPI_CFG0_CS_HOLD_OFFSET 16
+#define SPI_CFG0_CS_SETUP_OFFSET 24
+#define SPI_ADJUST_CFG0_CS_HOLD_OFFSET 0
+#define SPI_ADJUST_CFG0_CS_SETUP_OFFSET 16
+
+#define SPI_CFG1_CS_IDLE_OFFSET 0
+#define SPI_CFG1_PACKET_LOOP_OFFSET 8
+#define SPI_CFG1_PACKET_LENGTH_OFFSET 16
+#define SPI_CFG1_GET_TICKDLY_OFFSET 29
+
+#define SPI_CFG1_GET_TICKDLY_MASK GENMASK(31, 29)
+#define SPI_CFG1_CS_IDLE_MASK 0xff
+#define SPI_CFG1_PACKET_LOOP_MASK 0xff00
+#define SPI_CFG1_PACKET_LENGTH_MASK 0x3ff0000
+#define SPI_CFG1_IPM_PACKET_LENGTH_MASK GENMASK(31, 16)
+#define SPI_CFG2_SCK_HIGH_OFFSET 0
+#define SPI_CFG2_SCK_LOW_OFFSET 16
+#define SPI_CFG2_SCK_HIGH_MASK GENMASK(15, 0)
+#define SPI_CFG2_SCK_LOW_MASK GENMASK(31, 16)
+
+#define SPI_CMD_ACT BIT(0)
+#define SPI_CMD_RESUME BIT(1)
+#define SPI_CMD_RST BIT(2)
+#define SPI_CMD_PAUSE_EN BIT(4)
+#define SPI_CMD_DEASSERT BIT(5)
+#define SPI_CMD_SAMPLE_SEL BIT(6)
+#define SPI_CMD_CS_POL BIT(7)
+#define SPI_CMD_CPHA BIT(8)
+#define SPI_CMD_CPOL BIT(9)
+#define SPI_CMD_RX_DMA BIT(10)
+#define SPI_CMD_TX_DMA BIT(11)
+#define SPI_CMD_TXMSBF BIT(12)
+#define SPI_CMD_RXMSBF BIT(13)
+#define SPI_CMD_RX_ENDIAN BIT(14)
+#define SPI_CMD_TX_ENDIAN BIT(15)
+#define SPI_CMD_FINISH_IE BIT(16)
+#define SPI_CMD_PAUSE_IE BIT(17)
+#define SPI_CMD_IPM_NONIDLE_MODE BIT(19)
+#define SPI_CMD_IPM_SPIM_LOOP BIT(21)
+#define SPI_CMD_IPM_GET_TICKDLY_OFFSET 22
+
+#define SPI_CMD_IPM_GET_TICKDLY_MASK GENMASK(24, 22)
+
+#define PIN_MODE_CFG(x) ((x) / 2)
+
+#define SPI_CFG3_IPM_PIN_MODE_OFFSET 0
+#define SPI_CFG3_IPM_HALF_DUPLEX_DIR BIT(2)
+#define SPI_CFG3_IPM_HALF_DUPLEX_EN BIT(3)
+#define SPI_CFG3_IPM_XMODE_EN BIT(4)
+#define SPI_CFG3_IPM_NODATA_FLAG BIT(5)
+#define SPI_CFG3_IPM_CMD_BYTELEN_OFFSET 8
+#define SPI_CFG3_IPM_ADDR_BYTELEN_OFFSET 12
+#define SPI_CFG3_IPM_DUMMY_BYTELEN_OFFSET 16
+
+#define SPI_CFG3_IPM_CMD_PIN_MODE_MASK GENMASK(1, 0)
+#define SPI_CFG3_IPM_CMD_BYTELEN_MASK GENMASK(11, 8)
+#define SPI_CFG3_IPM_ADDR_BYTELEN_MASK GENMASK(15, 12)
+#define SPI_CFG3_IPM_DUMMY_BYTELEN_MASK GENMASK(19, 16)
+
+#define MT8173_SPI_MAX_PAD_SEL 3
+
+#define MTK_SPI_PAUSE_INT_STATUS 0x2
+
+#define MTK_SPI_IDLE 0
+#define MTK_SPI_PAUSED 1
+
+#define MTK_SPI_MAX_FIFO_SIZE 32U
+#define MTK_SPI_PACKET_SIZE 1024
+#define MTK_SPI_IPM_PACKET_SIZE SZ_64K
+#define MTK_SPI_IPM_PACKET_LOOP SZ_256
+
+#define MTK_SPI_32BITS_MASK 0xffffffff
+
+#define DMA_ADDR_EXT_BITS 36
+#define DMA_ADDR_DEF_BITS 32
+
+#define CLK_TO_US(freq, clkcnt) DIV_ROUND_UP((clkcnt), (freq) / 1000000)
+
+/* struct mtk_spim_capability
+ * @enhance_timing: Some IC design adjust cfg register to enhance time accuracy
+ * @dma_ext: Some IC support DMA addr extension
+ * @ipm_design: The IPM IP design improves some features, and supports dual/quad mode
+ * @support_quad: Whether quad mode is supported
+ */
+struct mtk_spim_capability {
+ bool enhance_timing;
+ bool dma_ext;
+ bool ipm_design;
+ bool support_quad;
+};
+
+/* struct mtk_spim_priv
+ * @base: Base address of the spi controller
+ * @state: Controller state
+ * @sel_clk: Pad clock
+ * @spi_clk: Core clock
+ * @xfer_len: Current length of data for transfer
+ * @hw_cap: Controller capabilities
+ * @tick_dly: Used to postpone SPI sampling time
+ * @sample_sel: Sample edge of MISO
+ * @dev: udevice of this spi controller
+ * @tx_dma: Tx DMA address
+ * @rx_dma: Rx DMA address
+ */
+struct mtk_spim_priv {
+ void __iomem *base;
+ u32 state;
+ struct clk sel_clk, spi_clk;
+ u32 xfer_len;
+ struct mtk_spim_capability hw_cap;
+ u32 tick_dly;
+ u32 sample_sel;
+
+ struct device *dev;
+ dma_addr_t tx_dma;
+ dma_addr_t rx_dma;
+};
+
+static void mtk_spim_reset(struct mtk_spim_priv *priv)
+{
+ /* set the software reset bit in SPI_CMD_REG. */
+ setbits_le32(priv->base + SPI_CMD_REG, SPI_CMD_RST);
+ clrbits_le32(priv->base + SPI_CMD_REG, SPI_CMD_RST);
+}
+
+static int mtk_spim_hw_init(struct spi_slave *slave)
+{
+ struct udevice *bus = dev_get_parent(slave->dev);
+ struct mtk_spim_priv *priv = dev_get_priv(bus);
+ u16 cpha, cpol;
+ u32 reg_val;
+
+ cpha = slave->mode & SPI_CPHA ? 1 : 0;
+ cpol = slave->mode & SPI_CPOL ? 1 : 0;
+
+ if (priv->hw_cap.enhance_timing) {
+ if (priv->hw_cap.ipm_design) {
+ /* CFG3 reg only used for spi-mem,
+ * here write to default value
+ */
+ writel(0x0, priv->base + SPI_CFG3_IPM_REG);
+ clrsetbits_le32(priv->base + SPI_CMD_REG,
+ SPI_CMD_IPM_GET_TICKDLY_MASK,
+ priv->tick_dly <<
+ SPI_CMD_IPM_GET_TICKDLY_OFFSET);
+ } else {
+ clrsetbits_le32(priv->base + SPI_CFG1_REG,
+ SPI_CFG1_GET_TICKDLY_MASK,
+ priv->tick_dly <<
+ SPI_CFG1_GET_TICKDLY_OFFSET);
+ }
+ }
+
+ reg_val = readl(priv->base + SPI_CMD_REG);
+ if (priv->hw_cap.ipm_design) {
+ /* SPI transfer without idle time until packet length done */
+ reg_val |= SPI_CMD_IPM_NONIDLE_MODE;
+ if (slave->mode & SPI_LOOP)
+ reg_val |= SPI_CMD_IPM_SPIM_LOOP;
+ else
+ reg_val &= ~SPI_CMD_IPM_SPIM_LOOP;
+ }
+
+ if (cpha)
+ reg_val |= SPI_CMD_CPHA;
+ else
+ reg_val &= ~SPI_CMD_CPHA;
+ if (cpol)
+ reg_val |= SPI_CMD_CPOL;
+ else
+ reg_val &= ~SPI_CMD_CPOL;
+
+ /* set the mlsbx and mlsbtx */
+ if (slave->mode & SPI_LSB_FIRST) {
+ reg_val &= ~SPI_CMD_TXMSBF;
+ reg_val &= ~SPI_CMD_RXMSBF;
+ } else {
+ reg_val |= SPI_CMD_TXMSBF;
+ reg_val |= SPI_CMD_RXMSBF;
+ }
+
+ /* do not reverse tx/rx endian */
+ reg_val &= ~SPI_CMD_TX_ENDIAN;
+ reg_val &= ~SPI_CMD_RX_ENDIAN;
+
+ if (priv->hw_cap.enhance_timing) {
+ /* set CS polarity */
+ if (slave->mode & SPI_CS_HIGH)
+ reg_val |= SPI_CMD_CS_POL;
+ else
+ reg_val &= ~SPI_CMD_CS_POL;
+
+ if (priv->sample_sel)
+ reg_val |= SPI_CMD_SAMPLE_SEL;
+ else
+ reg_val &= ~SPI_CMD_SAMPLE_SEL;
+ }
+
+ /* disable dma mode */
+ reg_val &= ~(SPI_CMD_TX_DMA | SPI_CMD_RX_DMA);
+
+ /* disable deassert mode */
+ reg_val &= ~SPI_CMD_DEASSERT;
+
+ writel(reg_val, priv->base + SPI_CMD_REG);
+
+ return 0;
+}
+
+static void mtk_spim_prepare_transfer(struct mtk_spim_priv *priv,
+ u32 speed_hz)
+{
+ u32 spi_clk_hz, div, sck_time, cs_time, reg_val;
+
+ spi_clk_hz = clk_get_rate(&priv->spi_clk);
+ if (speed_hz <= spi_clk_hz / 4)
+ div = DIV_ROUND_UP(spi_clk_hz, speed_hz);
+ else
+ div = 4;
+
+ sck_time = (div + 1) / 2;
+ cs_time = sck_time * 2;
+
+ if (priv->hw_cap.enhance_timing) {
+ reg_val = ((sck_time - 1) & 0xffff)
+ << SPI_CFG2_SCK_HIGH_OFFSET;
+ reg_val |= ((sck_time - 1) & 0xffff)
+ << SPI_CFG2_SCK_LOW_OFFSET;
+ writel(reg_val, priv->base + SPI_CFG2_REG);
+
+ reg_val = ((cs_time - 1) & 0xffff)
+ << SPI_ADJUST_CFG0_CS_HOLD_OFFSET;
+ reg_val |= ((cs_time - 1) & 0xffff)
+ << SPI_ADJUST_CFG0_CS_SETUP_OFFSET;
+ writel(reg_val, priv->base + SPI_CFG0_REG);
+ } else {
+ reg_val = ((sck_time - 1) & 0xff)
+ << SPI_CFG0_SCK_HIGH_OFFSET;
+ reg_val |= ((sck_time - 1) & 0xff) << SPI_CFG0_SCK_LOW_OFFSET;
+ reg_val |= ((cs_time - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET;
+ reg_val |= ((cs_time - 1) & 0xff) << SPI_CFG0_CS_SETUP_OFFSET;
+ writel(reg_val, priv->base + SPI_CFG0_REG);
+ }
+
+ reg_val = readl(priv->base + SPI_CFG1_REG);
+ reg_val &= ~SPI_CFG1_CS_IDLE_MASK;
+ reg_val |= ((cs_time - 1) & 0xff) << SPI_CFG1_CS_IDLE_OFFSET;
+ writel(reg_val, priv->base + SPI_CFG1_REG);
+}
+
+/**
+ * mtk_spim_setup_packet() - setup packet format.
+ * @priv: controller priv
+ *
+ * This controller sents/receives data in packets. The packet size is
+ * configurable.
+ *
+ * This function calculates the maximum packet size available for current
+ * data, and calculates the number of packets required to sent/receive data
+ * as much as possible.
+ */
+static void mtk_spim_setup_packet(struct mtk_spim_priv *priv)
+{
+ u32 packet_size, packet_loop, reg_val;
+
+ /* Calculate maximum packet size */
+ if (priv->hw_cap.ipm_design)
+ packet_size = min_t(u32,
+ priv->xfer_len,
+ MTK_SPI_IPM_PACKET_SIZE);
+ else
+ packet_size = min_t(u32,
+ priv->xfer_len,
+ MTK_SPI_PACKET_SIZE);
+
+ /* Calculates number of packets to sent/receive */
+ packet_loop = priv->xfer_len / packet_size;
+
+ reg_val = readl(priv->base + SPI_CFG1_REG);
+ if (priv->hw_cap.ipm_design)
+ reg_val &= ~SPI_CFG1_IPM_PACKET_LENGTH_MASK;
+ else
+ reg_val &= ~SPI_CFG1_PACKET_LENGTH_MASK;
+
+ reg_val |= (packet_size - 1) << SPI_CFG1_PACKET_LENGTH_OFFSET;
+
+ reg_val &= ~SPI_CFG1_PACKET_LOOP_MASK;
+
+ reg_val |= (packet_loop - 1) << SPI_CFG1_PACKET_LOOP_OFFSET;
+
+ writel(reg_val, priv->base + SPI_CFG1_REG);
+}
+
+static void mtk_spim_enable_transfer(struct mtk_spim_priv *priv)
+{
+ u32 cmd;
+
+ cmd = readl(priv->base + SPI_CMD_REG);
+ if (priv->state == MTK_SPI_IDLE)
+ cmd |= SPI_CMD_ACT;
+ else
+ cmd |= SPI_CMD_RESUME;
+ writel(cmd, priv->base + SPI_CMD_REG);
+}
+
+static bool mtk_spim_supports_op(struct spi_slave *slave,
+ const struct spi_mem_op *op)
+{
+ struct udevice *bus = dev_get_parent(slave->dev);
+ struct mtk_spim_priv *priv = dev_get_priv(bus);
+
+ if (op->cmd.buswidth == 0 || op->cmd.buswidth > 4 ||
+ op->addr.buswidth > 4 || op->dummy.buswidth > 4 ||
+ op->data.buswidth > 4)
+ return false;
+
+ if (!priv->hw_cap.support_quad && (op->cmd.buswidth > 2 ||
+ op->addr.buswidth > 2 || op->dummy.buswidth > 2 ||
+ op->data.buswidth > 2))
+ return false;
+
+ if (op->addr.nbytes && op->dummy.nbytes &&
+ op->addr.buswidth != op->dummy.buswidth)
+ return false;
+
+ if (op->addr.nbytes + op->dummy.nbytes > 16)
+ return false;
+
+ if (op->data.nbytes > MTK_SPI_IPM_PACKET_SIZE) {
+ if (op->data.nbytes / MTK_SPI_IPM_PACKET_SIZE >
+ MTK_SPI_IPM_PACKET_LOOP ||
+ op->data.nbytes % MTK_SPI_IPM_PACKET_SIZE != 0)
+ return false;
+ }
+
+ return true;
+}
+
+static void mtk_spim_setup_dma_xfer(struct mtk_spim_priv *priv,
+ const struct spi_mem_op *op)
+{
+ writel((u32)(priv->tx_dma & MTK_SPI_32BITS_MASK),
+ priv->base + SPI_TX_SRC_REG);
+
+ if (priv->hw_cap.dma_ext)
+ writel((u32)(priv->tx_dma >> 32),
+ priv->base + SPI_TX_SRC_REG_64);
+
+ if (op->data.dir == SPI_MEM_DATA_IN) {
+ writel((u32)(priv->rx_dma & MTK_SPI_32BITS_MASK),
+ priv->base + SPI_RX_DST_REG);
+
+ if (priv->hw_cap.dma_ext)
+ writel((u32)(priv->rx_dma >> 32),
+ priv->base + SPI_RX_DST_REG_64);
+ }
+}
+
+static int mtk_spim_transfer_wait(struct spi_slave *slave,
+ const struct spi_mem_op *op)
+{
+ struct udevice *bus = dev_get_parent(slave->dev);
+ struct mtk_spim_priv *priv = dev_get_priv(bus);
+ u32 sck_l, sck_h, spi_bus_clk, clk_count, reg;
+ ulong us = 1;
+ int ret = 0;
+
+ if (op->data.dir == SPI_MEM_NO_DATA)
+ clk_count = 32;
+ else
+ clk_count = op->data.nbytes;
+
+ spi_bus_clk = clk_get_rate(&priv->spi_clk);
+ sck_l = readl(priv->base + SPI_CFG2_REG) >> SPI_CFG2_SCK_LOW_OFFSET;
+ sck_h = readl(priv->base + SPI_CFG2_REG) & SPI_CFG2_SCK_HIGH_MASK;
+ do_div(spi_bus_clk, sck_l + sck_h + 2);
+
+ us = CLK_TO_US(spi_bus_clk, clk_count * 8);
+ us += 1000 * 1000; /* 1s tolerance */
+
+ if (us > UINT_MAX)
+ us = UINT_MAX;
+
+ ret = readl_poll_timeout(priv->base + SPI_STATUS_REG, reg,
+ reg & 0x1, us);
+ if (ret < 0) {
+ dev_err(priv->dev, "transfer timeout, val: 0x%lx\n", us);
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+static int mtk_spim_exec_op(struct spi_slave *slave,
+ const struct spi_mem_op *op)
+{
+ struct udevice *bus = dev_get_parent(slave->dev);
+ struct mtk_spim_priv *priv = dev_get_priv(bus);
+ u32 reg_val, nio = 1, tx_size;
+ char *tx_tmp_buf;
+ char *rx_tmp_buf;
+ int i, ret = 0;
+
+ mtk_spim_reset(priv);
+ mtk_spim_hw_init(slave);
+ mtk_spim_prepare_transfer(priv, slave->max_hz);
+
+ reg_val = readl(priv->base + SPI_CFG3_IPM_REG);
+ /* opcode byte len */
+ reg_val &= ~SPI_CFG3_IPM_CMD_BYTELEN_MASK;
+ reg_val |= 1 << SPI_CFG3_IPM_CMD_BYTELEN_OFFSET;
+
+ /* addr & dummy byte len */
+ if (op->addr.nbytes || op->dummy.nbytes)
+ reg_val |= (op->addr.nbytes + op->dummy.nbytes) <<
+ SPI_CFG3_IPM_ADDR_BYTELEN_OFFSET;
+
+ /* data byte len */
+ if (!op->data.nbytes) {
+ reg_val |= SPI_CFG3_IPM_NODATA_FLAG;
+ writel(0, priv->base + SPI_CFG1_REG);
+ } else {
+ reg_val &= ~SPI_CFG3_IPM_NODATA_FLAG;
+ priv->xfer_len = op->data.nbytes;
+ mtk_spim_setup_packet(priv);
+ }
+
+ if (op->addr.nbytes || op->dummy.nbytes) {
+ if (op->addr.buswidth == 1 || op->dummy.buswidth == 1)
+ reg_val |= SPI_CFG3_IPM_XMODE_EN;
+ else
+ reg_val &= ~SPI_CFG3_IPM_XMODE_EN;
+ }
+
+ if (op->addr.buswidth == 2 ||
+ op->dummy.buswidth == 2 ||
+ op->data.buswidth == 2)
+ nio = 2;
+ else if (op->addr.buswidth == 4 ||
+ op->dummy.buswidth == 4 ||
+ op->data.buswidth == 4)
+ nio = 4;
+
+ reg_val &= ~SPI_CFG3_IPM_CMD_PIN_MODE_MASK;
+ reg_val |= PIN_MODE_CFG(nio) << SPI_CFG3_IPM_PIN_MODE_OFFSET;
+
+ reg_val |= SPI_CFG3_IPM_HALF_DUPLEX_EN;
+ if (op->data.dir == SPI_MEM_DATA_IN)
+ reg_val |= SPI_CFG3_IPM_HALF_DUPLEX_DIR;
+ else
+ reg_val &= ~SPI_CFG3_IPM_HALF_DUPLEX_DIR;
+ writel(reg_val, priv->base + SPI_CFG3_IPM_REG);
+
+ tx_size = 1 + op->addr.nbytes + op->dummy.nbytes;
+ if (op->data.dir == SPI_MEM_DATA_OUT)
+ tx_size += op->data.nbytes;
+
+ tx_size = max(tx_size, (u32)32);
+
+ /* Fill up tx data */
+ tx_tmp_buf = kzalloc(tx_size, GFP_KERNEL);
+ if (!tx_tmp_buf) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+
+ tx_tmp_buf[0] = op->cmd.opcode;
+
+ if (op->addr.nbytes) {
+ for (i = 0; i < op->addr.nbytes; i++)
+ tx_tmp_buf[i + 1] = op->addr.val >>
+ (8 * (op->addr.nbytes - i - 1));
+ }
+
+ if (op->dummy.nbytes)
+ memset(tx_tmp_buf + op->addr.nbytes + 1, 0xff,
+ op->dummy.nbytes);
+
+ if (op->data.nbytes && op->data.dir == SPI_MEM_DATA_OUT)
+ memcpy(tx_tmp_buf + op->dummy.nbytes + op->addr.nbytes + 1,
+ op->data.buf.out, op->data.nbytes);
+ /* Finish filling up tx data */
+
+ priv->tx_dma = dma_map_single(tx_tmp_buf, tx_size, DMA_TO_DEVICE);
+ if (dma_mapping_error(priv->dev, priv->tx_dma)) {
+ ret = -ENOMEM;
+ goto tx_free;
+ }
+
+ if (op->data.dir == SPI_MEM_DATA_IN) {
+ if (!IS_ALIGNED((size_t)op->data.buf.in, 4)) {
+ rx_tmp_buf = kzalloc(op->data.nbytes, GFP_KERNEL);
+ if (!rx_tmp_buf) {
+ ret = -ENOMEM;
+ goto tx_unmap;
+ }
+ } else {
+ rx_tmp_buf = op->data.buf.in;
+ }
+
+ priv->rx_dma = dma_map_single(rx_tmp_buf, op->data.nbytes,
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(priv->dev, priv->rx_dma)) {
+ ret = -ENOMEM;
+ goto rx_free;
+ }
+ }
+
+ reg_val = readl(priv->base + SPI_CMD_REG);
+ reg_val |= SPI_CMD_TX_DMA;
+ if (op->data.dir == SPI_MEM_DATA_IN)
+ reg_val |= SPI_CMD_RX_DMA;
+
+ writel(reg_val, priv->base + SPI_CMD_REG);
+
+ mtk_spim_setup_dma_xfer(priv, op);
+
+ mtk_spim_enable_transfer(priv);
+
+ /* Wait for the interrupt. */
+ ret = mtk_spim_transfer_wait(slave, op);
+ if (ret)
+ goto rx_unmap;
+
+ if (op->data.dir == SPI_MEM_DATA_IN &&
+ !IS_ALIGNED((size_t)op->data.buf.in, 4))
+ memcpy(op->data.buf.in, rx_tmp_buf, op->data.nbytes);
+
+rx_unmap:
+ /* spi disable dma */
+ reg_val = readl(priv->base + SPI_CMD_REG);
+ reg_val &= ~SPI_CMD_TX_DMA;
+ if (op->data.dir == SPI_MEM_DATA_IN)
+ reg_val &= ~SPI_CMD_RX_DMA;
+ writel(reg_val, priv->base + SPI_CMD_REG);
+
+ writel(0, priv->base + SPI_TX_SRC_REG);
+ writel(0, priv->base + SPI_RX_DST_REG);
+
+ if (op->data.dir == SPI_MEM_DATA_IN)
+ dma_unmap_single(priv->rx_dma,
+ op->data.nbytes, DMA_FROM_DEVICE);
+rx_free:
+ if (op->data.dir == SPI_MEM_DATA_IN &&
+ !IS_ALIGNED((size_t)op->data.buf.in, 4))
+ kfree(rx_tmp_buf);
+tx_unmap:
+ dma_unmap_single(priv->tx_dma,
+ tx_size, DMA_TO_DEVICE);
+tx_free:
+ kfree(tx_tmp_buf);
+exit:
+ return ret;
+}
+
+static int mtk_spim_adjust_op_size(struct spi_slave *slave,
+ struct spi_mem_op *op)
+{
+ int opcode_len;
+
+ if (!op->data.nbytes)
+ return 0;
+
+ if (op->data.dir != SPI_MEM_NO_DATA) {
+ opcode_len = 1 + op->addr.nbytes + op->dummy.nbytes;
+ if (opcode_len + op->data.nbytes > MTK_SPI_IPM_PACKET_SIZE) {
+ op->data.nbytes = MTK_SPI_IPM_PACKET_SIZE - opcode_len;
+ /* force data buffer dma-aligned. */
+ op->data.nbytes -= op->data.nbytes % 4;
+ }
+ }
+
+ return 0;
+}
+
+static int mtk_spim_get_attr(struct mtk_spim_priv *priv, struct udevice *dev)
+{
+ int ret;
+
+ priv->hw_cap.enhance_timing = dev_read_bool(dev, "enhance_timing");
+ priv->hw_cap.dma_ext = dev_read_bool(dev, "dma_ext");
+ priv->hw_cap.ipm_design = dev_read_bool(dev, "ipm_design");
+ priv->hw_cap.support_quad = dev_read_bool(dev, "support_quad");
+
+ ret = dev_read_u32(dev, "tick_dly", &priv->tick_dly);
+ if (ret < 0)
+ dev_err(priv->dev, "tick dly not set.\n");
+
+ ret = dev_read_u32(dev, "sample_sel", &priv->sample_sel);
+ if (ret < 0)
+ dev_err(priv->dev, "sample sel not set.\n");
+
+ return ret;
+}
+
+static int mtk_spim_probe(struct udevice *dev)
+{
+ struct mtk_spim_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ priv->base = (void __iomem *)devfdt_get_addr(dev);
+ if (!priv->base)
+ return -EINVAL;
+
+ mtk_spim_get_attr(priv, dev);
+
+ ret = clk_get_by_name(dev, "sel-clk", &priv->sel_clk);
+ if (ret < 0) {
+ dev_err(dev, "failed to get sel-clk\n");
+ return ret;
+ }
+
+ ret = clk_get_by_name(dev, "spi-clk", &priv->spi_clk);
+ if (ret < 0) {
+ dev_err(dev, "failed to get spi-clk\n");
+ return ret;
+ }
+
+ clk_enable(&priv->sel_clk);
+ clk_enable(&priv->spi_clk);
+
+ return 0;
+}
+
+static int mtk_spim_set_speed(struct udevice *dev, uint speed)
+{
+ return 0;
+}
+
+static int mtk_spim_set_mode(struct udevice *dev, uint mode)
+{
+ return 0;
+}
+
+static const struct spi_controller_mem_ops mtk_spim_mem_ops = {
+ .adjust_op_size = mtk_spim_adjust_op_size,
+ .supports_op = mtk_spim_supports_op,
+ .exec_op = mtk_spim_exec_op
+};
+
+static const struct dm_spi_ops mtk_spim_ops = {
+ .mem_ops = &mtk_spim_mem_ops,
+ .set_speed = mtk_spim_set_speed,
+ .set_mode = mtk_spim_set_mode,
+};
+
+static const struct udevice_id mtk_spim_ids[] = {
+ { .compatible = "mediatek,ipm-spi" },
+ {}
+};
+
+U_BOOT_DRIVER(mtk_spim) = {
+ .name = "mtk_spim",
+ .id = UCLASS_SPI,
+ .of_match = mtk_spim_ids,
+ .ops = &mtk_spim_ops,
+ .priv_auto = sizeof(struct mtk_spim_priv),
+ .probe = mtk_spim_probe,
+};
diff --git a/drivers/timer/mtk_timer.c b/drivers/timer/mtk_timer.c
index f6b97f8..223e63f 100644
--- a/drivers/timer/mtk_timer.c
+++ b/drivers/timer/mtk_timer.c
@@ -13,24 +13,32 @@
#include <asm/io.h>
#include <linux/bitops.h>
-#define MTK_GPT4_CTRL 0x40
-#define MTK_GPT4_CLK 0x44
-#define MTK_GPT4_CNT 0x48
+#define MTK_GPT4_OFFSET_V1 0x40
+#define MTK_GPT4_OFFSET_V2 0x80
-#define GPT4_ENABLE BIT(0)
-#define GPT4_CLEAR BIT(1)
-#define GPT4_FREERUN GENMASK(5, 4)
-#define GPT4_CLK_SYS 0x0
-#define GPT4_CLK_DIV1 0x0
+#define MTK_GPT_CON 0x0
+#define MTK_GPT_V1_CLK 0x4
+#define MTK_GPT_CNT 0x8
+
+#define GPT_ENABLE BIT(0)
+#define GPT_CLEAR BIT(1)
+#define GPT_V1_FREERUN GENMASK(5, 4)
+#define GPT_V2_FREERUN GENMASK(6, 5)
+
+enum mtk_gpt_ver {
+ MTK_GPT_V1,
+ MTK_GPT_V2
+};
struct mtk_timer_priv {
void __iomem *base;
+ unsigned int gpt4_offset;
};
static u64 mtk_timer_get_count(struct udevice *dev)
{
struct mtk_timer_priv *priv = dev_get_priv(dev);
- u32 val = readl(priv->base + MTK_GPT4_CNT);
+ u32 val = readl(priv->base + priv->gpt4_offset + MTK_GPT_CNT);
return timer_conv_64(val);
}
@@ -40,12 +48,27 @@
struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
struct mtk_timer_priv *priv = dev_get_priv(dev);
struct clk clk, parent;
- int ret;
+ int ret, gpt_ver;
priv->base = dev_read_addr_ptr(dev);
+ gpt_ver = dev_get_driver_data(dev);
+
if (!priv->base)
return -ENOENT;
+ if (gpt_ver == MTK_GPT_V2) {
+ priv->gpt4_offset = MTK_GPT4_OFFSET_V2;
+
+ writel(GPT_V2_FREERUN | GPT_CLEAR | GPT_ENABLE,
+ priv->base + priv->gpt4_offset + MTK_GPT_CON);
+ } else {
+ priv->gpt4_offset = MTK_GPT4_OFFSET_V1;
+
+ writel(GPT_V1_FREERUN | GPT_CLEAR | GPT_ENABLE,
+ priv->base + priv->gpt4_offset + MTK_GPT_CON);
+ writel(0, priv->base + priv->gpt4_offset + MTK_GPT_V1_CLK);
+ }
+
ret = clk_get_by_index(dev, 0, &clk);
if (ret)
return ret;
@@ -61,16 +84,6 @@
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 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 },
{ }
};
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index fd13cf3..3afb45d 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -48,7 +48,7 @@
automatically probed when found on the bus.
config SPL_DM_USB
- bool "Enable driver model for USB host most in SPL"
+ bool "Enable driver model for USB host mode in SPL"
depends on SPL_DM && DM_USB
default n if ARCH_MVEBU
default y
diff --git a/drivers/usb/emul/sandbox_flash.c b/drivers/usb/emul/sandbox_flash.c
index 01b2b41..2589c70 100644
--- a/drivers/usb/emul/sandbox_flash.c
+++ b/drivers/usb/emul/sandbox_flash.c
@@ -7,8 +7,10 @@
#include <common.h>
#include <dm.h>
#include <log.h>
+#include <malloc.h>
#include <os.h>
#include <scsi.h>
+#include <scsi_emul.h>
#include <usb.h>
/*
@@ -21,14 +23,9 @@
SANDBOX_FLASH_EP_OUT = 1, /* endpoints */
SANDBOX_FLASH_EP_IN = 2,
SANDBOX_FLASH_BLOCK_LEN = 512,
+ SANDBOX_FLASH_BUF_SIZE = 512,
};
-enum cmd_phase {
- PHASE_START,
- PHASE_DATA,
- PHASE_STATUS,
-};
-
enum {
STRINGID_MANUFACTURER = 1,
STRINGID_PRODUCT,
@@ -40,29 +37,19 @@
/**
* struct sandbox_flash_priv - private state for this driver
*
+ * @eminfo: emulator state
* @error: true if there is an error condition
- * @alloc_len: Allocation length from the last incoming command
- * @transfer_len: Transfer length from CBW header
- * @read_len: Number of blocks of data left in the current read command
* @tag: Tag value from last command
* @fd: File descriptor of backing file
* @file_size: Size of file in bytes
* @status_buff: Data buffer for outgoing status
- * @buff_used: Number of bytes ready to transfer back to host
- * @buff: Data buffer for outgoing data
*/
struct sandbox_flash_priv {
+ struct scsi_emul_info eminfo;
bool error;
- int alloc_len;
- int transfer_len;
- int read_len;
- enum cmd_phase phase;
u32 tag;
int fd;
- loff_t file_size;
struct umass_bbb_csw status;
- int buff_used;
- u8 buff[512];
};
struct sandbox_flash_plat {
@@ -70,32 +57,6 @@
struct usb_string flash_strings[STRINGID_COUNT];
};
-struct scsi_inquiry_resp {
- u8 type;
- u8 flags;
- u8 version;
- u8 data_format;
- u8 additional_len;
- u8 spare[3];
- char vendor[8];
- char product[16];
- char revision[4];
-};
-
-struct scsi_read_capacity_resp {
- u32 last_block_addr;
- u32 block_len;
-};
-
-struct __packed scsi_read10_req {
- u8 cmd;
- u8 lun_flags;
- u32 lba;
- u8 spare;
- u16 transfer_len;
- u8 spare2[3];
-};
-
static struct usb_device_descriptor flash_device_desc = {
.bLength = sizeof(flash_device_desc),
.bDescriptorType = USB_DT_DEVICE,
@@ -200,7 +161,6 @@
csw->dCSWTag = priv->tag;
csw->dCSWDataResidue = 0;
csw->bCSWStatus = CSWSTATUS_FAILED;
- priv->buff_used = 0;
}
/**
@@ -210,8 +170,7 @@
* @resp: Response to send, or NULL if none
* @size: Size of response
*/
-static void setup_response(struct sandbox_flash_priv *priv, void *resp,
- int size)
+static void setup_response(struct sandbox_flash_priv *priv)
{
struct umass_bbb_csw *csw = &priv->status;
@@ -219,97 +178,45 @@
csw->dCSWTag = priv->tag;
csw->dCSWDataResidue = 0;
csw->bCSWStatus = CSWSTATUS_GOOD;
-
- assert(!resp || resp == priv->buff);
- priv->buff_used = size;
}
-static void handle_read(struct sandbox_flash_priv *priv, ulong lba,
- ulong transfer_len)
-{
- debug("%s: lba=%lx, transfer_len=%lx\n", __func__, lba, transfer_len);
- priv->read_len = transfer_len;
- if (priv->fd != -1) {
- os_lseek(priv->fd, lba * SANDBOX_FLASH_BLOCK_LEN, OS_SEEK_SET);
- setup_response(priv, priv->buff,
- transfer_len * SANDBOX_FLASH_BLOCK_LEN);
- } else {
- setup_fail_response(priv);
- }
-}
-
-static int handle_ufi_command(struct sandbox_flash_plat *plat,
- struct sandbox_flash_priv *priv, const void *buff,
+static int handle_ufi_command(struct sandbox_flash_priv *priv, const void *buff,
int len)
{
+ struct scsi_emul_info *info = &priv->eminfo;
const struct scsi_cmd *req = buff;
-
- switch (*req->cmd) {
- case SCSI_INQUIRY: {
- struct scsi_inquiry_resp *resp = (void *)priv->buff;
+ int ret;
- priv->alloc_len = req->cmd[4];
- memset(resp, '\0', sizeof(*resp));
- resp->data_format = 1;
- resp->additional_len = 0x1f;
- strncpy(resp->vendor,
- plat->flash_strings[STRINGID_MANUFACTURER - 1].s,
- sizeof(resp->vendor));
- strncpy(resp->product,
- plat->flash_strings[STRINGID_PRODUCT - 1].s,
- sizeof(resp->product));
- strncpy(resp->revision, "1.0", sizeof(resp->revision));
- setup_response(priv, resp, sizeof(*resp));
- break;
- }
- case SCSI_TST_U_RDY:
- setup_response(priv, NULL, 0);
- break;
- case SCSI_RD_CAPAC: {
- struct scsi_read_capacity_resp *resp = (void *)priv->buff;
- uint blocks;
-
- if (priv->file_size)
- blocks = priv->file_size / SANDBOX_FLASH_BLOCK_LEN - 1;
- else
- blocks = 0;
- resp->last_block_addr = cpu_to_be32(blocks);
- resp->block_len = cpu_to_be32(SANDBOX_FLASH_BLOCK_LEN);
- setup_response(priv, resp, sizeof(*resp));
- break;
- }
- case SCSI_READ10: {
- struct scsi_read10_req *req = (void *)buff;
-
- handle_read(priv, be32_to_cpu(req->lba),
- be16_to_cpu(req->transfer_len));
- break;
- }
- default:
- debug("Command not supported: %x\n", req->cmd[0]);
- return -EPROTONOSUPPORT;
+ ret = sb_scsi_emul_command(info, req, len);
+ if (!ret) {
+ setup_response(priv);
+ } else if (ret == SCSI_EMUL_DO_READ && priv->fd != -1) {
+ os_lseek(priv->fd, info->seek_block * info->block_size,
+ OS_SEEK_SET);
+ setup_response(priv);
+ } else {
+ setup_fail_response(priv);
}
- priv->phase = priv->transfer_len ? PHASE_DATA : PHASE_STATUS;
return 0;
}
static int sandbox_flash_bulk(struct udevice *dev, struct usb_device *udev,
unsigned long pipe, void *buff, int len)
{
- struct sandbox_flash_plat *plat = dev_get_plat(dev);
struct sandbox_flash_priv *priv = dev_get_priv(dev);
+ struct scsi_emul_info *info = &priv->eminfo;
int ep = usb_pipeendpoint(pipe);
struct umass_bbb_cbw *cbw = buff;
debug("%s: dev=%s, pipe=%lx, ep=%x, len=%x, phase=%d\n", __func__,
- dev->name, pipe, ep, len, priv->phase);
+ dev->name, pipe, ep, len, info->phase);
switch (ep) {
case SANDBOX_FLASH_EP_OUT:
- switch (priv->phase) {
- case PHASE_START:
- priv->alloc_len = 0;
- priv->read_len = 0;
+ switch (info->phase) {
+ case SCSIPH_START:
+ info->alloc_len = 0;
+ info->read_len = 0;
if (priv->error || len != UMASS_BBB_CBW_SIZE ||
cbw->dCBWSignature != CBWSIGNATURE)
goto err;
@@ -318,22 +225,22 @@
goto err;
if (cbw->bCDBLength < 1 || cbw->bCDBLength >= 0x10)
goto err;
- priv->transfer_len = cbw->dCBWDataTransferLength;
+ info->transfer_len = cbw->dCBWDataTransferLength;
priv->tag = cbw->dCBWTag;
- return handle_ufi_command(plat, priv, cbw->CBWCDB,
+ return handle_ufi_command(priv, cbw->CBWCDB,
cbw->bCDBLength);
- case PHASE_DATA:
+ case SCSIPH_DATA:
debug("data out\n");
break;
default:
break;
}
case SANDBOX_FLASH_EP_IN:
- switch (priv->phase) {
- case PHASE_DATA:
- debug("data in, len=%x, alloc_len=%x, priv->read_len=%x\n",
- len, priv->alloc_len, priv->read_len);
- if (priv->read_len) {
+ switch (info->phase) {
+ case SCSIPH_DATA:
+ debug("data in, len=%x, alloc_len=%x, info->read_len=%x\n",
+ len, info->alloc_len, info->read_len);
+ if (info->read_len) {
ulong bytes_read;
if (priv->fd == -1)
@@ -342,24 +249,24 @@
bytes_read = os_read(priv->fd, buff, len);
if (bytes_read != len)
return -EIO;
- priv->read_len -= len / SANDBOX_FLASH_BLOCK_LEN;
- if (!priv->read_len)
- priv->phase = PHASE_STATUS;
+ info->read_len -= len / info->block_size;
+ if (!info->read_len)
+ info->phase = SCSIPH_STATUS;
} else {
- if (priv->alloc_len && len > priv->alloc_len)
- len = priv->alloc_len;
- if (len > sizeof(priv->buff))
- len = sizeof(priv->buff);
- memcpy(buff, priv->buff, len);
- priv->phase = PHASE_STATUS;
+ if (info->alloc_len && len > info->alloc_len)
+ len = info->alloc_len;
+ if (len > SANDBOX_FLASH_BUF_SIZE)
+ len = SANDBOX_FLASH_BUF_SIZE;
+ memcpy(buff, info->buff, len);
+ info->phase = SCSIPH_STATUS;
}
return len;
- case PHASE_STATUS:
+ case SCSIPH_STATUS:
debug("status in, len=%x\n", len);
if (len > sizeof(priv->status))
len = sizeof(priv->status);
memcpy(buff, &priv->status, len);
- priv->phase = PHASE_START;
+ info->phase = SCSIPH_START;
return len;
default:
break;
@@ -400,10 +307,31 @@
{
struct sandbox_flash_plat *plat = dev_get_plat(dev);
struct sandbox_flash_priv *priv = dev_get_priv(dev);
+ struct scsi_emul_info *info = &priv->eminfo;
+ int ret;
priv->fd = os_open(plat->pathname, OS_O_RDONLY);
- if (priv->fd != -1)
- return os_get_filesize(plat->pathname, &priv->file_size);
+ if (priv->fd != -1) {
+ ret = os_get_filesize(plat->pathname, &info->file_size);
+ if (ret)
+ return log_msg_ret("sz", ret);
+ }
+ info->buff = malloc(SANDBOX_FLASH_BUF_SIZE);
+ if (!info->buff)
+ return log_ret(-ENOMEM);
+ info->vendor = plat->flash_strings[STRINGID_MANUFACTURER - 1].s;
+ info->product = plat->flash_strings[STRINGID_PRODUCT - 1].s;
+ info->block_size = SANDBOX_FLASH_BLOCK_LEN;
+
+ return 0;
+}
+
+static int sandbox_flash_remove(struct udevice *dev)
+{
+ struct sandbox_flash_priv *priv = dev_get_priv(dev);
+ struct scsi_emul_info *info = &priv->eminfo;
+
+ free(info->buff);
return 0;
}
@@ -424,6 +352,7 @@
.of_match = sandbox_usb_flash_ids,
.bind = sandbox_flash_bind,
.probe = sandbox_flash_probe,
+ .remove = sandbox_flash_remove,
.of_to_plat = sandbox_flash_of_to_plat,
.ops = &sandbox_usb_flash_ops,
.priv_auto = sizeof(struct sandbox_flash_priv),
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index 306dd31..dd09ee0 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -42,6 +42,5 @@
ifdef CONFIG_USB_DEVICE
obj-y += core.o
obj-y += ep0.o
-obj-$(CONFIG_DW_UDC) += designware_udc.o
endif
endif
diff --git a/drivers/usb/gadget/designware_udc.c b/drivers/usb/gadget/designware_udc.c
deleted file mode 100644
index 41a6e8c..0000000
--- a/drivers/usb/gadget/designware_udc.c
+++ /dev/null
@@ -1,1021 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Based on drivers/usb/gadget/omap1510_udc.c
- * TI OMAP1510 USB bus interface driver
- *
- * (C) Copyright 2009
- * Vipin Kumar, STMicroelectronics, vipin.kumar@st.com.
- */
-
-#include <common.h>
-#include <serial.h>
-#include <asm/io.h>
-#include <linux/delay.h>
-
-#include <env.h>
-#include <usbdevice.h>
-#include "ep0.h"
-#include <usb/designware_udc.h>
-#include <usb/udc.h>
-#include <asm/arch/hardware.h>
-
-#define UDC_INIT_MDELAY 80 /* Device settle delay */
-
-/* Some kind of debugging output... */
-#ifndef DEBUG_DWUSBTTY
-#define UDCDBG(str)
-#define UDCDBGA(fmt, args...)
-#else
-#define UDCDBG(str) serial_printf(str "\n")
-#define UDCDBGA(fmt, args...) serial_printf(fmt "\n", ##args)
-#endif
-
-static struct urb *ep0_urb;
-static struct usb_device_instance *udc_device;
-
-static struct plug_regs *const plug_regs_p =
- (struct plug_regs * const)CONFIG_SYS_PLUG_BASE;
-static struct udc_regs *const udc_regs_p =
- (struct udc_regs * const)CONFIG_SYS_USBD_BASE;
-static struct udc_endp_regs *const outep_regs_p =
- &((struct udc_regs * const)CONFIG_SYS_USBD_BASE)->out_regs[0];
-static struct udc_endp_regs *const inep_regs_p =
- &((struct udc_regs * const)CONFIG_SYS_USBD_BASE)->in_regs[0];
-
-/*
- * udc_state_transition - Write the next packet to TxFIFO.
- * @initial: Initial state.
- * @final: Final state.
- *
- * Helper function to implement device state changes. The device states and
- * the events that transition between them are:
- *
- * STATE_ATTACHED
- * || /\
- * \/ ||
- * DEVICE_HUB_CONFIGURED DEVICE_HUB_RESET
- * || /\
- * \/ ||
- * STATE_POWERED
- * || /\
- * \/ ||
- * DEVICE_RESET DEVICE_POWER_INTERRUPTION
- * || /\
- * \/ ||
- * STATE_DEFAULT
- * || /\
- * \/ ||
- * DEVICE_ADDRESS_ASSIGNED DEVICE_RESET
- * || /\
- * \/ ||
- * STATE_ADDRESSED
- * || /\
- * \/ ||
- * DEVICE_CONFIGURED DEVICE_DE_CONFIGURED
- * || /\
- * \/ ||
- * STATE_CONFIGURED
- *
- * udc_state_transition transitions up (in the direction from STATE_ATTACHED
- * to STATE_CONFIGURED) from the specified initial state to the specified final
- * state, passing through each intermediate state on the way. If the initial
- * state is at or above (i.e. nearer to STATE_CONFIGURED) the final state, then
- * no state transitions will take place.
- *
- * udc_state_transition also transitions down (in the direction from
- * STATE_CONFIGURED to STATE_ATTACHED) from the specified initial state to the
- * specified final state, passing through each intermediate state on the way.
- * If the initial state is at or below (i.e. nearer to STATE_ATTACHED) the final
- * state, then no state transitions will take place.
- *
- * This function must only be called with interrupts disabled.
- */
-static void udc_state_transition(usb_device_state_t initial,
- usb_device_state_t final)
-{
- if (initial < final) {
- switch (initial) {
- case STATE_ATTACHED:
- usbd_device_event_irq(udc_device,
- DEVICE_HUB_CONFIGURED, 0);
- if (final == STATE_POWERED)
- break;
- case STATE_POWERED:
- usbd_device_event_irq(udc_device, DEVICE_RESET, 0);
- if (final == STATE_DEFAULT)
- break;
- case STATE_DEFAULT:
- usbd_device_event_irq(udc_device,
- DEVICE_ADDRESS_ASSIGNED, 0);
- if (final == STATE_ADDRESSED)
- break;
- case STATE_ADDRESSED:
- usbd_device_event_irq(udc_device, DEVICE_CONFIGURED, 0);
- case STATE_CONFIGURED:
- break;
- default:
- break;
- }
- } else if (initial > final) {
- switch (initial) {
- case STATE_CONFIGURED:
- usbd_device_event_irq(udc_device,
- DEVICE_DE_CONFIGURED, 0);
- if (final == STATE_ADDRESSED)
- break;
- case STATE_ADDRESSED:
- usbd_device_event_irq(udc_device, DEVICE_RESET, 0);
- if (final == STATE_DEFAULT)
- break;
- case STATE_DEFAULT:
- usbd_device_event_irq(udc_device,
- DEVICE_POWER_INTERRUPTION, 0);
- if (final == STATE_POWERED)
- break;
- case STATE_POWERED:
- usbd_device_event_irq(udc_device, DEVICE_HUB_RESET, 0);
- case STATE_ATTACHED:
- break;
- default:
- break;
- }
- }
-}
-
-/* Stall endpoint */
-static void udc_stall_ep(u32 ep_num)
-{
- writel(readl(&inep_regs_p[ep_num].endp_cntl) | ENDP_CNTL_STALL,
- &inep_regs_p[ep_num].endp_cntl);
-
- writel(readl(&outep_regs_p[ep_num].endp_cntl) | ENDP_CNTL_STALL,
- &outep_regs_p[ep_num].endp_cntl);
-}
-
-static void *get_fifo(int ep_num, int in)
-{
- u32 *fifo_ptr = (u32 *)CONFIG_SYS_FIFO_BASE;
-
- switch (ep_num) {
- case UDC_EP3:
- fifo_ptr += readl(&inep_regs_p[1].endp_bsorfn);
- /* break intentionally left out */
-
- case UDC_EP1:
- fifo_ptr += readl(&inep_regs_p[0].endp_bsorfn);
- /* break intentionally left out */
-
- case UDC_EP0:
- default:
- if (in) {
- fifo_ptr +=
- readl(&outep_regs_p[2].endp_maxpacksize) >> 16;
- /* break intentionally left out */
- } else {
- break;
- }
-
- case UDC_EP2:
- fifo_ptr += readl(&outep_regs_p[0].endp_maxpacksize) >> 16;
- /* break intentionally left out */
- }
-
- return (void *)fifo_ptr;
-}
-
-static int usbgetpckfromfifo(int epNum, u8 *bufp, u32 len)
-{
- u8 *fifo_ptr = (u8 *)get_fifo(epNum, 0);
- u32 i, nw, nb;
- u32 *wrdp;
- u8 *bytp;
- u32 tmp[128];
-
- if (readl(&udc_regs_p->dev_stat) & DEV_STAT_RXFIFO_EMPTY)
- return -1;
-
- nw = len / sizeof(u32);
- nb = len % sizeof(u32);
-
- /* use tmp buf if bufp is not word aligned */
- if ((int)bufp & 0x3)
- wrdp = (u32 *)&tmp[0];
- else
- wrdp = (u32 *)bufp;
-
- for (i = 0; i < nw; i++) {
- writel(readl(fifo_ptr), wrdp);
- wrdp++;
- }
-
- bytp = (u8 *)wrdp;
- for (i = 0; i < nb; i++) {
- writeb(readb(fifo_ptr), bytp);
- fifo_ptr++;
- bytp++;
- }
- readl(&outep_regs_p[epNum].write_done);
-
- /* copy back tmp buffer to bufp if bufp is not word aligned */
- if ((int)bufp & 0x3)
- memcpy(bufp, tmp, len);
-
- return 0;
-}
-
-static void usbputpcktofifo(int epNum, u8 *bufp, u32 len)
-{
- u32 i, nw, nb;
- u32 *wrdp;
- u8 *bytp;
- u8 *fifo_ptr = get_fifo(epNum, 1);
-
- nw = len / sizeof(int);
- nb = len % sizeof(int);
- wrdp = (u32 *)bufp;
- for (i = 0; i < nw; i++) {
- writel(*wrdp, fifo_ptr);
- wrdp++;
- }
-
- bytp = (u8 *)wrdp;
- for (i = 0; i < nb; i++) {
- writeb(*bytp, fifo_ptr);
- fifo_ptr++;
- bytp++;
- }
-}
-
-/*
- * dw_write_noniso_tx_fifo - Write the next packet to TxFIFO.
- * @endpoint: Endpoint pointer.
- *
- * If the endpoint has an active tx_urb, then the next packet of data from the
- * URB is written to the tx FIFO. The total amount of data in the urb is given
- * by urb->actual_length. The maximum amount of data that can be sent in any
- * one packet is given by endpoint->tx_packetSize. The number of data bytes
- * from this URB that have already been transmitted is given by endpoint->sent.
- * endpoint->last is updated by this routine with the number of data bytes
- * transmitted in this packet.
- *
- */
-static void dw_write_noniso_tx_fifo(struct usb_endpoint_instance
- *endpoint)
-{
- struct urb *urb = endpoint->tx_urb;
- int align;
-
- if (urb) {
- u32 last;
-
- UDCDBGA("urb->buffer %p, buffer_length %d, actual_length %d",
- urb->buffer, urb->buffer_length, urb->actual_length);
-
- last = min_t(u32, urb->actual_length - endpoint->sent,
- endpoint->tx_packetSize);
-
- if (last) {
- u8 *cp = urb->buffer + endpoint->sent;
-
- /*
- * This ensures that USBD packet fifo is accessed
- * - through word aligned pointer or
- * - through non word aligned pointer but only
- * with a max length to make the next packet
- * word aligned
- */
-
- align = ((ulong)cp % sizeof(int));
- if (align)
- last = min(last, sizeof(int) - align);
-
- UDCDBGA("endpoint->sent %d, tx_packetSize %d, last %d",
- endpoint->sent, endpoint->tx_packetSize, last);
-
- usbputpcktofifo(endpoint->endpoint_address &
- USB_ENDPOINT_NUMBER_MASK, cp, last);
- }
- endpoint->last = last;
- }
-}
-
-/*
- * Handle SETUP USB interrupt.
- * This function implements TRM Figure 14-14.
- */
-static void dw_udc_setup(struct usb_endpoint_instance *endpoint)
-{
- u8 *datap = (u8 *)&ep0_urb->device_request;
- int ep_addr = endpoint->endpoint_address;
-
- UDCDBG("-> Entering device setup");
- usbgetpckfromfifo(ep_addr, datap, 8);
-
- /* Try to process setup packet */
- if (ep0_recv_setup(ep0_urb)) {
- /* Not a setup packet, stall next EP0 transaction */
- udc_stall_ep(0);
- UDCDBG("can't parse setup packet, still waiting for setup");
- return;
- }
-
- /* Check direction */
- if ((ep0_urb->device_request.bmRequestType & USB_REQ_DIRECTION_MASK)
- == USB_REQ_HOST2DEVICE) {
- UDCDBG("control write on EP0");
- if (le16_to_cpu(ep0_urb->device_request.wLength)) {
- /* Stall this request */
- UDCDBG("Stalling unsupported EP0 control write data "
- "stage.");
- udc_stall_ep(0);
- }
- } else {
-
- UDCDBG("control read on EP0");
- /*
- * The ep0_recv_setup function has already placed our response
- * packet data in ep0_urb->buffer and the packet length in
- * ep0_urb->actual_length.
- */
- endpoint->tx_urb = ep0_urb;
- endpoint->sent = 0;
- /*
- * Write packet data to the FIFO. dw_write_noniso_tx_fifo
- * will update endpoint->last with the number of bytes written
- * to the FIFO.
- */
- dw_write_noniso_tx_fifo(endpoint);
-
- writel(0x0, &inep_regs_p[ep_addr].write_done);
- }
-
- udc_unset_nak(endpoint->endpoint_address);
-
- UDCDBG("<- Leaving device setup");
-}
-
-/*
- * Handle endpoint 0 RX interrupt
- */
-static void dw_udc_ep0_rx(struct usb_endpoint_instance *endpoint)
-{
- u8 dummy[64];
-
- UDCDBG("RX on EP0");
-
- /* Check direction */
- if ((ep0_urb->device_request.bmRequestType
- & USB_REQ_DIRECTION_MASK) == USB_REQ_HOST2DEVICE) {
- /*
- * This rx interrupt must be for a control write data
- * stage packet.
- *
- * We don't support control write data stages.
- * We should never end up here.
- */
-
- UDCDBG("Stalling unexpected EP0 control write "
- "data stage packet");
- udc_stall_ep(0);
- } else {
- /*
- * This rx interrupt must be for a control read status
- * stage packet.
- */
- UDCDBG("ACK on EP0 control read status stage packet");
- u32 len = (readl(&outep_regs_p[0].endp_status) >> 11) & 0xfff;
- usbgetpckfromfifo(0, dummy, len);
- }
-}
-
-/*
- * Handle endpoint 0 TX interrupt
- */
-static void dw_udc_ep0_tx(struct usb_endpoint_instance *endpoint)
-{
- struct usb_device_request *request = &ep0_urb->device_request;
- int ep_addr;
-
- UDCDBG("TX on EP0");
-
- /* Check direction */
- if ((request->bmRequestType & USB_REQ_DIRECTION_MASK) ==
- USB_REQ_HOST2DEVICE) {
- /*
- * This tx interrupt must be for a control write status
- * stage packet.
- */
- UDCDBG("ACK on EP0 control write status stage packet");
- } else {
- /*
- * This tx interrupt must be for a control read data
- * stage packet.
- */
- int wLength = le16_to_cpu(request->wLength);
-
- /*
- * Update our count of bytes sent so far in this
- * transfer.
- */
- endpoint->sent += endpoint->last;
-
- /*
- * We are finished with this transfer if we have sent
- * all of the bytes in our tx urb (urb->actual_length)
- * unless we need a zero-length terminating packet. We
- * need a zero-length terminating packet if we returned
- * fewer bytes than were requested (wLength) by the host,
- * and the number of bytes we returned is an exact
- * multiple of the packet size endpoint->tx_packetSize.
- */
- if ((endpoint->sent == ep0_urb->actual_length) &&
- ((ep0_urb->actual_length == wLength) ||
- (endpoint->last != endpoint->tx_packetSize))) {
- /* Done with control read data stage. */
- UDCDBG("control read data stage complete");
- } else {
- /*
- * We still have another packet of data to send
- * in this control read data stage or else we
- * need a zero-length terminating packet.
- */
- UDCDBG("ACK control read data stage packet");
- dw_write_noniso_tx_fifo(endpoint);
-
- ep_addr = endpoint->endpoint_address;
- writel(0x0, &inep_regs_p[ep_addr].write_done);
- }
- }
-}
-
-static struct usb_endpoint_instance *dw_find_ep(int ep)
-{
- int i;
-
- for (i = 0; i < udc_device->bus->max_endpoints; i++) {
- if ((udc_device->bus->endpoint_array[i].endpoint_address &
- USB_ENDPOINT_NUMBER_MASK) == ep)
- return &udc_device->bus->endpoint_array[i];
- }
- return NULL;
-}
-
-/*
- * Handle RX transaction on non-ISO endpoint.
- * The ep argument is a physical endpoint number for a non-ISO IN endpoint
- * in the range 1 to 15.
- */
-static void dw_udc_epn_rx(int ep)
-{
- int nbytes = 0;
- struct urb *urb;
- struct usb_endpoint_instance *endpoint = dw_find_ep(ep);
-
- if (endpoint) {
- urb = endpoint->rcv_urb;
-
- if (urb) {
- u8 *cp = urb->buffer + urb->actual_length;
-
- nbytes = (readl(&outep_regs_p[ep].endp_status) >> 11) &
- 0xfff;
- usbgetpckfromfifo(ep, cp, nbytes);
- usbd_rcv_complete(endpoint, nbytes, 0);
- }
- }
-}
-
-/*
- * Handle TX transaction on non-ISO endpoint.
- * The ep argument is a physical endpoint number for a non-ISO IN endpoint
- * in the range 16 to 30.
- */
-static void dw_udc_epn_tx(int ep)
-{
- struct usb_endpoint_instance *endpoint = dw_find_ep(ep);
-
- if (!endpoint)
- return;
-
- /*
- * We need to transmit a terminating zero-length packet now if
- * we have sent all of the data in this URB and the transfer
- * size was an exact multiple of the packet size.
- */
- if (endpoint->tx_urb &&
- (endpoint->last == endpoint->tx_packetSize) &&
- (endpoint->tx_urb->actual_length - endpoint->sent -
- endpoint->last == 0)) {
- /* handle zero length packet here */
- writel(0x0, &inep_regs_p[ep].write_done);
-
- }
-
- if (endpoint->tx_urb && endpoint->tx_urb->actual_length) {
- /* retire the data that was just sent */
- usbd_tx_complete(endpoint);
- /*
- * Check to see if we have more data ready to transmit
- * now.
- */
- if (endpoint->tx_urb && endpoint->tx_urb->actual_length) {
- /* write data to FIFO */
- dw_write_noniso_tx_fifo(endpoint);
- writel(0x0, &inep_regs_p[ep].write_done);
-
- } else if (endpoint->tx_urb
- && (endpoint->tx_urb->actual_length == 0)) {
- /* udc_set_nak(ep); */
- }
- }
-}
-
-/*
- * Start of public functions.
- */
-
-/* Called to start packet transmission. */
-int udc_endpoint_write(struct usb_endpoint_instance *endpoint)
-{
- udc_unset_nak(endpoint->endpoint_address & USB_ENDPOINT_NUMBER_MASK);
- return 0;
-}
-
-/* Start to initialize h/w stuff */
-int udc_init(void)
-{
- int i;
- u32 plug_st;
-
- udc_device = NULL;
-
- UDCDBG("starting");
-
- readl(&plug_regs_p->plug_pending);
-
- for (i = 0; i < UDC_INIT_MDELAY; i++)
- udelay(1000);
-
- plug_st = readl(&plug_regs_p->plug_state);
- writel(plug_st | PLUG_STATUS_EN, &plug_regs_p->plug_state);
-
- writel(~0x0, &udc_regs_p->endp_int);
- writel(~0x0, &udc_regs_p->dev_int_mask);
- writel(~0x0, &udc_regs_p->endp_int_mask);
-
-#ifndef CONFIG_USBD_HS
- writel(DEV_CONF_FS_SPEED | DEV_CONF_REMWAKEUP | DEV_CONF_SELFPOW |
- DEV_CONF_PHYINT_16, &udc_regs_p->dev_conf);
-#else
- writel(DEV_CONF_HS_SPEED | DEV_CONF_REMWAKEUP | DEV_CONF_SELFPOW |
- DEV_CONF_PHYINT_16, &udc_regs_p->dev_conf);
-#endif
-
- writel(DEV_CNTL_SOFTDISCONNECT, &udc_regs_p->dev_cntl);
-
- /* Clear all interrupts pending */
- writel(DEV_INT_MSK, &udc_regs_p->dev_int);
-
- return 0;
-}
-
-int is_usbd_high_speed(void)
-{
- return (readl(&udc_regs_p->dev_stat) & DEV_STAT_ENUM) ? 0 : 1;
-}
-
-/*
- * udc_setup_ep - setup endpoint
- * Associate a physical endpoint with endpoint_instance
- */
-void udc_setup_ep(struct usb_device_instance *device,
- u32 ep, struct usb_endpoint_instance *endpoint)
-{
- UDCDBGA("setting up endpoint addr %x", endpoint->endpoint_address);
- int ep_addr;
- int ep_num, ep_type;
- int packet_size;
- int buffer_size;
- int attributes;
- char *tt;
- u32 endp_intmask;
-
- if ((ep != 0) && (udc_device->device_state < STATE_ADDRESSED))
- return;
-
- tt = env_get("usbtty");
- if (!tt)
- tt = "generic";
-
- ep_addr = endpoint->endpoint_address;
- ep_num = ep_addr & USB_ENDPOINT_NUMBER_MASK;
-
- if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {
- /* IN endpoint */
- packet_size = endpoint->tx_packetSize;
- buffer_size = packet_size * 2;
- attributes = endpoint->tx_attributes;
- } else {
- /* OUT endpoint */
- packet_size = endpoint->rcv_packetSize;
- buffer_size = packet_size * 2;
- attributes = endpoint->rcv_attributes;
- }
-
- switch (attributes & USB_ENDPOINT_XFERTYPE_MASK) {
- case USB_ENDPOINT_XFER_CONTROL:
- ep_type = ENDP_EPTYPE_CNTL;
- break;
- case USB_ENDPOINT_XFER_BULK:
- default:
- ep_type = ENDP_EPTYPE_BULK;
- break;
- case USB_ENDPOINT_XFER_INT:
- ep_type = ENDP_EPTYPE_INT;
- break;
- case USB_ENDPOINT_XFER_ISOC:
- ep_type = ENDP_EPTYPE_ISO;
- break;
- }
-
- struct udc_endp_regs *out_p = &outep_regs_p[ep_num];
- struct udc_endp_regs *in_p = &inep_regs_p[ep_num];
-
- if (!ep_addr) {
- /* Setup endpoint 0 */
- buffer_size = packet_size;
-
- writel(readl(&in_p->endp_cntl) | ENDP_CNTL_CNAK,
- &in_p->endp_cntl);
-
- writel(readl(&out_p->endp_cntl) | ENDP_CNTL_CNAK,
- &out_p->endp_cntl);
-
- writel(ENDP_CNTL_CONTROL | ENDP_CNTL_FLUSH, &in_p->endp_cntl);
-
- writel(buffer_size / sizeof(int), &in_p->endp_bsorfn);
-
- writel(packet_size, &in_p->endp_maxpacksize);
-
- writel(ENDP_CNTL_CONTROL | ENDP_CNTL_RRDY, &out_p->endp_cntl);
-
- writel(packet_size | ((buffer_size / sizeof(int)) << 16),
- &out_p->endp_maxpacksize);
-
- } else if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {
- /* Setup the IN endpoint */
- writel(0x0, &in_p->endp_status);
- writel((ep_type << 4) | ENDP_CNTL_RRDY, &in_p->endp_cntl);
- writel(buffer_size / sizeof(int), &in_p->endp_bsorfn);
- writel(packet_size, &in_p->endp_maxpacksize);
-
- if (!strcmp(tt, "cdc_acm")) {
- if (ep_type == ENDP_EPTYPE_INT) {
- /* Conf no. 1 Interface no. 0 */
- writel((packet_size << 19) |
- ENDP_EPDIR_IN | (1 << 7) |
- (0 << 11) | (ep_type << 5) | ep_num,
- &udc_regs_p->udc_endp_reg[ep_num]);
- } else {
- /* Conf no. 1 Interface no. 1 */
- writel((packet_size << 19) |
- ENDP_EPDIR_IN | (1 << 7) |
- (1 << 11) | (ep_type << 5) | ep_num,
- &udc_regs_p->udc_endp_reg[ep_num]);
- }
- } else {
- /* Conf no. 1 Interface no. 0 */
- writel((packet_size << 19) |
- ENDP_EPDIR_IN | (1 << 7) |
- (0 << 11) | (ep_type << 5) | ep_num,
- &udc_regs_p->udc_endp_reg[ep_num]);
- }
-
- } else {
- /* Setup the OUT endpoint */
- writel(0x0, &out_p->endp_status);
- writel((ep_type << 4) | ENDP_CNTL_RRDY, &out_p->endp_cntl);
- writel(packet_size | ((buffer_size / sizeof(int)) << 16),
- &out_p->endp_maxpacksize);
-
- if (!strcmp(tt, "cdc_acm")) {
- writel((packet_size << 19) |
- ENDP_EPDIR_OUT | (1 << 7) |
- (1 << 11) | (ep_type << 5) | ep_num,
- &udc_regs_p->udc_endp_reg[ep_num]);
- } else {
- writel((packet_size << 19) |
- ENDP_EPDIR_OUT | (1 << 7) |
- (0 << 11) | (ep_type << 5) | ep_num,
- &udc_regs_p->udc_endp_reg[ep_num]);
- }
-
- }
-
- endp_intmask = readl(&udc_regs_p->endp_int_mask);
- endp_intmask &= ~((1 << ep_num) | 0x10000 << ep_num);
- writel(endp_intmask, &udc_regs_p->endp_int_mask);
-}
-
-/* Turn on the USB connection by enabling the pullup resistor */
-void udc_connect(void)
-{
- u32 plug_st, dev_cntl;
-
- dev_cntl = readl(&udc_regs_p->dev_cntl);
- dev_cntl |= DEV_CNTL_SOFTDISCONNECT;
- writel(dev_cntl, &udc_regs_p->dev_cntl);
-
- udelay(1000);
-
- dev_cntl = readl(&udc_regs_p->dev_cntl);
- dev_cntl &= ~DEV_CNTL_SOFTDISCONNECT;
- writel(dev_cntl, &udc_regs_p->dev_cntl);
-
- plug_st = readl(&plug_regs_p->plug_state);
- plug_st &= ~(PLUG_STATUS_PHY_RESET | PLUG_STATUS_PHY_MODE);
- writel(plug_st, &plug_regs_p->plug_state);
-}
-
-/* Turn off the USB connection by disabling the pullup resistor */
-void udc_disconnect(void)
-{
- u32 plug_st;
-
- writel(DEV_CNTL_SOFTDISCONNECT, &udc_regs_p->dev_cntl);
-
- plug_st = readl(&plug_regs_p->plug_state);
- plug_st |= (PLUG_STATUS_PHY_RESET | PLUG_STATUS_PHY_MODE);
- writel(plug_st, &plug_regs_p->plug_state);
-}
-
-/* Switch on the UDC */
-void udc_enable(struct usb_device_instance *device)
-{
- UDCDBGA("enable device %p, status %d", device, device->status);
-
- /* Save the device structure pointer */
- udc_device = device;
-
- /* Setup ep0 urb */
- if (!ep0_urb) {
- ep0_urb =
- usbd_alloc_urb(udc_device, udc_device->bus->endpoint_array);
- } else {
- serial_printf("udc_enable: ep0_urb already allocated %p\n",
- ep0_urb);
- }
-
- writel(DEV_INT_SOF, &udc_regs_p->dev_int_mask);
-}
-
-/**
- * udc_startup - allow udc code to do any additional startup
- */
-void udc_startup_events(struct usb_device_instance *device)
-{
- /* The DEVICE_INIT event puts the USB device in the state STATE_INIT. */
- usbd_device_event_irq(device, DEVICE_INIT, 0);
-
- /*
- * The DEVICE_CREATE event puts the USB device in the state
- * STATE_ATTACHED.
- */
- usbd_device_event_irq(device, DEVICE_CREATE, 0);
-
- /*
- * Some USB controller driver implementations signal
- * DEVICE_HUB_CONFIGURED and DEVICE_RESET events here.
- * DEVICE_HUB_CONFIGURED causes a transition to the state STATE_POWERED,
- * and DEVICE_RESET causes a transition to the state STATE_DEFAULT.
- * The DW USB client controller has the capability to detect when the
- * USB cable is connected to a powered USB bus, so we will defer the
- * DEVICE_HUB_CONFIGURED and DEVICE_RESET events until later.
- */
-
- udc_enable(device);
-}
-
-/*
- * Plug detection interrupt handling
- */
-static void dw_udc_plug_irq(void)
-{
- if (readl(&plug_regs_p->plug_state) & PLUG_STATUS_ATTACHED) {
- /*
- * USB cable attached
- * Turn off PHY reset bit (PLUG detect).
- * Switch PHY opmode to normal operation (PLUG detect).
- */
- udc_connect();
- writel(DEV_INT_SOF, &udc_regs_p->dev_int_mask);
-
- UDCDBG("device attached and powered");
- udc_state_transition(udc_device->device_state, STATE_POWERED);
- } else {
- writel(~0x0, &udc_regs_p->dev_int_mask);
-
- UDCDBG("device detached or unpowered");
- udc_state_transition(udc_device->device_state, STATE_ATTACHED);
- }
-}
-
-/*
- * Device interrupt handling
- */
-static void dw_udc_dev_irq(void)
-{
- if (readl(&udc_regs_p->dev_int) & DEV_INT_USBRESET) {
- writel(~0x0, &udc_regs_p->endp_int_mask);
-
- writel(readl(&inep_regs_p[0].endp_cntl) | ENDP_CNTL_FLUSH,
- &inep_regs_p[0].endp_cntl);
-
- writel(DEV_INT_USBRESET, &udc_regs_p->dev_int);
-
- /*
- * This endpoint0 specific register can be programmed only
- * after the phy clock is initialized
- */
- writel((EP0_MAX_PACKET_SIZE << 19) | ENDP_EPTYPE_CNTL,
- &udc_regs_p->udc_endp_reg[0]);
-
- UDCDBG("device reset in progess");
- udc_state_transition(udc_device->device_state, STATE_DEFAULT);
- }
-
- /* Device Enumeration completed */
- if (readl(&udc_regs_p->dev_int) & DEV_INT_ENUM) {
- writel(DEV_INT_ENUM, &udc_regs_p->dev_int);
-
- /* Endpoint interrupt enabled for Ctrl IN & Ctrl OUT */
- writel(readl(&udc_regs_p->endp_int_mask) & ~0x10001,
- &udc_regs_p->endp_int_mask);
-
- UDCDBG("default -> addressed");
- udc_state_transition(udc_device->device_state, STATE_ADDRESSED);
- }
-
- /* The USB will be in SUSPEND in 3 ms */
- if (readl(&udc_regs_p->dev_int) & DEV_INT_INACTIVE) {
- writel(DEV_INT_INACTIVE, &udc_regs_p->dev_int);
-
- UDCDBG("entering inactive state");
- /* usbd_device_event_irq(udc_device, DEVICE_BUS_INACTIVE, 0); */
- }
-
- /* SetConfiguration command received */
- if (readl(&udc_regs_p->dev_int) & DEV_INT_SETCFG) {
- writel(DEV_INT_SETCFG, &udc_regs_p->dev_int);
-
- UDCDBG("entering configured state");
- udc_state_transition(udc_device->device_state,
- STATE_CONFIGURED);
- }
-
- /* SetInterface command received */
- if (readl(&udc_regs_p->dev_int) & DEV_INT_SETINTF)
- writel(DEV_INT_SETINTF, &udc_regs_p->dev_int);
-
- /* USB Suspend detected on cable */
- if (readl(&udc_regs_p->dev_int) & DEV_INT_SUSPUSB) {
- writel(DEV_INT_SUSPUSB, &udc_regs_p->dev_int);
-
- UDCDBG("entering suspended state");
- usbd_device_event_irq(udc_device, DEVICE_BUS_INACTIVE, 0);
- }
-
- /* USB Start-Of-Frame detected on cable */
- if (readl(&udc_regs_p->dev_int) & DEV_INT_SOF)
- writel(DEV_INT_SOF, &udc_regs_p->dev_int);
-}
-
-/*
- * Endpoint interrupt handling
- */
-static void dw_udc_endpoint_irq(void)
-{
- while (readl(&udc_regs_p->endp_int) & ENDP0_INT_CTRLOUT) {
-
- writel(ENDP0_INT_CTRLOUT, &udc_regs_p->endp_int);
-
- if ((readl(&outep_regs_p[0].endp_status) & ENDP_STATUS_OUTMSK)
- == ENDP_STATUS_OUT_SETUP) {
- dw_udc_setup(udc_device->bus->endpoint_array + 0);
- writel(ENDP_STATUS_OUT_SETUP,
- &outep_regs_p[0].endp_status);
-
- } else if ((readl(&outep_regs_p[0].endp_status) &
- ENDP_STATUS_OUTMSK) == ENDP_STATUS_OUT_DATA) {
- dw_udc_ep0_rx(udc_device->bus->endpoint_array + 0);
- writel(ENDP_STATUS_OUT_DATA,
- &outep_regs_p[0].endp_status);
-
- } else if ((readl(&outep_regs_p[0].endp_status) &
- ENDP_STATUS_OUTMSK) == ENDP_STATUS_OUT_NONE) {
- /* NONE received */
- }
-
- writel(0x0, &outep_regs_p[0].endp_status);
- }
-
- if (readl(&udc_regs_p->endp_int) & ENDP0_INT_CTRLIN) {
- dw_udc_ep0_tx(udc_device->bus->endpoint_array + 0);
-
- writel(ENDP_STATUS_IN, &inep_regs_p[0].endp_status);
- writel(ENDP0_INT_CTRLIN, &udc_regs_p->endp_int);
- }
-
- if (readl(&udc_regs_p->endp_int) & ENDP_INT_NONISOOUT_MSK) {
- u32 epnum = 0;
- u32 ep_int = readl(&udc_regs_p->endp_int) &
- ENDP_INT_NONISOOUT_MSK;
-
- ep_int >>= 16;
- while (0x0 == (ep_int & 0x1)) {
- ep_int >>= 1;
- epnum++;
- }
-
- writel((1 << 16) << epnum, &udc_regs_p->endp_int);
-
- if ((readl(&outep_regs_p[epnum].endp_status) &
- ENDP_STATUS_OUTMSK) == ENDP_STATUS_OUT_DATA) {
-
- dw_udc_epn_rx(epnum);
- writel(ENDP_STATUS_OUT_DATA,
- &outep_regs_p[epnum].endp_status);
- } else if ((readl(&outep_regs_p[epnum].endp_status) &
- ENDP_STATUS_OUTMSK) == ENDP_STATUS_OUT_NONE) {
- writel(0x0, &outep_regs_p[epnum].endp_status);
- }
- }
-
- if (readl(&udc_regs_p->endp_int) & ENDP_INT_NONISOIN_MSK) {
- u32 epnum = 0;
- u32 ep_int = readl(&udc_regs_p->endp_int) &
- ENDP_INT_NONISOIN_MSK;
-
- while (0x0 == (ep_int & 0x1)) {
- ep_int >>= 1;
- epnum++;
- }
-
- if (readl(&inep_regs_p[epnum].endp_status) & ENDP_STATUS_IN) {
- writel(ENDP_STATUS_IN,
- &outep_regs_p[epnum].endp_status);
- dw_udc_epn_tx(epnum);
-
- writel(ENDP_STATUS_IN,
- &outep_regs_p[epnum].endp_status);
- }
-
- writel((1 << epnum), &udc_regs_p->endp_int);
- }
-}
-
-/*
- * UDC interrupts
- */
-void udc_irq(void)
-{
- /*
- * Loop while we have interrupts.
- * If we don't do this, the input chain
- * polling delay is likely to miss
- * host requests.
- */
- while (readl(&plug_regs_p->plug_pending))
- dw_udc_plug_irq();
-
- while (readl(&udc_regs_p->dev_int))
- dw_udc_dev_irq();
-
- if (readl(&udc_regs_p->endp_int))
- dw_udc_endpoint_irq();
-}
-
-/* Flow control */
-void udc_set_nak(int epid)
-{
- writel(readl(&inep_regs_p[epid].endp_cntl) | ENDP_CNTL_SNAK,
- &inep_regs_p[epid].endp_cntl);
-
- writel(readl(&outep_regs_p[epid].endp_cntl) | ENDP_CNTL_SNAK,
- &outep_regs_p[epid].endp_cntl);
-}
-
-void udc_unset_nak(int epid)
-{
- u32 val;
-
- val = readl(&inep_regs_p[epid].endp_cntl);
- val &= ~ENDP_CNTL_SNAK;
- val |= ENDP_CNTL_CNAK;
- writel(val, &inep_regs_p[epid].endp_cntl);
-
- val = readl(&outep_regs_p[epid].endp_cntl);
- val &= ~ENDP_CNTL_SNAK;
- val |= ENDP_CNTL_CNAK;
- writel(val, &outep_regs_p[epid].endp_cntl);
-}
diff --git a/drivers/virtio/virtio_blk.c b/drivers/virtio/virtio_blk.c
index 9710b79..30cfc56 100644
--- a/drivers/virtio/virtio_blk.c
+++ b/drivers/virtio/virtio_blk.c
@@ -75,7 +75,7 @@
struct blk_desc *desc = dev_get_uclass_plat(dev);
int devnum;
- desc->if_type = UCLASS_VIRTIO;
+ desc->uclass_id = UCLASS_VIRTIO;
/*
* Initialize the devnum to -ENODEV. This is to make sure that
* blk_next_free_devnum() works as expected, since the default
diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c
index b098b2e..368b368 100644
--- a/drivers/watchdog/mtk_wdt.c
+++ b/drivers/watchdog/mtk_wdt.c
@@ -145,6 +145,7 @@
static const struct udevice_id mtk_wdt_ids[] = {
{ .compatible = "mediatek,wdt"},
{ .compatible = "mediatek,mt6589-wdt"},
+ { .compatible = "mediatek,mt7986-wdt" },
{}
};
diff --git a/drivers/xen/pvblock.c b/drivers/xen/pvblock.c
index 1090e52..970182c 100644
--- a/drivers/xen/pvblock.c
+++ b/drivers/xen/pvblock.c
@@ -665,7 +665,7 @@
struct blk_desc *desc = dev_get_uclass_plat(udev);
int devnum;
- desc->if_type = UCLASS_PVBLOCK;
+ desc->uclass_id = UCLASS_PVBLOCK;
/*
* Initialize the devnum to -ENODEV. This is to make sure that
* blk_next_free_devnum() works as expected, since the default
diff --git a/fs/fat/fat.c b/fs/fat/fat.c
index c64e253..a945904 100644
--- a/fs/fat/fat.c
+++ b/fs/fat/fat.c
@@ -1145,7 +1145,7 @@
}
if (blk_enabled()) {
- printf("Interface: %s\n", blk_get_if_type_name(cur_dev->if_type));
+ printf("Interface: %s\n", blk_get_uclass_name(cur_dev->uclass_id));
printf(" Device %d: ", cur_dev->devnum);
dev_print(cur_dev);
}
diff --git a/include/_exports.h b/include/_exports.h
index f6df8b6..1af946f 100644
--- a/include/_exports.h
+++ b/include/_exports.h
@@ -12,6 +12,9 @@
EXPORT_FUNC(tstc, int, tstc, void)
EXPORT_FUNC(putc, void, putc, const char)
EXPORT_FUNC(puts, void, puts, const char *)
+#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
+ EXPORT_FUNC(flush, void, flush, void)
+#endif
EXPORT_FUNC(printf, int, printf, const char*, ...)
#if (defined(CONFIG_X86) && !defined(CONFIG_X86_64)) || defined(CONFIG_PPC)
EXPORT_FUNC(irq_install_handler, void, install_hdlr,
diff --git a/include/blk.h b/include/blk.h
index 279f9ea..8806c38 100644
--- a/include/blk.h
+++ b/include/blk.h
@@ -54,7 +54,7 @@
* TODO: With driver model we should be able to use the parent
* device's uclass instead.
*/
- enum uclass_id if_type; /* type of the interface */
+ enum uclass_id uclass_id; /* type of the interface */
int devnum; /* device number */
unsigned char part_type; /* partition type */
unsigned char target; /* target SCSI ID */
@@ -114,7 +114,7 @@
/**
* blkcache_read() - attempt to read a set of blocks from cache
*
- * @param iftype - IF_TYPE_x for type of device
+ * @param iftype - uclass_id_x for type of device
* @param dev - device index of particular type
* @param start - starting block number
* @param blkcnt - number of blocks to read
@@ -131,7 +131,7 @@
* blkcache_fill() - make data read from a block device available
* to the block cache
*
- * @param iftype - IF_TYPE_x for type of device
+ * @param iftype - uclass_id_x for type of device
* @param dev - device index of particular type
* @param start - starting block number
* @param blkcnt - number of blocks available
@@ -147,7 +147,7 @@
* blkcache_invalidate() - discard the cache for a set of blocks
* because of a write or device (re)initialization.
*
- * @param iftype - IF_TYPE_x for type of device
+ * @param iftype - uclass_id_x for type of device
* @param dev - device index of particular type
*/
void blkcache_invalidate(int iftype, int dev);
@@ -279,22 +279,22 @@
* This function does not activate the device. The device will be returned
* whether or not it is activated.
*
- * @if_type: Interface type (enum uclass_id_t)
+ * @uclass_id: Interface type (enum uclass_id_t)
* @devnum: Device number (specific to each interface type)
* @devp: the device, if found
* Return: 0 if found, -ENODEV if no device found, or other -ve error value
*/
-int blk_find_device(int if_type, int devnum, struct udevice **devp);
+int blk_find_device(int uclass_id, int devnum, struct udevice **devp);
/**
* blk_get_device() - Find and probe a block device ready for use
*
- * @if_type: Interface type (enum uclass_id_t)
+ * @uclass_id: Interface type (enum uclass_id_t)
* @devnum: Device number (specific to each interface type)
* @devp: the device, if found
* Return: 0 if found, -ENODEV if no device found, or other -ve error value
*/
-int blk_get_device(int if_type, int devnum, struct udevice **devp);
+int blk_get_device(int uclass_id, int devnum, struct udevice **devp);
/**
* blk_first_device() - Find the first device for a given interface
@@ -305,7 +305,7 @@
* @devp: the device, if found
* Return: 0 if found, -ENODEV if no device, or other -ve error value
*/
-int blk_first_device(int if_type, struct udevice **devp);
+int blk_first_device(int uclass_id, struct udevice **devp);
/**
* blk_next_device() - Find the next device for a given interface
@@ -327,7 +327,7 @@
* @parent: Parent of the new device
* @drv_name: Driver name to use for the block device
* @name: Name for the device
- * @if_type: Interface type (enum uclass_id_t)
+ * @uclass_id: Interface type (enum uclass_id_t)
* @devnum: Device number, specific to the interface type, or -1 to
* allocate the next available number
* @blksz: Block size of the device in bytes (typically 512)
@@ -335,7 +335,7 @@
* @devp: the new device (which has not been probed)
*/
int blk_create_device(struct udevice *parent, const char *drv_name,
- const char *name, int if_type, int devnum, int blksz,
+ const char *name, int uclass_id, int devnum, int blksz,
lbaint_t lba, struct udevice **devp);
/**
@@ -344,7 +344,7 @@
* @parent: Parent of the new device
* @drv_name: Driver name to use for the block device
* @name: Name for the device (parent name is prepended)
- * @if_type: Interface type (enum uclass_id_t)
+ * @uclass_id: Interface type (enum uclass_id_t)
* @devnum: Device number, specific to the interface type, or -1 to
* allocate the next available number
* @blksz: Block size of the device in bytes (typically 512)
@@ -352,7 +352,7 @@
* @devp: the new device (which has not been probed)
*/
int blk_create_devicef(struct udevice *parent, const char *drv_name,
- const char *name, int if_type, int devnum, int blksz,
+ const char *name, int uclass_id, int devnum, int blksz,
lbaint_t lba, struct udevice **devp);
/**
@@ -372,33 +372,33 @@
*
* The devices are removed and then unbound.
*
- * @if_type: Interface type to unbind
+ * @uclass_id: Interface type to unbind
* Return: 0 if OK, -ve on error
*/
-int blk_unbind_all(int if_type);
+int blk_unbind_all(int uclass_id);
/**
* blk_find_max_devnum() - find the maximum device number for an interface type
*
- * Finds the last allocated device number for an interface type @if_type. The
+ * Finds the last allocated device number for an interface type @uclass_id. The
* next number is safe to use for a newly allocated device.
*
- * @if_type: Interface type to scan
+ * @uclass_id: Interface type to scan
* Return: maximum device number found, or -ENODEV if none, or other -ve on
* error
*/
-int blk_find_max_devnum(enum uclass_id if_type);
+int blk_find_max_devnum(enum uclass_id uclass_id);
/**
* blk_next_free_devnum() - get the next device number for an interface type
*
* Finds the next number that is safe to use for a newly allocated device for
- * an interface type @if_type.
+ * an interface type @uclass_id.
*
- * @if_type: Interface type to scan
+ * @uclass_id: Interface type to scan
* Return: next device number safe to use, or -ve on error
*/
-int blk_next_free_devnum(enum uclass_id if_type);
+int blk_next_free_devnum(enum uclass_id uclass_id);
/**
* blk_select_hwpart() - select a hardware partition
@@ -447,7 +447,7 @@
lbaint_t blkcnt, void *buffer)
{
ulong blks_read;
- if (blkcache_read(block_dev->if_type, block_dev->devnum,
+ if (blkcache_read(block_dev->uclass_id, block_dev->devnum,
start, blkcnt, block_dev->blksz, buffer))
return blkcnt;
@@ -458,7 +458,7 @@
*/
blks_read = block_dev->block_read(block_dev, start, blkcnt, buffer);
if (blks_read == blkcnt)
- blkcache_fill(block_dev->if_type, block_dev->devnum,
+ blkcache_fill(block_dev->uclass_id, block_dev->devnum,
start, blkcnt, block_dev->blksz, buffer);
return blks_read;
@@ -467,14 +467,14 @@
static inline ulong blk_dwrite(struct blk_desc *block_dev, lbaint_t start,
lbaint_t blkcnt, const void *buffer)
{
- blkcache_invalidate(block_dev->if_type, block_dev->devnum);
+ blkcache_invalidate(block_dev->uclass_id, block_dev->devnum);
return block_dev->block_write(block_dev, start, blkcnt, buffer);
}
static inline ulong blk_derase(struct blk_desc *block_dev, lbaint_t start,
lbaint_t blkcnt)
{
- blkcache_invalidate(block_dev->if_type, block_dev->devnum);
+ blkcache_invalidate(block_dev->uclass_id, block_dev->devnum);
return block_dev->block_erase(block_dev, start, blkcnt);
}
@@ -485,15 +485,15 @@
* driver should be provided using U_BOOT_LEGACY_BLK() for each interface
* type that is to be supported.
*
- * @if_typename: Interface type name
- * @if_type: Interface type
+ * @uclass_idname: Interface type name
+ * @uclass_id: Interface type
* @max_devs: Maximum number of devices supported
* @desc: Pointer to list of devices for this interface type,
* or NULL to use @get_dev() instead
*/
struct blk_driver {
- const char *if_typename;
- enum uclass_id if_type;
+ const char *uclass_idname;
+ enum uclass_id uclass_id;
int max_devs;
struct blk_desc *desc;
/**
@@ -540,33 +540,33 @@
#define U_BOOT_LEGACY_BLK(__name) \
ll_entry_declare(struct blk_driver, __name, blk_driver)
-struct blk_driver *blk_driver_lookup_type(int if_type);
+struct blk_driver *blk_driver_lookup_type(int uclass_id);
#endif /* !CONFIG_BLK */
/**
- * blk_get_devnum_by_typename() - Get a block device by type and number
+ * blk_get_devnum_by_uclass_idname() - Get a block device by type and number
*
* This looks through the available block devices of the given type, returning
* the one with the given @devnum.
*
- * @if_type: Block device type
+ * @uclass_id: Block device type
* @devnum: Device number
* Return: point to block device descriptor, or NULL if not found
*/
-struct blk_desc *blk_get_devnum_by_type(enum uclass_id if_type, int devnum);
+struct blk_desc *blk_get_devnum_by_uclass_id(enum uclass_id uclass_id, int devnum);
/**
- * blk_get_devnum_by_type() - Get a block device by type name, and number
+ * blk_get_devnum_by_uclass_id() - Get a block device by type name, and number
*
- * This looks up the block device type based on @if_typename, then calls
- * blk_get_devnum_by_type().
+ * This looks up the block device type based on @uclass_idname, then calls
+ * blk_get_devnum_by_uclass_id().
*
- * @if_typename: Block device type name
+ * @uclass_idname: Block device type name
* @devnum: Device number
* Return: point to block device descriptor, or NULL if not found
*/
-struct blk_desc *blk_get_devnum_by_typename(const char *if_typename,
+struct blk_desc *blk_get_devnum_by_uclass_idname(const char *uclass_idname,
int devnum);
/**
@@ -585,34 +585,34 @@
/**
* blk_list_part() - list the partitions for block devices of a given type
*
- * This looks up the partition type for each block device of type @if_type,
+ * This looks up the partition type for each block device of type @uclass_id,
* then displays a list of partitions.
*
- * @if_type: Block device type
+ * @uclass_id: Block device type
* Return: 0 if OK, -ENODEV if there is none of that type
*/
-int blk_list_part(enum uclass_id if_type);
+int blk_list_part(enum uclass_id uclass_id);
/**
* blk_list_devices() - list the block devices of a given type
*
- * This lists each block device of the type @if_type, showing the capacity
+ * This lists each block device of the type @uclass_id, showing the capacity
* as well as type-specific information.
*
- * @if_type: Block device type
+ * @uclass_id: Block device type
*/
-void blk_list_devices(enum uclass_id if_type);
+void blk_list_devices(enum uclass_id uclass_id);
/**
* blk_show_device() - show information about a given block device
*
* This shows the block device capacity as well as type-specific information.
*
- * @if_type: Block device type
+ * @uclass_id: Block device type
* @devnum: Device number
* Return: 0 if OK, -ENODEV for invalid device number
*/
-int blk_show_device(enum uclass_id if_type, int devnum);
+int blk_show_device(enum uclass_id uclass_id, int devnum);
/**
* blk_print_device_num() - show information about a given block device
@@ -620,45 +620,45 @@
* This is similar to blk_show_device() but returns an error if the block
* device type is unknown.
*
- * @if_type: Block device type
+ * @uclass_id: Block device type
* @devnum: Device number
* Return: 0 if OK, -ENODEV for invalid device number, -ENOENT if the block
* device is not connected
*/
-int blk_print_device_num(enum uclass_id if_type, int devnum);
+int blk_print_device_num(enum uclass_id uclass_id, int devnum);
/**
* blk_print_part_devnum() - print the partition information for a device
*
- * @if_type: Block device type
+ * @uclass_id: Block device type
* @devnum: Device number
* Return: 0 if OK, -ENOENT if the block device is not connected, -ENOSYS if
* the interface type is not supported, other -ve on other error
*/
-int blk_print_part_devnum(enum uclass_id if_type, int devnum);
+int blk_print_part_devnum(enum uclass_id uclass_id, int devnum);
/**
* blk_read_devnum() - read blocks from a device
*
- * @if_type: Block device type
+ * @uclass_id: Block device type
* @devnum: Device number
* @blkcnt: Number of blocks to read
* @buffer: Address to write data to
* Return: number of blocks read, or -ve error number on error
*/
-ulong blk_read_devnum(enum uclass_id if_type, int devnum, lbaint_t start,
+ulong blk_read_devnum(enum uclass_id uclass_id, int devnum, lbaint_t start,
lbaint_t blkcnt, void *buffer);
/**
* blk_write_devnum() - write blocks to a device
*
- * @if_type: Block device type
+ * @uclass_id: Block device type
* @devnum: Device number
* @blkcnt: Number of blocks to write
* @buffer: Address to read data from
* Return: number of blocks written, or -ve error number on error
*/
-ulong blk_write_devnum(enum uclass_id if_type, int devnum, lbaint_t start,
+ulong blk_write_devnum(enum uclass_id uclass_id, int devnum, lbaint_t start,
lbaint_t blkcnt, const void *buffer);
/**
@@ -667,31 +667,31 @@
* This is similar to blk_dselect_hwpart() but it looks up the interface and
* device number.
*
- * @if_type: Block device type
+ * @uclass_id: Block device type
* @devnum: Device number
* @hwpart: Partition number to select
* Return: 0 if OK, -ve on error
*/
-int blk_select_hwpart_devnum(enum uclass_id if_type, int devnum, int hwpart);
+int blk_select_hwpart_devnum(enum uclass_id uclass_id, int devnum, int hwpart);
/**
- * blk_get_if_type_name() - Get the name of an interface type
+ * blk_get_uclass_name() - Get the name of an interface type
*
- * @if_type: Interface type to check
+ * @uclass_id: Interface type to check
* Return: name of interface, or NULL if none
*/
-const char *blk_get_if_type_name(enum uclass_id if_type);
+const char *blk_get_uclass_name(enum uclass_id uclass_id);
/**
* blk_common_cmd() - handle common commands with block devices
*
* @args: Number of arguments to the command (argv[0] is the command itself)
* @argv: Command arguments
- * @if_type: Interface type
+ * @uclass_id: Interface type
* @cur_devnump: Current device number for this interface type
* Return: 0 if OK, CMD_RET_ERROR on error
*/
-int blk_common_cmd(int argc, char *const argv[], enum uclass_id if_type,
+int blk_common_cmd(int argc, char *const argv[], enum uclass_id uclass_id,
int *cur_devnump);
enum blk_flag_t {
diff --git a/include/configs/mt7981.h b/include/configs/mt7981.h
new file mode 100644
index 0000000..01ad309
--- /dev/null
+++ b/include/configs/mt7981.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Configuration for MediaTek MT7981 SoC
+ *
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+#ifndef __MT7981_H
+#define __MT7981_H
+
+#include <linux/sizes.h>
+
+#define CONFIG_SYS_NONCACHED_MEMORY SZ_1M
+
+/* Uboot definition */
+#define CONFIG_SYS_UBOOT_BASE CONFIG_SYS_TEXT_BASE
+
+/* SPL -> Uboot */
+#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE
+
+/* DRAM */
+#define CONFIG_SYS_SDRAM_BASE 0x40000000
+
+#endif
diff --git a/include/configs/mt7986.h b/include/configs/mt7986.h
new file mode 100644
index 0000000..ccdd6ab
--- /dev/null
+++ b/include/configs/mt7986.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Configuration for MediaTek MT7986 SoC
+ *
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+#ifndef __MT7986_H
+#define __MT7986_H
+
+#include <linux/sizes.h>
+
+#define CONFIG_SYS_NONCACHED_MEMORY SZ_1M
+
+/* Uboot definition */
+#define CONFIG_SYS_UBOOT_BASE CONFIG_SYS_TEXT_BASE
+
+/* SPL -> Uboot */
+#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE
+
+/* DRAM */
+#define CONFIG_SYS_SDRAM_BASE 0x40000000
+
+#endif
diff --git a/include/dt-bindings/clock/mt7981-clk.h b/include/dt-bindings/clock/mt7981-clk.h
new file mode 100644
index 0000000..e24c759
--- /dev/null
+++ b/include/dt-bindings/clock/mt7981-clk.h
@@ -0,0 +1,267 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2022 MediaTek Inc. All rights reserved.
+ *
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_MT7981_H
+#define _DT_BINDINGS_CLK_MT7981_H
+
+/* INFRACFG */
+
+#define CK_INFRA_CK_F26M 0
+#define CK_INFRA_UART 1
+#define CK_INFRA_ISPI0 2
+#define CK_INFRA_I2C 3
+#define CK_INFRA_ISPI1 4
+#define CK_INFRA_PWM 5
+#define CK_INFRA_66M_MCK 6
+#define CK_INFRA_CK_F32K 7
+#define CK_INFRA_PCIE_CK 8
+#define CK_INFRA_PWM_BCK 9
+#define CK_INFRA_PWM_CK1 10
+#define CK_INFRA_PWM_CK2 11
+#define CK_INFRA_133M_HCK 12
+#define CK_INFRA_66M_PHCK 13
+#define CK_INFRA_FAUD_L_CK 14
+#define CK_INFRA_FAUD_AUD_CK 15
+#define CK_INFRA_FAUD_EG2_CK 16
+#define CK_INFRA_I2CS_CK 17
+#define CK_INFRA_MUX_UART0 18
+#define CK_INFRA_MUX_UART1 19
+#define CK_INFRA_MUX_UART2 20
+#define CK_INFRA_NFI_CK 21
+#define CK_INFRA_SPINFI_CK 22
+#define CK_INFRA_MUX_SPI0 23
+#define CK_INFRA_MUX_SPI1 24
+#define CK_INFRA_MUX_SPI2 25
+#define CK_INFRA_RTC_32K 26
+#define CK_INFRA_FMSDC_CK 27
+#define CK_INFRA_FMSDC_HCK_CK 28
+#define CK_INFRA_PERI_133M 29
+#define CK_INFRA_133M_PHCK 30
+#define CK_INFRA_USB_SYS_CK 31
+#define CK_INFRA_USB_CK 32
+#define CK_INFRA_USB_XHCI_CK 33
+#define CK_INFRA_PCIE_GFMUX_TL_O_PRE 34
+#define CK_INFRA_F26M_CK0 35
+#define CK_INFRA_133M_MCK 36
+#define CLK_INFRA_NR_CLK 37
+
+/* TOPCKGEN */
+
+#define CK_TOP_CB_CKSQ_40M 0
+#define CK_TOP_CB_M_416M 1
+#define CK_TOP_CB_M_D2 2
+#define CK_TOP_CB_M_D3 3
+#define CK_TOP_M_D3_D2 4
+#define CK_TOP_CB_M_D4 5
+#define CK_TOP_CB_M_D8 6
+#define CK_TOP_M_D8_D2 7
+#define CK_TOP_CB_MM_720M 8
+#define CK_TOP_CB_MM_D2 9
+#define CK_TOP_CB_MM_D3 10
+#define CK_TOP_CB_MM_D3_D5 11
+#define CK_TOP_CB_MM_D4 12
+#define CK_TOP_CB_MM_D6 13
+#define CK_TOP_MM_D6_D2 14
+#define CK_TOP_CB_MM_D8 15
+#define CK_TOP_CB_APLL2_196M 16
+#define CK_TOP_APLL2_D2 17
+#define CK_TOP_APLL2_D4 18
+#define CK_TOP_NET1_2500M 19
+#define CK_TOP_CB_NET1_D4 20
+#define CK_TOP_CB_NET1_D5 21
+#define CK_TOP_NET1_D5_D2 22
+#define CK_TOP_NET1_D5_D4 23
+#define CK_TOP_CB_NET1_D8 24
+#define CK_TOP_NET1_D8_D2 25
+#define CK_TOP_NET1_D8_D4 26
+#define CK_TOP_CB_NET2_800M 27
+#define CK_TOP_CB_NET2_D2 28
+#define CK_TOP_CB_NET2_D4 29
+#define CK_TOP_NET2_D4_D2 30
+#define CK_TOP_NET2_D4_D4 31
+#define CK_TOP_CB_NET2_D6 32
+#define CK_TOP_CB_WEDMCU_208M 33
+#define CK_TOP_CB_SGM_325M 34
+#define CK_TOP_CKSQ_40M_D2 35
+#define CK_TOP_CB_RTC_32K 36
+#define CK_TOP_CB_RTC_32P7K 37
+#define CK_TOP_USB_TX250M 38
+#define CK_TOP_FAUD 39
+#define CK_TOP_NFI1X 40
+#define CK_TOP_USB_EQ_RX250M 41
+#define CK_TOP_USB_CDR_CK 42
+#define CK_TOP_USB_LN0_CK 43
+#define CK_TOP_SPINFI_BCK 44
+#define CK_TOP_SPI 45
+#define CK_TOP_SPIM_MST 46
+#define CK_TOP_UART_BCK 47
+#define CK_TOP_PWM_BCK 48
+#define CK_TOP_I2C_BCK 49
+#define CK_TOP_PEXTP_TL 50
+#define CK_TOP_EMMC_208M 51
+#define CK_TOP_EMMC_400M 52
+#define CK_TOP_DRAMC_REF 53
+#define CK_TOP_DRAMC_MD32 54
+#define CK_TOP_SYSAXI 55
+#define CK_TOP_SYSAPB 56
+#define CK_TOP_ARM_DB_MAIN 57
+#define CK_TOP_AP2CNN_HOST 58
+#define CK_TOP_NETSYS 59
+#define CK_TOP_NETSYS_500M 60
+#define CK_TOP_NETSYS_WED_MCU 61
+#define CK_TOP_NETSYS_2X 62
+#define CK_TOP_SGM_325M 63
+#define CK_TOP_SGM_REG 64
+#define CK_TOP_F26M 65
+#define CK_TOP_EIP97B 66
+#define CK_TOP_USB3_PHY 67
+#define CK_TOP_AUD 68
+#define CK_TOP_A1SYS 69
+#define CK_TOP_AUD_L 70
+#define CK_TOP_A_TUNER 71
+#define CK_TOP_U2U3_REF 72
+#define CK_TOP_U2U3_SYS 73
+#define CK_TOP_U2U3_XHCI 74
+#define CK_TOP_USB_FRMCNT 75
+#define CK_TOP_NFI1X_SEL 76
+#define CK_TOP_SPINFI_SEL 77
+#define CK_TOP_SPI_SEL 78
+#define CK_TOP_SPIM_MST_SEL 79
+#define CK_TOP_UART_SEL 80
+#define CK_TOP_PWM_SEL 81
+#define CK_TOP_I2C_SEL 82
+#define CK_TOP_PEXTP_TL_SEL 83
+#define CK_TOP_EMMC_208M_SEL 84
+#define CK_TOP_EMMC_400M_SEL 85
+#define CK_TOP_F26M_SEL 86
+#define CK_TOP_DRAMC_SEL 87
+#define CK_TOP_DRAMC_MD32_SEL 88
+#define CK_TOP_SYSAXI_SEL 89
+#define CK_TOP_SYSAPB_SEL 90
+#define CK_TOP_ARM_DB_MAIN_SEL 91
+#define CK_TOP_AP2CNN_HOST_SEL 92
+#define CK_TOP_NETSYS_SEL 93
+#define CK_TOP_NETSYS_500M_SEL 94
+#define CK_TOP_NETSYS_MCU_SEL 95
+#define CK_TOP_NETSYS_2X_SEL 96
+#define CK_TOP_SGM_325M_SEL 97
+#define CK_TOP_SGM_REG_SEL 98
+#define CK_TOP_EIP97B_SEL 99
+#define CK_TOP_USB3_PHY_SEL 100
+#define CK_TOP_AUD_SEL 101
+#define CK_TOP_A1SYS_SEL 102
+#define CK_TOP_AUD_L_SEL 103
+#define CK_TOP_A_TUNER_SEL 104
+#define CK_TOP_U2U3_SEL 105
+#define CK_TOP_U2U3_SYS_SEL 106
+#define CK_TOP_U2U3_XHCI_SEL 107
+#define CK_TOP_USB_FRMCNT_SEL 108
+#define CLK_TOP_NR_CLK 109
+
+/*
+ * INFRACFG_AO
+ * clock muxes need to be append to infracfg domain, and clock gates
+ * need to be keep in infracgh_ao domain
+ */
+#define INFRACFG_AO_OFFSET 10
+
+#define CK_INFRA_UART0_SEL (0 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_UART1_SEL (1 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_UART2_SEL (2 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_SPI0_SEL (3 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_SPI1_SEL (4 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_SPI2_SEL (5 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_PWM1_SEL (6 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_PWM2_SEL (7 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_PWM_BSEL (8 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_PCIE_SEL (9 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_GPT_STA (10 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_PWM_HCK (11 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_PWM_STA (12 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_PWM1_CK (13 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_PWM2_CK (14 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_CQ_DMA_CK (15 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_AUD_BUS_CK (16 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_AUD_26M_CK (17 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_AUD_L_CK (18 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_AUD_AUD_CK (19 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_AUD_EG2_CK (20 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_DRAMC_26M_CK (21 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_DBG_CK (22 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_AP_DMA_CK (23 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_SEJ_CK (24 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_SEJ_13M_CK (25 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_THERM_CK (26 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_I2CO_CK (27 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_UART0_CK (28 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_UART1_CK (29 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_UART2_CK (30 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_SPI2_CK (31 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_SPI2_HCK_CK (32 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_NFI1_CK (33 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_SPINFI1_CK (34 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_NFI_HCK_CK (35 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_SPI0_CK (36 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_SPI1_CK (37 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_SPI0_HCK_CK (38 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_SPI1_HCK_CK (39 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_FRTC_CK (40 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_MSDC_CK (41 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_MSDC_HCK_CK (42 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_MSDC_133M_CK (43 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_MSDC_66M_CK (44 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_ADC_26M_CK (45 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_ADC_FRC_CK (46 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_FBIST2FPC_CK (47 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_I2C_MCK_CK (48 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_I2C_PCK_CK (49 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_IUSB_133_CK (50 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_IUSB_66M_CK (51 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_IUSB_SYS_CK (52 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_IUSB_CK (53 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_IPCIE_CK (54 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_IPCIER_CK (55 - INFRACFG_AO_OFFSET)
+#define CK_INFRA_IPCIEB_CK (56 - INFRACFG_AO_OFFSET)
+#define CLK_INFRA_AO_NR_CLK (57 - INFRACFG_AO_OFFSET)
+
+/* APMIXEDSYS */
+
+#define CK_APMIXED_ARMPLL 0
+#define CK_APMIXED_NET2PLL 1
+#define CK_APMIXED_MMPLL 2
+#define CK_APMIXED_SGMPLL 3
+#define CK_APMIXED_WEDMCUPLL 4
+#define CK_APMIXED_NET1PLL 5
+#define CK_APMIXED_MPLL 6
+#define CK_APMIXED_APLL2 7
+#define CLK_APMIXED_NR_CLK 8
+
+/* SGMIISYS_0 */
+
+#define CK_SGM0_TX_EN 0
+#define CK_SGM0_RX_EN 1
+#define CK_SGM0_CK0_EN 2
+#define CK_SGM0_CDR_CK0_EN 3
+#define CLK_SGMII0_NR_CLK 4
+
+/* SGMIISYS_1 */
+
+#define CK_SGM1_TX_EN 0
+#define CK_SGM1_RX_EN 1
+#define CK_SGM1_CK1_EN 2
+#define CK_SGM1_CDR_CK1_EN 3
+#define CLK_SGMII1_NR_CLK 4
+
+/* ETHSYS */
+
+#define CK_ETH_FE_EN 0
+#define CK_ETH_GP2_EN 1
+#define CK_ETH_GP1_EN 2
+#define CK_ETH_WOCPU0_EN 3
+#define CLK_ETH_NR_CLK 4
+
+#endif /* _DT_BINDINGS_CLK_MT7981_H */
diff --git a/include/dt-bindings/clock/mt7986-clk.h b/include/dt-bindings/clock/mt7986-clk.h
new file mode 100644
index 0000000..820f863
--- /dev/null
+++ b/include/dt-bindings/clock/mt7986-clk.h
@@ -0,0 +1,249 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2022 MediaTek Inc. All rights reserved.
+ *
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_MT7986_H
+#define _DT_BINDINGS_CLK_MT7986_H
+
+/* INFRACFG */
+
+#define CK_INFRA_CK_F26M 0
+#define CK_INFRA_UART 1
+#define CK_INFRA_ISPI0 2
+#define CK_INFRA_I2C 3
+#define CK_INFRA_ISPI1 4
+#define CK_INFRA_PWM 5
+#define CK_INFRA_66M_MCK 6
+#define CK_INFRA_CK_F32K 7
+#define CK_INFRA_PCIE_CK 8
+#define CK_INFRA_PWM_BCK 9
+#define CK_INFRA_PWM_CK1 10
+#define CK_INFRA_PWM_CK2 11
+#define CK_INFRA_133M_HCK 12
+#define CK_INFRA_EIP_CK 13
+#define CK_INFRA_66M_PHCK 14
+#define CK_INFRA_FAUD_L_CK 15
+#define CK_INFRA_FAUD_AUD_CK 17
+#define CK_INFRA_FAUD_EG2_CK 17
+#define CK_INFRA_I2CS_CK 18
+#define CK_INFRA_MUX_UART0 19
+#define CK_INFRA_MUX_UART1 20
+#define CK_INFRA_MUX_UART2 21
+#define CK_INFRA_NFI_CK 22
+#define CK_INFRA_SPINFI_CK 23
+#define CK_INFRA_MUX_SPI0 24
+#define CK_INFRA_MUX_SPI1 25
+#define CK_INFRA_RTC_32K 26
+#define CK_INFRA_FMSDC_CK 27
+#define CK_INFRA_FMSDC_HCK_CK 28
+#define CK_INFRA_PERI_133M 29
+#define CK_INFRA_133M_PHCK 30
+#define CK_INFRA_USB_SYS_CK 31
+#define CK_INFRA_USB_CK 32
+#define CK_INFRA_USB_XHCI_CK 33
+#define CK_INFRA_PCIE_GFMUX_TL_O_PRE 34
+#define CK_INFRA_F26M_CK0 35
+#define CK_INFRA_HD_133M 36
+#define CLK_INFRA_NR_CLK 37
+
+/* TOPCKGEN */
+
+#define CK_TOP_CB_CKSQ_40M 0
+#define CK_TOP_CB_M_416M 1
+#define CK_TOP_CB_M_D2 2
+#define CK_TOP_CB_M_D4 3
+#define CK_TOP_CB_M_D8 4
+#define CK_TOP_M_D8_D2 5
+#define CK_TOP_M_D3_D2 6
+#define CK_TOP_CB_MM_D2 7
+#define CK_TOP_CB_MM_D4 8
+#define CK_TOP_CB_MM_D8 9
+#define CK_TOP_MM_D8_D2 10
+#define CK_TOP_MM_D3_D8 11
+#define CK_TOP_CB_U2_PHYD_CK 12
+#define CK_TOP_CB_APLL2_196M 13
+#define CK_TOP_APLL2_D4 14
+#define CK_TOP_CB_NET1_D4 15
+#define CK_TOP_CB_NET1_D5 16
+#define CK_TOP_NET1_D5_D2 17
+#define CK_TOP_NET1_D5_D4 18
+#define CK_TOP_NET1_D8_D2 19
+#define CK_TOP_NET1_D8_D4 20
+#define CK_TOP_CB_NET2_800M 21
+#define CK_TOP_CB_NET2_D4 22
+#define CK_TOP_NET2_D4_D2 23
+#define CK_TOP_NET2_D3_D2 24
+#define CK_TOP_CB_WEDMCU_760M 25
+#define CK_TOP_WEDMCU_D5_D2 26
+#define CK_TOP_CB_SGM_325M 27
+#define CK_TOP_CB_CKSQ_40M_D2 28
+#define CK_TOP_CB_RTC_32K 29
+#define CK_TOP_CB_RTC_32P7K 30
+#define CK_TOP_NFI1X 31
+#define CK_TOP_USB_EQ_RX250M 32
+#define CK_TOP_USB_TX250M 33
+#define CK_TOP_USB_LN0_CK 34
+#define CK_TOP_USB_CDR_CK 35
+#define CK_TOP_SPINFI_BCK 36
+#define CK_TOP_I2C_BCK 37
+#define CK_TOP_PEXTP_TL 38
+#define CK_TOP_EMMC_250M 39
+#define CK_TOP_EMMC_416M 40
+#define CK_TOP_F_26M_ADC_CK 41
+#define CK_TOP_SYSAXI 42
+#define CK_TOP_NETSYS_WED_MCU 43
+#define CK_TOP_NETSYS_2X 44
+#define CK_TOP_SGM_325M 45
+#define CK_TOP_A1SYS 46
+#define CK_TOP_EIP_B 47
+#define CK_TOP_F26M 48
+#define CK_TOP_AUD_L 49
+#define CK_TOP_A_TUNER 50
+#define CK_TOP_U2U3_REF 51
+#define CK_TOP_U2U3_SYS 52
+#define CK_TOP_U2U3_XHCI 53
+#define CK_TOP_AP2CNN_HOST 54
+#define CK_TOP_NFI1X_SEL 55
+#define CK_TOP_SPINFI_SEL 56
+#define CK_TOP_SPI_SEL 57
+#define CK_TOP_SPIM_MST_SEL 58
+#define CK_TOP_UART_SEL 59
+#define CK_TOP_PWM_SEL 60
+#define CK_TOP_I2C_SEL 61
+#define CK_TOP_PEXTP_TL_SEL 62
+#define CK_TOP_EMMC_250M_SEL 63
+#define CK_TOP_EMMC_416M_SEL 64
+#define CK_TOP_F_26M_ADC_SEL 65
+#define CK_TOP_DRAMC_SEL 66
+#define CK_TOP_DRAMC_MD32_SEL 67
+#define CK_TOP_SYSAXI_SEL 68
+#define CK_TOP_SYSAPB_SEL 69
+#define CK_TOP_ARM_DB_MAIN_SEL 70
+#define CK_TOP_ARM_DB_JTSEL 71
+#define CK_TOP_NETSYS_SEL 72
+#define CK_TOP_NETSYS_500M_SEL 73
+#define CK_TOP_NETSYS_MCU_SEL 74
+#define CK_TOP_NETSYS_2X_SEL 75
+#define CK_TOP_SGM_325M_SEL 76
+#define CK_TOP_SGM_REG_SEL 77
+#define CK_TOP_A1SYS_SEL 78
+#define CK_TOP_CONN_MCUSYS_SEL 79
+#define CK_TOP_EIP_B_SEL 80
+#define CK_TOP_PCIE_PHY_SEL 81
+#define CK_TOP_USB3_PHY_SEL 82
+#define CK_TOP_F26M_SEL 83
+#define CK_TOP_AUD_L_SEL 84
+#define CK_TOP_A_TUNER_SEL 85
+#define CK_TOP_U2U3_SEL 86
+#define CK_TOP_U2U3_SYS_SEL 87
+#define CK_TOP_U2U3_XHCI_SEL 88
+#define CK_TOP_DA_U2_REFSEL 89
+#define CK_TOP_DA_U2_CK_1P_SEL 90
+#define CK_TOP_AP2CNN_HOST_SEL 91
+#define CLK_TOP_NR_CLK 92
+
+/*
+ * INFRACFG_AO
+ * clock muxes need to be append to infracfg domain, and clock gates
+ * need to be keep in infracgh_ao domain
+ */
+
+#define CK_INFRA_UART0_SEL (0 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_UART1_SEL (1 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_UART2_SEL (2 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_SPI0_SEL (3 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_SPI1_SEL (4 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_PWM1_SEL (5 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_PWM2_SEL (6 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_PWM_BSEL (7 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_PCIE_SEL (8 + CLK_INFRA_NR_CLK)
+#define CK_INFRA_GPT_STA 0
+#define CK_INFRA_PWM_HCK 1
+#define CK_INFRA_PWM_STA 2
+#define CK_INFRA_PWM1_CK 3
+#define CK_INFRA_PWM2_CK 4
+#define CK_INFRA_CQ_DMA_CK 5
+#define CK_INFRA_EIP97_CK 6
+#define CK_INFRA_AUD_BUS_CK 7
+#define CK_INFRA_AUD_26M_CK 8
+#define CK_INFRA_AUD_L_CK 9
+#define CK_INFRA_AUD_AUD_CK 10
+#define CK_INFRA_AUD_EG2_CK 11
+#define CK_INFRA_DRAMC_26M_CK 12
+#define CK_INFRA_DBG_CK 13
+#define CK_INFRA_AP_DMA_CK 14
+#define CK_INFRA_SEJ_CK 15
+#define CK_INFRA_SEJ_13M_CK 16
+#define CK_INFRA_THERM_CK 17
+#define CK_INFRA_I2CO_CK 18
+#define CK_INFRA_TRNG_CK 19
+#define CK_INFRA_UART0_CK 20
+#define CK_INFRA_UART1_CK 21
+#define CK_INFRA_UART2_CK 22
+#define CK_INFRA_NFI1_CK 23
+#define CK_INFRA_SPINFI1_CK 24
+#define CK_INFRA_NFI_HCK_CK 25
+#define CK_INFRA_SPI0_CK 26
+#define CK_INFRA_SPI1_CK 27
+#define CK_INFRA_SPI0_HCK_CK 28
+#define CK_INFRA_SPI1_HCK_CK 29
+#define CK_INFRA_FRTC_CK 30
+#define CK_INFRA_MSDC_CK 31
+#define CK_INFRA_MSDC_HCK_CK 32
+#define CK_INFRA_MSDC_133M_CK 33
+#define CK_INFRA_MSDC_66M_CK 34
+#define CK_INFRA_ADC_26M_CK 35
+#define CK_INFRA_ADC_FRC_CK 36
+#define CK_INFRA_FBIST2FPC_CK 37
+#define CK_INFRA_IUSB_133_CK 38
+#define CK_INFRA_IUSB_66M_CK 39
+#define CK_INFRA_IUSB_SYS_CK 40
+#define CK_INFRA_IUSB_CK 41
+#define CK_INFRA_IPCIE_CK 42
+#define CK_INFRA_IPCIER_CK 43
+#define CK_INFRA_IPCIEB_CK 44
+#define CLK_INFRA_AO_NR_CLK 45
+
+/* APMIXEDSYS */
+
+#define CK_APMIXED_ARMPLL 0
+#define CK_APMIXED_NET2PLL 1
+#define CK_APMIXED_MMPLL 2
+#define CK_APMIXED_SGMPLL 3
+#define CK_APMIXED_WEDMCUPLL 4
+#define CK_APMIXED_NET1PLL 5
+#define CK_APMIXED_MPLL 6
+#define CK_APMIXED_APLL2 7
+#define CLK_APMIXED_NR_CLK 8
+
+/* SGMIISYS_0 */
+
+#define CK_SGM0_TX_EN 0
+#define CK_SGM0_RX_EN 1
+#define CK_SGM0_CK0_EN 2
+#define CK_SGM0_CDR_CK0_EN 3
+#define CLK_SGMII0_NR_CLK 4
+
+/* SGMIISYS_1 */
+
+#define CK_SGM1_TX_EN 0
+#define CK_SGM1_RX_EN 1
+#define CK_SGM1_CK1_EN 2
+#define CK_SGM1_CDR_CK1_EN 3
+#define CLK_SGMII1_NR_CLK 4
+
+/* ETHSYS */
+
+#define CK_ETH_FE_EN 0
+#define CK_ETH_GP2_EN 1
+#define CK_ETH_GP1_EN 2
+#define CK_ETH_WOCPU1_EN 3
+#define CK_ETH_WOCPU0_EN 4
+#define CLK_ETH_NR_CLK 5
+
+#endif
+
+/* _DT_BINDINGS_CLK_MT7986_H */
diff --git a/include/dt-bindings/pinctrl/mt65xx.h b/include/dt-bindings/pinctrl/mt65xx.h
new file mode 100644
index 0000000..fbea8d3
--- /dev/null
+++ b/include/dt-bindings/pinctrl/mt65xx.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Hongzhou.Yang <hongzhou.yang@mediatek.com>
+ */
+
+#ifndef _DT_BINDINGS_PINCTRL_MT65XX_H
+#define _DT_BINDINGS_PINCTRL_MT65XX_H
+
+#define MTK_PIN_NO(x) ((x) << 8)
+#define MTK_GET_PIN_NO(x) ((x) >> 8)
+#define MTK_GET_PIN_FUNC(x) ((x) & 0xf)
+
+#define MTK_PUPD_SET_R1R0_00 100
+#define MTK_PUPD_SET_R1R0_01 101
+#define MTK_PUPD_SET_R1R0_10 102
+#define MTK_PUPD_SET_R1R0_11 103
+
+#define MTK_PULL_SET_RSEL_000 200
+#define MTK_PULL_SET_RSEL_001 201
+#define MTK_PULL_SET_RSEL_010 202
+#define MTK_PULL_SET_RSEL_011 203
+#define MTK_PULL_SET_RSEL_100 204
+#define MTK_PULL_SET_RSEL_101 205
+#define MTK_PULL_SET_RSEL_110 206
+#define MTK_PULL_SET_RSEL_111 207
+
+#define MTK_DRIVE_2mA 2
+#define MTK_DRIVE_4mA 4
+#define MTK_DRIVE_6mA 6
+#define MTK_DRIVE_8mA 8
+#define MTK_DRIVE_10mA 10
+#define MTK_DRIVE_12mA 12
+#define MTK_DRIVE_14mA 14
+#define MTK_DRIVE_16mA 16
+#define MTK_DRIVE_20mA 20
+#define MTK_DRIVE_24mA 24
+#define MTK_DRIVE_28mA 28
+#define MTK_DRIVE_32mA 32
+
+#endif /* _DT_BINDINGS_PINCTRL_MT65XX_H */
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 7554f3b..ad01395 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -161,7 +161,7 @@
/* EFI system partition */
extern struct efi_system_partition {
- enum uclass_id if_type;
+ enum uclass_id uclass_id;
int devnum;
u8 part;
} efi_system_partition;
@@ -562,7 +562,7 @@
struct efi_loaded_image *loaded_image_info);
/* Create handles and protocols for the partitions of a block device */
int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc,
- const char *if_typename, int diskid,
+ const char *uclass_idname, int diskid,
const char *pdevname);
/* Called by bootefi to make GOP (graphical) interface available */
efi_status_t efi_gop_register(void);
diff --git a/include/init.h b/include/init.h
index 02bb4ce..50a8302 100644
--- a/include/init.h
+++ b/include/init.h
@@ -291,7 +291,7 @@
*
* @param total_size Size of U-Boot (unused?)
*/
-ulong board_get_usable_ram_top(ulong total_size);
+phys_size_t board_get_usable_ram_top(phys_size_t total_size);
int board_early_init_f(void);
diff --git a/include/os.h b/include/os.h
index 1481787..5b353ae 100644
--- a/include/os.h
+++ b/include/os.h
@@ -296,6 +296,14 @@
void os_puts(const char *str);
/**
+ * os_flush() - flush controlling OS terminal
+ *
+ * This bypasses the U-Boot console support and flushes directly the OS
+ * stdout file descriptor.
+ */
+void os_flush(void);
+
+/**
* os_write_ram_buf() - write the sandbox RAM buffer to a existing file
*
* @fname: filename to write memory to (simple binary format)
diff --git a/include/scsi.h b/include/scsi.h
index b47c746..94e1d8c 100644
--- a/include/scsi.h
+++ b/include/scsi.h
@@ -15,27 +15,47 @@
struct udevice;
+/**
+ * struct scsi_cmd - information about a SCSI command to be processed
+ *
+ * @cmd: command
+ * @sense_buf: for request sense
+ * @status: SCSI Status
+ * @target: Target ID
+ * @lun: Target LUN
+ * @cmdlen: command len
+ * @datalen: Total data length
+ * @pdata: pointer to data
+ * @msgout: Messge out buffer (NOT USED)
+ * @msgin: Message in buffer
+ * @sensecmdlen: Sense command len
+ * @sensedatalen: Sense data len
+ * @sensecmd: Sense command
+ * @contr_stat: Controller Status
+ * @trans_bytes: tranfered bytes
+ * @priv: Private value
+ * @dma_dir: Direction of data structure
+ */
struct scsi_cmd {
- unsigned char cmd[16]; /* command */
- /* for request sense */
- unsigned char sense_buf[64]
+ unsigned char cmd[16];
+ unsigned char sense_buf[64]
__attribute__((aligned(ARCH_DMA_MINALIGN)));
- unsigned char status; /* SCSI Status */
- unsigned char target; /* Target ID */
- unsigned char lun; /* Target LUN */
- unsigned char cmdlen; /* command len */
- unsigned long datalen; /* Total data length */
- unsigned char * pdata; /* pointer to data */
- unsigned char msgout[12]; /* Messge out buffer (NOT USED) */
- unsigned char msgin[12]; /* Message in buffer */
- unsigned char sensecmdlen; /* Sense command len */
- unsigned long sensedatalen; /* Sense data len */
- unsigned char sensecmd[6]; /* Sense command */
- unsigned long contr_stat; /* Controller Status */
- unsigned long trans_bytes; /* tranfered bytes */
+ unsigned char status;
+ unsigned char target;
+ unsigned char lun;
+ unsigned char cmdlen;
+ unsigned long datalen;
+ unsigned char *pdata;
+ unsigned char msgout[12];
+ unsigned char msgin[12];
+ unsigned char sensecmdlen;
+ unsigned long sensedatalen;
+ unsigned char sensecmd[6];
+ unsigned long contr_stat;
+ unsigned long trans_bytes;
- unsigned int priv;
- enum dma_data_direction dma_dir;
+ unsigned int priv;
+ enum dma_data_direction dma_dir;
};
/*-----------------------------------------------------------
@@ -168,6 +188,74 @@
#define SCSI_WRITE_SAME 0x41 /* Write Same (O) */
/**
+ * enum scsi_cmd_phase - current phase of the SCSI protocol
+ *
+ * @SCSIPH_START: Start phase
+ * @SCSIPH_DATA: Data phase
+ * @SCSIPH_STATUS: Status phase
+ */
+enum scsi_cmd_phase {
+ SCSIPH_START,
+ SCSIPH_DATA,
+ SCSIPH_STATUS,
+};
+
+/**
+ * struct scsi_inquiry_resp - holds a SCSI inquiry command
+ *
+ * @type; command type
+ * @flags; command flags
+ * @version; command version
+ * @data_format; data format
+ * @additional_len; additional data length
+ * @spare[3]; spare bytes
+ * @vendor[8]; vendor information
+ * @product[16]; production information
+ * @revision[4]; revision information
+ */
+struct scsi_inquiry_resp {
+ u8 type;
+ u8 flags;
+ u8 version;
+ u8 data_format;
+ u8 additional_len;
+ u8 spare[3];
+ char vendor[8];
+ char product[16];
+ char revision[4];
+};
+
+/**
+ * struct scsi_read_capacity_resp - holds the response to a read-capacity cmd
+ *
+ * @last_block_addr: Logical block address of last block
+ * @block_len: Length of each block in bytes
+ */
+struct scsi_read_capacity_resp {
+ u32 last_block_addr;
+ u32 block_len;
+};
+
+/**
+ * struct scsi_read10_req - holds a SCSI READ10 request
+ *
+ * @cmd; command type
+ * @lun_flags; LUN flags
+ * @lba; Logical block address to start reading from
+ * @spare; spare bytes
+ * @xfer_len: number of blocks to read
+ * @spare2: more spare bytes
+ */
+struct __packed scsi_read10_req {
+ u8 cmd;
+ u8 lun_flags;
+ u32 lba;
+ u8 spare;
+ u16 xfer_len;
+ u8 spare2[3];
+};
+
+/**
* struct scsi_plat - stores information about SCSI controller
*
* @base: Controller base address
diff --git a/include/scsi_emul.h b/include/scsi_emul.h
new file mode 100644
index 0000000..13c3f86
--- /dev/null
+++ b/include/scsi_emul.h
@@ -0,0 +1,70 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Emulation of enough SCSI commands to find and read from a unit
+ *
+ * Copyright 2022 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * implementations of SCSI functions required so that CONFIG_SCSI can be enabled
+ * for sandbox
+ */
+
+#ifndef __scsi_emul_h
+#define __scsi_emul_h
+
+/**
+ * struct scsi_emul_info - information for emulating a SCSI device
+ *
+ * @vendor: Vendor name
+ * @product: Product name
+ * @block_size: Block size of device in bytes (normally 512)
+ * @file_size: Size of the backing file for this emulator, in bytes
+ * @seek_block: Seek position for file (block number)
+ *
+ * @phase: Current SCSI phase
+ * @buff_used: Number of bytes ready to transfer back to host
+ * @read_len: Number of bytes of data left in the current read command
+ * @alloc_len: Allocation length from the last incoming command
+ * @transfer_len: Transfer length from CBW header
+ * @buff: Data buffer for outgoing data
+ */
+struct scsi_emul_info {
+ /* provided by the caller: */
+ void *buff;
+ const char *vendor;
+ const char *product;
+ int block_size;
+ loff_t file_size;
+ int seek_block;
+
+ /* state maintained by the emulator: */
+ enum scsi_cmd_phase phase;
+ int buff_used;
+ int read_len;
+ uint seek_pos;
+ int alloc_len;
+ uint transfer_len;
+};
+
+/* Indicates that a read is being started */
+#define SCSI_EMUL_DO_READ 1
+
+/**
+ * sb_scsi_emul_command() - Process a SCSI command
+ *
+ * This sets up the response in info->buff and updates various other values
+ * in info.
+ *
+ * If SCSI_EMUL_DO_READ is returned then the caller should set up so that the
+ * backing file can be read, or return an error status if there is no file.
+ *
+ * @info: Emulation information
+ * @req: Request to process
+ * @len: Length of request in bytes
+ * @return SCSI_EMUL_DO_READ if a read has started, 0 if some other operation
+ * has started, -ve if there was an error
+ */
+int sb_scsi_emul_command(struct scsi_emul_info *info,
+ const struct scsi_cmd *req, int len);
+
+#endif
diff --git a/include/serial.h b/include/serial.h
index 8c2e7ad..fe01bcf 100644
--- a/include/serial.h
+++ b/include/serial.h
@@ -362,6 +362,11 @@
void serial_putc(const char ch);
void serial_putc_raw(const char ch);
void serial_puts(const char *str);
+#if defined(CONFIG_CONSOLE_FLUSH_SUPPORT) && CONFIG_IS_ENABLED(DM_SERIAL)
+void serial_flush(void);
+#else
+static inline void serial_flush(void) {}
+#endif
int serial_getc(void);
int serial_tstc(void);
diff --git a/include/stdio.h b/include/stdio.h
index 1939a48..3241e2d 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -15,6 +15,11 @@
defined(CONFIG_SPL_SERIAL))
void putc(const char c);
void puts(const char *s);
+#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
+void flush(void);
+#else
+static inline void flush(void) {}
+#endif
int __printf(1, 2) printf(const char *fmt, ...);
int vprintf(const char *fmt, va_list args);
#else
@@ -26,6 +31,10 @@
{
}
+static inline void flush(void)
+{
+}
+
static inline int __printf(1, 2) printf(const char *fmt, ...)
{
return 0;
@@ -48,11 +57,17 @@
/* stderr */
#define eputc(c) fputc(stderr, c)
#define eputs(s) fputs(stderr, s)
+#define eflush() fflush(stderr)
#define eprintf(fmt, args...) fprintf(stderr, fmt, ##args)
int __printf(2, 3) fprintf(int file, const char *fmt, ...);
void fputs(int file, const char *s);
void fputc(int file, const char c);
+#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
+void fflush(int file);
+#else
+static inline void fflush(int file) {}
+#endif
int ftstc(int file);
int fgetc(int file);
diff --git a/include/stdio_dev.h b/include/stdio_dev.h
index 270fa27..3105928 100644
--- a/include/stdio_dev.h
+++ b/include/stdio_dev.h
@@ -37,6 +37,13 @@
void (*putc)(struct stdio_dev *dev, const char c);
/* To put a string (accelerator) */
void (*puts)(struct stdio_dev *dev, const char *s);
+#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
+ /* To flush output queue */
+ void (*flush)(struct stdio_dev *dev);
+#define STDIO_DEV_ASSIGN_FLUSH(dev, flush_func) ((dev)->flush = (flush_func))
+#else
+#define STDIO_DEV_ASSIGN_FLUSH(dev, flush_func)
+#endif
/* INPUT functions */
diff --git a/include/usb/designware_udc.h b/include/usb/designware_udc.h
deleted file mode 100644
index f716f07..0000000
--- a/include/usb/designware_udc.h
+++ /dev/null
@@ -1,183 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * (C) Copyright 2009
- * Vipin Kumar, STMicroelectronics, vipin.kumar@st.com.
- */
-
-#ifndef __DW_UDC_H
-#define __DW_UDC_H
-
-/*
- * Defines for USBD
- *
- * The udc_ahb controller has three AHB slaves:
- *
- * 1. THe UDC registers
- * 2. The plug detect
- * 3. The RX/TX FIFO
- */
-
-#define MAX_ENDPOINTS 16
-
-struct udc_endp_regs {
- u32 endp_cntl;
- u32 endp_status;
- u32 endp_bsorfn;
- u32 endp_maxpacksize;
- u32 reserved_1;
- u32 endp_desc_point;
- u32 reserved_2;
- u32 write_done;
-};
-
-/* Endpoint Control Register definitions */
-
-#define ENDP_CNTL_STALL 0x00000001
-#define ENDP_CNTL_FLUSH 0x00000002
-#define ENDP_CNTL_SNOOP 0x00000004
-#define ENDP_CNTL_POLL 0x00000008
-#define ENDP_CNTL_CONTROL 0x00000000
-#define ENDP_CNTL_ISO 0x00000010
-#define ENDP_CNTL_BULK 0x00000020
-#define ENDP_CNTL_INT 0x00000030
-#define ENDP_CNTL_NAK 0x00000040
-#define ENDP_CNTL_SNAK 0x00000080
-#define ENDP_CNTL_CNAK 0x00000100
-#define ENDP_CNTL_RRDY 0x00000200
-
-/* Endpoint Satus Register definitions */
-
-#define ENDP_STATUS_PIDMSK 0x0000000f
-#define ENDP_STATUS_OUTMSK 0x00000030
-#define ENDP_STATUS_OUT_NONE 0x00000000
-#define ENDP_STATUS_OUT_DATA 0x00000010
-#define ENDP_STATUS_OUT_SETUP 0x00000020
-#define ENDP_STATUS_IN 0x00000040
-#define ENDP_STATUS_BUFFNAV 0x00000080
-#define ENDP_STATUS_FATERR 0x00000100
-#define ENDP_STATUS_HOSTBUSERR 0x00000200
-#define ENDP_STATUS_TDC 0x00000400
-#define ENDP_STATUS_RXPKTMSK 0x003ff800
-
-struct udc_regs {
- struct udc_endp_regs in_regs[MAX_ENDPOINTS];
- struct udc_endp_regs out_regs[MAX_ENDPOINTS];
- u32 dev_conf;
- u32 dev_cntl;
- u32 dev_stat;
- u32 dev_int;
- u32 dev_int_mask;
- u32 endp_int;
- u32 endp_int_mask;
- u32 reserved_3[0x39];
- u32 reserved_4; /* offset 0x500 */
- u32 udc_endp_reg[MAX_ENDPOINTS];
-};
-
-/* Device Configuration Register definitions */
-
-#define DEV_CONF_HS_SPEED 0x00000000
-#define DEV_CONF_LS_SPEED 0x00000002
-#define DEV_CONF_FS_SPEED 0x00000003
-#define DEV_CONF_REMWAKEUP 0x00000004
-#define DEV_CONF_SELFPOW 0x00000008
-#define DEV_CONF_SYNCFRAME 0x00000010
-#define DEV_CONF_PHYINT_8 0x00000020
-#define DEV_CONF_PHYINT_16 0x00000000
-#define DEV_CONF_UTMI_BIDIR 0x00000040
-#define DEV_CONF_STATUS_STALL 0x00000080
-
-/* Device Control Register definitions */
-
-#define DEV_CNTL_RESUME 0x00000001
-#define DEV_CNTL_TFFLUSH 0x00000002
-#define DEV_CNTL_RXDMAEN 0x00000004
-#define DEV_CNTL_TXDMAEN 0x00000008
-#define DEV_CNTL_DESCRUPD 0x00000010
-#define DEV_CNTL_BIGEND 0x00000020
-#define DEV_CNTL_BUFFILL 0x00000040
-#define DEV_CNTL_TSHLDEN 0x00000080
-#define DEV_CNTL_BURSTEN 0x00000100
-#define DEV_CNTL_DMAMODE 0x00000200
-#define DEV_CNTL_SOFTDISCONNECT 0x00000400
-#define DEV_CNTL_SCALEDOWN 0x00000800
-#define DEV_CNTL_BURSTLENU 0x00010000
-#define DEV_CNTL_BURSTLENMSK 0x00ff0000
-#define DEV_CNTL_TSHLDLENU 0x01000000
-#define DEV_CNTL_TSHLDLENMSK 0xff000000
-
-/* Device Status Register definitions */
-
-#define DEV_STAT_CFG 0x0000000f
-#define DEV_STAT_INTF 0x000000f0
-#define DEV_STAT_ALT 0x00000f00
-#define DEV_STAT_SUSP 0x00001000
-#define DEV_STAT_ENUM 0x00006000
-#define DEV_STAT_ENUM_SPEED_HS 0x00000000
-#define DEV_STAT_ENUM_SPEED_FS 0x00002000
-#define DEV_STAT_ENUM_SPEED_LS 0x00004000
-#define DEV_STAT_RXFIFO_EMPTY 0x00008000
-#define DEV_STAT_PHY_ERR 0x00010000
-#define DEV_STAT_TS 0xf0000000
-
-/* Device Interrupt Register definitions */
-
-#define DEV_INT_MSK 0x0000007f
-#define DEV_INT_SETCFG 0x00000001
-#define DEV_INT_SETINTF 0x00000002
-#define DEV_INT_INACTIVE 0x00000004
-#define DEV_INT_USBRESET 0x00000008
-#define DEV_INT_SUSPUSB 0x00000010
-#define DEV_INT_SOF 0x00000020
-#define DEV_INT_ENUM 0x00000040
-
-/* Endpoint Interrupt Register definitions */
-
-#define ENDP0_INT_CTRLIN 0x00000001
-#define ENDP1_INT_BULKIN 0x00000002
-#define ENDP_INT_NONISOIN_MSK 0x0000AAAA
-#define ENDP2_INT_BULKIN 0x00000004
-#define ENDP0_INT_CTRLOUT 0x00010000
-#define ENDP1_INT_BULKOUT 0x00020000
-#define ENDP2_INT_BULKOUT 0x00040000
-#define ENDP_INT_NONISOOUT_MSK 0x55540000
-
-/* Endpoint Register definitions */
-#define ENDP_EPDIR_OUT 0x00000000
-#define ENDP_EPDIR_IN 0x00000010
-#define ENDP_EPTYPE_CNTL 0x0
-#define ENDP_EPTYPE_ISO 0x1
-#define ENDP_EPTYPE_BULK 0x2
-#define ENDP_EPTYPE_INT 0x3
-
-/*
- * Defines for Plug Detect
- */
-
-struct plug_regs {
- u32 plug_state;
- u32 plug_pending;
-};
-
-/* Plug State Register definitions */
-#define PLUG_STATUS_EN 0x1
-#define PLUG_STATUS_ATTACHED 0x2
-#define PLUG_STATUS_PHY_RESET 0x4
-#define PLUG_STATUS_PHY_MODE 0x8
-
-/*
- * Defines for UDC FIFO (Slave Mode)
- */
-struct udcfifo_regs {
- u32 *fifo_p;
-};
-
-/*
- * UDC endpoint definitions
- */
-#define UDC_EP0 0
-#define UDC_EP1 1
-#define UDC_EP2 2
-#define UDC_EP3 3
-
-#endif /* __DW_UDC_H */
diff --git a/lib/display_options.c b/lib/display_options.c
index 7feb446..80def52 100644
--- a/lib/display_options.c
+++ b/lib/display_options.c
@@ -127,6 +127,12 @@
if (m >= 10) {
m -= 10;
n += 1;
+
+ if (n == 1024 && i > 0) {
+ n = 1;
+ m = 0;
+ c = names[i - 1];
+ }
}
}
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
index e39968a..39ea1a6 100644
--- a/lib/efi_loader/efi_disk.c
+++ b/lib/efi_loader/efi_disk.c
@@ -498,13 +498,13 @@
diskobj->media.last_block);
/* Store first EFI system partition */
- if (part && !efi_system_partition.if_type) {
+ if (part && !efi_system_partition.uclass_id) {
if (part_info->bootable & PART_EFI_SYSTEM_PARTITION) {
- efi_system_partition.if_type = desc->if_type;
+ efi_system_partition.uclass_id = desc->uclass_id;
efi_system_partition.devnum = desc->devnum;
efi_system_partition.part = part;
EFI_PRINT("EFI system partition: %s %x:%x\n",
- blk_get_if_type_name(desc->if_type),
+ blk_get_uclass_name(desc->uclass_id),
desc->devnum, part);
}
}
@@ -640,7 +640,7 @@
* has already created an efi_disk at this moment.
*/
desc = dev_get_uclass_plat(dev);
- if (desc->if_type != UCLASS_EFI_LOADER) {
+ if (desc->uclass_id != UCLASS_EFI_LOADER) {
ret = efi_disk_create_raw(dev);
if (ret)
return -1;
@@ -675,7 +675,7 @@
return -1;
desc = dev_get_uclass_plat(dev);
- if (desc->if_type != UCLASS_EFI_LOADER) {
+ if (desc->uclass_id != UCLASS_EFI_LOADER) {
diskobj = container_of(handle, struct efi_disk_obj, header);
efi_free_pool(diskobj->dp);
}
@@ -794,7 +794,7 @@
} else {
return EFI_INVALID_PARAMETER;
}
- if_typename = blk_get_if_type_name(desc->if_type);
+ if_typename = blk_get_uclass_name(desc->uclass_id);
diskid = desc->devnum;
if (is_partition) {
diff --git a/lib/efi_loader/efi_var_file.c b/lib/efi_loader/efi_var_file.c
index 994e663..3d58caa 100644
--- a/lib/efi_loader/efi_var_file.c
+++ b/lib/efi_loader/efi_var_file.c
@@ -38,13 +38,13 @@
char part_str[PART_STR_LEN];
int r;
- if (efi_system_partition.if_type == UCLASS_INVALID) {
+ if (efi_system_partition.uclass_id == UCLASS_INVALID) {
log_err("No EFI system partition\n");
return EFI_DEVICE_ERROR;
}
snprintf(part_str, PART_STR_LEN, "%x:%x",
efi_system_partition.devnum, efi_system_partition.part);
- r = fs_set_blk_dev(blk_get_if_type_name(efi_system_partition.if_type),
+ r = fs_set_blk_dev(blk_get_uclass_name(efi_system_partition.uclass_id),
part_str, FS_TYPE_ANY);
if (r) {
log_err("Cannot read EFI system partition\n");
diff --git a/lib/efi_selftest/efi_selftest_loadimage.c b/lib/efi_selftest/efi_selftest_loadimage.c
index d4c76f5..24548f1 100644
--- a/lib/efi_selftest/efi_selftest_loadimage.c
+++ b/lib/efi_selftest/efi_selftest_loadimage.c
@@ -142,38 +142,39 @@
&priv_file_system_info.info;
/* Forward definitions of file and file system functions */
-static efi_status_t EFIAPI open_volume
+static efi_status_t EFIAPI efi_st_open_volume
(struct efi_simple_file_system_protocol *this,
struct efi_file_handle **root);
-static efi_status_t EFIAPI open
+static efi_status_t EFIAPI efi_st_open
(struct efi_file_handle *this,
struct efi_file_handle **new_handle,
u16 *file_name, u64 open_mode, u64 attributes);
-static efi_status_t EFIAPI close(struct efi_file_handle *this);
+static efi_status_t EFIAPI efi_st_close(struct efi_file_handle *this);
-static efi_status_t EFIAPI delete(struct efi_file_handle *this);
+static efi_status_t EFIAPI efi_st_delete(struct efi_file_handle *this);
-static efi_status_t EFIAPI read
+static efi_status_t EFIAPI efi_st_read
(struct efi_file_handle *this, efi_uintn_t *buffer_size, void *buffer);
-static efi_status_t EFIAPI write
+static efi_status_t EFIAPI efi_st_write
(struct efi_file_handle *this, efi_uintn_t *buffer_size, void *buffer);
-static efi_status_t EFIAPI getpos(struct efi_file_handle *this, u64 *pos);
+static efi_status_t EFIAPI efi_st_getpos(struct efi_file_handle *this,
+ u64 *pos);
-static efi_status_t EFIAPI setpos(struct efi_file_handle *this, u64 pos);
+static efi_status_t EFIAPI efi_st_setpos(struct efi_file_handle *this, u64 pos);
-static efi_status_t EFIAPI getinfo
+static efi_status_t EFIAPI efi_st_getinfo
(struct efi_file_handle *this, const efi_guid_t *info_type,
efi_uintn_t *buffer_size, void *buffer);
-static efi_status_t EFIAPI setinfo
+static efi_status_t EFIAPI efi_st_setinfo
(struct efi_file_handle *this, const efi_guid_t *info_type,
efi_uintn_t buffer_size, void *buffer);
-static efi_status_t EFIAPI flush(struct efi_file_handle *this);
+static efi_status_t EFIAPI efi_st_flush(struct efi_file_handle *this);
/* Internal information about status of file system */
static struct {
@@ -190,40 +191,40 @@
/* EFI_FILE_PROTOCOL for file */
static struct efi_file_handle file = {
.rev = 0x00010000,
- .open = open,
- .close = close,
- .delete = delete,
- .read = read,
- .write = write,
- .getpos = getpos,
- .setpos = setpos,
- .getinfo = getinfo,
- .setinfo = setinfo,
- .flush = flush,
+ .open = efi_st_open,
+ .close = efi_st_close,
+ .delete = efi_st_delete,
+ .read = efi_st_read,
+ .write = efi_st_write,
+ .getpos = efi_st_getpos,
+ .setpos = efi_st_setpos,
+ .getinfo = efi_st_getinfo,
+ .setinfo = efi_st_setinfo,
+ .flush = efi_st_flush,
};
/* EFI_FILE_PROTOCOL for root directory */
static struct efi_file_handle volume = {
.rev = 0x00010000,
- .open = open,
- .close = close,
- .delete = delete,
- .read = read,
- .write = write,
- .getpos = getpos,
- .setpos = setpos,
- .getinfo = getinfo,
- .setinfo = setinfo,
- .flush = flush,
+ .open = efi_st_open,
+ .close = efi_st_close,
+ .delete = efi_st_delete,
+ .read = efi_st_read,
+ .write = efi_st_write,
+ .getpos = efi_st_getpos,
+ .setpos = efi_st_setpos,
+ .getinfo = efi_st_getinfo,
+ .setinfo = efi_st_setinfo,
+ .flush = efi_st_flush,
};
/* EFI_SIMPLE_FILE_SYSTEM_PROTOCOL of the block device */
struct efi_simple_file_system_protocol file_system = {
.rev = 0x00010000,
- .open_volume = open_volume,
+ .open_volume = efi_st_open_volume,
};
-static efi_status_t EFIAPI open_volume
+static efi_status_t EFIAPI efi_st_open_volume
(struct efi_simple_file_system_protocol *this,
struct efi_file_handle **root)
{
@@ -236,7 +237,7 @@
return EFI_SUCCESS;
}
-static efi_status_t EFIAPI open
+static efi_status_t EFIAPI efi_st_open
(struct efi_file_handle *this,
struct efi_file_handle **new_handle,
u16 *file_name, u64 open_mode, u64 attributes)
@@ -251,7 +252,7 @@
return EFI_SUCCESS;
}
-static efi_status_t EFIAPI close(struct efi_file_handle *this)
+static efi_status_t EFIAPI efi_st_close(struct efi_file_handle *this)
{
if (this == &file)
priv.file_open_count--;
@@ -263,7 +264,7 @@
return EFI_SUCCESS;
}
-static efi_status_t EFIAPI delete(struct efi_file_handle *this)
+static efi_status_t EFIAPI efi_st_delete(struct efi_file_handle *this)
{
if (this != &file)
return EFI_INVALID_PARAMETER;
@@ -271,7 +272,7 @@
return EFI_UNSUPPORTED;
}
-static efi_status_t EFIAPI read
+static efi_status_t EFIAPI efi_st_read
(struct efi_file_handle *this, efi_uintn_t *buffer_size, void *buffer)
{
if (this != &file)
@@ -288,7 +289,7 @@
return EFI_SUCCESS;
}
-static efi_status_t EFIAPI write
+static efi_status_t EFIAPI efi_st_write
(struct efi_file_handle *this, efi_uintn_t *buffer_size, void *buffer)
{
if (this != &file)
@@ -297,7 +298,7 @@
return EFI_UNSUPPORTED;
}
-static efi_status_t EFIAPI getpos(struct efi_file_handle *this, u64 *pos)
+static efi_status_t EFIAPI efi_st_getpos(struct efi_file_handle *this, u64 *pos)
{
if (this != &file)
return EFI_INVALID_PARAMETER;
@@ -307,7 +308,7 @@
return EFI_SUCCESS;
}
-static efi_status_t EFIAPI setpos(struct efi_file_handle *this, u64 pos)
+static efi_status_t EFIAPI efi_st_setpos(struct efi_file_handle *this, u64 pos)
{
if (this != &file)
return EFI_INVALID_PARAMETER;
@@ -317,7 +318,7 @@
return EFI_SUCCESS;
}
-static efi_status_t EFIAPI getinfo
+static efi_status_t EFIAPI efi_st_getinfo
(struct efi_file_handle *this, const efi_guid_t *info_type,
efi_uintn_t *buffer_size, void *buffer)
{
@@ -348,7 +349,7 @@
return EFI_SUCCESS;
}
-static efi_status_t EFIAPI setinfo
+static efi_status_t EFIAPI efi_st_setinfo
(struct efi_file_handle *this, const efi_guid_t *info_type,
efi_uintn_t buffer_size, void *buffer)
{
@@ -358,7 +359,7 @@
return EFI_UNSUPPORTED;
}
-static efi_status_t EFIAPI flush(struct efi_file_handle *this)
+static efi_status_t EFIAPI efi_st_flush(struct efi_file_handle *this)
{
if (this != &file)
return EFI_INVALID_PARAMETER;
diff --git a/test/dm/Makefile b/test/dm/Makefile
index 7543df8..5178daa 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -91,6 +91,7 @@
obj-$(CONFIG_DM_RNG) += rng.o
obj-$(CONFIG_DM_RTC) += rtc.o
obj-$(CONFIG_SCMI_FIRMWARE) += scmi.o
+obj-$(CONFIG_SCSI) += scsi.o
obj-$(CONFIG_DM_SERIAL) += serial.o
obj-$(CONFIG_DM_SPI_FLASH) += sf.o
obj-$(CONFIG_SIMPLE_BUS) += simple-bus.o
diff --git a/test/dm/scsi.c b/test/dm/scsi.c
new file mode 100644
index 0000000..380cfc8
--- /dev/null
+++ b/test/dm/scsi.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2015 Google, Inc
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <part.h>
+#include <scsi.h>
+#include <dm/test.h>
+#include <test/test.h>
+#include <test/ut.h>
+
+/* Test that sandbox SCSI works correctly */
+static int dm_test_scsi_base(struct unit_test_state *uts)
+{
+ const struct disk_partition *info;
+ const struct disk_part *part;
+ struct udevice *dev;
+
+ ut_assertok(scsi_scan(false));
+
+ /*
+ * We expect some sort of partition on the disk image, created by
+ * test_ut_dm_init()
+ */
+ ut_assertok(uclass_first_device_err(UCLASS_PARTITION, &dev));
+
+ part = dev_get_uclass_plat(dev);
+ ut_asserteq(1, part->partnum);
+
+ info = &part->gpt_part_info;
+ ut_asserteq_str("sda1", info->name);
+ ut_asserteq_str("U-Boot", info->type);
+ ut_asserteq(0x83 /* linux */, info->sys_ind);
+
+ return 0;
+}
+DM_TEST(dm_test_scsi_base, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
diff --git a/test/lib/test_print.c b/test/lib/test_print.c
index a60a5a5..79b67c7 100644
--- a/test/lib/test_print.c
+++ b/test/lib/test_print.c
@@ -68,6 +68,9 @@
ut_assertok(test_print_size(uts, 7654321, "7.3 MiB;"));
ut_assertok(test_print_size(uts, 87654321, "83.6 MiB;"));
ut_assertok(test_print_size(uts, 987654321, "941.9 MiB;"));
+ ut_assertok(test_print_size(uts, 1073689395, "1023.9 MiB;"));
+ ut_assertok(test_print_size(uts, 1073689396, "1 GiB;"));
+ ut_assertok(test_print_size(uts, 1073741824, "1 GiB;"));
ut_assertok(test_print_size(uts, 1987654321, "1.9 GiB;"));
ut_assertok(test_print_size(uts, 54321987654321, "49.4 TiB;"));
return 0;
diff --git a/test/py/tests/test_ut.py b/test/py/tests/test_ut.py
index 35fb393..9d42390 100644
--- a/test/py/tests/test_ut.py
+++ b/test/py/tests/test_ut.py
@@ -114,6 +114,15 @@
with open(fn, 'wb') as fh:
fh.write(data)
+ # Create a file with a single partition
+ fn = u_boot_console.config.source_dir + '/scsi.img'
+ if not os.path.exists(fn):
+ data = b'\x00' * (2 * 1024 * 1024)
+ with open(fn, 'wb') as fh:
+ fh.write(data)
+ u_boot_utils.run_and_log(
+ u_boot_console, f'sfdisk {fn}', stdin=b'type=83')
+
@pytest.mark.buildconfigspec('cmd_bootflow')
def test_ut_dm_init_bootstd(u_boot_console):
"""Initialise data for bootflow tests"""
diff --git a/tools/Makefile b/tools/Makefile
index 3626919..34a1aa7 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -147,6 +147,7 @@
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/binman/bintool.py b/tools/binman/bintool.py
index 032179a..a582d9d 100644
--- a/tools/binman/bintool.py
+++ b/tools/binman/bintool.py
@@ -319,7 +319,7 @@
return result.stdout
@classmethod
- def build_from_git(cls, git_repo, make_target, bintool_path):
+ def build_from_git(cls, git_repo, make_target, bintool_path, flags=None):
"""Build a bintool from a git repo
This clones the repo in a temporary directory, builds it with 'make',
@@ -330,6 +330,7 @@
make_target (str): Target to pass to 'make' to build the tool
bintool_path (str): Relative path of the tool in the repo, after
build is complete
+ flags (list of str): Flags or variables to pass to make, or None
Returns:
tuple:
@@ -341,8 +342,11 @@
print(f"- clone git repo '{git_repo}' to '{tmpdir}'")
tools.run('git', 'clone', '--depth', '1', git_repo, tmpdir)
print(f"- build target '{make_target}'")
- tools.run('make', '-C', tmpdir, '-j', f'{multiprocessing.cpu_count()}',
- make_target)
+ cmd = ['make', '-C', tmpdir, '-j', f'{multiprocessing.cpu_count()}',
+ make_target]
+ if flags:
+ cmd += flags
+ tools.run(*cmd)
fname = os.path.join(tmpdir, bintool_path)
if not os.path.exists(fname):
print(f"- File '{fname}' was not produced")
diff --git a/tools/binman/btool/futility.py b/tools/binman/btool/futility.py
index 75a05c2..04c9aef 100644
--- a/tools/binman/btool/futility.py
+++ b/tools/binman/btool/futility.py
@@ -160,8 +160,17 @@
Raises:
Valuerror: Fetching could not be completed
"""
- if method != bintool.FETCH_BIN:
+ if method != bintool.FETCH_BUILD:
return None
- fname, tmpdir = self.fetch_from_drive(
- '1hdsInzsE4aJbmBeJ663kYgjOQyW1I-E0')
- return fname, tmpdir
+
+ # The Chromium OS repo is here:
+ # https://chromium.googlesource.com/chromiumos/platform/vboot_reference/
+ #
+ # Unfortunately this requires logging in and obtaining a line for the
+ # .gitcookies file. So use a mirror instead.
+ result = self.build_from_git(
+ 'https://github.com/sjg20/vboot_reference.git',
+ 'all',
+ 'build/futility/futility',
+ flags=['USE_FLASHROM=0'])
+ return result
diff --git a/tools/mtk_image.c b/tools/mtk_image.c
index de5ce4d..9b3136a 100644
--- a/tools/mtk_image.c
+++ b/tools/mtk_image.c
@@ -12,216 +12,7 @@
#include <u-boot/sha256.h>
#include "imagetool.h"
#include "mtk_image.h"
-
-/* NAND header for SPI-NAND with 2KB page + 64B spare */
-static const union nand_boot_header snand_hdr_2k_64_data = {
- .data = {
- 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
- 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
- 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x03, 0x00, 0x40, 0x00,
- 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x7B, 0xC4, 0x17, 0x9D,
- 0xCA, 0x42, 0x90, 0xD0, 0x98, 0xD0, 0xE0, 0xF7,
- 0xDB, 0xCD, 0x16, 0xF6, 0x03, 0x73, 0xD2, 0xB8,
- 0x93, 0xB2, 0x56, 0x5A, 0x84, 0x6E, 0x00, 0x00
- }
-};
-
-/* NAND header for SPI-NAND with 2KB page + 120B/128B spare */
-static const union nand_boot_header snand_hdr_2k_128_data = {
- .data = {
- 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
- 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
- 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
- 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x90, 0x28, 0xED, 0x13,
- 0x7F, 0x12, 0x22, 0xCD, 0x3D, 0x06, 0xF1, 0xB3,
- 0x6F, 0x2E, 0xD9, 0xA0, 0x9D, 0x7A, 0xBD, 0xD7,
- 0xB3, 0x28, 0x3C, 0x13, 0xDB, 0x4E, 0x00, 0x00
- }
-};
-
-/* NAND header for SPI-NAND with 4KB page + 256B spare */
-static const union nand_boot_header snand_hdr_4k_256_data = {
- .data = {
- 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
- 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
- 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0xE0, 0x00,
- 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x47, 0xED, 0x0E, 0xC3,
- 0x83, 0xBF, 0x41, 0xD2, 0x85, 0x21, 0x97, 0x57,
- 0xC4, 0x2E, 0x6B, 0x7A, 0x40, 0xE0, 0xCF, 0x8F,
- 0x37, 0xBD, 0x17, 0xB6, 0xC7, 0xFE, 0x00, 0x00
- }
-};
-
-/* NAND header for Parallel NAND 1Gb with 2KB page + 64B spare */
-static const union nand_boot_header nand_hdr_1gb_2k_64_data = {
- .data = {
- 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
- 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
- 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
- 0x40, 0x00, 0x00, 0x04, 0x0B, 0x00, 0x11, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x1C, 0x12,
- 0x8F, 0xFD, 0xF8, 0x32, 0x6F, 0x6D, 0xCF, 0x6C,
- 0xDA, 0x21, 0x70, 0x8C, 0xDA, 0x0A, 0x22, 0x82,
- 0xAA, 0x59, 0xFA, 0x7C, 0x42, 0x2D, 0x00, 0x00
- }
-};
-
-/* NAND header for Parallel NAND 2Gb with 2KB page + 64B spare */
-static const union nand_boot_header nand_hdr_2gb_2k_64_data = {
- .data = {
- 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
- 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
- 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
- 0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x20, 0x9C, 0x3D, 0x2D,
- 0x7B, 0x68, 0x63, 0x52, 0x2E, 0x04, 0x63, 0xF1,
- 0x35, 0x4E, 0x44, 0x3E, 0xF8, 0xAC, 0x9B, 0x95,
- 0xAB, 0xFE, 0xE4, 0xE1, 0xD5, 0xF9, 0x00, 0x00
- }
-};
-
-/* NAND header for Parallel NAND 4Gb with 2KB page + 64B spare */
-static const union nand_boot_header nand_hdr_4gb_2k_64_data = {
- .data = {
- 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
- 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
- 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xE3, 0x0F, 0x86, 0x32,
- 0x68, 0x05, 0xD9, 0xC8, 0x13, 0xDF, 0xC5, 0x0B,
- 0x35, 0x3A, 0x68, 0xA5, 0x3C, 0x0C, 0x73, 0x87,
- 0x63, 0xB0, 0xBE, 0xCC, 0x84, 0x47, 0x00, 0x00
- }
-};
-
-/* NAND header for Parallel NAND 2Gb with 2KB page + 128B spare */
-static const union nand_boot_header nand_hdr_2gb_2k_128_data = {
- .data = {
- 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
- 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
- 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
- 0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0xA5, 0xE9, 0x5A,
- 0xDF, 0x58, 0x62, 0x41, 0xD6, 0x26, 0x77, 0xBC,
- 0x76, 0x1F, 0x27, 0x4E, 0x4F, 0x6C, 0xC3, 0xF0,
- 0x36, 0xDE, 0xD9, 0xB3, 0xFF, 0x93, 0x00, 0x00
- }
-};
-
-/* NAND header for Parallel NAND 4Gb with 2KB page + 128B spare */
-static const union nand_boot_header nand_hdr_4gb_2k_128_data = {
- .data = {
- 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
- 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
- 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xC2, 0x36, 0x52, 0x45,
- 0xCC, 0x35, 0xD8, 0xDB, 0xEB, 0xFD, 0xD1, 0x46,
- 0x76, 0x6B, 0x0B, 0xD5, 0x8B, 0xCC, 0x2B, 0xE2,
- 0xFE, 0x90, 0x83, 0x9E, 0xAE, 0x2D, 0x00, 0x00
- }
-};
-
-static const struct nand_header_type {
- const char *name;
- const union nand_boot_header *data;
-} nand_headers[] = {
- {
- .name = "2k+64",
- .data = &snand_hdr_2k_64_data
- }, {
- .name = "2k+120",
- .data = &snand_hdr_2k_128_data
- }, {
- .name = "2k+128",
- .data = &snand_hdr_2k_128_data
- }, {
- .name = "4k+256",
- .data = &snand_hdr_4k_256_data
- }, {
- .name = "1g:2k+64",
- .data = &nand_hdr_1gb_2k_64_data
- }, {
- .name = "2g:2k+64",
- .data = &nand_hdr_2gb_2k_64_data
- }, {
- .name = "4g:2k+64",
- .data = &nand_hdr_4gb_2k_64_data
- }, {
- .name = "2g:2k+128",
- .data = &nand_hdr_2gb_2k_128_data
- }, {
- .name = "4g:2k+128",
- .data = &nand_hdr_4gb_2k_128_data
- }
-};
+#include "mtk_nand_headers.h"
static const struct brom_img_type {
const char *name;
@@ -242,6 +33,9 @@
}, {
.name = "snand",
.type = BRLYT_TYPE_SNAND
+ }, {
+ .name = "spim-nand",
+ .type = BRLYT_TYPE_SNAND
}
};
@@ -263,7 +57,8 @@
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 */
static char hdr_tmp[sizeof(struct gfh_header) + 0x2000];
@@ -402,12 +197,7 @@
}
/* parse nand header type */
- for (i = 0; i < ARRAY_SIZE(nand_headers); i++) {
- if (!strcmp(nand_headers[i].name, nandinfo)) {
- hdr_nand = nand_headers[i].data;
- break;
- }
- }
+ hdr_nand = mtk_nand_header_find(nandinfo);
/* parse device header offset */
if (hdr_offs && hdr_offs[0])
@@ -432,6 +222,9 @@
return -EINVAL;
}
+ if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND)
+ hdr_nand_size = mtk_nand_header_size(hdr_nand);
+
return 0;
}
@@ -468,7 +261,7 @@
}
if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND)
- tparams->header_size = 2 * le16_to_cpu(hdr_nand->pagesize);
+ tparams->header_size = hdr_nand_size;
else
tparams->header_size = sizeof(struct gen_device_header);
@@ -480,6 +273,25 @@
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,89 +354,57 @@
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)
{
- union nand_boot_header *nh = (union nand_boot_header *)ptr;
struct brom_layout_header *bh;
+ struct nand_header_info info;
struct gfh_header *gfh;
const char *bootmedia;
+ int ret;
- if (strncmp(nh->version, NAND_BOOT_VERSION, sizeof(nh->version)) ||
- strcmp(nh->id, NAND_BOOT_ID))
- return -1;
+ ret = mtk_nand_header_info(ptr, &info);
+ if (ret < 0)
+ return ret;
- bh = (struct brom_layout_header *)(ptr + le16_to_cpu(nh->pagesize));
+ 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;
- } else {
+ if (le32_to_cpu(bh->magic) != BRLYT_MAGIC)
+ return -1;
+
if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND)
bootmedia = "Parallel NAND";
else if (le32_to_cpu(bh->type) == BRLYT_TYPE_SNAND)
- bootmedia = "Serial NAND";
+ bootmedia = "Serial NAND (SNFI/AP)";
else
return -1;
+ } else {
+ if (info.snfi)
+ bootmedia = "Serial NAND (SNFI/HSM)";
+ else
+ bootmedia = "Serial NAND (SPIM)";
}
if (print) {
- printf("Boot Media: %s\n", bootmedia);
-
- if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND) {
- uint64_t capacity =
- (uint64_t)le16_to_cpu(nh->numblocks) *
- (uint64_t)le16_to_cpu(nh->pages_of_block) *
- (uint64_t)le16_to_cpu(nh->pagesize) * 8;
- printf("Capacity: %dGb\n",
- (uint32_t)(capacity >> 30));
- }
+ printf("Boot Media: %s\n", bootmedia);
- if (le16_to_cpu(nh->pagesize) >= 1024)
- printf("Page Size: %dKB\n",
- le16_to_cpu(nh->pagesize) >> 10);
+ if (info.page_size >= 1024)
+ printf("Page Size: %dKB\n", info.page_size >> 10);
else
- printf("Page Size: %dB\n",
- le16_to_cpu(nh->pagesize));
+ printf("Page Size: %dB\n", info.page_size);
- printf("Spare Size: %dB\n", le16_to_cpu(nh->oobsize));
+ printf("Spare Size: %dB\n", info.spare_size);
}
- gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(nh->pagesize));
-
- 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;
+ gfh = (struct gfh_header *)(ptr + info.gfh_offset);
- 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)
@@ -722,7 +502,7 @@
if (image_get_magic(hdr) == IH_MAGIC)
return mtk_image_verify_mt7621_header(ptr, 0);
- if (!strcmp((char *)ptr, NAND_BOOT_NAME))
+ if (is_mtk_nand_header(ptr))
return mtk_image_verify_nand_header(ptr, 0);
else
return mtk_image_verify_gen_header(ptr, 0);
@@ -748,7 +528,7 @@
return;
}
- if (!strcmp((char *)ptr, NAND_BOOT_NAME))
+ if (is_mtk_nand_header(ptr))
mtk_image_verify_nand_header(ptr, 1);
else
mtk_image_verify_gen_header(ptr, 1);
@@ -879,36 +659,33 @@
static void mtk_image_set_nand_header(void *ptr, off_t filesize,
uint32_t loadaddr)
{
- union nand_boot_header *nh = (union nand_boot_header *)ptr;
struct brom_layout_header *brlyt;
struct gfh_header *gfh;
- uint32_t payload_pages;
- int i;
+ uint32_t payload_pages, nand_page_size;
- /* NAND device header, repeat 4 times */
- for (i = 0; i < 4; i++)
- memcpy(nh + i, hdr_nand, sizeof(union nand_boot_header));
+ /* NAND header */
+ nand_page_size = mtk_nand_header_put(hdr_nand, ptr);
- /* BRLYT header */
- payload_pages = (filesize + le16_to_cpu(hdr_nand->pagesize) - 1) /
- le16_to_cpu(hdr_nand->pagesize);
- brlyt = (struct brom_layout_header *)
- (ptr + le16_to_cpu(hdr_nand->pagesize));
- put_brom_layout_header(brlyt, hdr_media);
- brlyt->header_size = cpu_to_le32(2);
- brlyt->total_size = cpu_to_le32(payload_pages);
- brlyt->header_size_2 = brlyt->header_size;
- brlyt->total_size_2 = brlyt->total_size;
- brlyt->unused = cpu_to_le32(1);
+ if (nand_page_size) {
+ /* BRLYT header */
+ payload_pages = (filesize + nand_page_size - 1) /
+ nand_page_size;
+ brlyt = (struct brom_layout_header *)(ptr + nand_page_size);
+ put_brom_layout_header(brlyt, hdr_media);
+ brlyt->header_size = cpu_to_le32(2);
+ brlyt->total_size = cpu_to_le32(payload_pages);
+ brlyt->header_size_2 = brlyt->header_size;
+ brlyt->total_size_2 = brlyt->total_size;
+ brlyt->unused = cpu_to_le32(1);
+ }
/* GFH header */
- gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(hdr_nand->pagesize));
- put_ghf_header(gfh, filesize, 2 * le16_to_cpu(hdr_nand->pagesize),
- loadaddr, GFH_FLASH_TYPE_NAND);
+ gfh = (struct gfh_header *)(ptr + hdr_nand_size);
+ put_ghf_header(gfh, filesize, hdr_nand_size, loadaddr,
+ GFH_FLASH_TYPE_NAND);
/* Generate SHA256 hash */
- put_hash((uint8_t *)gfh,
- filesize - 2 * le16_to_cpu(hdr_nand->pagesize) - SHA256_SUM_LEN);
+ put_hash((uint8_t *)gfh, filesize - hdr_nand_size - SHA256_SUM_LEN);
}
static void mtk_image_set_mt7621_header(void *ptr, off_t filesize,
diff --git a/tools/mtk_image.h b/tools/mtk_image.h
index d868545..fad9372 100644
--- a/tools/mtk_image.h
+++ b/tools/mtk_image.h
@@ -26,31 +26,6 @@
#define SF_BOOT_NAME "SF_BOOT"
#define SDMMC_BOOT_NAME "SDMMC_BOOT"
-/* Header for NAND */
-union nand_boot_header {
- struct {
- char name[12];
- char version[4];
- char id[8];
- uint16_t ioif;
- uint16_t pagesize;
- uint16_t addrcycles;
- uint16_t oobsize;
- uint16_t pages_of_block;
- uint16_t numblocks;
- uint16_t writesize_shift;
- uint16_t erasesize_shift;
- uint8_t dummy[60];
- uint8_t ecc_parity[28];
- };
-
- uint8_t data[0x80];
-};
-
-#define NAND_BOOT_NAME "BOOTLOADER!"
-#define NAND_BOOT_VERSION "V006"
-#define NAND_BOOT_ID "NFIINFO"
-
/* BootROM layout header */
struct brom_layout_header {
char name[8];
diff --git a/tools/mtk_nand_headers.c b/tools/mtk_nand_headers.c
new file mode 100644
index 0000000..2fa91e7
--- /dev/null
+++ b/tools/mtk_nand_headers.c
@@ -0,0 +1,668 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * MediaTek BootROM NAND header definitions
+ *
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "imagetool.h"
+#include "mtk_image.h"
+#include "mtk_nand_headers.h"
+
+/* NAND header for SPI-NAND with 2KB page + 64B spare */
+static const union nand_boot_header snand_hdr_2k_64_data = {
+ .data = {
+ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x03, 0x00, 0x40, 0x00,
+ 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x7B, 0xC4, 0x17, 0x9D,
+ 0xCA, 0x42, 0x90, 0xD0, 0x98, 0xD0, 0xE0, 0xF7,
+ 0xDB, 0xCD, 0x16, 0xF6, 0x03, 0x73, 0xD2, 0xB8,
+ 0x93, 0xB2, 0x56, 0x5A, 0x84, 0x6E, 0x00, 0x00
+ }
+};
+
+/* NAND header for SPI-NAND with 2KB page + 120B/128B spare */
+static const union nand_boot_header snand_hdr_2k_128_data = {
+ .data = {
+ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
+ 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x90, 0x28, 0xED, 0x13,
+ 0x7F, 0x12, 0x22, 0xCD, 0x3D, 0x06, 0xF1, 0xB3,
+ 0x6F, 0x2E, 0xD9, 0xA0, 0x9D, 0x7A, 0xBD, 0xD7,
+ 0xB3, 0x28, 0x3C, 0x13, 0xDB, 0x4E, 0x00, 0x00
+ }
+};
+
+/* NAND header for SPI-NAND with 4KB page + 256B spare */
+static const union nand_boot_header snand_hdr_4k_256_data = {
+ .data = {
+ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0xE0, 0x00,
+ 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x47, 0xED, 0x0E, 0xC3,
+ 0x83, 0xBF, 0x41, 0xD2, 0x85, 0x21, 0x97, 0x57,
+ 0xC4, 0x2E, 0x6B, 0x7A, 0x40, 0xE0, 0xCF, 0x8F,
+ 0x37, 0xBD, 0x17, 0xB6, 0xC7, 0xFE, 0x00, 0x00
+ }
+};
+
+/* NAND header for Parallel NAND 1Gb with 2KB page + 64B spare */
+static const union nand_boot_header nand_hdr_1gb_2k_64_data = {
+ .data = {
+ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
+ 0x40, 0x00, 0x00, 0x04, 0x0B, 0x00, 0x11, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x1C, 0x12,
+ 0x8F, 0xFD, 0xF8, 0x32, 0x6F, 0x6D, 0xCF, 0x6C,
+ 0xDA, 0x21, 0x70, 0x8C, 0xDA, 0x0A, 0x22, 0x82,
+ 0xAA, 0x59, 0xFA, 0x7C, 0x42, 0x2D, 0x00, 0x00
+ }
+};
+
+/* NAND header for Parallel NAND 2Gb with 2KB page + 64B spare */
+static const union nand_boot_header nand_hdr_2gb_2k_64_data = {
+ .data = {
+ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
+ 0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x20, 0x9C, 0x3D, 0x2D,
+ 0x7B, 0x68, 0x63, 0x52, 0x2E, 0x04, 0x63, 0xF1,
+ 0x35, 0x4E, 0x44, 0x3E, 0xF8, 0xAC, 0x9B, 0x95,
+ 0xAB, 0xFE, 0xE4, 0xE1, 0xD5, 0xF9, 0x00, 0x00
+ }
+};
+
+/* NAND header for Parallel NAND 4Gb with 2KB page + 64B spare */
+static const union nand_boot_header nand_hdr_4gb_2k_64_data = {
+ .data = {
+ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xE3, 0x0F, 0x86, 0x32,
+ 0x68, 0x05, 0xD9, 0xC8, 0x13, 0xDF, 0xC5, 0x0B,
+ 0x35, 0x3A, 0x68, 0xA5, 0x3C, 0x0C, 0x73, 0x87,
+ 0x63, 0xB0, 0xBE, 0xCC, 0x84, 0x47, 0x00, 0x00
+ }
+};
+
+/* NAND header for Parallel NAND 2Gb with 2KB page + 128B spare */
+static const union nand_boot_header nand_hdr_2gb_2k_128_data = {
+ .data = {
+ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
+ 0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0xA5, 0xE9, 0x5A,
+ 0xDF, 0x58, 0x62, 0x41, 0xD6, 0x26, 0x77, 0xBC,
+ 0x76, 0x1F, 0x27, 0x4E, 0x4F, 0x6C, 0xC3, 0xF0,
+ 0x36, 0xDE, 0xD9, 0xB3, 0xFF, 0x93, 0x00, 0x00
+ }
+};
+
+/* NAND header for Parallel NAND 4Gb with 2KB page + 128B spare */
+static const union nand_boot_header nand_hdr_4gb_2k_128_data = {
+ .data = {
+ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xC2, 0x36, 0x52, 0x45,
+ 0xCC, 0x35, 0xD8, 0xDB, 0xEB, 0xFD, 0xD1, 0x46,
+ 0x76, 0x6B, 0x0B, 0xD5, 0x8B, 0xCC, 0x2B, 0xE2,
+ 0xFE, 0x90, 0x83, 0x9E, 0xAE, 0x2D, 0x00, 0x00
+ }
+};
+
+/* HSM BROM NAND header for SPI NAND with 2KB page + 64B spare */
+static const union hsm_nand_boot_header hsm_nand_hdr_2k_64_data = {
+ .data = {
+ 0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+ 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0xFF, 0x00, 0x00, 0x00, 0x21, 0xD2, 0xEE, 0xF6,
+ 0xAE, 0xDD, 0x5E, 0xC2, 0x82, 0x8E, 0x9A, 0x62,
+ 0x09, 0x8E, 0x80, 0xE2, 0x37, 0x0D, 0xC9, 0xFA,
+ 0xA9, 0xDD, 0xFC, 0x92, 0x34, 0x2A, 0xED, 0x51,
+ 0xA4, 0x1B, 0xF7, 0x63, 0xCC, 0x5A, 0xC7, 0xFB,
+ 0xED, 0x21, 0x02, 0x23, 0x51, 0x31
+ }
+};
+
+/* HSM BROM NAND header for SPI NAND with 2KB page + 128B spare */
+static const union hsm_nand_boot_header hsm_nand_hdr_2k_128_data = {
+ .data = {
+ 0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+ 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0xFF, 0x00, 0x00, 0x00, 0x71, 0x7f, 0x71, 0xAC,
+ 0x42, 0xD0, 0x5B, 0xD2, 0x12, 0x81, 0x15, 0x0A,
+ 0x0C, 0xD4, 0xF6, 0x32, 0x1E, 0x63, 0xE7, 0x81,
+ 0x8A, 0x7F, 0xDE, 0xF9, 0x4B, 0x91, 0xEC, 0xC2,
+ 0x70, 0x00, 0x7F, 0x57, 0xAF, 0xDC, 0xE4, 0x24,
+ 0x57, 0x09, 0xBC, 0xC5, 0x35, 0xDC
+ }
+};
+
+/* HSM BROM NAND header for SPI NAND with 4KB page + 256B spare */
+static const union hsm_nand_boot_header hsm_nand_hdr_4k_256_data = {
+ .data = {
+ 0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+ 0x0C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0xFF, 0x00, 0x00, 0x00, 0x62, 0x04, 0xD6, 0x1F,
+ 0x2B, 0x57, 0x7A, 0x2D, 0xFE, 0xBB, 0x4A, 0x50,
+ 0xEC, 0xF8, 0x70, 0x1A, 0x44, 0x15, 0xF6, 0xA2,
+ 0x8E, 0xB0, 0xFD, 0xFA, 0xDC, 0xAA, 0x5A, 0x4E,
+ 0xCB, 0x8E, 0xC9, 0x72, 0x08, 0xDC, 0x20, 0xB9,
+ 0x98, 0xC8, 0x82, 0xD8, 0xBE, 0x44
+ }
+};
+
+/* HSM2.0 BROM NAND header for SPI NAND with 2KB page + 64B spare */
+static const union hsm20_nand_boot_header hsm20_nand_hdr_2k_64_data = {
+ .data = {
+ 0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+ 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+ 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x5F, 0x4B, 0xB2, 0x5B, 0x8B, 0x1C, 0x35, 0xDA,
+ 0x83, 0xE6, 0x6C, 0xC3, 0xFB, 0x8C, 0x78, 0x23,
+ 0xD0, 0x89, 0x24, 0xD9, 0x6C, 0x35, 0x2C, 0x5D,
+ 0x8F, 0xBB, 0xFC, 0x10, 0xD0, 0xE2, 0x22, 0x7D,
+ 0xC8, 0x97, 0x9A, 0xEF, 0xC6, 0xB5, 0xA7, 0x4E,
+ 0x4E, 0x0E
+ }
+};
+
+/* HSM2.0 BROM NAND header for SPI NAND with 2KB page + 128B spare */
+static const union hsm20_nand_boot_header hsm20_nand_hdr_2k_128_data = {
+ .data = {
+ 0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+ 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+ 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xF8, 0x7E, 0xC1, 0x5D, 0x61, 0x54, 0xEA, 0x9F,
+ 0x5E, 0x66, 0x39, 0x66, 0x21, 0xFF, 0x8C, 0x3B,
+ 0xBE, 0xA7, 0x5A, 0x9E, 0xD7, 0xBD, 0x9E, 0x89,
+ 0xEE, 0x7E, 0x10, 0x31, 0x9A, 0x1D, 0x82, 0x49,
+ 0xA3, 0x4E, 0xD8, 0x47, 0xD7, 0x19, 0xF4, 0x2D,
+ 0x8E, 0x53
+ }
+};
+
+/* HSM2.0 BROM NAND header for SPI NAND with 4KB page + 256B spare */
+static const union hsm20_nand_boot_header hsm20_nand_hdr_4k_256_data = {
+ .data = {
+ 0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+ 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+ 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x79, 0x01, 0x1F, 0x86, 0x62, 0x6A, 0x43, 0xAE,
+ 0xE6, 0xF8, 0xDD, 0x5B, 0x29, 0xB7, 0xA2, 0x7F,
+ 0x29, 0x72, 0x54, 0x37, 0xBE, 0x50, 0xD4, 0x24,
+ 0xAB, 0x60, 0xF4, 0x44, 0x97, 0x3B, 0x65, 0x21,
+ 0x73, 0x24, 0x1F, 0x93, 0x0E, 0x9E, 0x96, 0x88,
+ 0x78, 0x6C
+ }
+};
+
+/* SPIM-NAND header for SPI NAND with 2KB page + 64B spare */
+static const union spim_nand_boot_header spim_nand_hdr_2k_64_data = {
+ .data = {
+ 0x53, 0x50, 0x49, 0x4e, 0x41, 0x4e, 0x44, 0x21,
+ 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x20, 0x30,
+ 0x01, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ }
+};
+
+/* SPIM-NAND header for SPI NAND with 2KB page + 128B spare */
+static const union spim_nand_boot_header spim_nand_hdr_2k_128_data = {
+ .data = {
+ 0x53, 0x50, 0x49, 0x4e, 0x41, 0x4e, 0x44, 0x21,
+ 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x20, 0x30,
+ 0x01, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ }
+};
+
+/* SPIM-NAND header for SPI NAND with 4KB page + 256B spare */
+static const union spim_nand_boot_header spim_nand_hdr_4k_256_data = {
+ .data = {
+ 0x53, 0x50, 0x49, 0x4e, 0x41, 0x4e, 0x44, 0x21,
+ 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x40, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x20, 0x30,
+ 0x01, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ }
+};
+
+struct nand_header_type {
+ const char *name;
+ enum nand_boot_header_type type;
+ union {
+ const union nand_boot_header *ap;
+ const union hsm_nand_boot_header *hsm;
+ const union hsm20_nand_boot_header *hsm20;
+ const union spim_nand_boot_header *spim;
+ };
+} nand_headers[] = {
+ {
+ .name = "2k+64",
+ .type = NAND_BOOT_AP_HEADER,
+ .ap = &snand_hdr_2k_64_data,
+ }, {
+ .name = "2k+120",
+ .type = NAND_BOOT_AP_HEADER,
+ .ap = &snand_hdr_2k_128_data,
+ }, {
+ .name = "2k+128",
+ .type = NAND_BOOT_AP_HEADER,
+ .ap = &snand_hdr_2k_128_data,
+ }, {
+ .name = "4k+256",
+ .type = NAND_BOOT_AP_HEADER,
+ .ap = &snand_hdr_4k_256_data,
+ }, {
+ .name = "1g:2k+64",
+ .type = NAND_BOOT_AP_HEADER,
+ .ap = &nand_hdr_1gb_2k_64_data,
+ }, {
+ .name = "2g:2k+64",
+ .type = NAND_BOOT_AP_HEADER,
+ .ap = &nand_hdr_2gb_2k_64_data,
+ }, {
+ .name = "4g:2k+64",
+ .type = NAND_BOOT_AP_HEADER,
+ .ap = &nand_hdr_4gb_2k_64_data,
+ }, {
+ .name = "2g:2k+128",
+ .type = NAND_BOOT_AP_HEADER,
+ .ap = &nand_hdr_2gb_2k_128_data,
+ }, {
+ .name = "4g:2k+128",
+ .type = NAND_BOOT_AP_HEADER,
+ .ap = &nand_hdr_4gb_2k_128_data,
+ }, {
+ .name = "hsm:2k+64",
+ .type = NAND_BOOT_HSM_HEADER,
+ .hsm = &hsm_nand_hdr_2k_64_data,
+ }, {
+ .name = "hsm:2k+128",
+ .type = NAND_BOOT_HSM_HEADER,
+ .hsm = &hsm_nand_hdr_2k_128_data,
+ }, {
+ .name = "hsm:4k+256",
+ .type = NAND_BOOT_HSM_HEADER,
+ .hsm = &hsm_nand_hdr_4k_256_data,
+ }, {
+ .name = "hsm20:2k+64",
+ .type = NAND_BOOT_HSM20_HEADER,
+ .hsm20 = &hsm20_nand_hdr_2k_64_data,
+ }, {
+ .name = "hsm20:2k+128",
+ .type = NAND_BOOT_HSM20_HEADER,
+ .hsm20 = &hsm20_nand_hdr_2k_128_data,
+ }, {
+ .name = "hsm20:4k+256",
+ .type = NAND_BOOT_HSM20_HEADER,
+ .hsm20 = &hsm20_nand_hdr_4k_256_data,
+ }, {
+ .name = "spim:2k+64",
+ .type = NAND_BOOT_SPIM_HEADER,
+ .spim = &spim_nand_hdr_2k_64_data,
+ }, {
+ .name = "spim:2k+128",
+ .type = NAND_BOOT_SPIM_HEADER,
+ .spim = &spim_nand_hdr_2k_128_data,
+ }, {
+ .name = "spim:4k+256",
+ .type = NAND_BOOT_SPIM_HEADER,
+ .spim = &spim_nand_hdr_4k_256_data,
+ }
+};
+
+const struct nand_header_type *mtk_nand_header_find(const char *name)
+{
+ uint32_t i;
+
+ for (i = 0; i < ARRAY_SIZE(nand_headers); i++) {
+ if (!strcmp(nand_headers[i].name, name))
+ return &nand_headers[i];
+ }
+
+ return NULL;
+}
+
+uint32_t mtk_nand_header_size(const struct nand_header_type *hdr_nand)
+{
+ switch (hdr_nand->type) {
+ case NAND_BOOT_HSM_HEADER:
+ return le32_to_cpu(hdr_nand->hsm->page_size);
+
+ case NAND_BOOT_HSM20_HEADER:
+ return le32_to_cpu(hdr_nand->hsm20->page_size);
+
+ case NAND_BOOT_SPIM_HEADER:
+ return le32_to_cpu(hdr_nand->spim->page_size);
+
+ default:
+ return 2 * le16_to_cpu(hdr_nand->ap->pagesize);
+ }
+}
+
+static int mtk_nand_header_ap_info(const void *ptr,
+ struct nand_header_info *info)
+{
+ union nand_boot_header *nh = (union nand_boot_header *)ptr;
+
+ if (strncmp(nh->version, NAND_BOOT_VERSION, sizeof(nh->version)) ||
+ strcmp(nh->id, NAND_BOOT_ID))
+ return -1;
+
+ info->page_size = le16_to_cpu(nh->pagesize);
+ info->spare_size = le16_to_cpu(nh->oobsize);
+ info->gfh_offset = 2 * info->page_size;
+ info->snfi = true;
+
+ return 0;
+}
+
+static int mtk_nand_header_hsm_info(const void *ptr,
+ struct nand_header_info *info)
+{
+ union hsm_nand_boot_header *nh = (union hsm_nand_boot_header *)ptr;
+
+ info->page_size = le16_to_cpu(nh->page_size);
+ info->spare_size = le16_to_cpu(nh->spare_size);
+ info->gfh_offset = info->page_size;
+ info->snfi = true;
+
+ return 1;
+}
+
+static int mtk_nand_header_spim_info(const void *ptr,
+ struct nand_header_info *info)
+{
+ union spim_nand_boot_header *nh = (union spim_nand_boot_header *)ptr;
+
+ info->page_size = le16_to_cpu(nh->page_size);
+ info->spare_size = le16_to_cpu(nh->spare_size);
+ info->gfh_offset = info->page_size;
+ info->snfi = false;
+
+ return 1;
+}
+
+int mtk_nand_header_info(const void *ptr, struct nand_header_info *info)
+{
+ if (!strcmp((char *)ptr, NAND_BOOT_NAME))
+ return mtk_nand_header_ap_info(ptr, info);
+ else if (!strncmp((char *)ptr, HSM_NAND_BOOT_NAME, 8))
+ return mtk_nand_header_hsm_info(ptr, info);
+ else if (!strncmp((char *)ptr, SPIM_NAND_BOOT_NAME, 8))
+ return mtk_nand_header_spim_info(ptr, info);
+
+ return -1;
+}
+
+bool is_mtk_nand_header(const void *ptr)
+{
+ struct nand_header_info info;
+
+ if (mtk_nand_header_info(ptr, &info) >= 0)
+ return true;
+
+ return false;
+}
+
+static uint16_t crc16(const uint8_t *p, uint32_t len)
+{
+ uint16_t crc = 0x4f4e;
+ uint32_t i;
+
+ while (len--) {
+ crc ^= *p++ << 8;
+ for (i = 0; i < 8; i++)
+ crc = (crc << 1) ^ ((crc & 0x8000) ? 0x8005 : 0);
+ }
+
+ return crc;
+}
+
+static uint32_t mtk_nand_header_put_ap(const struct nand_header_type *hdr_nand,
+ void *ptr)
+{
+ int i;
+
+ /* NAND device header, repeat 4 times */
+ for (i = 0; i < 4; i++) {
+ memcpy(ptr, hdr_nand->ap, sizeof(*hdr_nand->ap));
+ ptr += sizeof(*hdr_nand->ap);
+ }
+
+ return le16_to_cpu(hdr_nand->ap->pagesize);
+}
+
+static uint32_t mtk_nand_header_put_hsm(const struct nand_header_type *hdr_nand,
+ void *ptr)
+{
+ memcpy(ptr, hdr_nand->hsm, sizeof(*hdr_nand->hsm));
+ return 0;
+}
+
+static uint32_t mtk_nand_header_put_hsm20(const struct nand_header_type *hdr_nand,
+ void *ptr)
+{
+ memcpy(ptr, hdr_nand->hsm20, sizeof(*hdr_nand->hsm20));
+ return 0;
+}
+
+static uint32_t mtk_nand_header_put_spim(const struct nand_header_type *hdr_nand,
+ void *ptr)
+{
+ uint16_t crc;
+
+ memcpy(ptr, hdr_nand->spim, sizeof(*hdr_nand->spim));
+
+ crc = crc16(ptr, 0x4e);
+ memcpy(ptr + 0x4e, &crc, sizeof(uint16_t));
+
+ return 0;
+}
+
+uint32_t mtk_nand_header_put(const struct nand_header_type *hdr_nand, void *ptr)
+{
+ switch (hdr_nand->type) {
+ case NAND_BOOT_HSM_HEADER:
+ return mtk_nand_header_put_hsm(hdr_nand, ptr);
+
+ case NAND_BOOT_HSM20_HEADER:
+ return mtk_nand_header_put_hsm20(hdr_nand, ptr);
+
+ case NAND_BOOT_SPIM_HEADER:
+ return mtk_nand_header_put_spim(hdr_nand, ptr);
+
+ default:
+ return mtk_nand_header_put_ap(hdr_nand, ptr);
+ }
+}
diff --git a/tools/mtk_nand_headers.h b/tools/mtk_nand_headers.h
new file mode 100644
index 0000000..9b1c4ba
--- /dev/null
+++ b/tools/mtk_nand_headers.h
@@ -0,0 +1,165 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * MediaTek BootROM NAND header definitions
+ *
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#ifndef _MTK_NAND_HEADERS_H
+#define _MTK_NAND_HEADERS_H
+
+#include <stdint.h>
+#include <stdbool.h>
+
+struct nand_header_info {
+ uint32_t page_size;
+ uint32_t spare_size;
+ uint32_t gfh_offset;
+ bool snfi;
+};
+
+/* AP BROM Header for NAND */
+union nand_boot_header {
+ struct {
+ char name[12];
+ char version[4];
+ char id[8];
+ uint16_t ioif; /* I/O interface */
+ uint16_t pagesize; /* NAND page size */
+ uint16_t addrcycles; /* Address cycles */
+ uint16_t oobsize; /* NAND page spare size */
+ uint16_t pages_of_block; /* Pages of one block */
+ uint16_t numblocks; /* Total blocks of NAND chip */
+ uint16_t writesize_shift;
+ uint16_t erasesize_shift;
+ uint8_t dummy[60];
+ uint8_t ecc_parity[28]; /* ECC parity of this header */
+ };
+
+ uint8_t data[0x80];
+};
+
+/* HSM BROM Header for NAND */
+union hsm_nand_boot_header {
+ struct {
+ char id[8];
+ uint32_t version; /* Header version */
+ uint32_t config; /* Header config */
+ uint32_t sector_size; /* ECC step size */
+ uint32_t fdm_size; /* User OOB size of a step */
+ uint32_t fdm_ecc_size; /* ECC parity size of a step */
+ uint32_t lbs;
+ uint32_t page_size; /* NAND page size */
+ uint32_t spare_size; /* NAND page spare size */
+ uint32_t page_per_block; /* Pages of one block */
+ uint32_t blocks; /* Total blocks of NAND chip */
+ uint32_t plane_sel_position; /* Plane bit position */
+ uint32_t pll; /* Value of pll reg */
+ uint32_t acccon; /* Value of access timing reg */
+ uint32_t strobe_sel; /* Value of DQS selection reg*/
+ uint32_t acccon1; /* Value of access timing reg */
+ uint32_t dqs_mux; /* Value of DQS mux reg */
+ uint32_t dqs_ctrl; /* Value of DQS control reg */
+ uint32_t delay_ctrl; /* Value of delay ctrl reg */
+ uint32_t latch_lat; /* Value of latch latency reg */
+ uint32_t sample_delay; /* Value of sample delay reg */
+ uint32_t driving; /* Value of driving reg */
+ uint32_t bl_start; /* Bootloader start addr */
+ uint32_t bl_end; /* Bootloader end addr */
+ uint8_t ecc_parity[42]; /* ECC parity of this header */
+ };
+
+ uint8_t data[0x8E];
+};
+
+/* HSM2.0 BROM Header for NAND */
+union hsm20_nand_boot_header {
+ struct {
+ char id[8];
+ uint32_t version; /* Header version */
+ uint32_t config; /* Header config */
+ uint32_t sector_size; /* ECC step size */
+ uint32_t fdm_size; /* User OOB size of a step */
+ uint32_t fdm_ecc_size; /* ECC parity size of a step */
+ uint32_t lbs;
+ uint32_t page_size; /* NAND page size */
+ uint32_t spare_size; /* NAND page spare size */
+ uint32_t page_per_block; /* Pages of one block */
+ uint32_t blocks; /* Total blocks of NAND chip */
+ uint32_t plane_sel_position; /* Plane bit position */
+ uint32_t pll; /* Value of pll reg */
+ uint32_t acccon; /* Value of access timing reg */
+ uint32_t strobe_sel; /* Value of DQS selection reg*/
+ uint32_t acccon1; /* Value of access timing reg */
+ uint32_t dqs_mux; /* Value of DQS mux reg */
+ uint32_t dqs_ctrl; /* Value of DQS control reg */
+ uint32_t delay_ctrl; /* Value of delay ctrl reg */
+ uint32_t latch_lat; /* Value of latch latency reg */
+ uint32_t sample_delay; /* Value of sample delay reg */
+ uint32_t driving; /* Value of driving reg */
+ uint32_t reserved;
+ uint32_t bl0_start; /* Bootloader start addr */
+ uint32_t bl0_end; /* Bootloader end addr */
+ uint32_t bl0_type; /* Bootloader type */
+ uint8_t bl_reserve[84];
+ uint8_t ecc_parity[42]; /* ECC parity of this header */
+ };
+
+ uint8_t data[0xEA];
+};
+
+/* SPIM BROM Header for SPI-NAND */
+union spim_nand_boot_header {
+ struct {
+ char id[8];
+ uint32_t version; /* Header version */
+ uint32_t config; /* Header config */
+ uint32_t page_size; /* NAND page size */
+ uint32_t spare_size; /* NAND page spare size */
+ uint16_t page_per_block; /* Pages of one block */
+ uint16_t plane_sel_position; /* Plane bit position */
+ uint16_t reserve_reg;
+ uint16_t reserve_val;
+ uint16_t ecc_error; /* ECC error reg addr */
+ uint16_t ecc_mask; /* ECC error bit mask */
+ uint32_t bl_start; /* Bootloader start addr */
+ uint32_t bl_end; /* Bootloader end addr */
+ uint8_t ecc_parity[32]; /* ECC parity of this header */
+ uint32_t integrity_crc; /* CRC of this header */
+ };
+
+ uint8_t data[0x50];
+};
+
+enum nand_boot_header_type {
+ NAND_BOOT_AP_HEADER,
+ NAND_BOOT_HSM_HEADER,
+ NAND_BOOT_HSM20_HEADER,
+ NAND_BOOT_SPIM_HEADER
+};
+
+#define NAND_BOOT_NAME "BOOTLOADER!"
+#define NAND_BOOT_VERSION "V006"
+#define NAND_BOOT_ID "NFIINFO"
+
+#define HSM_NAND_BOOT_NAME "NANDCFG!"
+#define SPIM_NAND_BOOT_NAME "SPINAND!"
+
+/* Find nand header data by name */
+const struct nand_header_type *mtk_nand_header_find(const char *name);
+
+/* Device header size using this nand header */
+uint32_t mtk_nand_header_size(const struct nand_header_type *hdr_nand);
+
+/* Get nand info from nand header (page size, spare size, ...) */
+int mtk_nand_header_info(const void *ptr, struct nand_header_info *info);
+
+/* Whether given header data is valid */
+bool is_mtk_nand_header(const void *ptr);
+
+/* Generate Device header using give nand header */
+uint32_t mtk_nand_header_put(const struct nand_header_type *hdr_nand,
+ void *ptr);
+
+#endif /* _MTK_NAND_HEADERS_H */