summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS3
-rw-r--r--Makefile1
-rw-r--r--README12
-rw-r--r--arch/arm/dts/mt8512-bm1-emmc.dts34
-rw-r--r--arch/arm/dts/mt8512.dtsi49
-rw-r--r--arch/arm/dts/r8a774c0.dtsi1960
-rw-r--r--arch/arm/dts/sam9x60.dtsi171
-rw-r--r--arch/arm/dts/sam9x60ek-u-boot.dtsi70
-rw-r--r--arch/arm/dts/sam9x60ek.dts12
-rw-r--r--arch/arm/mach-at91/arm926ejs/sam9x60_devices.c6
-rw-r--r--arch/arm/mach-at91/include/mach/sam9x60.h3
-rw-r--r--arch/arm/mach-rmobile/Kconfig.6414
-rw-r--r--common/spl/spl_fit.c7
-rw-r--r--configs/apalis_imx6_defconfig2
-rw-r--r--configs/aristainetos2_defconfig2
-rw-r--r--configs/aristainetos2b_defconfig2
-rw-r--r--configs/aristainetos2bcsl_defconfig2
-rw-r--r--configs/aristainetos2c_defconfig2
-rw-r--r--configs/cgtqmx6eval_defconfig2
-rw-r--r--configs/cm_fx6_defconfig1
-rw-r--r--configs/colibri-imx6ull_defconfig2
-rw-r--r--configs/colibri_imx6_defconfig2
-rw-r--r--configs/colibri_imx7_defconfig2
-rw-r--r--configs/colibri_imx7_emmc_defconfig2
-rw-r--r--configs/dms-ba16-1g_defconfig1
-rw-r--r--configs/dms-ba16_defconfig1
-rw-r--r--configs/imx6dl_icore_nand_defconfig2
-rw-r--r--configs/imx6q_icore_nand_defconfig2
-rw-r--r--configs/imx6qdl_icore_mmc_defconfig2
-rw-r--r--configs/imx6qdl_icore_nand_defconfig2
-rw-r--r--configs/imxrt1050-evk_defconfig2
-rw-r--r--configs/khadas-vim3_defconfig4
-rw-r--r--configs/khadas-vim3l_defconfig4
-rw-r--r--configs/libretech-ac_defconfig4
-rw-r--r--configs/libretech-cc_defconfig4
-rw-r--r--configs/libretech-s905d-pc_defconfig4
-rw-r--r--configs/libretech-s912-pc_defconfig4
-rw-r--r--configs/m53menlo_defconfig3
-rw-r--r--configs/marsboard_defconfig2
-rw-r--r--configs/mt8512_bm1_emmc_defconfig26
-rw-r--r--configs/mx23evk_defconfig2
-rw-r--r--configs/mx28evk_auart_console_defconfig2
-rw-r--r--configs/mx28evk_defconfig2
-rw-r--r--configs/mx28evk_nand_defconfig2
-rw-r--r--configs/mx28evk_spi_defconfig2
-rw-r--r--configs/mx51evk_defconfig1
-rw-r--r--configs/mx53loco_defconfig1
-rw-r--r--configs/mx6cuboxi_defconfig2
-rw-r--r--configs/mx6qsabrelite_defconfig3
-rw-r--r--configs/mx6sabreauto_defconfig2
-rw-r--r--configs/mx6sabresd_defconfig2
-rw-r--r--configs/mx6sxsabresd_defconfig1
-rw-r--r--configs/mx6ul_14x14_evk_defconfig2
-rw-r--r--configs/mx6ul_9x9_evk_defconfig2
-rw-r--r--configs/mx7dsabresd_defconfig1
-rw-r--r--configs/mx7dsabresd_qspi_defconfig1
-rw-r--r--configs/nitrogen6dl2g_defconfig3
-rw-r--r--configs/nitrogen6dl_defconfig3
-rw-r--r--configs/nitrogen6q2g_defconfig3
-rw-r--r--configs/nitrogen6q_defconfig3
-rw-r--r--configs/nitrogen6s1g_defconfig3
-rw-r--r--configs/nitrogen6s_defconfig3
-rw-r--r--configs/novena_defconfig2
-rw-r--r--configs/odroid-c2_defconfig4
-rw-r--r--configs/odroid-c4_defconfig4
-rw-r--r--configs/odroid-n2_defconfig4
-rw-r--r--configs/opos6uldev_defconfig4
-rw-r--r--configs/pico-dwarf-imx6ul_defconfig1
-rw-r--r--configs/pico-dwarf-imx7d_defconfig2
-rw-r--r--configs/pico-hobbit-imx6ul_defconfig1
-rw-r--r--configs/pico-hobbit-imx7d_defconfig2
-rw-r--r--configs/pico-imx6_defconfig2
-rw-r--r--configs/pico-imx7d_bl33_defconfig2
-rw-r--r--configs/pico-imx7d_defconfig2
-rw-r--r--configs/pico-nymph-imx7d_defconfig2
-rw-r--r--configs/pico-pi-imx6ul_defconfig1
-rw-r--r--configs/pico-pi-imx7d_defconfig2
-rw-r--r--configs/puma-rk3399_defconfig3
-rw-r--r--configs/pxm2_defconfig1
-rw-r--r--configs/riotboard_defconfig2
-rw-r--r--configs/riotboard_spl_defconfig2
-rw-r--r--configs/rut_defconfig1
-rw-r--r--configs/s5p4418_nanopi2_defconfig1
-rw-r--r--configs/sam9x60ek_mmc_defconfig4
-rw-r--r--configs/sam9x60ek_nandflash_defconfig4
-rw-r--r--configs/sam9x60ek_qspiflash_defconfig4
-rw-r--r--configs/sandbox64_defconfig1
-rw-r--r--configs/sandbox_defconfig1
-rw-r--r--configs/sandbox_flattree_defconfig1
-rw-r--r--configs/sandbox_spl_defconfig1
-rw-r--r--configs/sei510_defconfig4
-rw-r--r--configs/sei610_defconfig4
-rw-r--r--configs/stm32f746-disco_defconfig4
-rw-r--r--configs/stm32f769-disco_defconfig4
-rw-r--r--configs/stm32mp15_basic_defconfig4
-rw-r--r--configs/stm32mp15_dhcom_basic_defconfig4
-rw-r--r--configs/stm32mp15_dhcor_basic_defconfig4
-rw-r--r--configs/stm32mp15_trusted_defconfig4
-rw-r--r--configs/tbs2910_defconfig1
-rw-r--r--configs/theadorable-x86-conga-qa3-e3845-pcie-x4_defconfig1
-rw-r--r--configs/theadorable-x86-conga-qa3-e3845_defconfig1
-rw-r--r--configs/theadorable-x86-dfi-bt700_defconfig1
-rw-r--r--configs/theadorable_debug_defconfig3
-rw-r--r--configs/wandboard_defconfig2
-rw-r--r--doc/device-tree-bindings/usb/generic.txt31
-rw-r--r--doc/device-tree-bindings/usb/mediatek,mtu3.txt79
-rw-r--r--drivers/clk/at91/Makefile1
-rw-r--r--drivers/clk/at91/clk-master.c2
-rw-r--r--drivers/clk/at91/pmc.h2
-rw-r--r--drivers/clk/at91/sam9x60.c649
-rw-r--r--drivers/clk/at91/sama7g5.c4
-rw-r--r--drivers/clk/renesas/Kconfig18
-rw-r--r--drivers/clk/renesas/Makefile3
-rw-r--r--drivers/clk/renesas/r8a774a1-cpg-mssr.c4
-rw-r--r--drivers/clk/renesas/r8a774b1-cpg-mssr.c336
-rw-r--r--drivers/clk/renesas/r8a774c0-cpg-mssr.c308
-rw-r--r--drivers/clk/renesas/r8a774e1-cpg-mssr.c358
-rw-r--r--drivers/pinctrl/renesas/pfc-r8a77990.c57
-rw-r--r--drivers/spi/renesas_rpc_spi.c3
-rw-r--r--drivers/usb/Kconfig2
-rw-r--r--drivers/usb/common/common.c8
-rw-r--r--drivers/usb/gadget/dwc2_udc_otg_xfer_dma.c16
-rw-r--r--drivers/usb/gadget/gadget_chips.h8
-rw-r--r--drivers/usb/host/xhci-mem.c21
-rw-r--r--drivers/usb/mtu3/Kconfig44
-rw-r--r--drivers/usb/mtu3/Makefile11
-rw-r--r--drivers/usb/mtu3/mtu3.h424
-rw-r--r--drivers/usb/mtu3/mtu3_core.c838
-rw-r--r--drivers/usb/mtu3/mtu3_dr.h52
-rw-r--r--drivers/usb/mtu3/mtu3_gadget.c686
-rw-r--r--drivers/usb/mtu3/mtu3_gadget_ep0.c933
-rw-r--r--drivers/usb/mtu3/mtu3_host.c141
-rw-r--r--drivers/usb/mtu3/mtu3_hw_regs.h515
-rw-r--r--drivers/usb/mtu3/mtu3_plat.c369
-rw-r--r--drivers/usb/mtu3/mtu3_qmu.c505
-rw-r--r--drivers/usb/mtu3/mtu3_qmu.h37
-rw-r--r--drivers/usb/musb-new/musb_dsps.c2
-rw-r--r--drivers/video/Kconfig33
-rw-r--r--drivers/video/dw_mipi_dsi.c37
-rw-r--r--drivers/video/pwm_backlight.c4
-rw-r--r--include/configs/advantech_dms-ba16.h2
-rw-r--r--include/configs/apalis_imx6.h2
-rw-r--r--include/configs/aristainetos2.h2
-rw-r--r--include/configs/cgtqmx6eval.h2
-rw-r--r--include/configs/cm_fx6.h2
-rw-r--r--include/configs/colibri-imx6ull.h2
-rw-r--r--include/configs/colibri_imx6.h2
-rw-r--r--include/configs/colibri_imx7.h2
-rw-r--r--include/configs/embestmx6boards.h2
-rw-r--r--include/configs/imx6-engicam.h2
-rw-r--r--include/configs/imxrt1050-evk.h2
-rw-r--r--include/configs/m53menlo.h3
-rw-r--r--include/configs/meson64.h4
-rw-r--r--include/configs/mx23evk.h3
-rw-r--r--include/configs/mx28evk.h3
-rw-r--r--include/configs/mx51evk.h2
-rw-r--r--include/configs/mx53loco.h2
-rw-r--r--include/configs/mx6cuboxi.h2
-rw-r--r--include/configs/mx6sabre_common.h2
-rw-r--r--include/configs/mx6sxsabresd.h2
-rw-r--r--include/configs/mx6ul_14x14_evk.h2
-rw-r--r--include/configs/mx7dsabresd.h2
-rw-r--r--include/configs/nitrogen6x.h3
-rw-r--r--include/configs/novena.h2
-rw-r--r--include/configs/opos6uldev.h4
-rw-r--r--include/configs/pico-imx6.h2
-rw-r--r--include/configs/pico-imx6ul.h2
-rw-r--r--include/configs/pico-imx7d.h2
-rw-r--r--include/configs/puma_rk3399.h4
-rw-r--r--include/configs/pxm2.h1
-rw-r--r--include/configs/rut.h1
-rw-r--r--include/configs/s5p4418_nanopi2.h5
-rw-r--r--include/configs/s5pc210_universal.h2
-rw-r--r--include/configs/sam9x60ek.h3
-rw-r--r--include/configs/sandbox.h1
-rw-r--r--include/configs/stm32f746-disco.h6
-rw-r--r--include/configs/stm32mp1.h7
-rw-r--r--include/configs/tbs2910.h1
-rw-r--r--include/configs/theadorable-x86-common.h1
-rw-r--r--include/configs/theadorable.h4
-rw-r--r--include/configs/trats.h2
-rw-r--r--include/configs/trats2.h2
-rw-r--r--include/configs/wandboard.h2
-rw-r--r--include/dt-bindings/clock/r8a774c0-cpg-mssr.h61
-rw-r--r--include/dt-bindings/power/r8a774c0-sysc.h25
-rw-r--r--include/linux/usb/ch9.h5
-rw-r--r--include/mipi_dsi.h17
-rw-r--r--scripts/config_whitelist.txt5
-rw-r--r--test/dm/panel.c12
189 files changed, 8951 insertions, 399 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index fb9ba379842..5047ec6598a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -266,6 +266,7 @@ F: arch/arm/include/asm/arch-pxa/
ARM MEDIATEK
M: Ryder Lee <ryder.lee@mediatek.com>
M: Weijie Gao <weijie.gao@mediatek.com>
+M: Chunfeng Yun <chunfeng.yun@mediatek.com>
R: GSS_MTK_Uboot_upstream <GSS_MTK_Uboot_upstream@mediatek.com>
S: Maintained
F: arch/arm/mach-mediatek/
@@ -282,6 +283,8 @@ F: drivers/power/domain/mtk-power-domain.c
F: drivers/ram/mediatek/
F: drivers/spi/mtk_snfi_spi.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/reset/reset-mediatek.c
diff --git a/Makefile b/Makefile
index 28c9f31fb44..6c3a953fdbd 100644
--- a/Makefile
+++ b/Makefile
@@ -795,6 +795,7 @@ libs-y += drivers/usb/eth/
libs-$(CONFIG_USB_GADGET) += drivers/usb/gadget/
libs-$(CONFIG_USB_GADGET) += drivers/usb/gadget/udc/
libs-y += drivers/usb/host/
+libs-y += drivers/usb/mtu3/
libs-y += drivers/usb/musb/
libs-y += drivers/usb/musb-new/
libs-y += drivers/usb/phy/
diff --git a/README b/README
index 91c5a1a8fa3..df824b67e75 100644
--- a/README
+++ b/README
@@ -1250,18 +1250,6 @@ The following options need to be configured:
Enables an 'i2c edid' command which can read EDID
information over I2C from an attached LCD display.
-- Gzip compressed BMP image support: CONFIG_VIDEO_BMP_GZIP
-
- If this option is set, additionally to standard BMP
- images, gzipped BMP images can be displayed via the
- splashscreen support or the bmp command.
-
-- Run length encoded BMP image (RLE8) support: CONFIG_VIDEO_BMP_RLE8
-
- If this option is set, 8-bit RLE compressed BMP images
- can be displayed via the splashscreen support or the
- bmp command.
-
- MII/PHY support:
CONFIG_PHY_CLOCK_FREQ (ppc4xx)
diff --git a/arch/arm/dts/mt8512-bm1-emmc.dts b/arch/arm/dts/mt8512-bm1-emmc.dts
index 296ed93b9ee..12511b5fed4 100644
--- a/arch/arm/dts/mt8512-bm1-emmc.dts
+++ b/arch/arm/dts/mt8512-bm1-emmc.dts
@@ -43,6 +43,25 @@
regulator-boot-on;
regulator-always-on;
};
+
+ usb_p0_vbus: regulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "p0_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio 27 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ usb_p1_vbus: regulator@1 {
+ compatible = "regulator-fixed";
+ regulator-name = "p1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio 32 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-always-on;
+ };
};
&mmc0 {
@@ -95,6 +114,21 @@
};
};
+&ssusb {
+ dr_mode = "peripheral";
+ maximum-speed = "high-speed";
+ status = "okay";
+};
+
+&usb3 {
+ vbus-supply = <&usb_p0_vbus>;
+ status = "okay";
+};
+
+&u3phy {
+ status = "okay";
+};
+
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_pins>;
diff --git a/arch/arm/dts/mt8512.dtsi b/arch/arm/dts/mt8512.dtsi
index 01a02a7ebf2..bdb84f8ef00 100644
--- a/arch/arm/dts/mt8512.dtsi
+++ b/arch/arm/dts/mt8512.dtsi
@@ -9,6 +9,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/phy/phy.h>
/ {
compatible = "mediatek,mt8512";
@@ -100,6 +101,52 @@
status = "disabled";
};
+ usb3: usb@11213e00 {
+ compatible = "mediatek,mt8512-mtu3", "mediatek,mtu3";
+ reg = <0x11213e00 0x0100>;
+ reg-names = "ippc";
+ phys = <&u2port0 PHY_TYPE_USB2>, <&u2port1 PHY_TYPE_USB2>;
+ clocks = <&infracfg CLK_INFRA_USB_SYS>,
+ <&topckgen CLK_TOP_SSUSB_TOP_CK_EN>,
+ <&infracfg CLK_INFRA_ICUSB>;
+ clock-names = "sys_ck", "ref_ck", "mcu_ck";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ status = "disabled";
+
+ ssusb: usb@11210000 {
+ compatible = "mediatek,ssusb";
+ reg = <0x11210000 0x3e00>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_LOW>;
+ reg-names = "mac";
+ status = "disabled";
+ };
+ };
+
+ u3phy: usb-phy@11cc0000 {
+ compatible = "mediatek,mt8512-tphy",
+ "mediatek,generic-tphy-v2";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ status = "disabled";
+
+ u2port0: usb-phy@11cc0000 {
+ reg = <0x11cc0000 0x400>;
+ clocks = <&topckgen CLK_TOP_USB20_48M_EN>;
+ clock-names = "ref";
+ #phy-cells = <1>;
+ status = "okay";
+ };
+
+ u2port1: usb-phy@11c40000 {
+ reg = <0x11c40000 0x400>;
+ #phy-cells = <1>;
+ status = "okay";
+ };
+ };
+
mmc0: mmc@11230000 {
compatible = "mediatek,mt8512-mmc";
reg = <0x11230000 0x1000>,
@@ -112,4 +159,4 @@
status = "disabled";
};
-}; \ No newline at end of file
+};
diff --git a/arch/arm/dts/r8a774c0.dtsi b/arch/arm/dts/r8a774c0.dtsi
new file mode 100644
index 00000000000..e14db4d363d
--- /dev/null
+++ b/arch/arm/dts/r8a774c0.dtsi
@@ -0,0 +1,1960 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for the RZ/G2E (R8A774C0) SoC
+ *
+ * Copyright (C) 2020 Renesas Electronics Corp.
+ */
+
+#include <dt-bindings/clock/r8a774c0-cpg-mssr.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/r8a774c0-sysc.h>
+
+/ {
+ compatible = "renesas,r8a774c0";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ /*
+ * The external audio clocks are configured as 0 Hz fixed frequency
+ * clocks by default.
+ * Boards that provide audio clocks should override them.
+ */
+ audio_clk_a: audio_clk_a {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ audio_clk_b: audio_clk_b {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ audio_clk_c: audio_clk_c {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ /* External CAN clock - to be overridden by boards that provide it */
+ can_clk: can {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ cluster1_opp: opp_table10 {
+ compatible = "operating-points-v2";
+ opp-shared;
+ opp-800000000 {
+ opp-hz = /bits/ 64 <800000000>;
+ opp-microvolt = <820000>;
+ clock-latency-ns = <300000>;
+ };
+ opp-1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ opp-microvolt = <820000>;
+ clock-latency-ns = <300000>;
+ };
+ opp-1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+ opp-microvolt = <820000>;
+ clock-latency-ns = <300000>;
+ opp-suspend;
+ };
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ a53_0: cpu@0 {
+ compatible = "arm,cortex-a53";
+ reg = <0>;
+ device_type = "cpu";
+ #cooling-cells = <2>;
+ power-domains = <&sysc R8A774C0_PD_CA53_CPU0>;
+ next-level-cache = <&L2_CA53>;
+ enable-method = "psci";
+ dynamic-power-coefficient = <277>;
+ clocks = <&cpg CPG_CORE R8A774C0_CLK_Z2>;
+ operating-points-v2 = <&cluster1_opp>;
+ };
+
+ a53_1: cpu@1 {
+ compatible = "arm,cortex-a53";
+ reg = <1>;
+ device_type = "cpu";
+ power-domains = <&sysc R8A774C0_PD_CA53_CPU1>;
+ next-level-cache = <&L2_CA53>;
+ enable-method = "psci";
+ clocks = <&cpg CPG_CORE R8A774C0_CLK_Z2>;
+ operating-points-v2 = <&cluster1_opp>;
+ };
+
+ L2_CA53: cache-controller-0 {
+ compatible = "cache";
+ power-domains = <&sysc R8A774C0_PD_CA53_SCU>;
+ cache-unified;
+ cache-level = <2>;
+ };
+ };
+
+ extal_clk: extal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overridden by the board */
+ clock-frequency = <0>;
+ };
+
+ /* External PCIe clock - can be overridden by the board */
+ pcie_bus_clk: pcie_bus {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ pmu_a53 {
+ compatible = "arm,cortex-a53-pmu";
+ interrupts-extended = <&gic GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
+ <&gic GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-affinity = <&a53_0>, <&a53_1>;
+ };
+
+ psci {
+ compatible = "arm,psci-1.0", "arm,psci-0.2";
+ method = "smc";
+ };
+
+ /* External SCIF clock - to be overridden by boards that provide it */
+ scif_clk: scif {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ soc: soc {
+ compatible = "simple-bus";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ rwdt: watchdog@e6020000 {
+ compatible = "renesas,r8a774c0-wdt",
+ "renesas,rcar-gen3-wdt";
+ reg = <0 0xe6020000 0 0x0c>;
+ clocks = <&cpg CPG_MOD 402>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 402>;
+ status = "disabled";
+ };
+
+ gpio0: gpio@e6050000 {
+ compatible = "renesas,gpio-r8a774c0",
+ "renesas,rcar-gen3-gpio";
+ reg = <0 0xe6050000 0 0x50>;
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 0 18>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&cpg CPG_MOD 912>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 912>;
+ };
+
+ gpio1: gpio@e6051000 {
+ compatible = "renesas,gpio-r8a774c0",
+ "renesas,rcar-gen3-gpio";
+ reg = <0 0xe6051000 0 0x50>;
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 32 23>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&cpg CPG_MOD 911>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 911>;
+ };
+
+ gpio2: gpio@e6052000 {
+ compatible = "renesas,gpio-r8a774c0",
+ "renesas,rcar-gen3-gpio";
+ reg = <0 0xe6052000 0 0x50>;
+ interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 64 26>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&cpg CPG_MOD 910>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 910>;
+ };
+
+ gpio3: gpio@e6053000 {
+ compatible = "renesas,gpio-r8a774c0",
+ "renesas,rcar-gen3-gpio";
+ reg = <0 0xe6053000 0 0x50>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 96 16>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&cpg CPG_MOD 909>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 909>;
+ };
+
+ gpio4: gpio@e6054000 {
+ compatible = "renesas,gpio-r8a774c0",
+ "renesas,rcar-gen3-gpio";
+ reg = <0 0xe6054000 0 0x50>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 128 11>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&cpg CPG_MOD 908>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 908>;
+ };
+
+ gpio5: gpio@e6055000 {
+ compatible = "renesas,gpio-r8a774c0",
+ "renesas,rcar-gen3-gpio";
+ reg = <0 0xe6055000 0 0x50>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 160 20>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&cpg CPG_MOD 907>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 907>;
+ };
+
+ gpio6: gpio@e6055400 {
+ compatible = "renesas,gpio-r8a774c0",
+ "renesas,rcar-gen3-gpio";
+ reg = <0 0xe6055400 0 0x50>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 192 18>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&cpg CPG_MOD 906>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 906>;
+ };
+
+ pfc: pin-controller@e6060000 {
+ compatible = "renesas,pfc-r8a774c0";
+ reg = <0 0xe6060000 0 0x508>;
+ };
+
+ cmt0: timer@e60f0000 {
+ compatible = "renesas,r8a774c0-cmt0",
+ "renesas,rcar-gen3-cmt0";
+ reg = <0 0xe60f0000 0 0x1004>;
+ interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 303>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 303>;
+ status = "disabled";
+ };
+
+ cmt1: timer@e6130000 {
+ compatible = "renesas,r8a774c0-cmt1",
+ "renesas,rcar-gen3-cmt1";
+ reg = <0 0xe6130000 0 0x1004>;
+ interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 302>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 302>;
+ status = "disabled";
+ };
+
+ cmt2: timer@e6140000 {
+ compatible = "renesas,r8a774c0-cmt1",
+ "renesas,rcar-gen3-cmt1";
+ reg = <0 0xe6140000 0 0x1004>;
+ interrupts = <GIC_SPI 398 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 399 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 400 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 401 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 402 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 403 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 404 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 405 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 301>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 301>;
+ status = "disabled";
+ };
+
+ cmt3: timer@e6148000 {
+ compatible = "renesas,r8a774c0-cmt1",
+ "renesas,rcar-gen3-cmt1";
+ reg = <0 0xe6148000 0 0x1004>;
+ interrupts = <GIC_SPI 470 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 471 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 475 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 476 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 477 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 300>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 300>;
+ status = "disabled";
+ };
+
+ cpg: clock-controller@e6150000 {
+ compatible = "renesas,r8a774c0-cpg-mssr";
+ reg = <0 0xe6150000 0 0x1000>;
+ clocks = <&extal_clk>;
+ clock-names = "extal";
+ #clock-cells = <2>;
+ #power-domain-cells = <0>;
+ #reset-cells = <1>;
+ };
+
+ rst: reset-controller@e6160000 {
+ compatible = "renesas,r8a774c0-rst";
+ reg = <0 0xe6160000 0 0x0200>;
+ };
+
+ sysc: system-controller@e6180000 {
+ compatible = "renesas,r8a774c0-sysc";
+ reg = <0 0xe6180000 0 0x0400>;
+ #power-domain-cells = <1>;
+ };
+
+ thermal: thermal@e6190000 {
+ compatible = "renesas,thermal-r8a774c0";
+ reg = <0 0xe6190000 0 0x10>, <0 0xe6190100 0 0x38>;
+ interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 522>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 522>;
+ #thermal-sensor-cells = <0>;
+ };
+
+ intc_ex: interrupt-controller@e61c0000 {
+ compatible = "renesas,intc-ex-r8a774c0", "renesas,irqc";
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ reg = <0 0xe61c0000 0 0x200>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 407>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 407>;
+ };
+
+ tmu0: timer@e61e0000 {
+ compatible = "renesas,tmu-r8a774c0", "renesas,tmu";
+ reg = <0 0xe61e0000 0 0x30>;
+ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 125>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 125>;
+ status = "disabled";
+ };
+
+ tmu1: timer@e6fc0000 {
+ compatible = "renesas,tmu-r8a774c0", "renesas,tmu";
+ reg = <0 0xe6fc0000 0 0x30>;
+ interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 124>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 124>;
+ status = "disabled";
+ };
+
+ tmu2: timer@e6fd0000 {
+ compatible = "renesas,tmu-r8a774c0", "renesas,tmu";
+ reg = <0 0xe6fd0000 0 0x30>;
+ interrupts = <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 123>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 123>;
+ status = "disabled";
+ };
+
+ tmu3: timer@e6fe0000 {
+ compatible = "renesas,tmu-r8a774c0", "renesas,tmu";
+ reg = <0 0xe6fe0000 0 0x30>;
+ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 122>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 122>;
+ status = "disabled";
+ };
+
+ tmu4: timer@ffc00000 {
+ compatible = "renesas,tmu-r8a774c0", "renesas,tmu";
+ reg = <0 0xffc00000 0 0x30>;
+ interrupts = <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 121>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 121>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@e6500000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a774c0",
+ "renesas,rcar-gen3-i2c";
+ reg = <0 0xe6500000 0 0x40>;
+ interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 931>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 931>;
+ dmas = <&dmac1 0x91>, <&dmac1 0x90>,
+ <&dmac2 0x91>, <&dmac2 0x90>;
+ dma-names = "tx", "rx", "tx", "rx";
+ i2c-scl-internal-delay-ns = <110>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@e6508000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a774c0",
+ "renesas,rcar-gen3-i2c";
+ reg = <0 0xe6508000 0 0x40>;
+ interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 930>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 930>;
+ dmas = <&dmac1 0x93>, <&dmac1 0x92>,
+ <&dmac2 0x93>, <&dmac2 0x92>;
+ dma-names = "tx", "rx", "tx", "rx";
+ i2c-scl-internal-delay-ns = <6>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@e6510000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a774c0",
+ "renesas,rcar-gen3-i2c";
+ reg = <0 0xe6510000 0 0x40>;
+ interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 929>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 929>;
+ dmas = <&dmac1 0x95>, <&dmac1 0x94>,
+ <&dmac2 0x95>, <&dmac2 0x94>;
+ dma-names = "tx", "rx", "tx", "rx";
+ i2c-scl-internal-delay-ns = <6>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@e66d0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a774c0",
+ "renesas,rcar-gen3-i2c";
+ reg = <0 0xe66d0000 0 0x40>;
+ interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 928>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 928>;
+ dmas = <&dmac0 0x97>, <&dmac0 0x96>;
+ dma-names = "tx", "rx";
+ i2c-scl-internal-delay-ns = <110>;
+ status = "disabled";
+ };
+
+ i2c4: i2c@e66d8000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a774c0",
+ "renesas,rcar-gen3-i2c";
+ reg = <0 0xe66d8000 0 0x40>;
+ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 927>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 927>;
+ dmas = <&dmac0 0x99>, <&dmac0 0x98>;
+ dma-names = "tx", "rx";
+ i2c-scl-internal-delay-ns = <6>;
+ status = "disabled";
+ };
+
+ i2c5: i2c@e66e0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a774c0",
+ "renesas,rcar-gen3-i2c";
+ reg = <0 0xe66e0000 0 0x40>;
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 919>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 919>;
+ dmas = <&dmac0 0x9b>, <&dmac0 0x9a>;
+ dma-names = "tx", "rx";
+ i2c-scl-internal-delay-ns = <6>;
+ status = "disabled";
+ };
+
+ i2c6: i2c@e66e8000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a774c0",
+ "renesas,rcar-gen3-i2c";
+ reg = <0 0xe66e8000 0 0x40>;
+ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 918>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 918>;
+ dmas = <&dmac0 0x9d>, <&dmac0 0x9c>;
+ dma-names = "tx", "rx";
+ i2c-scl-internal-delay-ns = <6>;
+ status = "disabled";
+ };
+
+ i2c7: i2c@e6690000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a774c0",
+ "renesas,rcar-gen3-i2c";
+ reg = <0 0xe6690000 0 0x40>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 1003>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 1003>;
+ i2c-scl-internal-delay-ns = <6>;
+ status = "disabled";
+ };
+
+ i2c_dvfs: i2c@e60b0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,iic-r8a774c0";
+ reg = <0 0xe60b0000 0 0x15>;
+ interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 926>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 926>;
+ dmas = <&dmac0 0x11>, <&dmac0 0x10>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ hscif0: serial@e6540000 {
+ compatible = "renesas,hscif-r8a774c0",
+ "renesas,rcar-gen3-hscif",
+ "renesas,hscif";
+ reg = <0 0xe6540000 0 0x60>;
+ interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 520>,
+ <&cpg CPG_CORE R8A774C0_CLK_S3D1C>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac1 0x31>, <&dmac1 0x30>,
+ <&dmac2 0x31>, <&dmac2 0x30>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 520>;
+ status = "disabled";
+ };
+
+ hscif1: serial@e6550000 {
+ compatible = "renesas,hscif-r8a774c0",
+ "renesas,rcar-gen3-hscif",
+ "renesas,hscif";
+ reg = <0 0xe6550000 0 0x60>;
+ interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 519>,
+ <&cpg CPG_CORE R8A774C0_CLK_S3D1C>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac1 0x33>, <&dmac1 0x32>,
+ <&dmac2 0x33>, <&dmac2 0x32>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 519>;
+ status = "disabled";
+ };
+
+ hscif2: serial@e6560000 {
+ compatible = "renesas,hscif-r8a774c0",
+ "renesas,rcar-gen3-hscif",
+ "renesas,hscif";
+ reg = <0 0xe6560000 0 0x60>;
+ interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 518>,
+ <&cpg CPG_CORE R8A774C0_CLK_S3D1C>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac1 0x35>, <&dmac1 0x34>,
+ <&dmac2 0x35>, <&dmac2 0x34>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 518>;
+ status = "disabled";
+ };
+
+ hscif3: serial@e66a0000 {
+ compatible = "renesas,hscif-r8a774c0",
+ "renesas,rcar-gen3-hscif",
+ "renesas,hscif";
+ reg = <0 0xe66a0000 0 0x60>;
+ interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 517>,
+ <&cpg CPG_CORE R8A774C0_CLK_S3D1C>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0x37>, <&dmac0 0x36>;
+ dma-names = "tx", "rx";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 517>;
+ status = "disabled";
+ };
+
+ hscif4: serial@e66b0000 {
+ compatible = "renesas,hscif-r8a774c0",
+ "renesas,rcar-gen3-hscif",
+ "renesas,hscif";
+ reg = <0 0xe66b0000 0 0x60>;
+ interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 516>,
+ <&cpg CPG_CORE R8A774C0_CLK_S3D1C>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0x39>, <&dmac0 0x38>;
+ dma-names = "tx", "rx";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 516>;
+ status = "disabled";
+ };
+
+ hsusb: usb@e6590000 {
+ compatible = "renesas,usbhs-r8a774c0",
+ "renesas,rcar-gen3-usbhs";
+ reg = <0 0xe6590000 0 0x200>;
+ interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 704>, <&cpg CPG_MOD 703>;
+ dmas = <&usb_dmac0 0>, <&usb_dmac0 1>,
+ <&usb_dmac1 0>, <&usb_dmac1 1>;
+ dma-names = "ch0", "ch1", "ch2", "ch3";
+ renesas,buswait = <11>;
+ phys = <&usb2_phy0 3>;
+ phy-names = "usb";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 704>, <&cpg 703>;
+ status = "disabled";
+ };
+
+ usb_dmac0: dma-controller@e65a0000 {
+ compatible = "renesas,r8a774c0-usb-dmac",
+ "renesas,usb-dmac";
+ reg = <0 0xe65a0000 0 0x100>;
+ interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "ch0", "ch1";
+ clocks = <&cpg CPG_MOD 330>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 330>;
+ #dma-cells = <1>;
+ dma-channels = <2>;
+ };
+
+ usb_dmac1: dma-controller@e65b0000 {
+ compatible = "renesas,r8a774c0-usb-dmac",
+ "renesas,usb-dmac";
+ reg = <0 0xe65b0000 0 0x100>;
+ interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "ch0", "ch1";
+ clocks = <&cpg CPG_MOD 331>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 331>;
+ #dma-cells = <1>;
+ dma-channels = <2>;
+ };
+
+ dmac0: dma-controller@e6700000 {
+ compatible = "renesas,dmac-r8a774c0",
+ "renesas,rcar-dmac";
+ reg = <0 0xe6700000 0 0x10000>;
+ interrupts = <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "error",
+ "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5", "ch6", "ch7",
+ "ch8", "ch9", "ch10", "ch11",
+ "ch12", "ch13", "ch14", "ch15";
+ clocks = <&cpg CPG_MOD 219>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 219>;
+ #dma-cells = <1>;
+ dma-channels = <16>;
+ iommus = <&ipmmu_ds0 0>, <&ipmmu_ds0 1>,
+ <&ipmmu_ds0 2>, <&ipmmu_ds0 3>,
+ <&ipmmu_ds0 4>, <&ipmmu_ds0 5>,
+ <&ipmmu_ds0 6>, <&ipmmu_ds0 7>,
+ <&ipmmu_ds0 8>, <&ipmmu_ds0 9>,
+ <&ipmmu_ds0 10>, <&ipmmu_ds0 11>,
+ <&ipmmu_ds0 12>, <&ipmmu_ds0 13>,
+ <&ipmmu_ds0 14>, <&ipmmu_ds0 15>;
+ };
+
+ dmac1: dma-controller@e7300000 {
+ compatible = "renesas,dmac-r8a774c0",
+ "renesas,rcar-dmac";
+ reg = <0 0xe7300000 0 0x10000>;
+ interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "error",
+ "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5", "ch6", "ch7",
+ "ch8", "ch9", "ch10", "ch11",
+ "ch12", "ch13", "ch14", "ch15";
+ clocks = <&cpg CPG_MOD 218>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 218>;
+ #dma-cells = <1>;
+ dma-channels = <16>;
+ iommus = <&ipmmu_ds1 0>, <&ipmmu_ds1 1>,
+ <&ipmmu_ds1 2>, <&ipmmu_ds1 3>,
+ <&ipmmu_ds1 4>, <&ipmmu_ds1 5>,
+ <&ipmmu_ds1 6>, <&ipmmu_ds1 7>,
+ <&ipmmu_ds1 8>, <&ipmmu_ds1 9>,
+ <&ipmmu_ds1 10>, <&ipmmu_ds1 11>,
+ <&ipmmu_ds1 12>, <&ipmmu_ds1 13>,
+ <&ipmmu_ds1 14>, <&ipmmu_ds1 15>;
+ };
+
+ dmac2: dma-controller@e7310000 {
+ compatible = "renesas,dmac-r8a774c0",
+ "renesas,rcar-dmac";
+ reg = <0 0xe7310000 0 0x10000>;
+ interrupts = <GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 427 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 428 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 429 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 430 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 431 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 397 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "error",
+ "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5", "ch6", "ch7",
+ "ch8", "ch9", "ch10", "ch11",
+ "ch12", "ch13", "ch14", "ch15";
+ clocks = <&cpg CPG_MOD 217>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 217>;
+ #dma-cells = <1>;
+ dma-channels = <16>;
+ iommus = <&ipmmu_ds1 16>, <&ipmmu_ds1 17>,
+ <&ipmmu_ds1 18>, <&ipmmu_ds1 19>,
+ <&ipmmu_ds1 20>, <&ipmmu_ds1 21>,
+ <&ipmmu_ds1 22>, <&ipmmu_ds1 23>,
+ <&ipmmu_ds1 24>, <&ipmmu_ds1 25>,
+ <&ipmmu_ds1 26>, <&ipmmu_ds1 27>,
+ <&ipmmu_ds1 28>, <&ipmmu_ds1 29>,
+ <&ipmmu_ds1 30>, <&ipmmu_ds1 31>;
+ };
+
+ ipmmu_ds0: iommu@e6740000 {
+ compatible = "renesas,ipmmu-r8a774c0";
+ reg = <0 0xe6740000 0 0x1000>;
+ renesas,ipmmu-main = <&ipmmu_mm 0>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ #iommu-cells = <1>;
+ };
+
+ ipmmu_ds1: iommu@e7740000 {
+ compatible = "renesas,ipmmu-r8a774c0";
+ reg = <0 0xe7740000 0 0x1000>;
+ renesas,ipmmu-main = <&ipmmu_mm 1>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ #iommu-cells = <1>;
+ };
+
+ ipmmu_hc: iommu@e6570000 {
+ compatible = "renesas,ipmmu-r8a774c0";
+ reg = <0 0xe6570000 0 0x1000>;
+ renesas,ipmmu-main = <&ipmmu_mm 2>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ #iommu-cells = <1>;
+ };
+
+ ipmmu_mm: iommu@e67b0000 {
+ compatible = "renesas,ipmmu-r8a774c0";
+ reg = <0 0xe67b0000 0 0x1000>;
+ interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ #iommu-cells = <1>;
+ };
+
+ ipmmu_mp: iommu@ec670000 {
+ compatible = "renesas,ipmmu-r8a774c0";
+ reg = <0 0xec670000 0 0x1000>;
+ renesas,ipmmu-main = <&ipmmu_mm 4>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ #iommu-cells = <1>;
+ };
+
+ ipmmu_pv0: iommu@fd800000 {
+ compatible = "renesas,ipmmu-r8a774c0";
+ reg = <0 0xfd800000 0 0x1000>;
+ renesas,ipmmu-main = <&ipmmu_mm 6>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ #iommu-cells = <1>;
+ };
+
+ ipmmu_vc0: iommu@fe6b0000 {
+ compatible = "renesas,ipmmu-r8a774c0";
+ reg = <0 0xfe6b0000 0 0x1000>;
+ renesas,ipmmu-main = <&ipmmu_mm 12>;
+ power-domains = <&sysc R8A774C0_PD_A3VC>;
+ #iommu-cells = <1>;
+ };
+
+ ipmmu_vi0: iommu@febd0000 {
+ compatible = "renesas,ipmmu-r8a774c0";
+ reg = <0 0xfebd0000 0 0x1000>;
+ renesas,ipmmu-main = <&ipmmu_mm 14>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ #iommu-cells = <1>;
+ };
+
+ ipmmu_vp0: iommu@fe990000 {
+ compatible = "renesas,ipmmu-r8a774c0";
+ reg = <0 0xfe990000 0 0x1000>;
+ renesas,ipmmu-main = <&ipmmu_mm 16>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ #iommu-cells = <1>;
+ };
+
+ avb: ethernet@e6800000 {
+ compatible = "renesas,etheravb-r8a774c0",
+ "renesas,etheravb-rcar-gen3";
+ reg = <0 0xe6800000 0 0x800>;
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5", "ch6", "ch7",
+ "ch8", "ch9", "ch10", "ch11",
+ "ch12", "ch13", "ch14", "ch15",
+ "ch16", "ch17", "ch18", "ch19",
+ "ch20", "ch21", "ch22", "ch23",
+ "ch24";
+ clocks = <&cpg CPG_MOD 812>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 812>;
+ phy-mode = "rgmii";
+ iommus = <&ipmmu_ds0 16>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ can0: can@e6c30000 {
+ compatible = "renesas,can-r8a774c0",
+ "renesas,rcar-gen3-can";
+ reg = <0 0xe6c30000 0 0x1000>;
+ interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 916>,
+ <&cpg CPG_CORE R8A774C0_CLK_CANFD>,
+ <&can_clk>;
+ clock-names = "clkp1", "clkp2", "can_clk";
+ assigned-clocks = <&cpg CPG_CORE R8A774C0_CLK_CANFD>;
+ assigned-clock-rates = <40000000>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 916>;
+ status = "disabled";
+ };
+
+ can1: can@e6c38000 {
+ compatible = "renesas,can-r8a774c0",
+ "renesas,rcar-gen3-can";
+ reg = <0 0xe6c38000 0 0x1000>;
+ interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 915>,
+ <&cpg CPG_CORE R8A774C0_CLK_CANFD>,
+ <&can_clk>;
+ clock-names = "clkp1", "clkp2", "can_clk";
+ assigned-clocks = <&cpg CPG_CORE R8A774C0_CLK_CANFD>;
+ assigned-clock-rates = <40000000>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 915>;
+ status = "disabled";
+ };
+
+ canfd: can@e66c0000 {
+ compatible = "renesas,r8a774c0-canfd",
+ "renesas,rcar-gen3-canfd";
+ reg = <0 0xe66c0000 0 0x8000>;
+ interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 914>,
+ <&cpg CPG_CORE R8A774C0_CLK_CANFD>,
+ <&can_clk>;
+ clock-names = "fck", "canfd", "can_clk";
+ assigned-clocks = <&cpg CPG_CORE R8A774C0_CLK_CANFD>;
+ assigned-clock-rates = <40000000>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 914>;
+ status = "disabled";
+
+ channel0 {
+ status = "disabled";
+ };
+
+ channel1 {
+ status = "disabled";
+ };
+ };
+
+ pwm0: pwm@e6e30000 {
+ compatible = "renesas,pwm-r8a774c0", "renesas,pwm-rcar";
+ reg = <0 0xe6e30000 0 0x8>;
+ clocks = <&cpg CPG_MOD 523>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 523>;
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+ pwm1: pwm@e6e31000 {
+ compatible = "renesas,pwm-r8a774c0", "renesas,pwm-rcar";
+ reg = <0 0xe6e31000 0 0x8>;
+ clocks = <&cpg CPG_MOD 523>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 523>;
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+ pwm2: pwm@e6e32000 {
+ compatible = "renesas,pwm-r8a774c0", "renesas,pwm-rcar";
+ reg = <0 0xe6e32000 0 0x8>;
+ clocks = <&cpg CPG_MOD 523>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 523>;
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+ pwm3: pwm@e6e33000 {
+ compatible = "renesas,pwm-r8a774c0", "renesas,pwm-rcar";
+ reg = <0 0xe6e33000 0 0x8>;
+ clocks = <&cpg CPG_MOD 523>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 523>;
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+ pwm4: pwm@e6e34000 {
+ compatible = "renesas,pwm-r8a774c0", "renesas,pwm-rcar";
+ reg = <0 0xe6e34000 0 0x8>;
+ clocks = <&cpg CPG_MOD 523>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 523>;
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+ pwm5: pwm@e6e35000 {
+ compatible = "renesas,pwm-r8a774c0", "renesas,pwm-rcar";
+ reg = <0 0xe6e35000 0 0x8>;
+ clocks = <&cpg CPG_MOD 523>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 523>;
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+ pwm6: pwm@e6e36000 {
+ compatible = "renesas,pwm-r8a774c0", "renesas,pwm-rcar";
+ reg = <0 0xe6e36000 0 0x8>;
+ clocks = <&cpg CPG_MOD 523>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 523>;
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+ scif0: serial@e6e60000 {
+ compatible = "renesas,scif-r8a774c0",
+ "renesas,rcar-gen3-scif", "renesas,scif";
+ reg = <0 0xe6e60000 0 64>;
+ interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 207>,
+ <&cpg CPG_CORE R8A774C0_CLK_S3D1C>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac1 0x51>, <&dmac1 0x50>,
+ <&dmac2 0x51>, <&dmac2 0x50>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 207>;
+ status = "disabled";
+ };
+
+ scif1: serial@e6e68000 {
+ compatible = "renesas,scif-r8a774c0",
+ "renesas,rcar-gen3-scif", "renesas,scif";
+ reg = <0 0xe6e68000 0 64>;
+ interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 206>,
+ <&cpg CPG_CORE R8A774C0_CLK_S3D1C>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac1 0x53>, <&dmac1 0x52>,
+ <&dmac2 0x53>, <&dmac2 0x52>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 206>;
+ status = "disabled";
+ };
+
+ scif2: serial@e6e88000 {
+ compatible = "renesas,scif-r8a774c0",
+ "renesas,rcar-gen3-scif", "renesas,scif";
+ reg = <0 0xe6e88000 0 64>;
+ interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 310>,
+ <&cpg CPG_CORE R8A774C0_CLK_S3D1C>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac1 0x13>, <&dmac1 0x12>,
+ <&dmac2 0x13>, <&dmac2 0x12>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 310>;
+ status = "disabled";
+ };
+
+ scif3: serial@e6c50000 {
+ compatible = "renesas,scif-r8a774c0",
+ "renesas,rcar-gen3-scif", "renesas,scif";
+ reg = <0 0xe6c50000 0 64>;
+ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 204>,
+ <&cpg CPG_CORE R8A774C0_CLK_S3D1C>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0x57>, <&dmac0 0x56>;
+ dma-names = "tx", "rx";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 204>;
+ status = "disabled";
+ };
+
+ scif4: serial@e6c40000 {
+ compatible = "renesas,scif-r8a774c0",
+ "renesas,rcar-gen3-scif", "renesas,scif";
+ reg = <0 0xe6c40000 0 64>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 203>,
+ <&cpg CPG_CORE R8A774C0_CLK_S3D1C>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0x59>, <&dmac0 0x58>;
+ dma-names = "tx", "rx";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 203>;
+ status = "disabled";
+ };
+
+ scif5: serial@e6f30000 {
+ compatible = "renesas,scif-r8a774c0",
+ "renesas,rcar-gen3-scif", "renesas,scif";
+ reg = <0 0xe6f30000 0 64>;
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 202>,
+ <&cpg CPG_CORE R8A774C0_CLK_S3D1C>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0x5b>, <&dmac0 0x5a>;
+ dma-names = "tx", "rx";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 202>;
+ status = "disabled";
+ };
+
+ msiof0: spi@e6e90000 {
+ compatible = "renesas,msiof-r8a774c0",
+ "renesas,rcar-gen3-msiof";
+ reg = <0 0xe6e90000 0 0x0064>;
+ interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 211>;
+ dmas = <&dmac1 0x41>, <&dmac1 0x40>,
+ <&dmac2 0x41>, <&dmac2 0x40>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 211>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ msiof1: spi@e6ea0000 {
+ compatible = "renesas,msiof-r8a774c0",
+ "renesas,rcar-gen3-msiof";
+ reg = <0 0xe6ea0000 0 0x0064>;
+ interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 210>;
+ dmas = <&dmac1 0x43>, <&dmac1 0x42>,
+ <&dmac2 0x43>, <&dmac2 0x42>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 210>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ msiof2: spi@e6c00000 {
+ compatible = "renesas,msiof-r8a774c0",
+ "renesas,rcar-gen3-msiof";
+ reg = <0 0xe6c00000 0 0x0064>;
+ interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 209>;
+ dmas = <&dmac0 0x45>, <&dmac0 0x44>;
+ dma-names = "tx", "rx";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 209>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ msiof3: spi@e6c10000 {
+ compatible = "renesas,msiof-r8a774c0",
+ "renesas,rcar-gen3-msiof";
+ reg = <0 0xe6c10000 0 0x0064>;
+ interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 208>;
+ dmas = <&dmac0 0x47>, <&dmac0 0x46>;
+ dma-names = "tx", "rx";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 208>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ vin4: video@e6ef4000 {
+ compatible = "renesas,vin-r8a774c0";
+ reg = <0 0xe6ef4000 0 0x1000>;
+ interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 807>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 807>;
+ renesas,id = <4>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg = <1>;
+
+ vin4csi40: endpoint@2 {
+ reg = <2>;
+ remote-endpoint= <&csi40vin4>;
+ };
+ };
+ };
+ };
+
+ vin5: video@e6ef5000 {
+ compatible = "renesas,vin-r8a774c0";
+ reg = <0 0xe6ef5000 0 0x1000>;
+ interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 806>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 806>;
+ renesas,id = <5>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg = <1>;
+
+ vin5csi40: endpoint@2 {
+ reg = <2>;
+ remote-endpoint= <&csi40vin5>;
+ };
+ };
+ };
+ };
+
+ rcar_sound: sound@ec500000 {
+ /*
+ * #sound-dai-cells is required
+ *
+ * Single DAI : #sound-dai-cells = <0>; <&rcar_sound>;
+ * Multi DAI : #sound-dai-cells = <1>; <&rcar_sound N>;
+ */
+ /*
+ * #clock-cells is required for audio_clkout0/1/2/3
+ *
+ * clkout : #clock-cells = <0>; <&rcar_sound>;
+ * clkout0/1/2/3: #clock-cells = <1>; <&rcar_sound N>;
+ */
+ compatible = "renesas,rcar_sound-r8a774c0",
+ "renesas,rcar_sound-gen3";
+ reg = <0 0xec500000 0 0x1000>, /* SCU */
+ <0 0xec5a0000 0 0x100>, /* ADG */
+ <0 0xec540000 0 0x1000>, /* SSIU */
+ <0 0xec541000 0 0x280>, /* SSI */
+ <0 0xec760000 0 0x200>; /* Audio DMAC peri peri*/
+ reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
+
+ clocks = <&cpg CPG_MOD 1005>,
+ <&cpg CPG_MOD 1006>, <&cpg CPG_MOD 1007>,
+ <&cpg CPG_MOD 1008>, <&cpg CPG_MOD 1009>,
+ <&cpg CPG_MOD 1010>, <&cpg CPG_MOD 1011>,
+ <&cpg CPG_MOD 1012>, <&cpg CPG_MOD 1013>,
+ <&cpg CPG_MOD 1014>, <&cpg CPG_MOD 1015>,
+ <&cpg CPG_MOD 1022>, <&cpg CPG_MOD 1023>,
+ <&cpg CPG_MOD 1024>, <&cpg CPG_MOD 1025>,
+ <&cpg CPG_MOD 1026>, <&cpg CPG_MOD 1027>,
+ <&cpg CPG_MOD 1028>, <&cpg CPG_MOD 1029>,
+ <&cpg CPG_MOD 1030>, <&cpg CPG_MOD 1031>,
+ <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>,
+ <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>,
+ <&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
+ <&audio_clk_a>, <&audio_clk_b>,
+ <&audio_clk_c>,
+ <&cpg CPG_CORE R8A774C0_CLK_ZA2>;
+ clock-names = "ssi-all",
+ "ssi.9", "ssi.8", "ssi.7", "ssi.6",
+ "ssi.5", "ssi.4", "ssi.3", "ssi.2",
+ "ssi.1", "ssi.0",
+ "src.9", "src.8", "src.7", "src.6",
+ "src.5", "src.4", "src.3", "src.2",
+ "src.1", "src.0",
+ "mix.1", "mix.0",
+ "ctu.1", "ctu.0",
+ "dvc.0", "dvc.1",
+ "clk_a", "clk_b", "clk_c", "clk_i";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 1005>,
+ <&cpg 1006>, <&cpg 1007>,
+ <&cpg 1008>, <&cpg 1009>,
+ <&cpg 1010>, <&cpg 1011>,
+ <&cpg 1012>, <&cpg 1013>,
+ <&cpg 1014>, <&cpg 1015>;
+ reset-names = "ssi-all",
+ "ssi.9", "ssi.8", "ssi.7", "ssi.6",
+ "ssi.5", "ssi.4", "ssi.3", "ssi.2",
+ "ssi.1", "ssi.0";
+ status = "disabled";
+
+ rcar_sound,ctu {
+ ctu00: ctu-0 { };
+ ctu01: ctu-1 { };
+ ctu02: ctu-2 { };
+ ctu03: ctu-3 { };
+ ctu10: ctu-4 { };
+ ctu11: ctu-5 { };
+ ctu12: ctu-6 { };
+ ctu13: ctu-7 { };
+ };
+
+ rcar_sound,dvc {
+ dvc0: dvc-0 {
+ dmas = <&audma0 0xbc>;
+ dma-names = "tx";
+ };
+ dvc1: dvc-1 {
+ dmas = <&audma0 0xbe>;
+ dma-names = "tx";
+ };
+ };
+
+ rcar_sound,mix {
+ mix0: mix-0 { };
+ mix1: mix-1 { };
+ };
+
+ rcar_sound,src {
+ src0: src-0 {
+ interrupts = <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x85>, <&audma0 0x9a>;
+ dma-names = "rx", "tx";
+ };
+ src1: src-1 {
+ interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x87>, <&audma0 0x9c>;
+ dma-names = "rx", "tx";
+ };
+ src2: src-2 {
+ interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x89>, <&audma0 0x9e>;
+ dma-names = "rx", "tx";
+ };
+ src3: src-3 {
+ interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x8b>, <&audma0 0xa0>;
+ dma-names = "rx", "tx";
+ };
+ src4: src-4 {
+ interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x8d>, <&audma0 0xb0>;
+ dma-names = "rx", "tx";
+ };
+ src5: src-5 {
+ interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x8f>, <&audma0 0xb2>;
+ dma-names = "rx", "tx";
+ };
+ src6: src-6 {
+ interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x91>, <&audma0 0xb4>;
+ dma-names = "rx", "tx";
+ };
+ src7: src-7 {
+ interrupts = <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x93>, <&audma0 0xb6>;
+ dma-names = "rx", "tx";
+ };
+ src8: src-8 {
+ interrupts = <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x95>, <&audma0 0xb8>;
+ dma-names = "rx", "tx";
+ };
+ src9: src-9 {
+ interrupts = <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x97>, <&audma0 0xba>;
+ dma-names = "rx", "tx";
+ };
+ };
+
+ rcar_sound,ssi {
+ ssi0: ssi-0 {
+ interrupts = <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x01>, <&audma0 0x02>,
+ <&audma0 0x15>, <&audma0 0x16>;
+ dma-names = "rx", "tx", "rxu", "txu";
+ };
+ ssi1: ssi-1 {
+ interrupts = <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x03>, <&audma0 0x04>,
+ <&audma0 0x49>, <&audma0 0x4a>;
+ dma-names = "rx", "tx", "rxu", "txu";
+ };
+ ssi2: ssi-2 {
+ interrupts = <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x05>, <&audma0 0x06>,
+ <&audma0 0x63>, <&audma0 0x64>;
+ dma-names = "rx", "tx", "rxu", "txu";
+ };
+ ssi3: ssi-3 {
+ interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x07>, <&audma0 0x08>,
+ <&audma0 0x6f>, <&audma0 0x70>;
+ dma-names = "rx", "tx", "rxu", "txu";
+ };
+ ssi4: ssi-4 {
+ interrupts = <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x09>, <&audma0 0x0a>,
+ <&audma0 0x71>, <&audma0 0x72>;
+ dma-names = "rx", "tx", "rxu", "txu";
+ };
+ ssi5: ssi-5 {
+ interrupts = <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x0b>, <&audma0 0x0c>,
+ <&audma0 0x73>, <&audma0 0x74>;
+ dma-names = "rx", "tx", "rxu", "txu";
+ };
+ ssi6: ssi-6 {
+ interrupts = <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x0d>, <&audma0 0x0e>,
+ <&audma0 0x75>, <&audma0 0x76>;
+ dma-names = "rx", "tx", "rxu", "txu";
+ };
+ ssi7: ssi-7 {
+ interrupts = <GIC_SPI 377 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x0f>, <&audma0 0x10>,
+ <&audma0 0x79>, <&audma0 0x7a>;
+ dma-names = "rx", "tx", "rxu", "txu";
+ };
+ ssi8: ssi-8 {
+ interrupts = <GIC_SPI 378 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x11>, <&audma0 0x12>,
+ <&audma0 0x7b>, <&audma0 0x7c>;
+ dma-names = "rx", "tx", "rxu", "txu";
+ };
+ ssi9: ssi-9 {
+ interrupts = <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&audma0 0x13>, <&audma0 0x14>,
+ <&audma0 0x7d>, <&audma0 0x7e>;
+ dma-names = "rx", "tx", "rxu", "txu";
+ };
+ };
+ };
+
+ audma0: dma-controller@ec700000 {
+ compatible = "renesas,dmac-r8a774c0",
+ "renesas,rcar-dmac";
+ reg = <0 0xec700000 0 0x10000>;
+ interrupts = <GIC_SPI 350 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "error",
+ "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5", "ch6", "ch7",
+ "ch8", "ch9", "ch10", "ch11",
+ "ch12", "ch13", "ch14", "ch15";
+ clocks = <&cpg CPG_MOD 502>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 502>;
+ #dma-cells = <1>;
+ dma-channels = <16>;
+ iommus = <&ipmmu_mp 0>, <&ipmmu_mp 1>,
+ <&ipmmu_mp 2>, <&ipmmu_mp 3>,
+ <&ipmmu_mp 4>, <&ipmmu_mp 5>,
+ <&ipmmu_mp 6>, <&ipmmu_mp 7>,
+ <&ipmmu_mp 8>, <&ipmmu_mp 9>,
+ <&ipmmu_mp 10>, <&ipmmu_mp 11>,
+ <&ipmmu_mp 12>, <&ipmmu_mp 13>,
+ <&ipmmu_mp 14>, <&ipmmu_mp 15>;
+ };
+
+ xhci0: usb@ee000000 {
+ compatible = "renesas,xhci-r8a774c0",
+ "renesas,rcar-gen3-xhci";
+ reg = <0 0xee000000 0 0xc00>;
+ interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 328>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 328>;
+ status = "disabled";
+ };
+
+ usb3_peri0: usb@ee020000 {
+ compatible = "renesas,r8a774c0-usb3-peri",
+ "renesas,rcar-gen3-usb3-peri";
+ reg = <0 0xee020000 0 0x400>;
+ interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 328>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 328>;
+ status = "disabled";
+ };
+
+ ohci0: usb@ee080000 {
+ compatible = "generic-ohci";
+ reg = <0 0xee080000 0 0x100>;
+ interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>;
+ phys = <&usb2_phy0 1>;
+ phy-names = "usb";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 703>, <&cpg 704>;
+ status = "disabled";
+ };
+
+ ehci0: usb@ee080100 {
+ compatible = "generic-ehci";
+ reg = <0 0xee080100 0 0x100>;
+ interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>;
+ phys = <&usb2_phy0 2>;
+ phy-names = "usb";
+ companion = <&ohci0>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 703>, <&cpg 704>;
+ status = "disabled";
+ };
+
+ usb2_phy0: usb-phy@ee080200 {
+ compatible = "renesas,usb2-phy-r8a774c0",
+ "renesas,rcar-gen3-usb2-phy";
+ reg = <0 0xee080200 0 0x700>;
+ interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 703>, <&cpg 704>;
+ #phy-cells = <1>;
+ status = "disabled";
+ };
+
+ sdhi0: mmc@ee100000 {
+ compatible = "renesas,sdhi-r8a774c0",
+ "renesas,rcar-gen3-sdhi";
+ reg = <0 0xee100000 0 0x2000>;
+ interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 314>;
+ max-frequency = <200000000>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 314>;
+ status = "disabled";
+ };
+
+ sdhi1: mmc@ee120000 {
+ compatible = "renesas,sdhi-r8a774c0",
+ "renesas,rcar-gen3-sdhi";
+ reg = <0 0xee120000 0 0x2000>;
+ interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 313>;
+ max-frequency = <200000000>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 313>;
+ status = "disabled";
+ };
+
+ sdhi3: mmc@ee160000 {
+ compatible = "renesas,sdhi-r8a774c0",
+ "renesas,rcar-gen3-sdhi";
+ reg = <0 0xee160000 0 0x2000>;
+ interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 311>;
+ max-frequency = <200000000>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 311>;
+ status = "disabled";
+ };
+
+ gic: interrupt-controller@f1010000 {
+ compatible = "arm,gic-400";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0x0 0xf1010000 0 0x1000>,
+ <0x0 0xf1020000 0 0x20000>,
+ <0x0 0xf1040000 0 0x20000>,
+ <0x0 0xf1060000 0 0x20000>;
+ interrupts = <GIC_PPI 9
+ (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+ clocks = <&cpg CPG_MOD 408>;
+ clock-names = "clk";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 408>;
+ };
+
+ pciec0: pcie@fe000000 {
+ compatible = "renesas,pcie-r8a774c0",
+ "renesas,pcie-rcar-gen3";
+ reg = <0 0xfe000000 0 0x80000>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ bus-range = <0x00 0xff>;
+ device_type = "pci";
+ ranges = <0x01000000 0 0x00000000 0 0xfe100000 0 0x00100000>,
+ <0x02000000 0 0xfe200000 0 0xfe200000 0 0x00200000>,
+ <0x02000000 0 0x30000000 0 0x30000000 0 0x08000000>,
+ <0x42000000 0 0x38000000 0 0x38000000 0 0x08000000>;
+ /* Map all possible DDR as inbound ranges */
+ dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x40000000>;
+ interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &gic GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 319>, <&pcie_bus_clk>;
+ clock-names = "pcie", "pcie_bus";
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 319>;
+ status = "disabled";
+ };
+
+ vspb0: vsp@fe960000 {
+ compatible = "renesas,vsp2";
+ reg = <0 0xfe960000 0 0x8000>;
+ interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 626>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 626>;
+ renesas,fcp = <&fcpvb0>;
+ };
+
+ vspd0: vsp@fea20000 {
+ compatible = "renesas,vsp2";
+ reg = <0 0xfea20000 0 0x7000>;
+ interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 623>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 623>;
+ renesas,fcp = <&fcpvd0>;
+ };
+
+ vspd1: vsp@fea28000 {
+ compatible = "renesas,vsp2";
+ reg = <0 0xfea28000 0 0x7000>;
+ interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 622>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 622>;
+ renesas,fcp = <&fcpvd1>;
+ };
+
+ vspi0: vsp@fe9a0000 {
+ compatible = "renesas,vsp2";
+ reg = <0 0xfe9a0000 0 0x8000>;
+ interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 631>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 631>;
+ renesas,fcp = <&fcpvi0>;
+ };
+
+ fcpvb0: fcp@fe96f000 {
+ compatible = "renesas,fcpv";
+ reg = <0 0xfe96f000 0 0x200>;
+ clocks = <&cpg CPG_MOD 607>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 607>;
+ iommus = <&ipmmu_vp0 5>;
+ };
+
+ fcpvd0: fcp@fea27000 {
+ compatible = "renesas,fcpv";
+ reg = <0 0xfea27000 0 0x200>;
+ clocks = <&cpg CPG_MOD 603>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 603>;
+ iommus = <&ipmmu_vi0 8>;
+ };
+
+ fcpvd1: fcp@fea2f000 {
+ compatible = "renesas,fcpv";
+ reg = <0 0xfea2f000 0 0x200>;
+ clocks = <&cpg CPG_MOD 602>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 602>;
+ iommus = <&ipmmu_vi0 9>;
+ };
+
+ fcpvi0: fcp@fe9af000 {
+ compatible = "renesas,fcpv";
+ reg = <0 0xfe9af000 0 0x200>;
+ clocks = <&cpg CPG_MOD 611>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 611>;
+ iommus = <&ipmmu_vp0 8>;
+ };
+
+ csi40: csi2@feaa0000 {
+ compatible = "renesas,r8a774c0-csi2";
+ reg = <0 0xfeaa0000 0 0x10000>;
+ interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 716>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 716>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg = <1>;
+
+ csi40vin4: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&vin4csi40>;
+ };
+ csi40vin5: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&vin5csi40>;
+ };
+ };
+ };
+ };
+
+ du: display@feb00000 {
+ compatible = "renesas,du-r8a774c0";
+ reg = <0 0xfeb00000 0 0x40000>;
+ interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>;
+ clock-names = "du.0", "du.1";
+ resets = <&cpg 724>;
+ reset-names = "du.0";
+ renesas,vsps = <&vspd0 0>, <&vspd1 0>;
+
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ du_out_rgb: endpoint {
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ du_out_lvds0: endpoint {
+ remote-endpoint = <&lvds0_in>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+ du_out_lvds1: endpoint {
+ remote-endpoint = <&lvds1_in>;
+ };
+ };
+ };
+ };
+
+ lvds0: lvds-encoder@feb90000 {
+ compatible = "renesas,r8a774c0-lvds";
+ reg = <0 0xfeb90000 0 0x20>;
+ clocks = <&cpg CPG_MOD 727>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 727>;
+ status = "disabled";
+
+ renesas,companion = <&lvds1>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ lvds0_in: endpoint {
+ remote-endpoint = <&du_out_lvds0>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ lvds0_out: endpoint {
+ };
+ };
+ };
+ };
+
+ lvds1: lvds-encoder@feb90100 {
+ compatible = "renesas,r8a774c0-lvds";
+ reg = <0 0xfeb90100 0 0x20>;
+ clocks = <&cpg CPG_MOD 727>;
+ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+ resets = <&cpg 726>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ lvds1_in: endpoint {
+ remote-endpoint = <&du_out_lvds1>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ lvds1_out: endpoint {
+ };
+ };
+ };
+ };
+
+ prr: chipid@fff00044 {
+ compatible = "renesas,prr";
+ reg = <0 0xfff00044 0 4>;
+ };
+ };
+
+ thermal-zones {
+ cpu-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <0>;
+ thermal-sensors = <&thermal 0>;
+ sustainable-power = <717>;
+
+ cooling-maps {
+ map0 {
+ trip = <&target>;
+ cooling-device = <&a53_0 0 2>;
+ contribution = <1024>;
+ };
+ };
+
+ trips {
+ sensor1_crit: sensor1-crit {
+ temperature = <120000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+
+ target: trip-point1 {
+ temperature = <100000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ };
+ };
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+
+ /* External USB clocks - can be overridden by the board */
+ usb3s0_clk: usb3s0 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ usb_extal_clk: usb_extal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+};
diff --git a/arch/arm/dts/sam9x60.dtsi b/arch/arm/dts/sam9x60.dtsi
index 41ac1f164c8..7f3eae3f5d2 100644
--- a/arch/arm/dts/sam9x60.dtsi
+++ b/arch/arm/dts/sam9x60.dtsi
@@ -12,7 +12,7 @@
#include <dt-bindings/pinctrl/at91.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/clock/at91.h>
+#include <dt-bindings/clk/at91.h>
/{
model = "Microchip SAM9X60 SoC";
@@ -27,16 +27,26 @@
};
clocks {
+ slow_rc_osc: slow_rc_osc {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <18500>;
+ };
+
+ main_rc: main_rc {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <12000000>;
+ };
+
slow_xtal: slow_xtal {
compatible = "fixed-clock";
#clock-cells = <0>;
- clock-frequency = <0>;
};
main_xtal: main_xtal {
compatible = "fixed-clock";
#clock-cells = <0>;
- clock-frequency = <0>;
};
};
@@ -49,8 +59,11 @@
sdhci0: sdhci-host@80000000 {
compatible = "microchip,sam9x60-sdhci";
reg = <0x80000000 0x300>;
- clocks = <&sdhci0_clk>, <&sdhci0_gclk>, <&main>;
- clock-names = "hclock", "multclk", "baseclk";
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 12>, <&pmc PMC_TYPE_GCK 12>;
+ clock-names = "hclock", "multclk";
+ assigned-clocks = <&pmc PMC_TYPE_GCK 12>;
+ assigned-clock-rates = <100000000>;
+ assigned-clock-parents = <&pmc PMC_TYPE_CORE 10>; /* ID_PLL_A_DIV */
bus-width = <4>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sdhci0>;
@@ -66,7 +79,7 @@
compatible = "microchip,sam9x60-qspi";
reg = <0xf0014000 0x100>, <0x70000000 0x10000000>;
reg-names = "qspi_base", "qspi_mmap";
- clocks = <&qspi_clk>, <&qspick>;
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 35>, <&pmc PMC_TYPE_SYSTEM 18>; /* ID_QSPI */
clock-names = "pclk", "qspick";
#address-cells = <1>;
#size-cells = <0>;
@@ -76,7 +89,7 @@
flx0: flexcom@f801c600 {
compatible = "atmel,sama5d2-flexcom";
reg = <0xf801c000 0x200>;
- clocks = <&flx0_clk>;
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 5>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x0 0xf801c000 0x800>;
@@ -89,7 +102,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_macb0_rmii>;
clock-names = "hclk", "pclk";
- clocks = <&macb0_clk>, <&macb0_clk>;
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 24>, <&pmc PMC_TYPE_PERIPHERAL 24>;
status = "disabled";
};
@@ -98,7 +111,7 @@
reg = <0xfffff200 0x200>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_dbgu>;
- clocks = <&dbgu_clk>;
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 47>;
clock-names = "usart";
};
@@ -155,7 +168,7 @@
reg = <0xfffff400 0x200>;
#gpio-cells = <2>;
gpio-controller;
- clocks = <&pioA_clk>;
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 2>;
};
pioB: gpio@fffff600 {
@@ -163,7 +176,7 @@
reg = <0xfffff600 0x200>;
#gpio-cells = <2>;
gpio-controller;
- clocks = <&pioB_clk>;
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 3>;
};
pioD: gpio@fffffa00 {
@@ -171,143 +184,29 @@
reg = <0xfffffa00 0x200>;
#gpio-cells = <2>;
gpio-controller;
- clocks = <&pioD_clk>;
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 44>;
};
pmc: pmc@fffffc00 {
- compatible = "atmel,at91sam9x5-pmc";
+ compatible = "microchip,sam9x60-pmc";
reg = <0xfffffc00 0x200>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- main: mainck {
- compatible = "atmel,at91sam9x5-clk-main";
- #clock-cells = <0>;
- };
-
- plla: pllack {
- compatible = "microchip,sam9x60-clk-pll";
- #clock-cells = <0>;
- clocks = <&main>;
- reg = <0>;
- atmel,clk-input-range = <8000000 24000000>;
- #atmel,pll-clk-output-range-cells = <4>;
- atmel,pll-clk-output-ranges = <140000000 1200000000 0 0>;
- };
-
- mck: masterck {
- compatible = "atmel,at91sam9x5-clk-master";
- #clock-cells = <0>;
- clocks = <&md_slck>, <&main>, <&plla>;
- atmel,clk-output-range = <140000000 200000000>;
- atmel,clk-divisors = <1 2 4 6>;
- };
-
- system: systemck {
- compatible = "atmel,at91rm9200-clk-system";
- #address-cells = <1>;
- #size-cells = <0>;
-
- qspick: qspick {
- #clock-cells = <0>;
- reg = <19>;
- clocks = <&mck>;
- };
- };
-
- periph: periphck {
- compatible = "microchip,sam9x60-clk-peripheral";
- #address-cells = <1>;
- #size-cells = <0>;
- clocks = <&mck>;
-
- pioA_clk: pioA_clk {
- #clock-cells = <0>;
- reg = <2>;
- };
-
- pioB_clk: pioB_clk {
- #clock-cells = <0>;
- reg = <3>;
- };
-
- flx0_clk: flx0_clk {
- #clock-cells = <0>;
- reg = <5>;
- };
-
- pioD_clk: pioD_clk {
- #clock-cells = <0>;
- reg = <44>;
- };
-
- sdhci0_clk: sdhci0_clk {
- #clock-cells = <0>;
- reg = <12>;
- };
-
- dbgu_clk: dbgu_clk {
- #clock-cells = <0>;
- reg = <47>;
- };
-
- macb0_clk: macb0_clk {
- #clock-cells = <0>;
- reg = <24>;
- };
-
- qspi_clk: qspi_clk {
- #clock-cells = <0>;
- reg = <35>;
- };
- };
-
- generic: gck {
- compatible = "microchip,sam9x60-clk-generated";
- #address-cells = <1>;
- #size-cells = <0>;
- clocks = <&md_slck>, <&td_slck>, <&main>, <&mck>, <&plla>;
-
- sdhci0_gclk: sdhci0_gclk {
- #clock-cells = <0>;
- reg = <12>;
- };
- };
+ #clock-cells = <2>;
+ clocks = <&clk32 1>, <&clk32 0>, <&main_xtal>, <&main_rc>;
+ clock-names = "td_slck", "md_slck", "main_xtal", "main_rc";
+ status = "okay";
};
pit: timer@fffffe40 {
compatible = "atmel,at91sam9260-pit";
reg = <0xfffffe40 0x10>;
- clocks = <&mck>;
+ clocks = <&pmc PMC_TYPE_CORE 11>; /* ID_MCK. */
};
- slowckc: sckc@fffffe50 {
- compatible = "atmel,at91sam9x5-sckc";
+ clk32: sckc@fffffe50 {
+ compatible = "microchip,sam9x60-sckc";
reg = <0xfffffe50 0x4>;
-
- slow_osc: slow_osc {
- compatible = "atmel,at91sam9x5-clk-slow-osc";
- #clock-cells = <0>;
- clocks = <&slow_xtal>;
- };
-
- slow_rc_osc: slow_rc_osc {
- compatible = "atmel,at91sam9x5-clk-slow-rc-osc";
- #clock-cells = <0>;
- clock-frequency = <32768>;
- };
-
- td_slck: td_slck {
- compatible = "atmel,at91sam9x5-clk-slow";
- #clock-cells = <0>;
- clocks = <&slow_rc_osc>, <&slow_osc>;
- };
-
- md_slck: md_slck {
- compatible = "atmel,at91sam9x5-clk-slow";
- #clock-cells = <0>;
- clocks = <&slow_rc_osc>;
- };
+ clocks = <&slow_rc_osc>, <&slow_xtal>;
+ #clock-cells = <1>;
};
};
};
diff --git a/arch/arm/dts/sam9x60ek-u-boot.dtsi b/arch/arm/dts/sam9x60ek-u-boot.dtsi
index 93cf1262f6f..8c63ed869c8 100644
--- a/arch/arm/dts/sam9x60ek-u-boot.dtsi
+++ b/arch/arm/dts/sam9x60ek-u-boot.dtsi
@@ -23,7 +23,7 @@
};
};
-&sdhci0 {
+&clk32 {
u-boot,dm-pre-reloc;
};
@@ -31,7 +31,11 @@
u-boot,dm-pre-reloc;
};
-&qspi {
+&main_rc {
+ u-boot,dm-pre-reloc;
+};
+
+&main_xtal {
u-boot,dm-pre-reloc;
};
@@ -59,74 +63,18 @@
u-boot,dm-pre-reloc;
};
-&main {
- u-boot,dm-pre-reloc;
-};
-
-&plla {
- u-boot,dm-pre-reloc;
-};
-
-&mck {
- u-boot,dm-pre-reloc;
-};
-
-&system {
- u-boot,dm-pre-reloc;
-};
-
-&qspick {
- u-boot,dm-pre-reloc;
-};
-
-&periph {
- u-boot,dm-pre-reloc;
-};
-
-&pioA_clk {
- u-boot,dm-pre-reloc;
-};
-
-&pioB_clk {
- u-boot,dm-pre-reloc;
-};
-
-&sdhci0_clk {
- u-boot,dm-pre-reloc;
-};
-
-&dbgu_clk {
- u-boot,dm-pre-reloc;
-};
-
-&qspi_clk {
- u-boot,dm-pre-reloc;
-};
-
-&generic {
- u-boot,dm-pre-reloc;
-};
-
-&sdhci0_gclk {
+&qspi {
u-boot,dm-pre-reloc;
};
-&slowckc {
+&sdhci0 {
u-boot,dm-pre-reloc;
};
-&slow_osc {
+&slow_xtal {
u-boot,dm-pre-reloc;
};
&slow_rc_osc {
u-boot,dm-pre-reloc;
};
-
-&td_slck {
- u-boot,dm-pre-reloc;
-};
-
-&md_slck {
- u-boot,dm-pre-reloc;
-};
diff --git a/arch/arm/dts/sam9x60ek.dts b/arch/arm/dts/sam9x60ek.dts
index 8767de98b8d..96914b3ea2c 100644
--- a/arch/arm/dts/sam9x60ek.dts
+++ b/arch/arm/dts/sam9x60ek.dts
@@ -18,6 +18,16 @@
i2c0 = &flx0;
};
+ clocks {
+ slow_xtal: slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal: main_xtal {
+ clock-frequency = <24000000>;
+ };
+ };
+
onewire_tm: onewire {
gpios = <&pioD 14 0>;
pinctrl-names = "default";
@@ -57,7 +67,7 @@
pinctrl-0 = <&pinctrl_flx0>;
#address-cells = <1>;
#size-cells = <0>;
- clocks = <&flx0_clk>;
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 5>;
status = "okay";
eeprom@53 {
diff --git a/arch/arm/mach-at91/arm926ejs/sam9x60_devices.c b/arch/arm/mach-at91/arm926ejs/sam9x60_devices.c
index d463bbc7886..e3d3dd880ca 100644
--- a/arch/arm/mach-at91/arm926ejs/sam9x60_devices.c
+++ b/arch/arm/mach-at91/arm926ejs/sam9x60_devices.c
@@ -44,6 +44,12 @@ char *get_cpu_name(void)
switch (extension_id) {
case ARCH_EXID_SAM9X60:
return "SAM9X60";
+ case ARCH_EXID_SAM9X60_D6K:
+ return "SAM9X60 8MiB SDRAM SiP";
+ case ARCH_EXID_SAM9X60_D5M:
+ return "SAM9X60 64MiB DDR2 SiP";
+ case ARCH_EXID_SAM9X60_D1G:
+ return "SAM9X60 128MiB DDR2 SiP";
default:
return "Unknown CPU type";
}
diff --git a/arch/arm/mach-at91/include/mach/sam9x60.h b/arch/arm/mach-at91/include/mach/sam9x60.h
index 0f00a9ae871..b7f43226b7e 100644
--- a/arch/arm/mach-at91/include/mach/sam9x60.h
+++ b/arch/arm/mach-at91/include/mach/sam9x60.h
@@ -128,6 +128,9 @@
#define ARCH_ID_SAM9X60 0x819b35a0
#define ARCH_ID_VERSION_MASK 0x1f
#define ARCH_EXID_SAM9X60 0x00000000
+#define ARCH_EXID_SAM9X60_D6K 0x00000011
+#define ARCH_EXID_SAM9X60_D5M 0x00000001
+#define ARCH_EXID_SAM9X60_D1G 0x00000010
#define cpu_is_sam9x60() (get_chip_id() == ARCH_ID_SAM9X60)
diff --git a/arch/arm/mach-rmobile/Kconfig.64 b/arch/arm/mach-rmobile/Kconfig.64
index 07f607dd9d1..be3ea3c1a9c 100644
--- a/arch/arm/mach-rmobile/Kconfig.64
+++ b/arch/arm/mach-rmobile/Kconfig.64
@@ -3,7 +3,19 @@ if RCAR_GEN3
menu "Select Target SoC"
config R8A774A1
- bool "Renesas SoC R8A774A1"
+ bool "Renesas SoC R8A774A1"
+
+config R8A774B1
+ bool "Renesas SoC R8A774B1"
+ imply CLK_R8A774B1
+
+config R8A774C0
+ bool "Renesas SoC R8A774C0"
+ imply CLK_R8A774C0
+
+config R8A774E1
+ bool "Renesas SoC R8A774E1"
+ imply CLK_R8A774E1
config R8A7795
bool "Renesas SoC R8A7795"
diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
index 0e27ad1d6a5..a90d821c82e 100644
--- a/common/spl/spl_fit.c
+++ b/common/spl/spl_fit.c
@@ -349,12 +349,9 @@ static int spl_fit_append_fdt(struct spl_image_info *spl_image,
/*
* Use the address following the image as target address for the
- * device tree. Load address is aligned to 8 bytes to match the required
- * alignment specified for linux arm [1] and arm 64 [2] booting
- * [1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/arm/booting.rst#n126
- * [2]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/arm64/booting.rst#n45
+ * device tree.
*/
- image_info.load_addr = ALIGN(spl_image->load_addr + spl_image->size, 8);
+ image_info.load_addr = spl_image->load_addr + spl_image->size;
/* Figure out which device tree the board wants to use */
node = spl_fit_get_image_node(fit, images, FIT_FDT_PROP, index++);
diff --git a/configs/apalis_imx6_defconfig b/configs/apalis_imx6_defconfig
index 3f3ac3764ff..bc0327b7dae 100644
--- a/configs/apalis_imx6_defconfig
+++ b/configs/apalis_imx6_defconfig
@@ -106,4 +106,6 @@ CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_VIDEO_IPUV3=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/configs/aristainetos2_defconfig b/configs/aristainetos2_defconfig
index 241b3fea5e5..81863f601d6 100644
--- a/configs/aristainetos2_defconfig
+++ b/configs/aristainetos2_defconfig
@@ -114,5 +114,7 @@ CONFIG_DISPLAY=y
CONFIG_VIDEO_IPUV3=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
CONFIG_IMX_WATCHDOG=y
# CONFIG_EFI_LOADER is not set
diff --git a/configs/aristainetos2b_defconfig b/configs/aristainetos2b_defconfig
index 25a712cfd99..2e59c3014e3 100644
--- a/configs/aristainetos2b_defconfig
+++ b/configs/aristainetos2b_defconfig
@@ -108,5 +108,7 @@ CONFIG_DISPLAY=y
CONFIG_VIDEO_IPUV3=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
CONFIG_IMX_WATCHDOG=y
# CONFIG_EFI_LOADER is not set
diff --git a/configs/aristainetos2bcsl_defconfig b/configs/aristainetos2bcsl_defconfig
index 460a5cf0e79..8e6d2994fbe 100644
--- a/configs/aristainetos2bcsl_defconfig
+++ b/configs/aristainetos2bcsl_defconfig
@@ -108,5 +108,7 @@ CONFIG_DISPLAY=y
CONFIG_VIDEO_IPUV3=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
CONFIG_IMX_WATCHDOG=y
# CONFIG_EFI_LOADER is not set
diff --git a/configs/aristainetos2c_defconfig b/configs/aristainetos2c_defconfig
index 6c708b8e950..372d70567ad 100644
--- a/configs/aristainetos2c_defconfig
+++ b/configs/aristainetos2c_defconfig
@@ -114,5 +114,7 @@ CONFIG_DISPLAY=y
CONFIG_VIDEO_IPUV3=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
CONFIG_IMX_WATCHDOG=y
# CONFIG_EFI_LOADER is not set
diff --git a/configs/cgtqmx6eval_defconfig b/configs/cgtqmx6eval_defconfig
index a31e6794947..c3f608264d3 100644
--- a/configs/cgtqmx6eval_defconfig
+++ b/configs/cgtqmx6eval_defconfig
@@ -93,4 +93,6 @@ CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_VIDEO_IPUV3=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
CONFIG_OF_LIBFDT=y
diff --git a/configs/cm_fx6_defconfig b/configs/cm_fx6_defconfig
index 3ce28a89ede..654a4fcc48e 100644
--- a/configs/cm_fx6_defconfig
+++ b/configs/cm_fx6_defconfig
@@ -97,4 +97,5 @@ CONFIG_DM_VIDEO=y
CONFIG_VIDEO_IPUV3=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SOURCE=y
+CONFIG_VIDEO_BMP_RLE8=y
CONFIG_FDT_FIXUP_PARTITIONS=y
diff --git a/configs/colibri-imx6ull_defconfig b/configs/colibri-imx6ull_defconfig
index 26de8ab0860..2c33e0eedac 100644
--- a/configs/colibri-imx6ull_defconfig
+++ b/configs/colibri-imx6ull_defconfig
@@ -96,5 +96,7 @@ CONFIG_DM_VIDEO=y
CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
CONFIG_OF_LIBFDT_OVERLAY=y
CONFIG_FDT_FIXUP_PARTITIONS=y
diff --git a/configs/colibri_imx6_defconfig b/configs/colibri_imx6_defconfig
index 2808561ad0d..e2cb9eb7414 100644
--- a/configs/colibri_imx6_defconfig
+++ b/configs/colibri_imx6_defconfig
@@ -104,4 +104,6 @@ CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_VIDEO_IPUV3=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/configs/colibri_imx7_defconfig b/configs/colibri_imx7_defconfig
index 23fceaff34b..a6a00536815 100644
--- a/configs/colibri_imx7_defconfig
+++ b/configs/colibri_imx7_defconfig
@@ -95,5 +95,7 @@ CONFIG_DM_VIDEO=y
CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
CONFIG_OF_LIBFDT_OVERLAY=y
CONFIG_FDT_FIXUP_PARTITIONS=y
diff --git a/configs/colibri_imx7_emmc_defconfig b/configs/colibri_imx7_emmc_defconfig
index cc0ee467f19..2b21f3442f3 100644
--- a/configs/colibri_imx7_emmc_defconfig
+++ b/configs/colibri_imx7_emmc_defconfig
@@ -91,4 +91,6 @@ CONFIG_DM_VIDEO=y
CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/configs/dms-ba16-1g_defconfig b/configs/dms-ba16-1g_defconfig
index f7b6bc6dedb..eb5ee09b9ef 100644
--- a/configs/dms-ba16-1g_defconfig
+++ b/configs/dms-ba16-1g_defconfig
@@ -63,4 +63,5 @@ CONFIG_USB_GADGET_DOWNLOAD=y
CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
CONFIG_OF_LIBFDT=y
diff --git a/configs/dms-ba16_defconfig b/configs/dms-ba16_defconfig
index c7080874547..fe6d6a5fd65 100644
--- a/configs/dms-ba16_defconfig
+++ b/configs/dms-ba16_defconfig
@@ -62,4 +62,5 @@ CONFIG_USB_GADGET_DOWNLOAD=y
CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
CONFIG_OF_LIBFDT=y
diff --git a/configs/imx6dl_icore_nand_defconfig b/configs/imx6dl_icore_nand_defconfig
index bc4b26f8462..3749ae1e6ed 100644
--- a/configs/imx6dl_icore_nand_defconfig
+++ b/configs/imx6dl_icore_nand_defconfig
@@ -66,3 +66,5 @@ CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_VIDEO_IPUV3=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
diff --git a/configs/imx6q_icore_nand_defconfig b/configs/imx6q_icore_nand_defconfig
index 5d4f6c9f003..751eee8c0eb 100644
--- a/configs/imx6q_icore_nand_defconfig
+++ b/configs/imx6q_icore_nand_defconfig
@@ -67,3 +67,5 @@ CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_VIDEO_IPUV3=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
diff --git a/configs/imx6qdl_icore_mmc_defconfig b/configs/imx6qdl_icore_mmc_defconfig
index 49492f12f80..3e3d0a9f91b 100644
--- a/configs/imx6qdl_icore_mmc_defconfig
+++ b/configs/imx6qdl_icore_mmc_defconfig
@@ -83,4 +83,6 @@ CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_VIDEO_IPUV3=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
CONFIG_IMX_WATCHDOG=y
diff --git a/configs/imx6qdl_icore_nand_defconfig b/configs/imx6qdl_icore_nand_defconfig
index 5d4f6c9f003..751eee8c0eb 100644
--- a/configs/imx6qdl_icore_nand_defconfig
+++ b/configs/imx6qdl_icore_nand_defconfig
@@ -67,3 +67,5 @@ CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_VIDEO_IPUV3=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
diff --git a/configs/imxrt1050-evk_defconfig b/configs/imxrt1050-evk_defconfig
index 3f7b6704597..72613828119 100644
--- a/configs/imxrt1050-evk_defconfig
+++ b/configs/imxrt1050-evk_defconfig
@@ -70,6 +70,8 @@ CONFIG_BACKLIGHT_GPIO=y
CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
CONFIG_SHA1=y
CONFIG_SHA256=y
CONFIG_HEXDUMP=y
diff --git a/configs/khadas-vim3_defconfig b/configs/khadas-vim3_defconfig
index 1c87400fbf9..9d7ba72d440 100644
--- a/configs/khadas-vim3_defconfig
+++ b/configs/khadas-vim3_defconfig
@@ -76,4 +76,8 @@ CONFIG_VIDEO_MESON=y
CONFIG_VIDEO_DT_SIMPLEFB=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
+CONFIG_BMP_24BPP=y
+CONFIG_BMP_32BPP=y
CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/configs/khadas-vim3l_defconfig b/configs/khadas-vim3l_defconfig
index e0763a5eefd..f37993e580d 100644
--- a/configs/khadas-vim3l_defconfig
+++ b/configs/khadas-vim3l_defconfig
@@ -76,4 +76,8 @@ CONFIG_VIDEO_MESON=y
CONFIG_VIDEO_DT_SIMPLEFB=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
+CONFIG_BMP_24BPP=y
+CONFIG_BMP_32BPP=y
CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/configs/libretech-ac_defconfig b/configs/libretech-ac_defconfig
index e8519e446b2..171d793ae30 100644
--- a/configs/libretech-ac_defconfig
+++ b/configs/libretech-ac_defconfig
@@ -82,4 +82,8 @@ CONFIG_VIDEO_MESON=y
CONFIG_VIDEO_DT_SIMPLEFB=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
+CONFIG_BMP_24BPP=y
+CONFIG_BMP_32BPP=y
CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/configs/libretech-cc_defconfig b/configs/libretech-cc_defconfig
index 8cc655429ef..aaab1a2d080 100644
--- a/configs/libretech-cc_defconfig
+++ b/configs/libretech-cc_defconfig
@@ -65,4 +65,8 @@ CONFIG_VIDEO_MESON=y
CONFIG_VIDEO_DT_SIMPLEFB=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
+CONFIG_BMP_24BPP=y
+CONFIG_BMP_32BPP=y
CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/configs/libretech-s905d-pc_defconfig b/configs/libretech-s905d-pc_defconfig
index ace9537435d..f4e289aca1b 100644
--- a/configs/libretech-s905d-pc_defconfig
+++ b/configs/libretech-s905d-pc_defconfig
@@ -75,4 +75,8 @@ CONFIG_VIDEO_MESON=y
CONFIG_VIDEO_DT_SIMPLEFB=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
+CONFIG_BMP_24BPP=y
+CONFIG_BMP_32BPP=y
CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/configs/libretech-s912-pc_defconfig b/configs/libretech-s912-pc_defconfig
index 79b20e3ccb1..24e410c5aa7 100644
--- a/configs/libretech-s912-pc_defconfig
+++ b/configs/libretech-s912-pc_defconfig
@@ -74,4 +74,8 @@ CONFIG_VIDEO_MESON=y
CONFIG_VIDEO_DT_SIMPLEFB=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
+CONFIG_BMP_24BPP=y
+CONFIG_BMP_32BPP=y
CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/configs/m53menlo_defconfig b/configs/m53menlo_defconfig
index f68395f26de..251f1bc9542 100644
--- a/configs/m53menlo_defconfig
+++ b/configs/m53menlo_defconfig
@@ -104,5 +104,8 @@ CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASHIMAGE_GUARD=y
CONFIG_SPLASH_SCREEN_ALIGN=y
CONFIG_SPLASH_SOURCE=y
+CONFIG_VIDEO_BMP_GZIP=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
CONFIG_WATCHDOG_TIMEOUT_MSECS=8000
CONFIG_IMX_WATCHDOG=y
diff --git a/configs/marsboard_defconfig b/configs/marsboard_defconfig
index 0b8eff8df53..22578714b5c 100644
--- a/configs/marsboard_defconfig
+++ b/configs/marsboard_defconfig
@@ -52,4 +52,6 @@ CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_VIDEO_IPUV3=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
CONFIG_OF_LIBFDT=y
diff --git a/configs/mt8512_bm1_emmc_defconfig b/configs/mt8512_bm1_emmc_defconfig
index 950507fddcf..aaf59f52a8a 100644
--- a/configs/mt8512_bm1_emmc_defconfig
+++ b/configs/mt8512_bm1_emmc_defconfig
@@ -9,11 +9,16 @@ CONFIG_DM_GPIO=y
CONFIG_TARGET_MT8512=y
CONFIG_DEFAULT_DEVICE_TREE="mt8512-bm1-emmc"
CONFIG_FIT=y
+CONFIG_EFI_PARTITION=y
CONFIG_FIT_SIGNATURE=y
CONFIG_DEFAULT_FDT_FILE="mt8512-bm1-emmc.dtb"
CONFIG_SYS_PROMPT="MT8512> "
CONFIG_CMD_BOOTMENU=y
CONFIG_CMD_MMC=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+# CONFIG_DOS_PARTITION is not set
CONFIG_ENV_OVERWRITE=y
CONFIG_REGMAP=y
CONFIG_SYSCON=y
@@ -26,6 +31,16 @@ CONFIG_PINCONF=y
CONFIG_PINCTRL_MT8512=y
CONFIG_RAM=y
CONFIG_BAUDRATE=921600
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_BUF_ADDR=0x56000000
+CONFIG_FASTBOOT_BUF_SIZE=0x1e00000
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_MMC_BOOT1_SUPPORT=y
+CONFIG_PHY=y
+CONFIG_PHY_MTK_TPHY=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
CONFIG_DM_SERIAL=y
CONFIG_MTK_SERIAL=y
CONFIG_TIMER=y
@@ -33,3 +48,14 @@ CONFIG_MTK_TIMER=y
CONFIG_WDT=y
CONFIG_WDT_MTK=y
CONFIG_LZO=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_DM_USB_GADGET=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_MTU3=y
+# CONFIG_USB_MTU3_HOST is not set
+CONFIG_USB_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_MANUFACTURER="MediaTek"
+CONFIG_USB_GADGET_VENDOR_NUM=0x0e8d
+CONFIG_USB_GADGET_PRODUCT_NUM=0x201c
diff --git a/configs/mx23evk_defconfig b/configs/mx23evk_defconfig
index 6b89937cdbd..a5f7cc7f975 100644
--- a/configs/mx23evk_defconfig
+++ b/configs/mx23evk_defconfig
@@ -39,4 +39,6 @@ CONFIG_USB_EHCI_HCD=y
CONFIG_USB_STORAGE=y
CONFIG_VIDEO=y
CONFIG_SPLASH_SCREEN=y
+CONFIG_VIDEO_BMP_GZIP=y
+CONFIG_VIDEO_BMP_RLE8=y
CONFIG_OF_LIBFDT=y
diff --git a/configs/mx28evk_auart_console_defconfig b/configs/mx28evk_auart_console_defconfig
index fe632215a90..ec4fd6585ee 100644
--- a/configs/mx28evk_auart_console_defconfig
+++ b/configs/mx28evk_auart_console_defconfig
@@ -58,4 +58,6 @@ CONFIG_USB_ETHER_ASIX=y
CONFIG_USB_ETHER_SMSC95XX=y
CONFIG_VIDEO=y
CONFIG_SPLASH_SCREEN=y
+CONFIG_VIDEO_BMP_GZIP=y
+CONFIG_VIDEO_BMP_RLE8=y
CONFIG_OF_LIBFDT=y
diff --git a/configs/mx28evk_defconfig b/configs/mx28evk_defconfig
index 59857774c72..4f0ed83bc1f 100644
--- a/configs/mx28evk_defconfig
+++ b/configs/mx28evk_defconfig
@@ -58,4 +58,6 @@ CONFIG_USB_ETHER_ASIX=y
CONFIG_USB_ETHER_SMSC95XX=y
CONFIG_VIDEO=y
CONFIG_SPLASH_SCREEN=y
+CONFIG_VIDEO_BMP_GZIP=y
+CONFIG_VIDEO_BMP_RLE8=y
CONFIG_OF_LIBFDT=y
diff --git a/configs/mx28evk_nand_defconfig b/configs/mx28evk_nand_defconfig
index 7954e03f372..7d95b8fc52d 100644
--- a/configs/mx28evk_nand_defconfig
+++ b/configs/mx28evk_nand_defconfig
@@ -59,4 +59,6 @@ CONFIG_USB_ETHER_ASIX=y
CONFIG_USB_ETHER_SMSC95XX=y
CONFIG_VIDEO=y
CONFIG_SPLASH_SCREEN=y
+CONFIG_VIDEO_BMP_GZIP=y
+CONFIG_VIDEO_BMP_RLE8=y
CONFIG_OF_LIBFDT=y
diff --git a/configs/mx28evk_spi_defconfig b/configs/mx28evk_spi_defconfig
index 8ed9a5aeca1..e969d50af7f 100644
--- a/configs/mx28evk_spi_defconfig
+++ b/configs/mx28evk_spi_defconfig
@@ -55,4 +55,6 @@ CONFIG_USB_ETHER_ASIX=y
CONFIG_USB_ETHER_SMSC95XX=y
CONFIG_VIDEO=y
CONFIG_SPLASH_SCREEN=y
+CONFIG_VIDEO_BMP_GZIP=y
+CONFIG_VIDEO_BMP_RLE8=y
CONFIG_OF_LIBFDT=y
diff --git a/configs/mx51evk_defconfig b/configs/mx51evk_defconfig
index 343816f89f3..72b1417de92 100644
--- a/configs/mx51evk_defconfig
+++ b/configs/mx51evk_defconfig
@@ -39,4 +39,5 @@ CONFIG_USB_ETHER_ASIX=y
CONFIG_USB_ETHER_SMSC95XX=y
CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_SPLASH_SCREEN=y
+CONFIG_VIDEO_BMP_RLE8=y
CONFIG_OF_LIBFDT=y
diff --git a/configs/mx53loco_defconfig b/configs/mx53loco_defconfig
index a1096a7f93f..a97c7503960 100644
--- a/configs/mx53loco_defconfig
+++ b/configs/mx53loco_defconfig
@@ -40,4 +40,5 @@ CONFIG_USB_ETHER_MCS7830=y
CONFIG_USB_ETHER_SMSC95XX=y
CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_SPLASH_SCREEN=y
+CONFIG_VIDEO_BMP_RLE8=y
CONFIG_OF_LIBFDT=y
diff --git a/configs/mx6cuboxi_defconfig b/configs/mx6cuboxi_defconfig
index 84640aaa608..4cabe9076a3 100644
--- a/configs/mx6cuboxi_defconfig
+++ b/configs/mx6cuboxi_defconfig
@@ -80,3 +80,5 @@ CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_VIDEO_IPUV3=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
diff --git a/configs/mx6qsabrelite_defconfig b/configs/mx6qsabrelite_defconfig
index aeb266de308..47ff35f56ce 100644
--- a/configs/mx6qsabrelite_defconfig
+++ b/configs/mx6qsabrelite_defconfig
@@ -82,3 +82,6 @@ CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_VIDEO_IPUV3=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_GZIP=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
diff --git a/configs/mx6sabreauto_defconfig b/configs/mx6sabreauto_defconfig
index 46529fc50a3..3241ef8e065 100644
--- a/configs/mx6sabreauto_defconfig
+++ b/configs/mx6sabreauto_defconfig
@@ -107,3 +107,5 @@ CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_VIDEO_IPUV3=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
diff --git a/configs/mx6sabresd_defconfig b/configs/mx6sabresd_defconfig
index 47881a74d60..baa304f7449 100644
--- a/configs/mx6sabresd_defconfig
+++ b/configs/mx6sabresd_defconfig
@@ -116,3 +116,5 @@ CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_VIDEO_IPUV3=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
diff --git a/configs/mx6sxsabresd_defconfig b/configs/mx6sxsabresd_defconfig
index 3d883e2b905..584e79572ac 100644
--- a/configs/mx6sxsabresd_defconfig
+++ b/configs/mx6sxsabresd_defconfig
@@ -76,3 +76,4 @@ CONFIG_USB_ETHER_ASIX=y
CONFIG_VIDEO=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
diff --git a/configs/mx6ul_14x14_evk_defconfig b/configs/mx6ul_14x14_evk_defconfig
index f6831cfcd61..1fb5c004c12 100644
--- a/configs/mx6ul_14x14_evk_defconfig
+++ b/configs/mx6ul_14x14_evk_defconfig
@@ -92,3 +92,5 @@ CONFIG_DM_VIDEO=y
CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
diff --git a/configs/mx6ul_9x9_evk_defconfig b/configs/mx6ul_9x9_evk_defconfig
index 41646503e13..3d4f0e0c3ff 100644
--- a/configs/mx6ul_9x9_evk_defconfig
+++ b/configs/mx6ul_9x9_evk_defconfig
@@ -82,3 +82,5 @@ CONFIG_DM_VIDEO=y
CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
diff --git a/configs/mx7dsabresd_defconfig b/configs/mx7dsabresd_defconfig
index 498e4096ff5..9e2e24982ff 100644
--- a/configs/mx7dsabresd_defconfig
+++ b/configs/mx7dsabresd_defconfig
@@ -87,4 +87,5 @@ CONFIG_USB_ETHER_ASIX=y
CONFIG_VIDEO=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
CONFIG_ERRNO_STR=y
diff --git a/configs/mx7dsabresd_qspi_defconfig b/configs/mx7dsabresd_qspi_defconfig
index 0ed5839cd25..7f73956aebe 100644
--- a/configs/mx7dsabresd_qspi_defconfig
+++ b/configs/mx7dsabresd_qspi_defconfig
@@ -94,4 +94,5 @@ CONFIG_USB_ETHER_ASIX=y
CONFIG_VIDEO=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
CONFIG_ERRNO_STR=y
diff --git a/configs/nitrogen6dl2g_defconfig b/configs/nitrogen6dl2g_defconfig
index afe39436fec..5e76c96ad50 100644
--- a/configs/nitrogen6dl2g_defconfig
+++ b/configs/nitrogen6dl2g_defconfig
@@ -83,3 +83,6 @@ CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_VIDEO_IPUV3=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_GZIP=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
diff --git a/configs/nitrogen6dl_defconfig b/configs/nitrogen6dl_defconfig
index 610055a19a2..d7efcfd091d 100644
--- a/configs/nitrogen6dl_defconfig
+++ b/configs/nitrogen6dl_defconfig
@@ -83,3 +83,6 @@ CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_VIDEO_IPUV3=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_GZIP=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
diff --git a/configs/nitrogen6q2g_defconfig b/configs/nitrogen6q2g_defconfig
index a31d4a62c2e..3042b0f1a91 100644
--- a/configs/nitrogen6q2g_defconfig
+++ b/configs/nitrogen6q2g_defconfig
@@ -85,3 +85,6 @@ CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_VIDEO_IPUV3=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_GZIP=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
diff --git a/configs/nitrogen6q_defconfig b/configs/nitrogen6q_defconfig
index d6224bce8cf..5369535275f 100644
--- a/configs/nitrogen6q_defconfig
+++ b/configs/nitrogen6q_defconfig
@@ -85,3 +85,6 @@ CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_VIDEO_IPUV3=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_GZIP=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
diff --git a/configs/nitrogen6s1g_defconfig b/configs/nitrogen6s1g_defconfig
index 37393e975b0..ffd91167a83 100644
--- a/configs/nitrogen6s1g_defconfig
+++ b/configs/nitrogen6s1g_defconfig
@@ -83,3 +83,6 @@ CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_VIDEO_IPUV3=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_GZIP=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
diff --git a/configs/nitrogen6s_defconfig b/configs/nitrogen6s_defconfig
index 8c8344d2c82..18ddb7c5fad 100644
--- a/configs/nitrogen6s_defconfig
+++ b/configs/nitrogen6s_defconfig
@@ -83,3 +83,6 @@ CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_VIDEO_IPUV3=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_GZIP=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
diff --git a/configs/novena_defconfig b/configs/novena_defconfig
index 1dae73439d3..b5657590ff8 100644
--- a/configs/novena_defconfig
+++ b/configs/novena_defconfig
@@ -80,3 +80,5 @@ CONFIG_USB_ETHER_SMSC95XX=y
CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_VIDEO_IPUV3=y
CONFIG_SPLASH_SCREEN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
diff --git a/configs/odroid-c2_defconfig b/configs/odroid-c2_defconfig
index b5bf4368554..5fdce3b4638 100644
--- a/configs/odroid-c2_defconfig
+++ b/configs/odroid-c2_defconfig
@@ -59,5 +59,9 @@ CONFIG_VIDEO_MESON=y
CONFIG_VIDEO_DT_SIMPLEFB=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
+CONFIG_BMP_24BPP=y
+CONFIG_BMP_32BPP=y
CONFIG_OF_LIBFDT_OVERLAY=y
CONFIG_SMBIOS_MANUFACTURER="Hardkernel Co., Ltd."
diff --git a/configs/odroid-c4_defconfig b/configs/odroid-c4_defconfig
index fd4463b059c..367d22db0b6 100644
--- a/configs/odroid-c4_defconfig
+++ b/configs/odroid-c4_defconfig
@@ -64,4 +64,8 @@ CONFIG_VIDEO_MESON=y
CONFIG_VIDEO_DT_SIMPLEFB=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
+CONFIG_BMP_24BPP=y
+CONFIG_BMP_32BPP=y
CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/configs/odroid-n2_defconfig b/configs/odroid-n2_defconfig
index 0fd73702003..76c60ab0321 100644
--- a/configs/odroid-n2_defconfig
+++ b/configs/odroid-n2_defconfig
@@ -62,4 +62,8 @@ CONFIG_DM_VIDEO=y
CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_VIDEO_MESON=y
CONFIG_VIDEO_DT_SIMPLEFB=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
+CONFIG_BMP_24BPP=y
+CONFIG_BMP_32BPP=y
CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/configs/opos6uldev_defconfig b/configs/opos6uldev_defconfig
index 9592ee8879c..2b83fa206f8 100644
--- a/configs/opos6uldev_defconfig
+++ b/configs/opos6uldev_defconfig
@@ -109,5 +109,9 @@ CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
CONFIG_SPLASH_SOURCE=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
+CONFIG_BMP_24BPP=y
+CONFIG_BMP_32BPP=y
CONFIG_OF_LIBFDT_OVERLAY=y
# CONFIG_EFI_LOADER is not set
diff --git a/configs/pico-dwarf-imx6ul_defconfig b/configs/pico-dwarf-imx6ul_defconfig
index 16e7111b9c4..f14b80f8cbd 100644
--- a/configs/pico-dwarf-imx6ul_defconfig
+++ b/configs/pico-dwarf-imx6ul_defconfig
@@ -72,3 +72,4 @@ CONFIG_CI_UDC=y
CONFIG_VIDEO=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
diff --git a/configs/pico-dwarf-imx7d_defconfig b/configs/pico-dwarf-imx7d_defconfig
index 08a05e241aa..085913ef82d 100644
--- a/configs/pico-dwarf-imx7d_defconfig
+++ b/configs/pico-dwarf-imx7d_defconfig
@@ -80,3 +80,5 @@ CONFIG_DM_VIDEO=y
CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
diff --git a/configs/pico-hobbit-imx6ul_defconfig b/configs/pico-hobbit-imx6ul_defconfig
index b0f4ea3f79a..42c419d3e8f 100644
--- a/configs/pico-hobbit-imx6ul_defconfig
+++ b/configs/pico-hobbit-imx6ul_defconfig
@@ -75,3 +75,4 @@ CONFIG_CI_UDC=y
CONFIG_VIDEO=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
diff --git a/configs/pico-hobbit-imx7d_defconfig b/configs/pico-hobbit-imx7d_defconfig
index d41312187f0..6b3b100d20e 100644
--- a/configs/pico-hobbit-imx7d_defconfig
+++ b/configs/pico-hobbit-imx7d_defconfig
@@ -80,3 +80,5 @@ CONFIG_DM_VIDEO=y
CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
diff --git a/configs/pico-imx6_defconfig b/configs/pico-imx6_defconfig
index 21ed5e3b40f..b08fa5f9b79 100644
--- a/configs/pico-imx6_defconfig
+++ b/configs/pico-imx6_defconfig
@@ -90,3 +90,5 @@ CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_VIDEO_IPUV3=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
diff --git a/configs/pico-imx7d_bl33_defconfig b/configs/pico-imx7d_bl33_defconfig
index 9168345fd1a..be9661fc3ce 100644
--- a/configs/pico-imx7d_bl33_defconfig
+++ b/configs/pico-imx7d_bl33_defconfig
@@ -76,4 +76,6 @@ CONFIG_DM_VIDEO=y
CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/configs/pico-imx7d_defconfig b/configs/pico-imx7d_defconfig
index 0af1c6b5b1f..e2e3a56437f 100644
--- a/configs/pico-imx7d_defconfig
+++ b/configs/pico-imx7d_defconfig
@@ -80,3 +80,5 @@ CONFIG_DM_VIDEO=y
CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
diff --git a/configs/pico-nymph-imx7d_defconfig b/configs/pico-nymph-imx7d_defconfig
index 08a05e241aa..085913ef82d 100644
--- a/configs/pico-nymph-imx7d_defconfig
+++ b/configs/pico-nymph-imx7d_defconfig
@@ -80,3 +80,5 @@ CONFIG_DM_VIDEO=y
CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
diff --git a/configs/pico-pi-imx6ul_defconfig b/configs/pico-pi-imx6ul_defconfig
index 84032eda6d0..2572f31504a 100644
--- a/configs/pico-pi-imx6ul_defconfig
+++ b/configs/pico-pi-imx6ul_defconfig
@@ -75,3 +75,4 @@ CONFIG_CI_UDC=y
CONFIG_VIDEO=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
diff --git a/configs/pico-pi-imx7d_defconfig b/configs/pico-pi-imx7d_defconfig
index ad4e248a5dc..4005f8d1afb 100644
--- a/configs/pico-pi-imx7d_defconfig
+++ b/configs/pico-pi-imx7d_defconfig
@@ -80,3 +80,5 @@ CONFIG_DM_VIDEO=y
CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
diff --git a/configs/puma-rk3399_defconfig b/configs/puma-rk3399_defconfig
index a0ad3258d8d..60178e3754c 100644
--- a/configs/puma-rk3399_defconfig
+++ b/configs/puma-rk3399_defconfig
@@ -95,4 +95,7 @@ CONFIG_DM_VIDEO=y
CONFIG_DISPLAY=y
CONFIG_VIDEO_ROCKCHIP=y
CONFIG_DISPLAY_ROCKCHIP_HDMI=y
+CONFIG_BMP_16BPP=y
+CONFIG_BMP_24BPP=y
+CONFIG_BMP_32BPP=y
CONFIG_ERRNO_STR=y
diff --git a/configs/pxm2_defconfig b/configs/pxm2_defconfig
index 9238571c276..a547398ae34 100644
--- a/configs/pxm2_defconfig
+++ b/configs/pxm2_defconfig
@@ -106,3 +106,4 @@ CONFIG_SYS_CONSOLE_BG_COL=0xff
CONFIG_SYS_CONSOLE_FG_COL=0x00
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
diff --git a/configs/riotboard_defconfig b/configs/riotboard_defconfig
index 4d317f606d4..1c632770b3b 100644
--- a/configs/riotboard_defconfig
+++ b/configs/riotboard_defconfig
@@ -53,4 +53,6 @@ CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_VIDEO_IPUV3=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
CONFIG_OF_LIBFDT=y
diff --git a/configs/riotboard_spl_defconfig b/configs/riotboard_spl_defconfig
index 61534a96e78..42d737771c4 100644
--- a/configs/riotboard_spl_defconfig
+++ b/configs/riotboard_spl_defconfig
@@ -63,5 +63,7 @@ CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_VIDEO_IPUV3=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
CONFIG_OF_LIBFDT=y
CONFIG_SPL_OF_LIBFDT=y
diff --git a/configs/rut_defconfig b/configs/rut_defconfig
index b13641032ca..4037c6a9f45 100644
--- a/configs/rut_defconfig
+++ b/configs/rut_defconfig
@@ -106,3 +106,4 @@ CONFIG_SYS_CONSOLE_BG_COL=0xff
CONFIG_SYS_CONSOLE_FG_COL=0x00
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
diff --git a/configs/s5p4418_nanopi2_defconfig b/configs/s5p4418_nanopi2_defconfig
index 8fb382c0814..075210942f1 100644
--- a/configs/s5p4418_nanopi2_defconfig
+++ b/configs/s5p4418_nanopi2_defconfig
@@ -55,4 +55,5 @@ CONFIG_VIDEO_NX_HDMI=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
CONFIG_SPLASH_SOURCE=y
+CONFIG_BMP_24BPP=y
CONFIG_ERRNO_STR=y
diff --git a/configs/sam9x60ek_mmc_defconfig b/configs/sam9x60ek_mmc_defconfig
index f05addb6c36..e97b20aeb33 100644
--- a/configs/sam9x60ek_mmc_defconfig
+++ b/configs/sam9x60ek_mmc_defconfig
@@ -2,7 +2,7 @@ CONFIG_ARM=y
CONFIG_ARCH_AT91=y
CONFIG_SYS_TEXT_BASE=0x23f00000
CONFIG_TARGET_SAM9X60EK=y
-CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_NR_DRAM_BANKS=8
CONFIG_ENV_SIZE=0x4000
CONFIG_DM_GPIO=y
@@ -36,8 +36,10 @@ CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_DM=y
CONFIG_CLK=y
+CONFIG_CLK_CCF=y
CONFIG_CLK_AT91=y
CONFIG_AT91_GENERIC_CLK=y
+CONFIG_AT91_SAM9X60_PLL=y
CONFIG_AT91_GPIO=y
CONFIG_DM_I2C=y
CONFIG_SYS_I2C_AT91=y
diff --git a/configs/sam9x60ek_nandflash_defconfig b/configs/sam9x60ek_nandflash_defconfig
index 6d93c7610b4..bc326f96368 100644
--- a/configs/sam9x60ek_nandflash_defconfig
+++ b/configs/sam9x60ek_nandflash_defconfig
@@ -2,7 +2,7 @@ CONFIG_ARM=y
CONFIG_ARCH_AT91=y
CONFIG_SYS_TEXT_BASE=0x23f00000
CONFIG_TARGET_SAM9X60EK=y
-CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_NR_DRAM_BANKS=8
CONFIG_DM_GPIO=y
CONFIG_DEBUG_UART_BOARD_INIT=y
@@ -40,8 +40,10 @@ CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_DM=y
CONFIG_CLK=y
+CONFIG_CLK_CCF=y
CONFIG_CLK_AT91=y
CONFIG_AT91_GENERIC_CLK=y
+CONFIG_AT91_SAM9X60_PLL=y
CONFIG_AT91_GPIO=y
CONFIG_DM_I2C=y
CONFIG_SYS_I2C_AT91=y
diff --git a/configs/sam9x60ek_qspiflash_defconfig b/configs/sam9x60ek_qspiflash_defconfig
index d7da981e860..2f50f2fe47b 100644
--- a/configs/sam9x60ek_qspiflash_defconfig
+++ b/configs/sam9x60ek_qspiflash_defconfig
@@ -2,7 +2,7 @@ CONFIG_ARM=y
CONFIG_ARCH_AT91=y
CONFIG_SYS_TEXT_BASE=0x23f00000
CONFIG_TARGET_SAM9X60EK=y
-CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_NR_DRAM_BANKS=8
CONFIG_ENV_SECT_SIZE=0x1000
CONFIG_DM_GPIO=y
@@ -48,8 +48,10 @@ CONFIG_ENV_SPI_MODE=0x0
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_DM=y
CONFIG_CLK=y
+CONFIG_CLK_CCF=y
CONFIG_CLK_AT91=y
CONFIG_AT91_GENERIC_CLK=y
+CONFIG_AT91_SAM9X60_PLL=y
CONFIG_AT91_GPIO=y
CONFIG_DM_I2C=y
CONFIG_SYS_I2C_AT91=y
diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig
index 7c713cb4a4f..e9928d5fc2e 100644
--- a/configs/sandbox64_defconfig
+++ b/configs/sandbox64_defconfig
@@ -217,6 +217,7 @@ CONFIG_VIDEO_SANDBOX_SDL=y
CONFIG_OSD=y
CONFIG_SANDBOX_OSD=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
CONFIG_WDT=y
CONFIG_WDT_SANDBOX=y
CONFIG_FS_CBFS=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 6ac29199777..b15b1889e07 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -253,6 +253,7 @@ CONFIG_VIDEO_DSI_HOST_SANDBOX=y
CONFIG_OSD=y
CONFIG_SANDBOX_OSD=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
CONFIG_W1=y
CONFIG_W1_GPIO=y
CONFIG_W1_EEPROM=y
diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig
index dd93167e1b7..6ee23c4a619 100644
--- a/configs/sandbox_flattree_defconfig
+++ b/configs/sandbox_flattree_defconfig
@@ -192,6 +192,7 @@ CONFIG_CONSOLE_TRUETYPE_CANTORAONE=y
CONFIG_VIDEO_SANDBOX_SDL=y
CONFIG_OSD=y
CONFIG_SANDBOX_OSD=y
+CONFIG_VIDEO_BMP_RLE8=y
CONFIG_CMD_DHRYSTONE=y
CONFIG_RSA_VERIFY_WITH_PKEY=y
CONFIG_TPM=y
diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig
index 6d8e827aebc..1d49e816393 100644
--- a/configs/sandbox_spl_defconfig
+++ b/configs/sandbox_spl_defconfig
@@ -211,6 +211,7 @@ CONFIG_VIDEO_SANDBOX_SDL=y
CONFIG_OSD=y
CONFIG_SANDBOX_OSD=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
CONFIG_FS_CBFS=y
CONFIG_FS_CRAMFS=y
# CONFIG_SPL_USE_TINY_PRINTF is not set
diff --git a/configs/sei510_defconfig b/configs/sei510_defconfig
index 4dbc806ea74..7b97a2f6f34 100644
--- a/configs/sei510_defconfig
+++ b/configs/sei510_defconfig
@@ -80,4 +80,8 @@ CONFIG_VIDEO_MESON=y
CONFIG_VIDEO_DT_SIMPLEFB=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
+CONFIG_BMP_24BPP=y
+CONFIG_BMP_32BPP=y
CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/configs/sei610_defconfig b/configs/sei610_defconfig
index 5990de6abfd..0ed17091b58 100644
--- a/configs/sei610_defconfig
+++ b/configs/sei610_defconfig
@@ -80,4 +80,8 @@ CONFIG_VIDEO_MESON=y
CONFIG_VIDEO_DT_SIMPLEFB=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
+CONFIG_BMP_24BPP=y
+CONFIG_BMP_32BPP=y
CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/configs/stm32f746-disco_defconfig b/configs/stm32f746-disco_defconfig
index b41a1d5220b..106ef28b831 100644
--- a/configs/stm32f746-disco_defconfig
+++ b/configs/stm32f746-disco_defconfig
@@ -62,4 +62,8 @@ CONFIG_VIDEO_STM32_MAX_XRES=480
CONFIG_VIDEO_STM32_MAX_YRES=640
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
+CONFIG_BMP_24BPP=y
+CONFIG_BMP_32BPP=y
CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/configs/stm32f769-disco_defconfig b/configs/stm32f769-disco_defconfig
index fafc71ee77c..cc3fad603b2 100644
--- a/configs/stm32f769-disco_defconfig
+++ b/configs/stm32f769-disco_defconfig
@@ -64,4 +64,8 @@ CONFIG_VIDEO_STM32_MAX_XRES=480
CONFIG_VIDEO_STM32_MAX_YRES=800
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
+CONFIG_BMP_24BPP=y
+CONFIG_BMP_32BPP=y
CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig
index a8c4112dbe1..ce7225cee11 100644
--- a/configs/stm32mp15_basic_defconfig
+++ b/configs/stm32mp15_basic_defconfig
@@ -149,6 +149,10 @@ CONFIG_VIDEO_STM32=y
CONFIG_VIDEO_STM32_DSI=y
CONFIG_VIDEO_STM32_MAX_XRES=1280
CONFIG_VIDEO_STM32_MAX_YRES=800
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
+CONFIG_BMP_24BPP=y
+CONFIG_BMP_32BPP=y
CONFIG_WDT=y
CONFIG_WDT_STM32MP=y
CONFIG_ERRNO_STR=y
diff --git a/configs/stm32mp15_dhcom_basic_defconfig b/configs/stm32mp15_dhcom_basic_defconfig
index 7668fd01cd7..d7b4cd76c86 100644
--- a/configs/stm32mp15_dhcom_basic_defconfig
+++ b/configs/stm32mp15_dhcom_basic_defconfig
@@ -148,5 +148,9 @@ CONFIG_VIDEO_STM32=y
CONFIG_VIDEO_STM32_DSI=y
CONFIG_VIDEO_STM32_MAX_XRES=1280
CONFIG_VIDEO_STM32_MAX_YRES=800
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
+CONFIG_BMP_24BPP=y
+CONFIG_BMP_32BPP=y
CONFIG_LZO=y
CONFIG_FDT_FIXUP_PARTITIONS=y
diff --git a/configs/stm32mp15_dhcor_basic_defconfig b/configs/stm32mp15_dhcor_basic_defconfig
index aa384517c3c..a6620561aca 100644
--- a/configs/stm32mp15_dhcor_basic_defconfig
+++ b/configs/stm32mp15_dhcor_basic_defconfig
@@ -142,5 +142,9 @@ CONFIG_VIDEO_STM32=y
CONFIG_VIDEO_STM32_DSI=y
CONFIG_VIDEO_STM32_MAX_XRES=1280
CONFIG_VIDEO_STM32_MAX_YRES=800
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
+CONFIG_BMP_24BPP=y
+CONFIG_BMP_32BPP=y
CONFIG_LZO=y
CONFIG_FDT_FIXUP_PARTITIONS=y
diff --git a/configs/stm32mp15_trusted_defconfig b/configs/stm32mp15_trusted_defconfig
index 0792884a9d8..50288fe8664 100644
--- a/configs/stm32mp15_trusted_defconfig
+++ b/configs/stm32mp15_trusted_defconfig
@@ -130,6 +130,10 @@ CONFIG_VIDEO_STM32=y
CONFIG_VIDEO_STM32_DSI=y
CONFIG_VIDEO_STM32_MAX_XRES=1280
CONFIG_VIDEO_STM32_MAX_YRES=800
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
+CONFIG_BMP_24BPP=y
+CONFIG_BMP_32BPP=y
CONFIG_WDT=y
CONFIG_WDT_STM32MP=y
CONFIG_ERRNO_STR=y
diff --git a/configs/tbs2910_defconfig b/configs/tbs2910_defconfig
index 8b0795093e6..f846533f3ba 100644
--- a/configs/tbs2910_defconfig
+++ b/configs/tbs2910_defconfig
@@ -106,6 +106,7 @@ CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_VIDCONSOLE_AS_LCD=y
CONFIG_I2C_EDID=y
CONFIG_VIDEO_IPUV3=y
+CONFIG_VIDEO_BMP_RLE8=y
# CONFIG_GZIP is not set
CONFIG_OF_LIBFDT_ASSUME_MASK=0xff
# CONFIG_EFI_LOADER is not set
diff --git a/configs/theadorable-x86-conga-qa3-e3845-pcie-x4_defconfig b/configs/theadorable-x86-conga-qa3-e3845-pcie-x4_defconfig
index 532863dff09..897d061416e 100644
--- a/configs/theadorable-x86-conga-qa3-e3845-pcie-x4_defconfig
+++ b/configs/theadorable-x86-conga-qa3-e3845-pcie-x4_defconfig
@@ -67,4 +67,5 @@ CONFIG_USB_ETHER_RTL8152=y
CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
CONFIG_FRAMEBUFFER_VESA_MODE_114=y
CONFIG_CONSOLE_SCROLL_LINES=5
+CONFIG_BMP_16BPP=y
# CONFIG_GZIP is not set
diff --git a/configs/theadorable-x86-conga-qa3-e3845_defconfig b/configs/theadorable-x86-conga-qa3-e3845_defconfig
index 8e5b6a5a5c4..a8890eb4e8c 100644
--- a/configs/theadorable-x86-conga-qa3-e3845_defconfig
+++ b/configs/theadorable-x86-conga-qa3-e3845_defconfig
@@ -66,4 +66,5 @@ CONFIG_USB_ETHER_RTL8152=y
CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
CONFIG_FRAMEBUFFER_VESA_MODE_114=y
CONFIG_CONSOLE_SCROLL_LINES=5
+CONFIG_BMP_16BPP=y
# CONFIG_GZIP is not set
diff --git a/configs/theadorable-x86-dfi-bt700_defconfig b/configs/theadorable-x86-dfi-bt700_defconfig
index 28a5f98ef7a..51aeaafe874 100644
--- a/configs/theadorable-x86-dfi-bt700_defconfig
+++ b/configs/theadorable-x86-dfi-bt700_defconfig
@@ -63,4 +63,5 @@ CONFIG_USB_ETHER_RTL8152=y
CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
CONFIG_FRAMEBUFFER_VESA_MODE_114=y
CONFIG_CONSOLE_SCROLL_LINES=5
+CONFIG_BMP_16BPP=y
# CONFIG_GZIP is not set
diff --git a/configs/theadorable_debug_defconfig b/configs/theadorable_debug_defconfig
index 48fd12425f9..dbf006b1903 100644
--- a/configs/theadorable_debug_defconfig
+++ b/configs/theadorable_debug_defconfig
@@ -82,3 +82,6 @@ CONFIG_DM_VIDEO=y
# CONFIG_VIDEO_BPP8 is not set
# CONFIG_VIDEO_BPP32 is not set
CONFIG_VIDEO_MVEBU=y
+CONFIG_BMP_16BPP=y
+CONFIG_BMP_24BPP=y
+CONFIG_BMP_32BPP=y
diff --git a/configs/wandboard_defconfig b/configs/wandboard_defconfig
index 6de5b551161..7c54999f1c8 100644
--- a/configs/wandboard_defconfig
+++ b/configs/wandboard_defconfig
@@ -81,3 +81,5 @@ CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_VIDEO_IPUV3=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
diff --git a/doc/device-tree-bindings/usb/generic.txt b/doc/device-tree-bindings/usb/generic.txt
new file mode 100644
index 00000000000..a02a198dfbe
--- /dev/null
+++ b/doc/device-tree-bindings/usb/generic.txt
@@ -0,0 +1,31 @@
+Generic USB Properties
+
+Optional properties:
+ - maximum-speed: tells USB controllers we want to work up to a certain
+ speed. Valid arguments are "super-speed-plus",
+ "super-speed", "high-speed", "full-speed" and
+ "low-speed". In case this isn't passed via DT, USB
+ controllers should default to their maximum HW
+ capability.
+ - dr_mode: tells Dual-Role USB controllers that we want to work on a
+ particular mode. Valid arguments are "host",
+ "peripheral" and "otg". In case this attribute isn't
+ passed via DT, USB DRD controllers should default to
+ OTG.
+ - phy_type: tells USB controllers that we want to configure the core to support
+ a UTMI+ PHY with an 8- or 16-bit interface if UTMI+ is
+ selected. Valid arguments are "utmi" and "utmi_wide".
+ In case this isn't passed via DT, USB controllers should
+ default to HW capability.
+
+This is an attribute to a USB controller such as:
+
+dwc3@4a030000 {
+ compatible = "synopsys,dwc3";
+ reg = <0x4a030000 0xcfff>;
+ interrupts = <0 92 4>
+ usb-phy = <&usb2_phy>, <&usb3,phy>;
+ maximum-speed = "super-speed";
+ dr_mode = "otg";
+ phy_type = "utmi_wide";
+};
diff --git a/doc/device-tree-bindings/usb/mediatek,mtu3.txt b/doc/device-tree-bindings/usb/mediatek,mtu3.txt
new file mode 100644
index 00000000000..ab877bfa89f
--- /dev/null
+++ b/doc/device-tree-bindings/usb/mediatek,mtu3.txt
@@ -0,0 +1,79 @@
+The device node for Mediatek USB3 DRD controller
+
+Required properties:
+ - compatible : should be "mediatek,<soc-model>-mtu3", "mediatek,mtu3",
+ soc-model is the name of SoC, such as mt8512 etc,
+ when using "mediatek,mtu3" compatible string, you need SoC specific
+ ones in addition, one of:
+ - "mediatek,mt8512-mtu3"
+ - reg : specifies physical base address and size of the registers
+ - reg-names: should be
+ - "ippc" : IP Port Control
+ - power-domains : a phandle to USB power domain node to control USB's MTCMOS
+ - clocks : a list of phandle + clock-specifier pairs, one for each
+ entry in clock-names
+ - clock-names : must contain "sys_ck" for clock of controller,
+ the following clocks are optional:
+ "ref_ck", "mcu_ck", "dma_ck" and "xhci_ck";
+ - phys : list of all the USB PHYs on this HCD
+ - #address-cells, #size-cells : used for sub-nodes with 'reg' property
+ - ranges : allows valid 1:1 translation between child's address space and
+ parent's address space
+
+Optional properties:
+ - vusb33-supply : regulator of USB AVDD3.3v
+ - vbus-supply : regulator of VBUS 5v, needed when supports host mode.
+
+Sub-nodes:
+Required properties:
+ - compatible : should be "mediatek,ssusb"
+ - reg : specifies physical base address and size of the registers
+ - reg-names: should be
+ - "mac" : SSUSB MAC, include xHCI and device
+ - interrupts : interrupt used by xHCI or device
+ - dr_mode : should be one of "host" or "peripheral",
+ see : usb/generic.txt
+
+Optional properties:
+ - pinctrl-names : a pinctrl state named "default" is optional
+ - pinctrl-0 : pin control group
+ See: pinctrl/pinctrl-bindings.txt
+
+ - device mode:
+ - maximum-speed : valid arguments are "full-speed", "high-speed",
+ "super-speed" and "super-speed-plus",
+ see: usb/generic.txt
+ - mediatek,force-vbus : force vbus as valid by SW
+
+ - host mode (dr_mode is "host"):
+ - mediatek,u3p-dis-msk : mask to disable u3ports, bit0 for u3port0,
+ bit1 for u3port1, ... etc;
+
+Example:
+usb3: usb@11213e00 {
+ compatible = "mediatek,mt8512-mtu3", "mediatek,mtu3";
+ reg = <0x11213e00 0x0100>;
+ reg-names = "ippc";
+ phys = <&u2port0 PHY_TYPE_USB2>, <&u2port1 PHY_TYPE_USB2>;
+ power-domains = <&scpsys MT8512_POWER_DOMAIN_USB>;
+ clocks = <&infracfg CLK_INFRA_USB_SYS>,
+ <&topckgen CLK_TOP_SSUSB_TOP_CK_EN>,
+ <&infracfg CLK_INFRA_ICUSB>;
+ clock-names = "sys_ck", "ref_ck", "mcu_ck";
+ vusb33-supply = <reg_3p3v>;
+ vbus-supply = <&usb_p0_vbus>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ status = "disabled";
+
+ ssusb: usb@11210000 {
+ compatible = "mediatek,ssusb";
+ reg = <0x11210000 0x3e00>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_LOW>;
+ reg-names = "mac";
+ dr_mode = "peripheral";
+ maximum-speed = "high-speed";
+ status = "disabled";
+ };
+};
diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index 2453c38af1a..580b406d7bd 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_AT91_GENERIC_CLK) += clk-generic.o
obj-$(CONFIG_AT91_UTMI) += clk-utmi.o
obj-$(CONFIG_AT91_SAM9X60_PLL) += clk-sam9x60-pll.o
obj-$(CONFIG_SAMA7G5) += sama7g5.o
+obj-$(CONFIG_SAM9X60) += sam9x60.o
else
obj-y += compat.o
endif
diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c
index 759df93697d..5d93e6a7e52 100644
--- a/drivers/clk/at91/clk-master.c
+++ b/drivers/clk/at91/clk-master.c
@@ -24,7 +24,7 @@
#define MASTER_PRES_MASK 0x7
#define MASTER_PRES_MAX MASTER_PRES_MASK
#define MASTER_DIV_SHIFT 8
-#define MASTER_DIV_MASK 0x3
+#define MASTER_DIV_MASK 0x7
#define PMC_MCR 0x30
#define PMC_MCR_ID_MSK GENMASK(3, 0)
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
index a6a714fd220..f07f535e492 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -30,7 +30,7 @@ extern const struct clk_master_layout at91sam9x5_master_layout;
struct clk_master_characteristics {
struct clk_range output;
- u32 divisors[4];
+ u32 divisors[5];
u8 have_div3_pres;
};
diff --git a/drivers/clk/at91/sam9x60.c b/drivers/clk/at91/sam9x60.c
new file mode 100644
index 00000000000..c3235f565d7
--- /dev/null
+++ b/drivers/clk/at91/sam9x60.c
@@ -0,0 +1,649 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Claudiu Beznea <claudiu.beznea@microchip.com>
+ *
+ * Based on sam9x60.c on Linux.
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <dt-bindings/clk/at91.h>
+#include <linux/clk-provider.h>
+
+#include "pmc.h"
+
+/**
+ * Clock identifiers to be used in conjunction with macros like
+ * AT91_TO_CLK_ID()
+ *
+ * @ID_MD_SLCK: TD slow clock identifier
+ * @ID_TD_SLCK: MD slow clock identifier
+ * @ID_MAIN_XTAL: Main Xtal clock identifier
+ * @ID_MAIN_RC: Main RC clock identifier
+ * @ID_MAIN_RC_OSC: Main RC Oscillator clock identifier
+ * @ID_MAIN_OSC: Main Oscillator clock identifier
+ * @ID_MAINCK: MAINCK clock identifier
+ * @ID_PLL_U_FRAC: UPLL fractional clock identifier
+ * @ID_PLL_U_DIV: UPLL divider clock identifier
+ * @ID_PLL_A_FRAC: APLL fractional clock identifier
+ * @ID_PLL_A_DIV: APLL divider clock identifier
+
+ * @ID_MCK: MCK clock identifier
+
+ * @ID_UTMI: UTMI clock identifier
+
+ * @ID_PROG0: Programmable 0 clock identifier
+ * @ID_PROG1: Programmable 1 clock identifier
+
+ * @ID_PCK0: PCK0 system clock identifier
+ * @ID_PCK1: PCK1 system clock identifier
+ * @ID_DDR: DDR system clock identifier
+ * @ID_QSPI: QSPI system clock identifier
+ *
+ * Note: if changing the values of this enums please sync them with
+ * device tree
+ */
+enum pmc_clk_ids {
+ ID_MD_SLCK = 0,
+ ID_TD_SLCK = 1,
+ ID_MAIN_XTAL = 2,
+ ID_MAIN_RC = 3,
+ ID_MAIN_RC_OSC = 4,
+ ID_MAIN_OSC = 5,
+ ID_MAINCK = 6,
+
+ ID_PLL_U_FRAC = 7,
+ ID_PLL_U_DIV = 8,
+ ID_PLL_A_FRAC = 9,
+ ID_PLL_A_DIV = 10,
+
+ ID_MCK = 11,
+
+ ID_UTMI = 12,
+
+ ID_PROG0 = 13,
+ ID_PROG1 = 14,
+
+ ID_PCK0 = 15,
+ ID_PCK1 = 16,
+
+ ID_DDR = 17,
+ ID_QSPI = 18,
+
+ ID_MAX,
+};
+
+/**
+ * PLL type identifiers
+ * @PLL_TYPE_FRAC: fractional PLL identifier
+ * @PLL_TYPE_DIV: divider PLL identifier
+ */
+enum pll_type {
+ PLL_TYPE_FRAC,
+ PLL_TYPE_DIV,
+};
+
+/* Clock names used as parents for multiple clocks. */
+static const char *clk_names[] = {
+ [ID_MAIN_RC_OSC] = "main_rc_osc",
+ [ID_MAIN_OSC] = "main_osc",
+ [ID_MAINCK] = "mainck",
+ [ID_PLL_U_DIV] = "upll_divpmcck",
+ [ID_PLL_A_DIV] = "plla_divpmcck",
+ [ID_MCK] = "mck",
+};
+
+/* Fractional PLL output range. */
+static const struct clk_range plla_outputs[] = {
+ { .min = 2343750, .max = 1200000000 },
+};
+
+static const struct clk_range upll_outputs[] = {
+ { .min = 300000000, .max = 500000000 },
+};
+
+/* PLL characteristics. */
+static const struct clk_pll_characteristics apll_characteristics = {
+ .input = { .min = 12000000, .max = 48000000 },
+ .num_output = ARRAY_SIZE(plla_outputs),
+ .output = plla_outputs,
+};
+
+static const struct clk_pll_characteristics upll_characteristics = {
+ .input = { .min = 12000000, .max = 48000000 },
+ .num_output = ARRAY_SIZE(upll_outputs),
+ .output = upll_outputs,
+ .upll = true,
+};
+
+/* Layout for fractional PLLs. */
+static const struct clk_pll_layout pll_layout_frac = {
+ .mul_mask = GENMASK(31, 24),
+ .frac_mask = GENMASK(21, 0),
+ .mul_shift = 24,
+ .frac_shift = 0,
+};
+
+/* Layout for DIV PLLs. */
+static const struct clk_pll_layout pll_layout_div = {
+ .div_mask = GENMASK(7, 0),
+ .endiv_mask = BIT(29),
+ .div_shift = 0,
+ .endiv_shift = 29,
+};
+
+/* MCK characteristics. */
+static const struct clk_master_characteristics mck_characteristics = {
+ .output = { .min = 140000000, .max = 200000000 },
+ .divisors = { 1, 2, 4, 3 },
+ .have_div3_pres = 1,
+};
+
+/* MCK layout. */
+static const struct clk_master_layout mck_layout = {
+ .mask = 0x373,
+ .pres_shift = 4,
+ .offset = 0x28,
+};
+
+/* Programmable clock layout. */
+static const struct clk_programmable_layout programmable_layout = {
+ .pres_mask = 0xff,
+ .pres_shift = 8,
+ .css_mask = 0x1f,
+ .have_slck_mck = 0,
+ .is_pres_direct = 1,
+};
+
+/* Peripheral clock layout. */
+static const struct clk_pcr_layout pcr_layout = {
+ .offset = 0x88,
+ .cmd = BIT(31),
+ .gckcss_mask = GENMASK(12, 8),
+ .pid_mask = GENMASK(6, 0),
+};
+
+/**
+ * PLL clocks description
+ * @n: clock name
+ * @p: clock parent
+ * @l: clock layout
+ * @t: clock type
+ * @f: true if clock is fixed and not changeable by driver
+ * @id: clock id corresponding to PLL driver
+ * @cid: clock id corresponding to clock subsystem
+ */
+static const struct {
+ const char *n;
+ const char *p;
+ const struct clk_pll_layout *l;
+ const struct clk_pll_characteristics *c;
+ u8 t;
+ u8 f;
+ u8 id;
+ u8 cid;
+} sam9x60_plls[] = {
+ {
+ .n = "plla_fracck",
+ .p = "mainck",
+ .l = &pll_layout_frac,
+ .c = &apll_characteristics,
+ .t = PLL_TYPE_FRAC,
+ .f = 1,
+ .id = 0,
+ .cid = ID_PLL_A_FRAC,
+ },
+
+ {
+ .n = "plla_divpmcck",
+ .p = "plla_fracck",
+ .l = &pll_layout_div,
+ .c = &apll_characteristics,
+ .t = PLL_TYPE_DIV,
+ .f = 1,
+ .id = 0,
+ .cid = ID_PLL_A_DIV,
+ },
+
+ {
+ .n = "upll_fracck",
+ .p = "main_osc",
+ .l = &pll_layout_frac,
+ .c = &upll_characteristics,
+ .t = PLL_TYPE_FRAC,
+ .f = 1,
+ .id = 1,
+ .cid = ID_PLL_U_FRAC,
+ },
+
+ {
+ .n = "upll_divpmcck",
+ .p = "upll_fracck",
+ .l = &pll_layout_div,
+ .c = &upll_characteristics,
+ .t = PLL_TYPE_DIV,
+ .f = 1,
+ .id = 1,
+ .cid = ID_PLL_U_DIV,
+ },
+};
+
+/**
+ * Programmable clock description
+ * @n: clock name
+ * @cid: clock id corresponding to clock subsystem
+ */
+static const struct {
+ const char *n;
+ u8 cid;
+} sam9x60_prog[] = {
+ { .n = "prog0", .cid = ID_PROG0, },
+ { .n = "prog1", .cid = ID_PROG1, },
+};
+
+/* Mux table for programmable clocks. */
+static u32 sam9x60_prog_mux_table[] = { 0, 1, 2, 3, 4, 5, };
+
+/**
+ * System clock description
+ * @n: clock name
+ * @p: parent clock name
+ * @id: clock id corresponding to system clock driver
+ * @cid: clock id corresponding to clock subsystem
+ */
+static const struct {
+ const char *n;
+ const char *p;
+ u8 id;
+ u8 cid;
+} sam9x60_systemck[] = {
+ { .n = "ddrck", .p = "mck", .id = 2, .cid = ID_DDR, },
+ { .n = "pck0", .p = "prog0", .id = 8, .cid = ID_PCK0, },
+ { .n = "pck1", .p = "prog1", .id = 9, .cid = ID_PCK1, },
+ { .n = "qspick", .p = "mck", .id = 19, .cid = ID_QSPI, },
+};
+
+/**
+ * Peripheral clock description
+ * @n: clock name
+ * @id: clock id
+ */
+static const struct {
+ const char *n;
+ u8 id;
+} sam9x60_periphck[] = {
+ { .n = "pioA_clk", .id = 2, },
+ { .n = "pioB_clk", .id = 3, },
+ { .n = "pioC_clk", .id = 4, },
+ { .n = "flex0_clk", .id = 5, },
+ { .n = "flex1_clk", .id = 6, },
+ { .n = "flex2_clk", .id = 7, },
+ { .n = "flex3_clk", .id = 8, },
+ { .n = "flex6_clk", .id = 9, },
+ { .n = "flex7_clk", .id = 10, },
+ { .n = "flex8_clk", .id = 11, },
+ { .n = "sdmmc0_clk", .id = 12, },
+ { .n = "flex4_clk", .id = 13, },
+ { .n = "flex5_clk", .id = 14, },
+ { .n = "flex9_clk", .id = 15, },
+ { .n = "flex10_clk", .id = 16, },
+ { .n = "tcb0_clk", .id = 17, },
+ { .n = "pwm_clk", .id = 18, },
+ { .n = "adc_clk", .id = 19, },
+ { .n = "dma0_clk", .id = 20, },
+ { .n = "matrix_clk", .id = 21, },
+ { .n = "uhphs_clk", .id = 22, },
+ { .n = "udphs_clk", .id = 23, },
+ { .n = "macb0_clk", .id = 24, },
+ { .n = "lcd_clk", .id = 25, },
+ { .n = "sdmmc1_clk", .id = 26, },
+ { .n = "macb1_clk", .id = 27, },
+ { .n = "ssc_clk", .id = 28, },
+ { .n = "can0_clk", .id = 29, },
+ { .n = "can1_clk", .id = 30, },
+ { .n = "flex11_clk", .id = 32, },
+ { .n = "flex12_clk", .id = 33, },
+ { .n = "i2s_clk", .id = 34, },
+ { .n = "qspi_clk", .id = 35, },
+ { .n = "gfx2d_clk", .id = 36, },
+ { .n = "pit64b_clk", .id = 37, },
+ { .n = "trng_clk", .id = 38, },
+ { .n = "aes_clk", .id = 39, },
+ { .n = "tdes_clk", .id = 40, },
+ { .n = "sha_clk", .id = 41, },
+ { .n = "classd_clk", .id = 42, },
+ { .n = "isi_clk", .id = 43, },
+ { .n = "pioD_clk", .id = 44, },
+ { .n = "tcb1_clk", .id = 45, },
+ { .n = "dbgu_clk", .id = 47, },
+ { .n = "mpddr_clk", .id = 49, },
+};
+
+/**
+ * Generic clock description
+ * @n: clock name
+ * @ep: extra parents parents names
+ * @ep_mux_table: extra parents mux table
+ * @ep_clk_mux_table: extra parents clock mux table (for CCF)
+ * @r: clock output range
+ * @ep_count: extra parents count
+ * @id: clock id
+ */
+static const struct {
+ const char *n;
+ struct clk_range r;
+ u8 id;
+} sam9x60_gck[] = {
+ { .n = "flex0_gclk", .id = 5, },
+ { .n = "flex1_gclk", .id = 6, },
+ { .n = "flex2_gclk", .id = 7, },
+ { .n = "flex3_gclk", .id = 8, },
+ { .n = "flex6_gclk", .id = 9, },
+ { .n = "flex7_gclk", .id = 10, },
+ { .n = "flex8_gclk", .id = 11, },
+ { .n = "sdmmc0_gclk", .id = 12, .r = { .min = 0, .max = 105000000 }, },
+ { .n = "flex4_gclk", .id = 13, },
+ { .n = "flex5_gclk", .id = 14, },
+ { .n = "flex9_gclk", .id = 15, },
+ { .n = "flex10_gclk", .id = 16, },
+ { .n = "tcb0_gclk", .id = 17, },
+ { .n = "adc_gclk", .id = 19, },
+ { .n = "lcd_gclk", .id = 25, .r = { .min = 0, .max = 140000000 }, },
+ { .n = "sdmmc1_gclk", .id = 26, .r = { .min = 0, .max = 105000000 }, },
+ { .n = "flex11_gclk", .id = 32, },
+ { .n = "flex12_gclk", .id = 33, },
+ { .n = "i2s_gclk", .id = 34, .r = { .min = 0, .max = 105000000 }, },
+ { .n = "pit64b_gclk", .id = 37, },
+ { .n = "classd_gclk", .id = 42, .r = { .min = 0, .max = 100000000 }, },
+ { .n = "tcb1_gclk", .id = 45, },
+ { .n = "dbgu_gclk", .id = 47, },
+};
+
+#define prepare_mux_table(_allocs, _index, _dst, _src, _num, _label) \
+ do { \
+ int _i; \
+ (_dst) = kzalloc(sizeof(*(_dst)) * (_num), GFP_KERNEL); \
+ if (!(_dst)) { \
+ ret = -ENOMEM; \
+ goto _label; \
+ } \
+ (_allocs)[(_index)++] = (_dst); \
+ for (_i = 0; _i < (_num); _i++) \
+ (_dst)[_i] = (_src)[_i]; \
+ } while (0)
+
+static int sam9x60_clk_probe(struct udevice *dev)
+{
+ void __iomem *base = (void *)devfdt_get_addr_ptr(dev);
+ unsigned int *clkmuxallocs[64], *muxallocs[64];
+ const char *p[10];
+ unsigned int cm[10], m[10], *tmpclkmux, *tmpmux;
+ struct clk clk, *c;
+ bool main_osc_bypass;
+ int ret, muxallocindex = 0, clkmuxallocindex = 0, i;
+ static const struct clk_range r = { 0, 0 };
+
+ if (!base)
+ return -EINVAL;
+
+ memset(muxallocs, 0, ARRAY_SIZE(muxallocs));
+ memset(clkmuxallocs, 0, ARRAY_SIZE(clkmuxallocs));
+
+ ret = clk_get_by_index(dev, 0, &clk);
+ if (ret)
+ return ret;
+
+ ret = clk_get_by_id(clk.id, &c);
+ if (ret)
+ return ret;
+
+ clk_names[ID_TD_SLCK] = kmemdup(clk_hw_get_name(c),
+ strlen(clk_hw_get_name(c)) + 1,
+ GFP_KERNEL);
+ if (!clk_names[ID_TD_SLCK])
+ return -ENOMEM;
+
+ ret = clk_get_by_index(dev, 1, &clk);
+ if (ret)
+ return ret;
+
+ ret = clk_get_by_id(clk.id, &c);
+ if (ret)
+ return ret;
+
+ clk_names[ID_MD_SLCK] = kmemdup(clk_hw_get_name(c),
+ strlen(clk_hw_get_name(c)) + 1,
+ GFP_KERNEL);
+ if (!clk_names[ID_MD_SLCK])
+ return -ENOMEM;
+
+ ret = clk_get_by_index(dev, 2, &clk);
+ if (ret)
+ return ret;
+
+ clk_names[ID_MAIN_XTAL] = kmemdup(clk_hw_get_name(&clk),
+ strlen(clk_hw_get_name(&clk)) + 1,
+ GFP_KERNEL);
+ if (!clk_names[ID_MAIN_XTAL])
+ return -ENOMEM;
+
+ ret = clk_get_by_index(dev, 3, &clk);
+ if (ret)
+ goto fail;
+
+ clk_names[ID_MAIN_RC] = kmemdup(clk_hw_get_name(&clk),
+ strlen(clk_hw_get_name(&clk)) + 1,
+ GFP_KERNEL);
+ if (ret)
+ goto fail;
+
+ main_osc_bypass = dev_read_bool(dev, "atmel,main-osc-bypass");
+
+ /* Register main rc oscillator. */
+ c = at91_clk_main_rc(base, clk_names[ID_MAIN_RC_OSC],
+ clk_names[ID_MAIN_RC]);
+ if (IS_ERR(c)) {
+ ret = PTR_ERR(c);
+ goto fail;
+ }
+ clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_RC_OSC), c);
+
+ /* Register main oscillator. */
+ c = at91_clk_main_osc(base, clk_names[ID_MAIN_OSC],
+ clk_names[ID_MAIN_XTAL], main_osc_bypass);
+ if (IS_ERR(c)) {
+ ret = PTR_ERR(c);
+ goto fail;
+ }
+ clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_OSC), c);
+
+ /* Register mainck. */
+ p[0] = clk_names[ID_MAIN_RC_OSC];
+ p[1] = clk_names[ID_MAIN_OSC];
+ cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_RC_OSC);
+ cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_OSC);
+ prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm, 2,
+ fail);
+ c = at91_clk_sam9x5_main(base, clk_names[ID_MAINCK], p,
+ 2, tmpclkmux, PMC_TYPE_CORE);
+ if (IS_ERR(c)) {
+ ret = PTR_ERR(c);
+ goto fail;
+ }
+ clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK), c);
+
+ /* Register PLL fracs clocks. */
+ for (i = 0; i < ARRAY_SIZE(sam9x60_plls); i++) {
+ if (sam9x60_plls[i].t != PLL_TYPE_FRAC)
+ continue;
+
+ c = sam9x60_clk_register_frac_pll(base, sam9x60_plls[i].n,
+ sam9x60_plls[i].p,
+ sam9x60_plls[i].id,
+ sam9x60_plls[i].c,
+ sam9x60_plls[i].l,
+ sam9x60_plls[i].f);
+ if (IS_ERR(c)) {
+ ret = PTR_ERR(c);
+ goto fail;
+ }
+ clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sam9x60_plls[i].cid), c);
+ }
+
+ /* Register PLL div clocks. */
+ for (i = 0; i < ARRAY_SIZE(sam9x60_plls); i++) {
+ if (sam9x60_plls[i].t != PLL_TYPE_DIV)
+ continue;
+
+ c = sam9x60_clk_register_div_pll(base, sam9x60_plls[i].n,
+ sam9x60_plls[i].p,
+ sam9x60_plls[i].id,
+ sam9x60_plls[i].c,
+ sam9x60_plls[i].l,
+ sam9x60_plls[i].f);
+ if (IS_ERR(c)) {
+ ret = PTR_ERR(c);
+ goto fail;
+ }
+ clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sam9x60_plls[i].cid), c);
+ }
+
+ /* Register MCK clock. */
+ p[0] = clk_names[ID_MD_SLCK];
+ p[1] = clk_names[ID_MAINCK];
+ p[2] = clk_names[ID_PLL_A_DIV];
+ p[3] = clk_names[ID_PLL_U_DIV];
+ cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK);
+ cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK);
+ cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_A_DIV);
+ cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_U_DIV);
+ prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm, 4,
+ fail);
+ c = at91_clk_register_master(base, clk_names[ID_MCK], p, 4, &mck_layout,
+ &mck_characteristics, tmpclkmux);
+ if (IS_ERR(c)) {
+ ret = PTR_ERR(c);
+ goto fail;
+ }
+ clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK), c);
+
+ /* Register programmable clocks. */
+ p[0] = clk_names[ID_MD_SLCK];
+ p[1] = clk_names[ID_TD_SLCK];
+ p[2] = clk_names[ID_MAINCK];
+ p[3] = clk_names[ID_MCK];
+ p[4] = clk_names[ID_PLL_A_DIV];
+ p[5] = clk_names[ID_PLL_U_DIV];
+ cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK);
+ cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK);
+ cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK);
+ cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK);
+ cm[4] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_A_DIV);
+ cm[5] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_U_DIV);
+ for (i = 0; i < ARRAY_SIZE(sam9x60_prog); i++) {
+ prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm,
+ 6, fail);
+
+ c = at91_clk_register_programmable(base, sam9x60_prog[i].n, p,
+ 10, i, &programmable_layout,
+ tmpclkmux,
+ sam9x60_prog_mux_table);
+ if (IS_ERR(c)) {
+ ret = PTR_ERR(c);
+ goto fail;
+ }
+ clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sam9x60_prog[i].cid), c);
+ }
+
+ /* System clocks. */
+ for (i = 0; i < ARRAY_SIZE(sam9x60_systemck); i++) {
+ c = at91_clk_register_system(base, sam9x60_systemck[i].n,
+ sam9x60_systemck[i].p,
+ sam9x60_systemck[i].id);
+ if (IS_ERR(c)) {
+ ret = PTR_ERR(c);
+ goto fail;
+ }
+ clk_dm(AT91_TO_CLK_ID(PMC_TYPE_SYSTEM, sam9x60_systemck[i].cid),
+ c);
+ }
+
+ /* Peripheral clocks. */
+ for (i = 0; i < ARRAY_SIZE(sam9x60_periphck); i++) {
+ c = at91_clk_register_sam9x5_peripheral(base, &pcr_layout,
+ sam9x60_periphck[i].n,
+ clk_names[ID_MCK],
+ sam9x60_periphck[i].id,
+ &r);
+ if (IS_ERR(c)) {
+ ret = PTR_ERR(c);
+ goto fail;
+ }
+ clk_dm(AT91_TO_CLK_ID(PMC_TYPE_PERIPHERAL,
+ sam9x60_periphck[i].id), c);
+ }
+
+ /* Generic clocks. */
+ p[0] = clk_names[ID_MD_SLCK];
+ p[1] = clk_names[ID_TD_SLCK];
+ p[2] = clk_names[ID_MAINCK];
+ p[3] = clk_names[ID_MCK];
+ p[4] = clk_names[ID_PLL_A_DIV];
+ p[5] = clk_names[ID_PLL_U_DIV];
+ m[0] = 0;
+ m[1] = 1;
+ m[2] = 2;
+ m[3] = 3;
+ m[4] = 4;
+ m[5] = 5;
+ cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK);
+ cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK);
+ cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK);
+ cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK);
+ cm[4] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_A_DIV);
+ cm[5] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_U_DIV);
+ for (i = 0; i < ARRAY_SIZE(sam9x60_gck); i++) {
+ prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm,
+ 6, fail);
+ prepare_mux_table(muxallocs, muxallocindex, tmpmux, m,
+ 6, fail);
+
+ c = at91_clk_register_generic(base, &pcr_layout,
+ sam9x60_gck[i].n, p, tmpclkmux,
+ tmpmux, 6, sam9x60_gck[i].id,
+ &sam9x60_gck[i].r);
+ if (IS_ERR(c)) {
+ ret = PTR_ERR(c);
+ goto fail;
+ }
+ clk_dm(AT91_TO_CLK_ID(PMC_TYPE_GCK, sam9x60_gck[i].id), c);
+ }
+
+ return 0;
+
+fail:
+ for (i = 0; i < ARRAY_SIZE(muxallocs); i++)
+ kfree(muxallocs[i]);
+
+ for (i = 0; i < ARRAY_SIZE(clkmuxallocs); i++)
+ kfree(clkmuxallocs[i]);
+
+ return ret;
+}
+
+static const struct udevice_id sam9x60_clk_ids[] = {
+ { .compatible = "microchip,sam9x60-pmc" },
+ { /* Sentinel. */ },
+};
+
+U_BOOT_DRIVER(at91_sam9x60_pmc) = {
+ .name = "at91-sam9x60-pmc",
+ .id = UCLASS_CLK,
+ .of_match = sam9x60_clk_ids,
+ .ops = &at91_clk_ops,
+ .probe = sam9x60_clk_probe,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/at91/sama7g5.c b/drivers/clk/at91/sama7g5.c
index b96937673be..c0d9271966d 100644
--- a/drivers/clk/at91/sama7g5.c
+++ b/drivers/clk/at91/sama7g5.c
@@ -189,13 +189,13 @@ static const struct clk_pll_layout pll_layout_divio = {
/* MCK0 characteristics. */
static const struct clk_master_characteristics mck0_characteristics = {
.output = { .min = 140000000, .max = 200000000 },
- .divisors = { 1, 2, 4, 3 },
+ .divisors = { 1, 2, 4, 3, 5 },
.have_div3_pres = 1,
};
/* MCK0 layout. */
static const struct clk_master_layout mck0_layout = {
- .mask = 0x373,
+ .mask = 0x773,
.pres_shift = 4,
.offset = 0x28,
};
diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig
index 284e2138b39..0c8b9eb47de 100644
--- a/drivers/clk/renesas/Kconfig
+++ b/drivers/clk/renesas/Kconfig
@@ -55,6 +55,24 @@ config CLK_R8A774A1
help
Enable this to support the clocks on Renesas R8A774A1 SoC.
+config CLK_R8A774B1
+ bool "Renesas R8A774B1 clock driver"
+ depends on CLK_RCAR_GEN3
+ help
+ Enable this to support the clocks on Renesas R8A774B1 SoC.
+
+config CLK_R8A774C0
+ bool "Renesas R8A774C0 clock driver"
+ depends on CLK_RCAR_GEN3
+ help
+ Enable this to support the clocks on Renesas R8A774C0 SoC.
+
+config CLK_R8A774E1
+ bool "Renesas R8A774E1 clock driver"
+ depends on CLK_RCAR_GEN3
+ help
+ Enable this to support the clocks on Renesas R8A774E1 SoC.
+
config CLK_R8A7795
bool "Renesas R8A7795 clock driver"
depends on CLK_RCAR_GEN3
diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile
index dd599b757e8..ed1a1252c40 100644
--- a/drivers/clk/renesas/Makefile
+++ b/drivers/clk/renesas/Makefile
@@ -1,6 +1,9 @@
obj-$(CONFIG_CLK_RENESAS) += renesas-cpg-mssr.o
obj-$(CONFIG_CLK_RCAR_GEN2) += clk-rcar-gen2.o
obj-$(CONFIG_CLK_R8A774A1) += r8a774a1-cpg-mssr.o
+obj-$(CONFIG_CLK_R8A774B1) += r8a774b1-cpg-mssr.o
+obj-$(CONFIG_CLK_R8A774C0) += r8a774c0-cpg-mssr.o
+obj-$(CONFIG_CLK_R8A774E1) += r8a774e1-cpg-mssr.o
obj-$(CONFIG_CLK_R8A7790) += r8a7790-cpg-mssr.o
obj-$(CONFIG_CLK_R8A7791) += r8a7791-cpg-mssr.o
obj-$(CONFIG_CLK_R8A7792) += r8a7792-cpg-mssr.o
diff --git a/drivers/clk/renesas/r8a774a1-cpg-mssr.c b/drivers/clk/renesas/r8a774a1-cpg-mssr.c
index 8935667736f..6997054b304 100644
--- a/drivers/clk/renesas/r8a774a1-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a774a1-cpg-mssr.c
@@ -41,6 +41,7 @@ enum clk_ids {
CLK_S2,
CLK_S3,
CLK_SDSRC,
+ CLK_RPCSRC,
CLK_RINT,
/* Module Clocks */
@@ -67,6 +68,7 @@ static const struct cpg_core_clk r8a774a1_core_clks[] = {
DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1),
DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1),
DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1),
+ DEF_FIXED(".rpcsrc", CLK_RPCSRC, CLK_PLL1, 2, 1),
DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32),
@@ -97,6 +99,7 @@ static const struct cpg_core_clk r8a774a1_core_clks[] = {
DEF_GEN3_SD("sd1", R8A774A1_CLK_SD1, CLK_SDSRC, 0x078),
DEF_GEN3_SD("sd2", R8A774A1_CLK_SD2, CLK_SDSRC, 0x268),
DEF_GEN3_SD("sd3", R8A774A1_CLK_SD3, CLK_SDSRC, 0x26c),
+ DEF_GEN3_RPC("rpc", R8A774A1_CLK_RPC, CLK_RPCSRC, 0x238),
DEF_FIXED("cl", R8A774A1_CLK_CL, CLK_PLL1_DIV2, 48, 1),
DEF_FIXED("cp", R8A774A1_CLK_CP, CLK_EXTAL, 2, 1),
@@ -200,6 +203,7 @@ static const struct mssr_mod_clk r8a774a1_mod_clks[] = {
DEF_MOD("can-fd", 914, R8A774A1_CLK_S3D2),
DEF_MOD("can-if1", 915, R8A774A1_CLK_S3D4),
DEF_MOD("can-if0", 916, R8A774A1_CLK_S3D4),
+ DEF_MOD("rpc", 917, R8A774A1_CLK_RPC),
DEF_MOD("i2c6", 918, R8A774A1_CLK_S0D6),
DEF_MOD("i2c5", 919, R8A774A1_CLK_S0D6),
DEF_MOD("i2c-dvfs", 926, R8A774A1_CLK_CP),
diff --git a/drivers/clk/renesas/r8a774b1-cpg-mssr.c b/drivers/clk/renesas/r8a774b1-cpg-mssr.c
new file mode 100644
index 00000000000..7b6947b5b90
--- /dev/null
+++ b/drivers/clk/renesas/r8a774b1-cpg-mssr.c
@@ -0,0 +1,336 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * r8a774b1 Clock Pulse Generator / Module Standby and Software Reset
+ *
+ * Copyright (C) 2020 Renesas Electronics Corp.
+ *
+ * Based on r8a7796-cpg-mssr.c
+ *
+ * Copyright (C) 2016 Glider bvba
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+
+#include <dt-bindings/clock/r8a774b1-cpg-mssr.h>
+
+#include "renesas-cpg-mssr.h"
+#include "rcar-gen3-cpg.h"
+
+enum clk_ids {
+ /* Core Clock Outputs exported to DT */
+ LAST_DT_CORE_CLK = R8A774B1_CLK_CANFD,
+
+ /* External Input Clocks */
+ CLK_EXTAL,
+ CLK_EXTALR,
+
+ /* Internal Core Clocks */
+ CLK_MAIN,
+ CLK_PLL0,
+ CLK_PLL1,
+ CLK_PLL3,
+ CLK_PLL4,
+ CLK_PLL1_DIV2,
+ CLK_PLL1_DIV4,
+ CLK_S0,
+ CLK_S1,
+ CLK_S2,
+ CLK_S3,
+ CLK_SDSRC,
+ CLK_RINT,
+
+ /* Module Clocks */
+ MOD_CLK_BASE
+};
+
+static const struct cpg_core_clk r8a774b1_core_clks[] = {
+ /* External Clock Inputs */
+ DEF_INPUT("extal", CLK_EXTAL),
+ DEF_INPUT("extalr", CLK_EXTALR),
+
+ /* Internal Core Clocks */
+ DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL),
+ DEF_BASE(".pll0", CLK_PLL0, CLK_TYPE_GEN3_PLL0, CLK_MAIN),
+ DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN),
+ DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN),
+ DEF_BASE(".pll4", CLK_PLL4, CLK_TYPE_GEN3_PLL4, CLK_MAIN),
+
+ DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1),
+ DEF_FIXED(".pll1_div4", CLK_PLL1_DIV4, CLK_PLL1_DIV2, 2, 1),
+ DEF_FIXED(".s0", CLK_S0, CLK_PLL1_DIV2, 2, 1),
+ DEF_FIXED(".s1", CLK_S1, CLK_PLL1_DIV2, 3, 1),
+ DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1),
+ DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1),
+ DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1),
+
+ DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32),
+
+ /* Core Clock Outputs */
+ DEF_GEN3_Z("z", R8A774B1_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0, 2, 8),
+ DEF_FIXED("ztr", R8A774B1_CLK_ZTR, CLK_PLL1_DIV2, 6, 1),
+ DEF_FIXED("ztrd2", R8A774B1_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1),
+ DEF_FIXED("zt", R8A774B1_CLK_ZT, CLK_PLL1_DIV2, 4, 1),
+ DEF_FIXED("zx", R8A774B1_CLK_ZX, CLK_PLL1_DIV2, 2, 1),
+ DEF_FIXED("s0d1", R8A774B1_CLK_S0D1, CLK_S0, 1, 1),
+ DEF_FIXED("s0d2", R8A774B1_CLK_S0D2, CLK_S0, 2, 1),
+ DEF_FIXED("s0d3", R8A774B1_CLK_S0D3, CLK_S0, 3, 1),
+ DEF_FIXED("s0d4", R8A774B1_CLK_S0D4, CLK_S0, 4, 1),
+ DEF_FIXED("s0d6", R8A774B1_CLK_S0D6, CLK_S0, 6, 1),
+ DEF_FIXED("s0d8", R8A774B1_CLK_S0D8, CLK_S0, 8, 1),
+ DEF_FIXED("s0d12", R8A774B1_CLK_S0D12, CLK_S0, 12, 1),
+ DEF_FIXED("s1d2", R8A774B1_CLK_S1D2, CLK_S1, 2, 1),
+ DEF_FIXED("s1d4", R8A774B1_CLK_S1D4, CLK_S1, 4, 1),
+ DEF_FIXED("s2d1", R8A774B1_CLK_S2D1, CLK_S2, 1, 1),
+ DEF_FIXED("s2d2", R8A774B1_CLK_S2D2, CLK_S2, 2, 1),
+ DEF_FIXED("s2d4", R8A774B1_CLK_S2D4, CLK_S2, 4, 1),
+ DEF_FIXED("s3d1", R8A774B1_CLK_S3D1, CLK_S3, 1, 1),
+ DEF_FIXED("s3d2", R8A774B1_CLK_S3D2, CLK_S3, 2, 1),
+ DEF_FIXED("s3d4", R8A774B1_CLK_S3D4, CLK_S3, 4, 1),
+
+ DEF_GEN3_SD("sd0", R8A774B1_CLK_SD0, CLK_SDSRC, 0x074),
+ DEF_GEN3_SD("sd1", R8A774B1_CLK_SD1, CLK_SDSRC, 0x078),
+ DEF_GEN3_SD("sd2", R8A774B1_CLK_SD2, CLK_SDSRC, 0x268),
+ DEF_GEN3_SD("sd3", R8A774B1_CLK_SD3, CLK_SDSRC, 0x26c),
+
+ DEF_FIXED("cl", R8A774B1_CLK_CL, CLK_PLL1_DIV2, 48, 1),
+ DEF_FIXED("cp", R8A774B1_CLK_CP, CLK_EXTAL, 2, 1),
+ DEF_FIXED("cpex", R8A774B1_CLK_CPEX, CLK_EXTAL, 2, 1),
+
+ DEF_DIV6P1("canfd", R8A774B1_CLK_CANFD, CLK_PLL1_DIV4, 0x244),
+ DEF_DIV6P1("csi0", R8A774B1_CLK_CSI0, CLK_PLL1_DIV4, 0x00c),
+ DEF_DIV6P1("mso", R8A774B1_CLK_MSO, CLK_PLL1_DIV4, 0x014),
+ DEF_DIV6P1("hdmi", R8A774B1_CLK_HDMI, CLK_PLL1_DIV4, 0x250),
+
+ DEF_GEN3_OSC("osc", R8A774B1_CLK_OSC, CLK_EXTAL, 8),
+
+ DEF_BASE("r", R8A774B1_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT),
+};
+
+static const struct mssr_mod_clk r8a774b1_mod_clks[] = {
+ DEF_MOD("tmu4", 121, R8A774B1_CLK_S0D6),
+ DEF_MOD("tmu3", 122, R8A774B1_CLK_S3D2),
+ DEF_MOD("tmu2", 123, R8A774B1_CLK_S3D2),
+ DEF_MOD("tmu1", 124, R8A774B1_CLK_S3D2),
+ DEF_MOD("tmu0", 125, R8A774B1_CLK_CP),
+ DEF_MOD("fdp1-0", 119, R8A774B1_CLK_S0D1),
+ DEF_MOD("scif5", 202, R8A774B1_CLK_S3D4),
+ DEF_MOD("scif4", 203, R8A774B1_CLK_S3D4),
+ DEF_MOD("scif3", 204, R8A774B1_CLK_S3D4),
+ DEF_MOD("scif1", 206, R8A774B1_CLK_S3D4),
+ DEF_MOD("scif0", 207, R8A774B1_CLK_S3D4),
+ DEF_MOD("msiof3", 208, R8A774B1_CLK_MSO),
+ DEF_MOD("msiof2", 209, R8A774B1_CLK_MSO),
+ DEF_MOD("msiof1", 210, R8A774B1_CLK_MSO),
+ DEF_MOD("msiof0", 211, R8A774B1_CLK_MSO),
+ DEF_MOD("sys-dmac2", 217, R8A774B1_CLK_S3D1),
+ DEF_MOD("sys-dmac1", 218, R8A774B1_CLK_S3D1),
+ DEF_MOD("sys-dmac0", 219, R8A774B1_CLK_S0D3),
+ DEF_MOD("cmt3", 300, R8A774B1_CLK_R),
+ DEF_MOD("cmt2", 301, R8A774B1_CLK_R),
+ DEF_MOD("cmt1", 302, R8A774B1_CLK_R),
+ DEF_MOD("cmt0", 303, R8A774B1_CLK_R),
+ DEF_MOD("tpu0", 304, R8A774B1_CLK_S3D4),
+ DEF_MOD("scif2", 310, R8A774B1_CLK_S3D4),
+ DEF_MOD("sdif3", 311, R8A774B1_CLK_SD3),
+ DEF_MOD("sdif2", 312, R8A774B1_CLK_SD2),
+ DEF_MOD("sdif1", 313, R8A774B1_CLK_SD1),
+ DEF_MOD("sdif0", 314, R8A774B1_CLK_SD0),
+ DEF_MOD("pcie1", 318, R8A774B1_CLK_S3D1),
+ DEF_MOD("pcie0", 319, R8A774B1_CLK_S3D1),
+ DEF_MOD("usb3-if0", 328, R8A774B1_CLK_S3D1),
+ DEF_MOD("usb-dmac0", 330, R8A774B1_CLK_S3D1),
+ DEF_MOD("usb-dmac1", 331, R8A774B1_CLK_S3D1),
+ DEF_MOD("rwdt", 402, R8A774B1_CLK_R),
+ DEF_MOD("intc-ex", 407, R8A774B1_CLK_CP),
+ DEF_MOD("intc-ap", 408, R8A774B1_CLK_S0D3),
+ DEF_MOD("audmac1", 501, R8A774B1_CLK_S1D2),
+ DEF_MOD("audmac0", 502, R8A774B1_CLK_S1D2),
+ DEF_MOD("hscif4", 516, R8A774B1_CLK_S3D1),
+ DEF_MOD("hscif3", 517, R8A774B1_CLK_S3D1),
+ DEF_MOD("hscif2", 518, R8A774B1_CLK_S3D1),
+ DEF_MOD("hscif1", 519, R8A774B1_CLK_S3D1),
+ DEF_MOD("hscif0", 520, R8A774B1_CLK_S3D1),
+ DEF_MOD("thermal", 522, R8A774B1_CLK_CP),
+ DEF_MOD("pwm", 523, R8A774B1_CLK_S0D12),
+ DEF_MOD("fcpvd1", 602, R8A774B1_CLK_S0D2),
+ DEF_MOD("fcpvd0", 603, R8A774B1_CLK_S0D2),
+ DEF_MOD("fcpvb0", 607, R8A774B1_CLK_S0D1),
+ DEF_MOD("fcpvi0", 611, R8A774B1_CLK_S0D1),
+ DEF_MOD("fcpf0", 615, R8A774B1_CLK_S0D1),
+ DEF_MOD("fcpcs", 619, R8A774B1_CLK_S0D2),
+ DEF_MOD("vspd1", 622, R8A774B1_CLK_S0D2),
+ DEF_MOD("vspd0", 623, R8A774B1_CLK_S0D2),
+ DEF_MOD("vspb", 626, R8A774B1_CLK_S0D1),
+ DEF_MOD("vspi0", 631, R8A774B1_CLK_S0D1),
+ DEF_MOD("ehci1", 702, R8A774B1_CLK_S3D2),
+ DEF_MOD("ehci0", 703, R8A774B1_CLK_S3D2),
+ DEF_MOD("hsusb", 704, R8A774B1_CLK_S3D2),
+ DEF_MOD("csi20", 714, R8A774B1_CLK_CSI0),
+ DEF_MOD("csi40", 716, R8A774B1_CLK_CSI0),
+ DEF_MOD("du3", 721, R8A774B1_CLK_S2D1),
+ DEF_MOD("du1", 723, R8A774B1_CLK_S2D1),
+ DEF_MOD("du0", 724, R8A774B1_CLK_S2D1),
+ DEF_MOD("lvds", 727, R8A774B1_CLK_S2D1),
+ DEF_MOD("hdmi0", 729, R8A774B1_CLK_HDMI),
+ DEF_MOD("vin7", 804, R8A774B1_CLK_S0D2),
+ DEF_MOD("vin6", 805, R8A774B1_CLK_S0D2),
+ DEF_MOD("vin5", 806, R8A774B1_CLK_S0D2),
+ DEF_MOD("vin4", 807, R8A774B1_CLK_S0D2),
+ DEF_MOD("vin3", 808, R8A774B1_CLK_S0D2),
+ DEF_MOD("vin2", 809, R8A774B1_CLK_S0D2),
+ DEF_MOD("vin1", 810, R8A774B1_CLK_S0D2),
+ DEF_MOD("vin0", 811, R8A774B1_CLK_S0D2),
+ DEF_MOD("etheravb", 812, R8A774B1_CLK_S0D6),
+ DEF_MOD("sata0", 815, R8A774B1_CLK_S3D2),
+ DEF_MOD("gpio7", 905, R8A774B1_CLK_S3D4),
+ DEF_MOD("gpio6", 906, R8A774B1_CLK_S3D4),
+ DEF_MOD("gpio5", 907, R8A774B1_CLK_S3D4),
+ DEF_MOD("gpio4", 908, R8A774B1_CLK_S3D4),
+ DEF_MOD("gpio3", 909, R8A774B1_CLK_S3D4),
+ DEF_MOD("gpio2", 910, R8A774B1_CLK_S3D4),
+ DEF_MOD("gpio1", 911, R8A774B1_CLK_S3D4),
+ DEF_MOD("gpio0", 912, R8A774B1_CLK_S3D4),
+ DEF_MOD("can-fd", 914, R8A774B1_CLK_S3D2),
+ DEF_MOD("can-if1", 915, R8A774B1_CLK_S3D4),
+ DEF_MOD("can-if0", 916, R8A774B1_CLK_S3D4),
+ DEF_MOD("i2c6", 918, R8A774B1_CLK_S0D6),
+ DEF_MOD("i2c5", 919, R8A774B1_CLK_S0D6),
+ DEF_MOD("i2c-dvfs", 926, R8A774B1_CLK_CP),
+ DEF_MOD("i2c4", 927, R8A774B1_CLK_S0D6),
+ DEF_MOD("i2c3", 928, R8A774B1_CLK_S0D6),
+ DEF_MOD("i2c2", 929, R8A774B1_CLK_S3D2),
+ DEF_MOD("i2c1", 930, R8A774B1_CLK_S3D2),
+ DEF_MOD("i2c0", 931, R8A774B1_CLK_S3D2),
+ DEF_MOD("ssi-all", 1005, R8A774B1_CLK_S3D4),
+ DEF_MOD("ssi9", 1006, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi8", 1007, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi7", 1008, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi6", 1009, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi5", 1010, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi4", 1011, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi3", 1012, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi2", 1013, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi1", 1014, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi0", 1015, MOD_CLK_ID(1005)),
+ DEF_MOD("scu-all", 1017, R8A774B1_CLK_S3D4),
+ DEF_MOD("scu-dvc1", 1018, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-dvc0", 1019, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-ctu1-mix1", 1020, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-ctu0-mix0", 1021, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src9", 1022, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src8", 1023, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src7", 1024, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src6", 1025, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src5", 1026, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src4", 1027, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src3", 1028, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src2", 1029, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src1", 1030, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src0", 1031, MOD_CLK_ID(1017)),
+};
+
+/*
+ * CPG Clock Data
+ */
+
+/*
+ * MD EXTAL PLL0 PLL1 PLL3 PLL4 OSC
+ * 14 13 19 17 (MHz)
+ *-----------------------------------------------------------------
+ * 0 0 0 0 16.66 x 1 x180 x192 x192 x144 /16
+ * 0 0 0 1 16.66 x 1 x180 x192 x128 x144 /16
+ * 0 0 1 0 Prohibited setting
+ * 0 0 1 1 16.66 x 1 x180 x192 x192 x144 /16
+ * 0 1 0 0 20 x 1 x150 x160 x160 x120 /19
+ * 0 1 0 1 20 x 1 x150 x160 x106 x120 /19
+ * 0 1 1 0 Prohibited setting
+ * 0 1 1 1 20 x 1 x150 x160 x160 x120 /19
+ * 1 0 0 0 25 x 1 x120 x128 x128 x96 /24
+ * 1 0 0 1 25 x 1 x120 x128 x84 x96 /24
+ * 1 0 1 0 Prohibited setting
+ * 1 0 1 1 25 x 1 x120 x128 x128 x96 /24
+ * 1 1 0 0 33.33 / 2 x180 x192 x192 x144 /32
+ * 1 1 0 1 33.33 / 2 x180 x192 x128 x144 /32
+ * 1 1 1 0 Prohibited setting
+ * 1 1 1 1 33.33 / 2 x180 x192 x192 x144 /32
+ */
+#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 11) | \
+ (((md) & BIT(13)) >> 11) | \
+ (((md) & BIT(19)) >> 18) | \
+ (((md) & BIT(17)) >> 17))
+
+static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] = {
+ /* EXTAL div PLL1 mult/div PLL3 mult/div OSC prediv */
+ { 1, 192, 1, 192, 1, 16, },
+ { 1, 192, 1, 128, 1, 16, },
+ { 0, /* Prohibited setting */ },
+ { 1, 192, 1, 192, 1, 16, },
+ { 1, 160, 1, 160, 1, 19, },
+ { 1, 160, 1, 106, 1, 19, },
+ { 0, /* Prohibited setting */ },
+ { 1, 160, 1, 160, 1, 19, },
+ { 1, 128, 1, 128, 1, 24, },
+ { 1, 128, 1, 84, 1, 24, },
+ { 0, /* Prohibited setting */ },
+ { 1, 128, 1, 128, 1, 24, },
+ { 2, 192, 1, 192, 1, 32, },
+ { 2, 192, 1, 128, 1, 32, },
+ { 0, /* Prohibited setting */ },
+ { 2, 192, 1, 192, 1, 32, },
+};
+
+/* RMSTPCR[0-11] is not present on RZ/G2N */
+static const struct mstp_stop_table r8a774b1_mstp_table[] = {
+ { 0x00200000, 0x0, 0x0, 0 },
+ { 0xFFFFFFFF, 0x0, 0x0, 0 },
+ { 0x340E2FDC, 0x2040, 0x0, 0 },
+ { 0xFFFFFFDF, 0x400, 0x0, 0 },
+ { 0x80000184, 0x180, 0x0, 0 },
+ { 0xC3FFFFFF, 0x0, 0x0, 0 },
+ { 0xFFFFFFFF, 0x0, 0x0, 0 },
+ { 0xFFFFFFFF, 0x0, 0x0, 0 },
+ { 0x01F1FFF7, 0x0, 0x0, 0 },
+ { 0xFFFFFFFE, 0x0, 0x0, 0 },
+ { 0xFFFEFFE0, 0x0, 0x0, 0 },
+ { 0x000000B7, 0x0, 0x0, 0 },
+};
+
+static const void *r8a774b1_get_pll_config(const u32 cpg_mode)
+{
+ return &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
+}
+
+static const struct cpg_mssr_info r8a774b1_cpg_mssr_info = {
+ .core_clk = r8a774b1_core_clks,
+ .core_clk_size = ARRAY_SIZE(r8a774b1_core_clks),
+ .mod_clk = r8a774b1_mod_clks,
+ .mod_clk_size = ARRAY_SIZE(r8a774b1_mod_clks),
+ .mstp_table = r8a774b1_mstp_table,
+ .mstp_table_size = ARRAY_SIZE(r8a774b1_mstp_table),
+ .reset_node = "renesas,r8a774b1-rst",
+ .extalr_node = "extalr",
+ .mod_clk_base = MOD_CLK_BASE,
+ .clk_extal_id = CLK_EXTAL,
+ .clk_extalr_id = CLK_EXTALR,
+ .get_pll_config = r8a774b1_get_pll_config,
+};
+
+static const struct udevice_id r8a774b1_clk_ids[] = {
+ {
+ .compatible = "renesas,r8a774b1-cpg-mssr",
+ .data = (ulong)&r8a774b1_cpg_mssr_info,
+ },
+ { }
+};
+
+U_BOOT_DRIVER(clk_r8a774b1) = {
+ .name = "clk_r8a774b1",
+ .id = UCLASS_CLK,
+ .of_match = r8a774b1_clk_ids,
+ .priv_auto_alloc_size = sizeof(struct gen3_clk_priv),
+ .ops = &gen3_clk_ops,
+ .probe = gen3_clk_probe,
+ .remove = gen3_clk_remove,
+};
diff --git a/drivers/clk/renesas/r8a774c0-cpg-mssr.c b/drivers/clk/renesas/r8a774c0-cpg-mssr.c
new file mode 100644
index 00000000000..c9f0f7221d7
--- /dev/null
+++ b/drivers/clk/renesas/r8a774c0-cpg-mssr.c
@@ -0,0 +1,308 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * r8a774c0 Clock Pulse Generator / Module Standby and Software Reset
+ *
+ * Copyright (C) 2020 Renesas Electronics Corp.
+ *
+ * Based on r8a77990-cpg-mssr.c
+ *
+ * Copyright (C) 2015 Glider bvba
+ * Copyright (C) 2020 Renesas Electronics Corp.
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <linux/bitops.h>
+
+#include <dt-bindings/clock/r8a774c0-cpg-mssr.h>
+
+#include "renesas-cpg-mssr.h"
+#include "rcar-gen3-cpg.h"
+
+enum clk_ids {
+ /* Core Clock Outputs exported to DT */
+ LAST_DT_CORE_CLK = R8A774C0_CLK_CANFD,
+
+ /* External Input Clocks */
+ CLK_EXTAL,
+
+ /* Internal Core Clocks */
+ CLK_MAIN,
+ CLK_PLL0,
+ CLK_PLL1,
+ CLK_PLL3,
+ CLK_PLL0D4,
+ CLK_PLL0D6,
+ CLK_PLL0D8,
+ CLK_PLL0D20,
+ CLK_PLL0D24,
+ CLK_PLL1D2,
+ CLK_PE,
+ CLK_S0,
+ CLK_S1,
+ CLK_S2,
+ CLK_S3,
+ CLK_SDSRC,
+ CLK_RINT,
+ CLK_OCO,
+
+ /* Module Clocks */
+ MOD_CLK_BASE
+};
+
+static const struct cpg_core_clk r8a774c0_core_clks[] = {
+ /* External Clock Inputs */
+ DEF_INPUT("extal", CLK_EXTAL),
+
+ /* Internal Core Clocks */
+ DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL),
+ DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN),
+ DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN),
+
+ DEF_FIXED(".pll0", CLK_PLL0, CLK_MAIN, 1, 100),
+ DEF_FIXED(".pll0d4", CLK_PLL0D4, CLK_PLL0, 4, 1),
+ DEF_FIXED(".pll0d6", CLK_PLL0D6, CLK_PLL0, 6, 1),
+ DEF_FIXED(".pll0d8", CLK_PLL0D8, CLK_PLL0, 8, 1),
+ DEF_FIXED(".pll0d20", CLK_PLL0D20, CLK_PLL0, 20, 1),
+ DEF_FIXED(".pll0d24", CLK_PLL0D24, CLK_PLL0, 24, 1),
+ DEF_FIXED(".pll1d2", CLK_PLL1D2, CLK_PLL1, 2, 1),
+ DEF_FIXED(".pe", CLK_PE, CLK_PLL0D20, 1, 1),
+ DEF_FIXED(".s0", CLK_S0, CLK_PLL1, 2, 1),
+ DEF_FIXED(".s1", CLK_S1, CLK_PLL1, 3, 1),
+ DEF_FIXED(".s2", CLK_S2, CLK_PLL1, 4, 1),
+ DEF_FIXED(".s3", CLK_S3, CLK_PLL1, 6, 1),
+ DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1, 2, 1),
+
+ DEF_DIV6_RO(".r", CLK_RINT, CLK_EXTAL, CPG_RCKCR, 32),
+
+ DEF_RATE(".oco", CLK_OCO, 8 * 1000 * 1000),
+
+ /* Core Clock Outputs */
+ DEF_FIXED("za2", R8A774C0_CLK_ZA2, CLK_PLL0D24, 1, 1),
+ DEF_FIXED("za8", R8A774C0_CLK_ZA8, CLK_PLL0D8, 1, 1),
+ DEF_GEN3_Z("z2", R8A774C0_CLK_Z2, CLK_TYPE_GEN3_Z, CLK_PLL0, 4, 8),
+ DEF_FIXED("ztr", R8A774C0_CLK_ZTR, CLK_PLL1, 6, 1),
+ DEF_FIXED("zt", R8A774C0_CLK_ZT, CLK_PLL1, 4, 1),
+ DEF_FIXED("zx", R8A774C0_CLK_ZX, CLK_PLL1, 3, 1),
+ DEF_FIXED("s0d1", R8A774C0_CLK_S0D1, CLK_S0, 1, 1),
+ DEF_FIXED("s0d3", R8A774C0_CLK_S0D3, CLK_S0, 3, 1),
+ DEF_FIXED("s0d6", R8A774C0_CLK_S0D6, CLK_S0, 6, 1),
+ DEF_FIXED("s0d12", R8A774C0_CLK_S0D12, CLK_S0, 12, 1),
+ DEF_FIXED("s0d24", R8A774C0_CLK_S0D24, CLK_S0, 24, 1),
+ DEF_FIXED("s1d1", R8A774C0_CLK_S1D1, CLK_S1, 1, 1),
+ DEF_FIXED("s1d2", R8A774C0_CLK_S1D2, CLK_S1, 2, 1),
+ DEF_FIXED("s1d4", R8A774C0_CLK_S1D4, CLK_S1, 4, 1),
+ DEF_FIXED("s2d1", R8A774C0_CLK_S2D1, CLK_S2, 1, 1),
+ DEF_FIXED("s2d2", R8A774C0_CLK_S2D2, CLK_S2, 2, 1),
+ DEF_FIXED("s2d4", R8A774C0_CLK_S2D4, CLK_S2, 4, 1),
+ DEF_FIXED("s3d1", R8A774C0_CLK_S3D1, CLK_S3, 1, 1),
+ DEF_FIXED("s3d2", R8A774C0_CLK_S3D2, CLK_S3, 2, 1),
+ DEF_FIXED("s3d4", R8A774C0_CLK_S3D4, CLK_S3, 4, 1),
+
+ DEF_GEN3_SD("sd0", R8A774C0_CLK_SD0, CLK_SDSRC, 0x0074),
+ DEF_GEN3_SD("sd1", R8A774C0_CLK_SD1, CLK_SDSRC, 0x0078),
+ DEF_GEN3_SD("sd3", R8A774C0_CLK_SD3, CLK_SDSRC, 0x026c),
+
+ DEF_FIXED("cl", R8A774C0_CLK_CL, CLK_PLL1, 48, 1),
+ DEF_FIXED("cp", R8A774C0_CLK_CP, CLK_EXTAL, 2, 1),
+ DEF_FIXED("cpex", R8A774C0_CLK_CPEX, CLK_EXTAL, 4, 1),
+
+ DEF_DIV6_RO("osc", R8A774C0_CLK_OSC, CLK_EXTAL, CPG_RCKCR, 8),
+
+ DEF_GEN3_PE("s0d6c", R8A774C0_CLK_S0D6C, CLK_S0, 6, CLK_PE, 2),
+ DEF_GEN3_PE("s3d1c", R8A774C0_CLK_S3D1C, CLK_S3, 1, CLK_PE, 1),
+ DEF_GEN3_PE("s3d2c", R8A774C0_CLK_S3D2C, CLK_S3, 2, CLK_PE, 2),
+ DEF_GEN3_PE("s3d4c", R8A774C0_CLK_S3D4C, CLK_S3, 4, CLK_PE, 4),
+
+ DEF_DIV6P1("canfd", R8A774C0_CLK_CANFD, CLK_PLL0D6, 0x244),
+ DEF_DIV6P1("csi0", R8A774C0_CLK_CSI0, CLK_PLL1D2, 0x00c),
+ DEF_DIV6P1("mso", R8A774C0_CLK_MSO, CLK_PLL1D2, 0x014),
+
+ DEF_GEN3_RCKSEL("r", R8A774C0_CLK_R, CLK_RINT, 1, CLK_OCO, 61 * 4),
+};
+
+static const struct mssr_mod_clk r8a774c0_mod_clks[] = {
+ DEF_MOD("tmu4", 121, R8A774C0_CLK_S0D6C),
+ DEF_MOD("tmu3", 122, R8A774C0_CLK_S3D2C),
+ DEF_MOD("tmu2", 123, R8A774C0_CLK_S3D2C),
+ DEF_MOD("tmu1", 124, R8A774C0_CLK_S3D2C),
+ DEF_MOD("tmu0", 125, R8A774C0_CLK_CP),
+ DEF_MOD("scif5", 202, R8A774C0_CLK_S3D4C),
+ DEF_MOD("scif4", 203, R8A774C0_CLK_S3D4C),
+ DEF_MOD("scif3", 204, R8A774C0_CLK_S3D4C),
+ DEF_MOD("scif1", 206, R8A774C0_CLK_S3D4C),
+ DEF_MOD("scif0", 207, R8A774C0_CLK_S3D4C),
+ DEF_MOD("msiof3", 208, R8A774C0_CLK_MSO),
+ DEF_MOD("msiof2", 209, R8A774C0_CLK_MSO),
+ DEF_MOD("msiof1", 210, R8A774C0_CLK_MSO),
+ DEF_MOD("msiof0", 211, R8A774C0_CLK_MSO),
+ DEF_MOD("sys-dmac2", 217, R8A774C0_CLK_S3D1),
+ DEF_MOD("sys-dmac1", 218, R8A774C0_CLK_S3D1),
+ DEF_MOD("sys-dmac0", 219, R8A774C0_CLK_S3D1),
+
+ DEF_MOD("cmt3", 300, R8A774C0_CLK_R),
+ DEF_MOD("cmt2", 301, R8A774C0_CLK_R),
+ DEF_MOD("cmt1", 302, R8A774C0_CLK_R),
+ DEF_MOD("cmt0", 303, R8A774C0_CLK_R),
+ DEF_MOD("scif2", 310, R8A774C0_CLK_S3D4C),
+ DEF_MOD("sdif3", 311, R8A774C0_CLK_SD3),
+ DEF_MOD("sdif1", 313, R8A774C0_CLK_SD1),
+ DEF_MOD("sdif0", 314, R8A774C0_CLK_SD0),
+ DEF_MOD("pcie0", 319, R8A774C0_CLK_S3D1),
+ DEF_MOD("usb3-if0", 328, R8A774C0_CLK_S3D1),
+ DEF_MOD("usb-dmac0", 330, R8A774C0_CLK_S3D1),
+ DEF_MOD("usb-dmac1", 331, R8A774C0_CLK_S3D1),
+
+ DEF_MOD("rwdt", 402, R8A774C0_CLK_R),
+ DEF_MOD("intc-ex", 407, R8A774C0_CLK_CP),
+ DEF_MOD("intc-ap", 408, R8A774C0_CLK_S0D3),
+
+ DEF_MOD("audmac0", 502, R8A774C0_CLK_S1D2),
+ DEF_MOD("hscif4", 516, R8A774C0_CLK_S3D1C),
+ DEF_MOD("hscif3", 517, R8A774C0_CLK_S3D1C),
+ DEF_MOD("hscif2", 518, R8A774C0_CLK_S3D1C),
+ DEF_MOD("hscif1", 519, R8A774C0_CLK_S3D1C),
+ DEF_MOD("hscif0", 520, R8A774C0_CLK_S3D1C),
+ DEF_MOD("thermal", 522, R8A774C0_CLK_CP),
+ DEF_MOD("pwm", 523, R8A774C0_CLK_S3D4C),
+
+ DEF_MOD("fcpvd1", 602, R8A774C0_CLK_S1D2),
+ DEF_MOD("fcpvd0", 603, R8A774C0_CLK_S1D2),
+ DEF_MOD("fcpvb0", 607, R8A774C0_CLK_S0D1),
+ DEF_MOD("fcpvi0", 611, R8A774C0_CLK_S0D1),
+ DEF_MOD("fcpf0", 615, R8A774C0_CLK_S0D1),
+ DEF_MOD("fcpcs", 619, R8A774C0_CLK_S0D1),
+ DEF_MOD("vspd1", 622, R8A774C0_CLK_S1D2),
+ DEF_MOD("vspd0", 623, R8A774C0_CLK_S1D2),
+ DEF_MOD("vspb", 626, R8A774C0_CLK_S0D1),
+ DEF_MOD("vspi0", 631, R8A774C0_CLK_S0D1),
+
+ DEF_MOD("ehci0", 703, R8A774C0_CLK_S3D2),
+ DEF_MOD("hsusb", 704, R8A774C0_CLK_S3D2),
+ DEF_MOD("csi40", 716, R8A774C0_CLK_CSI0),
+ DEF_MOD("du1", 723, R8A774C0_CLK_S1D1),
+ DEF_MOD("du0", 724, R8A774C0_CLK_S1D1),
+ DEF_MOD("lvds", 727, R8A774C0_CLK_S2D1),
+
+ DEF_MOD("vin5", 806, R8A774C0_CLK_S1D2),
+ DEF_MOD("vin4", 807, R8A774C0_CLK_S1D2),
+ DEF_MOD("etheravb", 812, R8A774C0_CLK_S3D2),
+
+ DEF_MOD("gpio6", 906, R8A774C0_CLK_S3D4),
+ DEF_MOD("gpio5", 907, R8A774C0_CLK_S3D4),
+ DEF_MOD("gpio4", 908, R8A774C0_CLK_S3D4),
+ DEF_MOD("gpio3", 909, R8A774C0_CLK_S3D4),
+ DEF_MOD("gpio2", 910, R8A774C0_CLK_S3D4),
+ DEF_MOD("gpio1", 911, R8A774C0_CLK_S3D4),
+ DEF_MOD("gpio0", 912, R8A774C0_CLK_S3D4),
+ DEF_MOD("can-fd", 914, R8A774C0_CLK_S3D2),
+ DEF_MOD("can-if1", 915, R8A774C0_CLK_S3D4),
+ DEF_MOD("can-if0", 916, R8A774C0_CLK_S3D4),
+ DEF_MOD("i2c6", 918, R8A774C0_CLK_S3D2),
+ DEF_MOD("i2c5", 919, R8A774C0_CLK_S3D2),
+ DEF_MOD("i2c-dvfs", 926, R8A774C0_CLK_CP),
+ DEF_MOD("i2c4", 927, R8A774C0_CLK_S3D2),
+ DEF_MOD("i2c3", 928, R8A774C0_CLK_S3D2),
+ DEF_MOD("i2c2", 929, R8A774C0_CLK_S3D2),
+ DEF_MOD("i2c1", 930, R8A774C0_CLK_S3D2),
+ DEF_MOD("i2c0", 931, R8A774C0_CLK_S3D2),
+
+ DEF_MOD("i2c7", 1003, R8A774C0_CLK_S3D2),
+ DEF_MOD("ssi-all", 1005, R8A774C0_CLK_S3D4),
+ DEF_MOD("ssi9", 1006, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi8", 1007, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi7", 1008, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi6", 1009, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi5", 1010, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi4", 1011, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi3", 1012, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi2", 1013, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi1", 1014, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi0", 1015, MOD_CLK_ID(1005)),
+ DEF_MOD("scu-all", 1017, R8A774C0_CLK_S3D4),
+ DEF_MOD("scu-dvc1", 1018, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-dvc0", 1019, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-ctu1-mix1", 1020, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-ctu0-mix0", 1021, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src9", 1022, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src8", 1023, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src7", 1024, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src6", 1025, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src5", 1026, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src4", 1027, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src3", 1028, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src2", 1029, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src1", 1030, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src0", 1031, MOD_CLK_ID(1017)),
+};
+
+/*
+ * CPG Clock Data
+ */
+
+/*
+ * MD19 EXTAL (MHz) PLL0 PLL1 PLL3
+ *--------------------------------------------------------------------
+ * 0 48 x 1 x100/1 x100/3 x100/3
+ * 1 48 x 1 x100/1 x100/3 x58/3
+ */
+#define CPG_PLL_CONFIG_INDEX(md) (((md) & BIT(19)) >> 19)
+
+static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[2] = {
+ /* EXTAL div PLL1 mult/div PLL3 mult/div */
+ { 1, 100, 3, 100, 3, },
+ { 1, 100, 3, 58, 3, },
+};
+
+static const struct mstp_stop_table r8a774c0_mstp_table[] = {
+ { 0x00200000, 0x0, 0x00200000, 0 },
+ { 0xFFFFFFFF, 0x0, 0xFFFFFFFF, 0 },
+ { 0x340E2FDC, 0x2040, 0x340E2FDC, 0 },
+ { 0xFFFFFFDF, 0x400, 0xFFFFFFDF, 0 },
+ { 0x80000184, 0x180, 0x80000184, 0 },
+ { 0xC3FFFFFF, 0x0, 0xC3FFFFFF, 0 },
+ { 0xFFFFFFFF, 0x0, 0xFFFFFFFF, 0 },
+ { 0xFFFFFFFF, 0x0, 0xFFFFFFFF, 0 },
+ { 0x01F1FFF7, 0x0, 0x01F1FFF7, 0 },
+ { 0xFFFFFFFE, 0x0, 0xFFFFFFFE, 0 },
+ { 0xFFFEFFE0, 0x0, 0xFFFEFFE0, 0 },
+ { 0x000000B7, 0x0, 0x000000B7, 0 },
+};
+
+static const void *r8a774c0_get_pll_config(const u32 cpg_mode)
+{
+ return &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
+}
+
+const struct cpg_mssr_info r8a774c0_cpg_mssr_info = {
+ .core_clk = r8a774c0_core_clks,
+ .core_clk_size = ARRAY_SIZE(r8a774c0_core_clks),
+ .mod_clk = r8a774c0_mod_clks,
+ .mod_clk_size = ARRAY_SIZE(r8a774c0_mod_clks),
+ .mstp_table = r8a774c0_mstp_table,
+ .mstp_table_size = ARRAY_SIZE(r8a774c0_mstp_table),
+ .reset_node = "renesas,r8a774c0-rst",
+ .mod_clk_base = MOD_CLK_BASE,
+ .clk_extal_id = CLK_EXTAL,
+ .clk_extalr_id = ~0,
+ .get_pll_config = r8a774c0_get_pll_config,
+};
+
+static const struct udevice_id r8a774c0_clk_ids[] = {
+ {
+ .compatible = "renesas,r8a774c0-cpg-mssr",
+ .data = (ulong)&r8a774c0_cpg_mssr_info
+ },
+ { }
+};
+
+U_BOOT_DRIVER(clk_r8a774c0) = {
+ .name = "clk_r8a774c0",
+ .id = UCLASS_CLK,
+ .of_match = r8a774c0_clk_ids,
+ .priv_auto_alloc_size = sizeof(struct gen3_clk_priv),
+ .ops = &gen3_clk_ops,
+ .probe = gen3_clk_probe,
+ .remove = gen3_clk_remove,
+};
diff --git a/drivers/clk/renesas/r8a774e1-cpg-mssr.c b/drivers/clk/renesas/r8a774e1-cpg-mssr.c
new file mode 100644
index 00000000000..6cce007aa13
--- /dev/null
+++ b/drivers/clk/renesas/r8a774e1-cpg-mssr.c
@@ -0,0 +1,358 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * r8a774e1 Clock Pulse Generator / Module Standby and Software Reset
+ *
+ * Copyright (C) 2020 Renesas Electronics Corp.
+ *
+ * Based on r8a7795-cpg-mssr.c
+ *
+ * Copyright (C) 2015 Glider bvba
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <linux/bitops.h>
+
+#include <dt-bindings/clock/r8a774e1-cpg-mssr.h>
+
+#include "renesas-cpg-mssr.h"
+#include "rcar-gen3-cpg.h"
+
+enum clk_ids {
+ /* Core Clock Outputs exported to DT */
+ LAST_DT_CORE_CLK = R8A774E1_CLK_CANFD,
+
+ /* External Input Clocks */
+ CLK_EXTAL,
+ CLK_EXTALR,
+
+ /* Internal Core Clocks */
+ CLK_MAIN,
+ CLK_PLL0,
+ CLK_PLL1,
+ CLK_PLL2,
+ CLK_PLL3,
+ CLK_PLL4,
+ CLK_PLL1_DIV2,
+ CLK_PLL1_DIV4,
+ CLK_S0,
+ CLK_S1,
+ CLK_S2,
+ CLK_S3,
+ CLK_SDSRC,
+ CLK_RPCSRC,
+ CLK_RINT,
+
+ /* Module Clocks */
+ MOD_CLK_BASE
+};
+
+static const struct cpg_core_clk r8a774e1_core_clks[] = {
+ /* External Clock Inputs */
+ DEF_INPUT("extal", CLK_EXTAL),
+ DEF_INPUT("extalr", CLK_EXTALR),
+
+ /* Internal Core Clocks */
+ DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL),
+ DEF_BASE(".pll0", CLK_PLL0, CLK_TYPE_GEN3_PLL0, CLK_MAIN),
+ DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN),
+ DEF_BASE(".pll2", CLK_PLL2, CLK_TYPE_GEN3_PLL2, CLK_MAIN),
+ DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN),
+ DEF_BASE(".pll4", CLK_PLL4, CLK_TYPE_GEN3_PLL4, CLK_MAIN),
+
+ DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1),
+ DEF_FIXED(".pll1_div4", CLK_PLL1_DIV4, CLK_PLL1_DIV2, 2, 1),
+ DEF_FIXED(".s0", CLK_S0, CLK_PLL1_DIV2, 2, 1),
+ DEF_FIXED(".s1", CLK_S1, CLK_PLL1_DIV2, 3, 1),
+ DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1),
+ DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1),
+ DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1),
+ DEF_BASE(".rpcsrc", CLK_RPCSRC, CLK_TYPE_GEN3_RPCSRC, CLK_PLL1),
+
+ DEF_BASE("rpc", R8A774E1_CLK_RPC, CLK_TYPE_GEN3_RPC,
+ CLK_RPCSRC),
+ DEF_BASE("rpcd2", R8A774E1_CLK_RPCD2, CLK_TYPE_GEN3_RPCD2,
+ R8A774E1_CLK_RPC),
+
+ DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32),
+
+ /* Core Clock Outputs */
+ DEF_GEN3_Z("z", R8A774E1_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0, 2, 8),
+ DEF_GEN3_Z("z2", R8A774E1_CLK_Z2, CLK_TYPE_GEN3_Z, CLK_PLL2, 2, 0),
+ DEF_FIXED("ztr", R8A774E1_CLK_ZTR, CLK_PLL1_DIV2, 6, 1),
+ DEF_FIXED("ztrd2", R8A774E1_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1),
+ DEF_FIXED("zt", R8A774E1_CLK_ZT, CLK_PLL1_DIV2, 4, 1),
+ DEF_FIXED("zx", R8A774E1_CLK_ZX, CLK_PLL1_DIV2, 2, 1),
+ DEF_FIXED("s0d1", R8A774E1_CLK_S0D1, CLK_S0, 1, 1),
+ DEF_FIXED("s0d2", R8A774E1_CLK_S0D2, CLK_S0, 2, 1),
+ DEF_FIXED("s0d3", R8A774E1_CLK_S0D3, CLK_S0, 3, 1),
+ DEF_FIXED("s0d4", R8A774E1_CLK_S0D4, CLK_S0, 4, 1),
+ DEF_FIXED("s0d6", R8A774E1_CLK_S0D6, CLK_S0, 6, 1),
+ DEF_FIXED("s0d8", R8A774E1_CLK_S0D8, CLK_S0, 8, 1),
+ DEF_FIXED("s0d12", R8A774E1_CLK_S0D12, CLK_S0, 12, 1),
+ DEF_FIXED("s1d2", R8A774E1_CLK_S1D2, CLK_S1, 2, 1),
+ DEF_FIXED("s1d4", R8A774E1_CLK_S1D4, CLK_S1, 4, 1),
+ DEF_FIXED("s2d1", R8A774E1_CLK_S2D1, CLK_S2, 1, 1),
+ DEF_FIXED("s2d2", R8A774E1_CLK_S2D2, CLK_S2, 2, 1),
+ DEF_FIXED("s2d4", R8A774E1_CLK_S2D4, CLK_S2, 4, 1),
+ DEF_FIXED("s3d1", R8A774E1_CLK_S3D1, CLK_S3, 1, 1),
+ DEF_FIXED("s3d2", R8A774E1_CLK_S3D2, CLK_S3, 2, 1),
+ DEF_FIXED("s3d4", R8A774E1_CLK_S3D4, CLK_S3, 4, 1),
+
+ DEF_GEN3_SD("sd0", R8A774E1_CLK_SD0, CLK_SDSRC, 0x074),
+ DEF_GEN3_SD("sd1", R8A774E1_CLK_SD1, CLK_SDSRC, 0x078),
+ DEF_GEN3_SD("sd2", R8A774E1_CLK_SD2, CLK_SDSRC, 0x268),
+ DEF_GEN3_SD("sd3", R8A774E1_CLK_SD3, CLK_SDSRC, 0x26c),
+
+ DEF_FIXED("cl", R8A774E1_CLK_CL, CLK_PLL1_DIV2, 48, 1),
+ DEF_FIXED("cr", R8A774E1_CLK_CR, CLK_PLL1_DIV4, 2, 1),
+ DEF_FIXED("cp", R8A774E1_CLK_CP, CLK_EXTAL, 2, 1),
+ DEF_FIXED("cpex", R8A774E1_CLK_CPEX, CLK_EXTAL, 2, 1),
+
+ DEF_DIV6P1("canfd", R8A774E1_CLK_CANFD, CLK_PLL1_DIV4, 0x244),
+ DEF_DIV6P1("csi0", R8A774E1_CLK_CSI0, CLK_PLL1_DIV4, 0x00c),
+ DEF_DIV6P1("mso", R8A774E1_CLK_MSO, CLK_PLL1_DIV4, 0x014),
+ DEF_DIV6P1("hdmi", R8A774E1_CLK_HDMI, CLK_PLL1_DIV4, 0x250),
+
+ DEF_GEN3_OSC("osc", R8A774E1_CLK_OSC, CLK_EXTAL, 8),
+
+ DEF_BASE("r", R8A774E1_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT),
+};
+
+static const struct mssr_mod_clk r8a774e1_mod_clks[] = {
+ DEF_MOD("fdp1-1", 118, R8A774E1_CLK_S0D1),
+ DEF_MOD("fdp1-0", 119, R8A774E1_CLK_S0D1),
+ DEF_MOD("tmu4", 121, R8A774E1_CLK_S0D6),
+ DEF_MOD("tmu3", 122, R8A774E1_CLK_S3D2),
+ DEF_MOD("tmu2", 123, R8A774E1_CLK_S3D2),
+ DEF_MOD("tmu1", 124, R8A774E1_CLK_S3D2),
+ DEF_MOD("tmu0", 125, R8A774E1_CLK_CP),
+ DEF_MOD("vcplf", 130, R8A774E1_CLK_S2D1),
+ DEF_MOD("vdpb", 131, R8A774E1_CLK_S2D1),
+ DEF_MOD("scif5", 202, R8A774E1_CLK_S3D4),
+ DEF_MOD("scif4", 203, R8A774E1_CLK_S3D4),
+ DEF_MOD("scif3", 204, R8A774E1_CLK_S3D4),
+ DEF_MOD("scif1", 206, R8A774E1_CLK_S3D4),
+ DEF_MOD("scif0", 207, R8A774E1_CLK_S3D4),
+ DEF_MOD("msiof3", 208, R8A774E1_CLK_MSO),
+ DEF_MOD("msiof2", 209, R8A774E1_CLK_MSO),
+ DEF_MOD("msiof1", 210, R8A774E1_CLK_MSO),
+ DEF_MOD("msiof0", 211, R8A774E1_CLK_MSO),
+ DEF_MOD("sys-dmac2", 217, R8A774E1_CLK_S3D1),
+ DEF_MOD("sys-dmac1", 218, R8A774E1_CLK_S3D1),
+ DEF_MOD("sys-dmac0", 219, R8A774E1_CLK_S0D3),
+ DEF_MOD("cmt3", 300, R8A774E1_CLK_R),
+ DEF_MOD("cmt2", 301, R8A774E1_CLK_R),
+ DEF_MOD("cmt1", 302, R8A774E1_CLK_R),
+ DEF_MOD("cmt0", 303, R8A774E1_CLK_R),
+ DEF_MOD("tpu0", 304, R8A774E1_CLK_S3D4),
+ DEF_MOD("scif2", 310, R8A774E1_CLK_S3D4),
+ DEF_MOD("sdif3", 311, R8A774E1_CLK_SD3),
+ DEF_MOD("sdif2", 312, R8A774E1_CLK_SD2),
+ DEF_MOD("sdif1", 313, R8A774E1_CLK_SD1),
+ DEF_MOD("sdif0", 314, R8A774E1_CLK_SD0),
+ DEF_MOD("pcie1", 318, R8A774E1_CLK_S3D1),
+ DEF_MOD("pcie0", 319, R8A774E1_CLK_S3D1),
+ DEF_MOD("usb3-if0", 328, R8A774E1_CLK_S3D1),
+ DEF_MOD("usb-dmac0", 330, R8A774E1_CLK_S3D1),
+ DEF_MOD("usb-dmac1", 331, R8A774E1_CLK_S3D1),
+ DEF_MOD("rwdt", 402, R8A774E1_CLK_R),
+ DEF_MOD("intc-ex", 407, R8A774E1_CLK_CP),
+ DEF_MOD("intc-ap", 408, R8A774E1_CLK_S0D3),
+ DEF_MOD("audmac1", 501, R8A774E1_CLK_S1D2),
+ DEF_MOD("audmac0", 502, R8A774E1_CLK_S1D2),
+ DEF_MOD("hscif4", 516, R8A774E1_CLK_S3D1),
+ DEF_MOD("hscif3", 517, R8A774E1_CLK_S3D1),
+ DEF_MOD("hscif2", 518, R8A774E1_CLK_S3D1),
+ DEF_MOD("hscif1", 519, R8A774E1_CLK_S3D1),
+ DEF_MOD("hscif0", 520, R8A774E1_CLK_S3D1),
+ DEF_MOD("thermal", 522, R8A774E1_CLK_CP),
+ DEF_MOD("pwm", 523, R8A774E1_CLK_S0D12),
+ DEF_MOD("fcpvd1", 602, R8A774E1_CLK_S0D2),
+ DEF_MOD("fcpvd0", 603, R8A774E1_CLK_S0D2),
+ DEF_MOD("fcpvb1", 606, R8A774E1_CLK_S0D1),
+ DEF_MOD("fcpvb0", 607, R8A774E1_CLK_S0D1),
+ DEF_MOD("fcpvi1", 610, R8A774E1_CLK_S0D1),
+ DEF_MOD("fcpvi0", 611, R8A774E1_CLK_S0D1),
+ DEF_MOD("fcpf1", 614, R8A774E1_CLK_S0D1),
+ DEF_MOD("fcpf0", 615, R8A774E1_CLK_S0D1),
+ DEF_MOD("fcpcs", 619, R8A774E1_CLK_S0D1),
+ DEF_MOD("vspd1", 622, R8A774E1_CLK_S0D2),
+ DEF_MOD("vspd0", 623, R8A774E1_CLK_S0D2),
+ DEF_MOD("vspbc", 624, R8A774E1_CLK_S0D1),
+ DEF_MOD("vspbd", 626, R8A774E1_CLK_S0D1),
+ DEF_MOD("vspi1", 630, R8A774E1_CLK_S0D1),
+ DEF_MOD("vspi0", 631, R8A774E1_CLK_S0D1),
+ DEF_MOD("ehci1", 702, R8A774E1_CLK_S3D2),
+ DEF_MOD("ehci0", 703, R8A774E1_CLK_S3D2),
+ DEF_MOD("hsusb", 704, R8A774E1_CLK_S3D2),
+ DEF_MOD("csi20", 714, R8A774E1_CLK_CSI0),
+ DEF_MOD("csi40", 716, R8A774E1_CLK_CSI0),
+ DEF_MOD("du3", 721, R8A774E1_CLK_S2D1),
+ DEF_MOD("du1", 723, R8A774E1_CLK_S2D1),
+ DEF_MOD("du0", 724, R8A774E1_CLK_S2D1),
+ DEF_MOD("lvds", 727, R8A774E1_CLK_S0D4),
+ DEF_MOD("hdmi0", 729, R8A774E1_CLK_HDMI),
+ DEF_MOD("vin7", 804, R8A774E1_CLK_S0D2),
+ DEF_MOD("vin6", 805, R8A774E1_CLK_S0D2),
+ DEF_MOD("vin5", 806, R8A774E1_CLK_S0D2),
+ DEF_MOD("vin4", 807, R8A774E1_CLK_S0D2),
+ DEF_MOD("vin3", 808, R8A774E1_CLK_S0D2),
+ DEF_MOD("vin2", 809, R8A774E1_CLK_S0D2),
+ DEF_MOD("vin1", 810, R8A774E1_CLK_S0D2),
+ DEF_MOD("vin0", 811, R8A774E1_CLK_S0D2),
+ DEF_MOD("etheravb", 812, R8A774E1_CLK_S0D6),
+ DEF_MOD("sata0", 815, R8A774E1_CLK_S3D2),
+ DEF_MOD("gpio7", 905, R8A774E1_CLK_S3D4),
+ DEF_MOD("gpio6", 906, R8A774E1_CLK_S3D4),
+ DEF_MOD("gpio5", 907, R8A774E1_CLK_S3D4),
+ DEF_MOD("gpio4", 908, R8A774E1_CLK_S3D4),
+ DEF_MOD("gpio3", 909, R8A774E1_CLK_S3D4),
+ DEF_MOD("gpio2", 910, R8A774E1_CLK_S3D4),
+ DEF_MOD("gpio1", 911, R8A774E1_CLK_S3D4),
+ DEF_MOD("gpio0", 912, R8A774E1_CLK_S3D4),
+ DEF_MOD("can-fd", 914, R8A774E1_CLK_S3D2),
+ DEF_MOD("can-if1", 915, R8A774E1_CLK_S3D4),
+ DEF_MOD("can-if0", 916, R8A774E1_CLK_S3D4),
+ DEF_MOD("rpc-if", 917, R8A774E1_CLK_RPCD2),
+ DEF_MOD("i2c6", 918, R8A774E1_CLK_S0D6),
+ DEF_MOD("i2c5", 919, R8A774E1_CLK_S0D6),
+ DEF_MOD("adg", 922, R8A774E1_CLK_S0D1),
+ DEF_MOD("i2c-dvfs", 926, R8A774E1_CLK_CP),
+ DEF_MOD("i2c4", 927, R8A774E1_CLK_S0D6),
+ DEF_MOD("i2c3", 928, R8A774E1_CLK_S0D6),
+ DEF_MOD("i2c2", 929, R8A774E1_CLK_S3D2),
+ DEF_MOD("i2c1", 930, R8A774E1_CLK_S3D2),
+ DEF_MOD("i2c0", 931, R8A774E1_CLK_S3D2),
+ DEF_MOD("ssi-all", 1005, R8A774E1_CLK_S3D4),
+ DEF_MOD("ssi9", 1006, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi8", 1007, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi7", 1008, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi6", 1009, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi5", 1010, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi4", 1011, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi3", 1012, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi2", 1013, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi1", 1014, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi0", 1015, MOD_CLK_ID(1005)),
+ DEF_MOD("scu-all", 1017, R8A774E1_CLK_S3D4),
+ DEF_MOD("scu-dvc1", 1018, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-dvc0", 1019, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-ctu1-mix1", 1020, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-ctu0-mix0", 1021, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src9", 1022, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src8", 1023, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src7", 1024, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src6", 1025, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src5", 1026, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src4", 1027, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src3", 1028, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src2", 1029, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src1", 1030, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src0", 1031, MOD_CLK_ID(1017)),
+};
+
+/*
+ * CPG Clock Data
+ */
+
+/*
+ * MD EXTAL PLL0 PLL1 PLL2 PLL3 PLL4 OSC
+ * 14 13 19 17 (MHz)
+ *-------------------------------------------------------------------------
+ * 0 0 0 0 16.66 x 1 x180 x192 x144 x192 x144 /16
+ * 0 0 0 1 16.66 x 1 x180 x192 x144 x128 x144 /16
+ * 0 0 1 0 Prohibited setting
+ * 0 0 1 1 16.66 x 1 x180 x192 x144 x192 x144 /16
+ * 0 1 0 0 20 x 1 x150 x160 x120 x160 x120 /19
+ * 0 1 0 1 20 x 1 x150 x160 x120 x106 x120 /19
+ * 0 1 1 0 Prohibited setting
+ * 0 1 1 1 20 x 1 x150 x160 x120 x160 x120 /19
+ * 1 0 0 0 25 x 1 x120 x128 x96 x128 x96 /24
+ * 1 0 0 1 25 x 1 x120 x128 x96 x84 x96 /24
+ * 1 0 1 0 Prohibited setting
+ * 1 0 1 1 25 x 1 x120 x128 x96 x128 x96 /24
+ * 1 1 0 0 33.33 / 2 x180 x192 x144 x192 x144 /32
+ * 1 1 0 1 33.33 / 2 x180 x192 x144 x128 x144 /32
+ * 1 1 1 0 Prohibited setting
+ * 1 1 1 1 33.33 / 2 x180 x192 x144 x192 x144 /32
+ */
+#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 11) | \
+ (((md) & BIT(13)) >> 11) | \
+ (((md) & BIT(19)) >> 18) | \
+ (((md) & BIT(17)) >> 17))
+
+static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] = {
+ /* EXTAL div PLL1 mult/div PLL3 mult/div OSC prediv */
+ { 1, 192, 1, 192, 1, 16, },
+ { 1, 192, 1, 128, 1, 16, },
+ { 0, /* Prohibited setting */ },
+ { 1, 192, 1, 192, 1, 16, },
+ { 1, 160, 1, 160, 1, 19, },
+ { 1, 160, 1, 106, 1, 19, },
+ { 0, /* Prohibited setting */ },
+ { 1, 160, 1, 160, 1, 19, },
+ { 1, 128, 1, 128, 1, 24, },
+ { 1, 128, 1, 84, 1, 24, },
+ { 0, /* Prohibited setting */ },
+ { 1, 128, 1, 128, 1, 24, },
+ { 2, 192, 1, 192, 1, 32, },
+ { 2, 192, 1, 128, 1, 32, },
+ { 0, /* Prohibited setting */ },
+ { 2, 192, 1, 192, 1, 32, },
+};
+
+/* RMSTPCR[0-11] is not present on RZ/G2H */
+static const struct mstp_stop_table r8a774e1_mstp_table[] = {
+ { 0x00640800, 0x0, 0x0, 0 },
+ { 0xF3EE9390, 0x0, 0x0, 0 },
+ { 0x340FAFDC, 0x2040, 0x0, 0 },
+ { 0xD80C7CDF, 0x400, 0x0, 0 },
+ { 0x80000184, 0x180, 0x0, 0 },
+ { 0x40BFFF46, 0x0, 0x0, 0 },
+ { 0xE5FBEECF, 0x0, 0x0, 0 },
+ { 0x39FFFF0E, 0x0, 0x0, 0 },
+ { 0x01F19FF4, 0x0, 0x0, 0 },
+ { 0xFFDFFFFF, 0x0, 0x0, 0 },
+ { 0xFFFEFFE0, 0x0, 0x0, 0 },
+ { 0x00000000, 0x0, 0x0, 0 },
+};
+
+static const void *r8a774e1_get_pll_config(const u32 cpg_mode)
+{
+ return &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
+}
+
+static const struct cpg_mssr_info r8a774e1_cpg_mssr_info = {
+ .core_clk = r8a774e1_core_clks,
+ .core_clk_size = ARRAY_SIZE(r8a774e1_core_clks),
+ .mod_clk = r8a774e1_mod_clks,
+ .mod_clk_size = ARRAY_SIZE(r8a774e1_mod_clks),
+ .mstp_table = r8a774e1_mstp_table,
+ .mstp_table_size = ARRAY_SIZE(r8a774e1_mstp_table),
+ .reset_node = "renesas,r8a774e1-rst",
+ .extalr_node = "extalr",
+ .mod_clk_base = MOD_CLK_BASE,
+ .clk_extal_id = CLK_EXTAL,
+ .clk_extalr_id = CLK_EXTALR,
+ .get_pll_config = r8a774e1_get_pll_config,
+};
+
+static const struct udevice_id r8a774e1_clk_ids[] = {
+ {
+ .compatible = "renesas,r8a774e1-cpg-mssr",
+ .data = (ulong)&r8a774e1_cpg_mssr_info
+ },
+ { }
+};
+
+U_BOOT_DRIVER(clk_r8a774e1) = {
+ .name = "clk_r8a774e1",
+ .id = UCLASS_CLK,
+ .of_match = r8a774e1_clk_ids,
+ .priv_auto_alloc_size = sizeof(struct gen3_clk_priv),
+ .ops = &gen3_clk_ops,
+ .probe = gen3_clk_probe,
+ .remove = gen3_clk_remove,
+};
diff --git a/drivers/pinctrl/renesas/pfc-r8a77990.c b/drivers/pinctrl/renesas/pfc-r8a77990.c
index de22e49ebef..b13fc0ba632 100644
--- a/drivers/pinctrl/renesas/pfc-r8a77990.c
+++ b/drivers/pinctrl/renesas/pfc-r8a77990.c
@@ -217,8 +217,8 @@
#define IP2_11_8 FM(AVB_MDC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP2_15_12 FM(BS_N) FM(PWM0_A) FM(AVB_MAGIC) FM(VI4_CLK) F_(0, 0) FM(TX3_C) F_(0, 0) FM(VI5_CLK_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP2_19_16 FM(RD_N) FM(PWM1_A) FM(AVB_LINK) FM(VI4_FIELD) F_(0, 0) FM(RX3_C) FM(FSCLKST2_N_A) FM(VI5_DATA0_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
-#define IP2_23_20 FM(RD_WR_N) FM(SCL7_A) FM(AVB_AVTP_MATCH_A) FM(VI4_VSYNC_N) FM(TX5_B) FM(SCK3_C) FM(PWM5_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
-#define IP2_27_24 FM(EX_WAIT0) FM(SDA7_A) FM(AVB_AVTP_CAPTURE_A) FM(VI4_HSYNC_N) FM(RX5_B) FM(PWM6_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP2_23_20 FM(RD_WR_N) FM(SCL7_A) FM(AVB_AVTP_MATCH) FM(VI4_VSYNC_N) FM(TX5_B) FM(SCK3_C) FM(PWM5_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP2_27_24 FM(EX_WAIT0) FM(SDA7_A) FM(AVB_AVTP_CAPTURE) FM(VI4_HSYNC_N) FM(RX5_B) FM(PWM6_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP2_31_28 FM(A0) FM(IRQ0) FM(PWM2_A) FM(MSIOF3_SS1_B) FM(VI5_CLK_A) FM(DU_CDE) FM(HRX3_D) FM(IERX) FM(QSTB_QHE) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP3_3_0 FM(A1) FM(IRQ1) FM(PWM3_A) FM(DU_DOTCLKIN1) FM(VI5_DATA0_A) FM(DU_DISP_CDE) FM(SDA6_B) FM(IETX) FM(QCPV_QDE) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP3_7_4 FM(A2) FM(IRQ2) FM(AVB_AVTP_PPS) FM(VI4_CLKENB) FM(VI5_DATA1_A) FM(DU_DISP) FM(SCL6_B) F_(0, 0) FM(QSTVB_QVE) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
@@ -433,6 +433,8 @@ FM(IP12_31_28) IP12_31_28 FM(IP13_31_28) IP13_31_28 FM(IP14_31_28) IP14_31_28 FM
#define MOD_SEL0_1_0 REV4(FM(SEL_SPEED_PULSE_IF_0), FM(SEL_SPEED_PULSE_IF_1), FM(SEL_SPEED_PULSE_IF_2), F_(0, 0))
/* MOD_SEL1 */ /* 0 */ /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 */ /* 7 */
+#define MOD_SEL1_31 FM(SEL_SIMCARD_0) FM(SEL_SIMCARD_1)
+#define MOD_SEL1_30 FM(SEL_SSI2_0) FM(SEL_SSI2_1)
#define MOD_SEL1_29 FM(SEL_TIMER_TMU_0) FM(SEL_TIMER_TMU_1)
#define MOD_SEL1_28 FM(SEL_USB_20_CH0_0) FM(SEL_USB_20_CH0_1)
#define MOD_SEL1_26 FM(SEL_DRIF2_0) FM(SEL_DRIF2_1)
@@ -453,7 +455,8 @@ FM(IP12_31_28) IP12_31_28 FM(IP13_31_28) IP13_31_28 FM(IP14_31_28) IP14_31_28 FM
#define PINMUX_MOD_SELS \
\
-MOD_SEL0_30_29 \
+ MOD_SEL1_31 \
+MOD_SEL0_30_29 MOD_SEL1_30 \
MOD_SEL1_29 \
MOD_SEL0_28 MOD_SEL1_28 \
MOD_SEL0_27_26 \
@@ -619,7 +622,7 @@ static const u16 pinmux_data[] = {
PINMUX_IPSR_GPSR(IP2_23_20, RD_WR_N),
PINMUX_IPSR_MSEL(IP2_23_20, SCL7_A, SEL_I2C7_0),
- PINMUX_IPSR_GPSR(IP2_23_20, AVB_AVTP_MATCH_A),
+ PINMUX_IPSR_GPSR(IP2_23_20, AVB_AVTP_MATCH),
PINMUX_IPSR_GPSR(IP2_23_20, VI4_VSYNC_N),
PINMUX_IPSR_GPSR(IP2_23_20, TX5_B),
PINMUX_IPSR_MSEL(IP2_23_20, SCK3_C, SEL_SCIF3_2),
@@ -627,7 +630,7 @@ static const u16 pinmux_data[] = {
PINMUX_IPSR_GPSR(IP2_27_24, EX_WAIT0),
PINMUX_IPSR_MSEL(IP2_27_24, SDA7_A, SEL_I2C7_0),
- PINMUX_IPSR_GPSR(IP2_27_24, AVB_AVTP_CAPTURE_A),
+ PINMUX_IPSR_GPSR(IP2_27_24, AVB_AVTP_CAPTURE),
PINMUX_IPSR_GPSR(IP2_27_24, VI4_HSYNC_N),
PINMUX_IPSR_MSEL(IP2_27_24, RX5_B, SEL_SCIF5_1),
PINMUX_IPSR_MSEL(IP2_27_24, PWM6_A, SEL_PWM6_0),
@@ -1043,7 +1046,7 @@ static const u16 pinmux_data[] = {
PINMUX_IPSR_MSEL(IP10_27_24, RIF0_CLK_B, SEL_DRIF0_1),
PINMUX_IPSR_MSEL(IP10_27_24, SCL2_B, SEL_I2C2_1),
PINMUX_IPSR_MSEL(IP10_27_24, TCLK1_A, SEL_TIMER_TMU_0),
- PINMUX_IPSR_GPSR(IP10_27_24, SSI_SCK2_B),
+ PINMUX_IPSR_MSEL(IP10_27_24, SSI_SCK2_B, SEL_SSI2_1),
PINMUX_IPSR_GPSR(IP10_27_24, TS_SCK0),
PINMUX_IPSR_GPSR(IP10_31_28, SD0_WP),
@@ -1052,7 +1055,7 @@ static const u16 pinmux_data[] = {
PINMUX_IPSR_MSEL(IP10_31_28, RIF0_D0_B, SEL_DRIF0_1),
PINMUX_IPSR_MSEL(IP10_31_28, SDA2_B, SEL_I2C2_1),
PINMUX_IPSR_MSEL(IP10_31_28, TCLK2_A, SEL_TIMER_TMU_0),
- PINMUX_IPSR_GPSR(IP10_31_28, SSI_WS2_B),
+ PINMUX_IPSR_MSEL(IP10_31_28, SSI_WS2_B, SEL_SSI2_1),
PINMUX_IPSR_GPSR(IP10_31_28, TS_SDAT0),
/* IPSR11 */
@@ -1070,13 +1073,13 @@ static const u16 pinmux_data[] = {
PINMUX_IPSR_MSEL(IP11_11_8, RX0_A, SEL_SCIF0_0),
PINMUX_IPSR_MSEL(IP11_11_8, HRX1_A, SEL_HSCIF1_0),
- PINMUX_IPSR_GPSR(IP11_11_8, SSI_SCK2_A),
+ PINMUX_IPSR_MSEL(IP11_11_8, SSI_SCK2_A, SEL_SSI2_0),
PINMUX_IPSR_GPSR(IP11_11_8, RIF1_SYNC),
PINMUX_IPSR_GPSR(IP11_11_8, TS_SCK1),
PINMUX_IPSR_MSEL(IP11_15_12, TX0_A, SEL_SCIF0_0),
PINMUX_IPSR_GPSR(IP11_15_12, HTX1_A),
- PINMUX_IPSR_GPSR(IP11_15_12, SSI_WS2_A),
+ PINMUX_IPSR_MSEL(IP11_15_12, SSI_WS2_A, SEL_SSI2_0),
PINMUX_IPSR_GPSR(IP11_15_12, RIF1_D0),
PINMUX_IPSR_GPSR(IP11_15_12, TS_SDAT1),
@@ -1181,7 +1184,7 @@ static const u16 pinmux_data[] = {
PINMUX_IPSR_MSEL(IP13_19_16, RIF0_D1_A, SEL_DRIF0_0),
PINMUX_IPSR_MSEL(IP13_19_16, SDA1_B, SEL_I2C1_1),
PINMUX_IPSR_MSEL(IP13_19_16, TCLK2_B, SEL_TIMER_TMU_1),
- PINMUX_IPSR_GPSR(IP13_19_16, SIM0_D_A),
+ PINMUX_IPSR_MSEL(IP13_19_16, SIM0_D_A, SEL_SIMCARD_0),
PINMUX_IPSR_GPSR(IP13_23_20, MLB_DAT),
PINMUX_IPSR_MSEL(IP13_23_20, TX0_B, SEL_SCIF0_1),
@@ -1249,7 +1252,7 @@ static const u16 pinmux_data[] = {
PINMUX_IPSR_GPSR(IP15_15_12, TPU0TO2),
PINMUX_IPSR_MSEL(IP15_15_12, SDA1_D, SEL_I2C1_3),
PINMUX_IPSR_MSEL(IP15_15_12, FSO_CFE_1_N_B, SEL_FSO_1),
- PINMUX_IPSR_GPSR(IP15_15_12, SIM0_D_B),
+ PINMUX_IPSR_MSEL(IP15_15_12, SIM0_D_B, SEL_SIMCARD_1),
PINMUX_IPSR_GPSR(IP15_19_16, SSI_SDATA6),
PINMUX_IPSR_MSEL(IP15_19_16, HRTS2_N_A, SEL_HSCIF2_0),
@@ -1534,22 +1537,22 @@ static const unsigned int avb_avtp_pps_mux[] = {
AVB_AVTP_PPS_MARK,
};
-static const unsigned int avb_avtp_match_a_pins[] = {
- /* AVB_AVTP_MATCH_A */
+static const unsigned int avb_avtp_match_pins[] = {
+ /* AVB_AVTP_MATCH */
RCAR_GP_PIN(2, 24),
};
-static const unsigned int avb_avtp_match_a_mux[] = {
- AVB_AVTP_MATCH_A_MARK,
+static const unsigned int avb_avtp_match_mux[] = {
+ AVB_AVTP_MATCH_MARK,
};
-static const unsigned int avb_avtp_capture_a_pins[] = {
- /* AVB_AVTP_CAPTURE_A */
+static const unsigned int avb_avtp_capture_pins[] = {
+ /* AVB_AVTP_CAPTURE */
RCAR_GP_PIN(2, 25),
};
-static const unsigned int avb_avtp_capture_a_mux[] = {
- AVB_AVTP_CAPTURE_A_MARK,
+static const unsigned int avb_avtp_capture_mux[] = {
+ AVB_AVTP_CAPTURE_MARK,
};
/* - CAN ------------------------------------------------------------------ */
@@ -3794,8 +3797,8 @@ static const struct {
SH_PFC_PIN_GROUP(avb_phy_int),
SH_PFC_PIN_GROUP(avb_mii),
SH_PFC_PIN_GROUP(avb_avtp_pps),
- SH_PFC_PIN_GROUP(avb_avtp_match_a),
- SH_PFC_PIN_GROUP(avb_avtp_capture_a),
+ SH_PFC_PIN_GROUP(avb_avtp_match),
+ SH_PFC_PIN_GROUP(avb_avtp_capture),
SH_PFC_PIN_GROUP(can0_data),
SH_PFC_PIN_GROUP(can1_data),
SH_PFC_PIN_GROUP(can_clk),
@@ -4071,8 +4074,8 @@ static const char * const avb_groups[] = {
"avb_phy_int",
"avb_mii",
"avb_avtp_pps",
- "avb_avtp_match_a",
- "avb_avtp_capture_a",
+ "avb_avtp_match",
+ "avb_avtp_capture",
};
static const char * const can0_groups[] = {
@@ -4967,11 +4970,11 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = {
MOD_SEL0_1_0 ))
},
{ PINMUX_CFG_REG_VAR("MOD_SEL1", 0xe6060504, 32,
- GROUP(2, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1,
- 2, 2, 2, 1, 1, 2, 1, 4),
+ GROUP(1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1,
+ 1, 2, 2, 2, 1, 1, 2, 1, 4),
GROUP(
- /* RESERVED 31, 30 */
- 0, 0, 0, 0,
+ MOD_SEL1_31
+ MOD_SEL1_30
MOD_SEL1_29
MOD_SEL1_28
/* RESERVED 27 */
diff --git a/drivers/spi/renesas_rpc_spi.c b/drivers/spi/renesas_rpc_spi.c
index 3ea59b8fb82..d0ff918af88 100644
--- a/drivers/spi/renesas_rpc_spi.c
+++ b/drivers/spi/renesas_rpc_spi.c
@@ -448,12 +448,13 @@ static const struct dm_spi_ops rpc_spi_ops = {
};
static const struct udevice_id rpc_spi_ids[] = {
+ { .compatible = "renesas,rpc-r7s72100" },
{ .compatible = "renesas,rpc-r8a7795" },
{ .compatible = "renesas,rpc-r8a7796" },
{ .compatible = "renesas,rpc-r8a77965" },
{ .compatible = "renesas,rpc-r8a77970" },
{ .compatible = "renesas,rpc-r8a77995" },
- { .compatible = "renesas,rpc-r7s72100" },
+ { .compatible = "renesas,rcar-gen3-rpc" },
{ }
};
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 34881a12b8b..fedc0134f5f 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -72,6 +72,8 @@ source "drivers/usb/cdns3/Kconfig"
source "drivers/usb/dwc3/Kconfig"
+source "drivers/usb/mtu3/Kconfig"
+
source "drivers/usb/musb/Kconfig"
source "drivers/usb/musb-new/Kconfig"
diff --git a/drivers/usb/common/common.c b/drivers/usb/common/common.c
index d4ae18693c6..5e5c3c3e3dc 100644
--- a/drivers/usb/common/common.c
+++ b/drivers/usb/common/common.c
@@ -46,8 +46,16 @@ static const char *const speed_names[] = {
[USB_SPEED_HIGH] = "high-speed",
[USB_SPEED_WIRELESS] = "wireless",
[USB_SPEED_SUPER] = "super-speed",
+ [USB_SPEED_SUPER_PLUS] = "super-speed-plus",
};
+const char *usb_speed_string(enum usb_device_speed speed)
+{
+ if (speed < 0 || speed >= ARRAY_SIZE(speed_names))
+ speed = USB_SPEED_UNKNOWN;
+ return speed_names[speed];
+}
+
enum usb_device_speed usb_get_maximum_speed(ofnode node)
{
const char *max_speed;
diff --git a/drivers/usb/gadget/dwc2_udc_otg_xfer_dma.c b/drivers/usb/gadget/dwc2_udc_otg_xfer_dma.c
index 1c0505eb28c..f17009a29e0 100644
--- a/drivers/usb/gadget/dwc2_udc_otg_xfer_dma.c
+++ b/drivers/usb/gadget/dwc2_udc_otg_xfer_dma.c
@@ -421,6 +421,9 @@ static void process_ep_out_intr(struct dwc2_udc *dev)
{
u32 ep_intr, ep_intr_status;
u8 ep_num = 0;
+ u32 ep_tsr = 0, xfer_size = 0;
+ u32 epsiz_reg = reg->out_endp[ep_num].doeptsiz;
+ u32 req_size = sizeof(struct usb_ctrlrequest);
ep_intr = readl(&reg->daint);
debug_cond(DEBUG_OUT_EP != 0,
@@ -441,10 +444,17 @@ static void process_ep_out_intr(struct dwc2_udc *dev)
if (ep_num == 0) {
if (ep_intr_status & TRANSFER_DONE) {
- if (dev->ep0state !=
- WAIT_FOR_OUT_COMPLETE)
+ ep_tsr = readl(&epsiz_reg);
+ xfer_size = ep_tsr &
+ DOEPT_SIZ_XFER_SIZE_MAX_EP0;
+
+ if (xfer_size == req_size &&
+ dev->ep0state == WAIT_FOR_SETUP) {
+ dwc2_udc_pre_setup();
+ } else if (dev->ep0state !=
+ WAIT_FOR_OUT_COMPLETE) {
complete_rx(dev, ep_num);
- else {
+ } else {
dev->ep0state = WAIT_FOR_SETUP;
dwc2_udc_pre_setup();
}
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h
index 587204cfb7a..0cdf47c2dda 100644
--- a/drivers/usb/gadget/gadget_chips.h
+++ b/drivers/usb/gadget/gadget_chips.h
@@ -161,6 +161,12 @@
#define gadget_is_max3420(g) 0
#endif
+#ifdef CONFIG_USB_MTU3_GADGET
+#define gadget_is_mtu3(g) (!strcmp("mtu3-gadget", (g)->name))
+#else
+#define gadget_is_mtu3(g) 0
+#endif
+
/**
* usb_gadget_controller_number - support bcdDevice id convention
* @gadget: the controller being driven
@@ -224,5 +230,7 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
return 0x24;
else if (gadget_is_max3420(gadget))
return 0x25;
+ else if (gadget_is_mtu3(gadget))
+ return 0x26;
return -ENOENT;
}
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 0b496149956..b002d6f1664 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -279,10 +279,10 @@ static struct xhci_segment *xhci_segment_alloc(void)
{
struct xhci_segment *seg;
- seg = (struct xhci_segment *)malloc(sizeof(struct xhci_segment));
+ seg = malloc(sizeof(struct xhci_segment));
BUG_ON(!seg);
- seg->trbs = (union xhci_trb *)xhci_malloc(SEGMENT_SIZE);
+ seg->trbs = xhci_malloc(SEGMENT_SIZE);
seg->next = NULL;
@@ -309,7 +309,7 @@ struct xhci_ring *xhci_ring_alloc(unsigned int num_segs, bool link_trbs)
struct xhci_ring *ring;
struct xhci_segment *prev;
- ring = (struct xhci_ring *)malloc(sizeof(struct xhci_ring));
+ ring = malloc(sizeof(struct xhci_ring));
BUG_ON(!ring);
if (num_segs == 0)
@@ -425,8 +425,7 @@ static struct xhci_container_ctx
{
struct xhci_container_ctx *ctx;
- ctx = (struct xhci_container_ctx *)
- malloc(sizeof(struct xhci_container_ctx));
+ ctx = malloc(sizeof(struct xhci_container_ctx));
BUG_ON(!ctx);
BUG_ON((type != XHCI_CTX_TYPE_DEVICE) && (type != XHCI_CTX_TYPE_INPUT));
@@ -436,7 +435,7 @@ static struct xhci_container_ctx
if (type == XHCI_CTX_TYPE_INPUT)
ctx->size += CTX_SIZE(readl(&ctrl->hccr->cr_hccparams));
- ctx->bytes = (u8 *)xhci_malloc(ctx->size);
+ ctx->bytes = xhci_malloc(ctx->size);
return ctx;
}
@@ -458,8 +457,7 @@ int xhci_alloc_virt_device(struct xhci_ctrl *ctrl, unsigned int slot_id)
return -EEXIST;
}
- ctrl->devs[slot_id] = (struct xhci_virt_device *)
- malloc(sizeof(struct xhci_virt_device));
+ ctrl->devs[slot_id] = malloc(sizeof(struct xhci_virt_device));
if (!ctrl->devs[slot_id]) {
puts("Failed to allocate virtual device\n");
@@ -518,8 +516,7 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr *hccr,
struct xhci_segment *seg;
/* DCBAA initialization */
- ctrl->dcbaa = (struct xhci_device_context_array *)
- xhci_malloc(sizeof(struct xhci_device_context_array));
+ ctrl->dcbaa = xhci_malloc(sizeof(struct xhci_device_context_array));
if (ctrl->dcbaa == NULL) {
puts("unable to allocate DCBA\n");
return -ENOMEM;
@@ -555,8 +552,8 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr *hccr,
/* Event ring does not maintain link TRB */
ctrl->event_ring = xhci_ring_alloc(ERST_NUM_SEGS, false);
- ctrl->erst.entries = (struct xhci_erst_entry *)
- xhci_malloc(sizeof(struct xhci_erst_entry) * ERST_NUM_SEGS);
+ ctrl->erst.entries = xhci_malloc(sizeof(struct xhci_erst_entry) *
+ ERST_NUM_SEGS);
ctrl->erst.num_entries = ERST_NUM_SEGS;
diff --git a/drivers/usb/mtu3/Kconfig b/drivers/usb/mtu3/Kconfig
new file mode 100644
index 00000000000..a2a59917132
--- /dev/null
+++ b/drivers/usb/mtu3/Kconfig
@@ -0,0 +1,44 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# For MTK USB3.0 IP
+
+config USB_MTU3
+ bool "MediaTek USB3 Dual Role controller"
+ depends on USB_HOST || USB_GADGET
+ depends on ARCH_MEDIATEK
+ help
+ Say Y here if your system runs on MediaTek SoCs with
+ Dual Role SuperSpeed USB controller. You can select usb
+ mode as peripheral role or host role.
+
+ If you don't know what this is, please say N.
+
+if USB_MTU3
+choice
+ bool "MTU3 Mode Selection"
+ default USB_MTU3_GADGET if USB_GADGET
+ default USB_MTU3_HOST if (USB_HOST && !USB_GADGET)
+
+config USB_MTU3_HOST
+ bool "Host only mode"
+ depends on USB_XHCI_HCD
+ help
+ Select this when you want to use MTU3 in host mode only,
+ thereby the gadget feature will be regressed.
+
+config USB_MTU3_GADGET
+ bool "Gadget only mode"
+ depends on USB_GADGET
+ select USB_GADGET_DUALSPEED
+ help
+ Select this when you want to use MTU3 in gadget mode only,
+ thereby the host feature will be regressed.
+
+endchoice
+
+config USB_MTU3_DEBUG
+ bool "Enable Debugging Messages"
+ help
+ Say Y here to enable debugging messages in the MTU3 Driver.
+
+endif
diff --git a/drivers/usb/mtu3/Makefile b/drivers/usb/mtu3/Makefile
new file mode 100644
index 00000000000..234f3a380a3
--- /dev/null
+++ b/drivers/usb/mtu3/Makefile
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0
+
+ccflags-$(CONFIG_USB_MTU3_DEBUG) += -DDEBUG
+
+obj-$(CONFIG_USB_MTU3) += mtu3.o
+
+mtu3-y := mtu3_plat.o
+
+obj-$(CONFIG_USB_MTU3_GADGET) += mtu3_core.o mtu3_gadget_ep0.o mtu3_gadget.o
+obj-$(CONFIG_USB_MTU3_GADGET) += mtu3_qmu.o
+obj-$(CONFIG_USB_MTU3_HOST) += mtu3_host.o
diff --git a/drivers/usb/mtu3/mtu3.h b/drivers/usb/mtu3/mtu3.h
new file mode 100644
index 00000000000..8a7ae83ee99
--- /dev/null
+++ b/drivers/usb/mtu3/mtu3.h
@@ -0,0 +1,424 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * mtu3.h - MediaTek USB3 DRD header
+ *
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * Author: Chunfeng Yun <chunfeng.yun@mediatek.com>
+ */
+
+#ifndef __MTU3_H__
+#define __MTU3_H__
+
+#include <asm/io.h>
+#include <clk.h>
+#include <dm.h>
+#include <dm/device_compat.h>
+#include <dm/devres.h>
+#include <generic-phy.h>
+#include <linux/bug.h>
+#include <linux/delay.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/otg.h>
+#include <power/regulator.h>
+#include <usb/xhci.h>
+
+struct mtu3;
+struct mtu3_ep;
+struct mtu3_request;
+struct mtu3_host;
+
+#include "mtu3_hw_regs.h"
+#include "mtu3_qmu.h"
+
+#define MU3D_EP_TXCR0(epnum) (U3D_TX1CSR0 + (((epnum) - 1) * 0x10))
+#define MU3D_EP_TXCR1(epnum) (U3D_TX1CSR1 + (((epnum) - 1) * 0x10))
+#define MU3D_EP_TXCR2(epnum) (U3D_TX1CSR2 + (((epnum) - 1) * 0x10))
+
+#define MU3D_EP_RXCR0(epnum) (U3D_RX1CSR0 + (((epnum) - 1) * 0x10))
+#define MU3D_EP_RXCR1(epnum) (U3D_RX1CSR1 + (((epnum) - 1) * 0x10))
+#define MU3D_EP_RXCR2(epnum) (U3D_RX1CSR2 + (((epnum) - 1) * 0x10))
+
+#define USB_QMU_RQCSR(epnum) (U3D_RXQCSR1 + (((epnum) - 1) * 0x10))
+#define USB_QMU_RQSAR(epnum) (U3D_RXQSAR1 + (((epnum) - 1) * 0x10))
+#define USB_QMU_RQCPR(epnum) (U3D_RXQCPR1 + (((epnum) - 1) * 0x10))
+
+#define USB_QMU_TQCSR(epnum) (U3D_TXQCSR1 + (((epnum) - 1) * 0x10))
+#define USB_QMU_TQSAR(epnum) (U3D_TXQSAR1 + (((epnum) - 1) * 0x10))
+#define USB_QMU_TQCPR(epnum) (U3D_TXQCPR1 + (((epnum) - 1) * 0x10))
+
+#define SSUSB_U3_CTRL(p) (U3D_SSUSB_U3_CTRL_0P + ((p) * 0x08))
+#define SSUSB_U2_CTRL(p) (U3D_SSUSB_U2_CTRL_0P + ((p) * 0x08))
+
+#define MTU3_DRIVER_NAME "mtu3-gadget"
+#define DMA_ADDR_INVALID (~(dma_addr_t)0)
+
+#define MTU3_EP_ENABLED BIT(0)
+#define MTU3_EP_STALL BIT(1)
+#define MTU3_EP_WEDGE BIT(2)
+#define MTU3_EP_BUSY BIT(3)
+
+/* should be set as 1 */
+#define MTU3_U2_IP_SLOT_DEFAULT 1
+#define MTU3_U3_IP_SLOT_DEFAULT (MTU3_U2_IP_SLOT_DEFAULT)
+
+/**
+ * IP TRUNK version
+ * from 0x1003 version, USB3 Gen2 is supported, two changes affect driver:
+ * 1. MAXPKT and MULTI bits layout of TXCSR1 and RXCSR1 are adjusted,
+ * but not backward compatible
+ * 2. QMU extend buffer length supported
+ */
+#define MTU3_TRUNK_VERS_1003 0x1003
+
+/**
+ * Normally the device works on HS or SS, to simplify fifo management,
+ * devide fifo into some 2*maxp parts, use bitmap to manage it; And
+ * 32 bits size of bitmap is large enough, that means it can manage
+ * up to 32KB/64KB fifo size.
+ * NOTE: MTU3_U2/3IP_EP_FIFO_UNIT should be power of two;
+ * FIFO size is allocated according to @slot which is 1 by default
+ */
+#define USB_HS_MAXP 512
+#define USB_SS_MAXP 1024
+#define MTU3_U2IP_EP_FIFO_UNIT \
+ ((USB_HS_MAXP) * ((MTU3_U2_IP_SLOT_DEFAULT) + 1))
+#define MTU3_U3IP_EP_FIFO_UNIT \
+ ((USB_SS_MAXP) * ((MTU3_U3_IP_SLOT_DEFAULT) + 1))
+
+#define MTU3_FIFO_BIT_SIZE 32
+#define MTU3_U2_IP_EP0_FIFO_SIZE 64
+
+/**
+ * Maximum size of ep0 response buffer for ch9 requests,
+ * the SET_SEL request uses 6 so far, and GET_STATUS is 2
+ */
+#define EP0_RESPONSE_BUF 6
+
+/* device operated link and speed got from DEVICE_CONF register */
+enum mtu3_speed {
+ MTU3_SPEED_INACTIVE = 0,
+ MTU3_SPEED_FULL = 1,
+ MTU3_SPEED_HIGH = 3,
+ MTU3_SPEED_SUPER = 4,
+ MTU3_SPEED_SUPER_PLUS = 5,
+};
+
+/**
+ * @MU3D_EP0_STATE_SETUP: waits for SETUP or received a SETUP
+ * without data stage.
+ * @MU3D_EP0_STATE_TX: IN data stage
+ * @MU3D_EP0_STATE_RX: OUT data stage
+ * @MU3D_EP0_STATE_TX_END: the last IN data is transferred, and
+ * waits for its completion interrupt
+ * @MU3D_EP0_STATE_STALL: ep0 is in stall status, will be auto-cleared
+ * after receives a SETUP.
+ */
+enum mtu3_g_ep0_state {
+ MU3D_EP0_STATE_SETUP = 1,
+ MU3D_EP0_STATE_TX,
+ MU3D_EP0_STATE_RX,
+ MU3D_EP0_STATE_TX_END,
+ MU3D_EP0_STATE_STALL,
+};
+
+/**
+ * MTU3_DR_FORCE_NONE: automatically switch host and peripheral mode
+ * by IDPIN signal.
+ * MTU3_DR_FORCE_HOST: force to enter host mode and override OTG
+ * IDPIN signal.
+ * MTU3_DR_FORCE_DEVICE: force to enter peripheral mode.
+ */
+enum mtu3_dr_force_mode {
+ MTU3_DR_FORCE_NONE = 0,
+ MTU3_DR_FORCE_HOST,
+ MTU3_DR_FORCE_DEVICE,
+};
+
+/**
+ * @mac_base: register base address of MAC, include xHCI and device
+ * @ippc_base: register base address of IP Power and Clock interface (IPPC)
+ * @vusb33_supply: usb3.3V shared by device/host IP
+ * @vbus_supply: vbus 5v of OTG port
+ * @clks: optional clocks, include "sys_ck", "ref_ck", "mcu_ck",
+ * "dma_ck" and "xhci_ck"
+ * @phys: phys used
+ * @dr_mode: works in which mode:
+ * host only, device only or dual-role mode
+ */
+struct ssusb_mtk {
+ struct udevice *dev;
+ struct mtu3 *u3d;
+ struct mtu3_host *u3h;
+ void __iomem *mac_base;
+ void __iomem *ippc_base;
+ /* common power & clock */
+ struct udevice *vusb33_supply;
+ struct udevice *vbus_supply;
+ struct clk_bulk clks;
+ struct phy_bulk phys;
+ /* otg */
+ enum usb_dr_mode dr_mode;
+};
+
+/**
+ * @ctrl: xHCI controller, needs to come first in this struct!
+ * @hcd: xHCI's register base address
+ * @u2_ports: number of usb2 host ports
+ * @u3_ports: number of usb3 host ports
+ * @u3p_dis_msk: mask of disabling usb3 ports, for example, bit0==1 to
+ * disable u3port0, bit1==1 to disable u3port1,... etc
+ */
+struct mtu3_host {
+ struct xhci_ctrl ctrl;
+ struct xhci_hccr *hcd;
+ void __iomem *ippc_base;
+ struct ssusb_mtk *ssusb;
+ struct udevice *dev;
+ u32 u2_ports;
+ u32 u3_ports;
+ u32 u3p_dis_msk;
+};
+
+/**
+ * @base: the base address of fifo
+ * @limit: the bitmap size in bits
+ * @bitmap: fifo bitmap in unit of @MTU3_EP_FIFO_UNIT
+ */
+struct mtu3_fifo_info {
+ u32 base;
+ u32 limit;
+ DECLARE_BITMAP(bitmap, MTU3_FIFO_BIT_SIZE);
+};
+
+/**
+ * General Purpose Descriptor (GPD):
+ * The format of TX GPD is a little different from RX one.
+ * And the size of GPD is 16 bytes.
+ *
+ * @flag:
+ * bit0: Hardware Own (HWO)
+ * bit1: Buffer Descriptor Present (BDP), always 0, BD is not supported
+ * bit2: Bypass (BPS), 1: HW skips this GPD if HWO = 1
+ * bit7: Interrupt On Completion (IOC)
+ * @chksum: This is used to validate the contents of this GPD;
+ * If TXQ_CS_EN / RXQ_CS_EN bit is set, an interrupt is issued
+ * when checksum validation fails;
+ * Checksum value is calculated over the 16 bytes of the GPD by default;
+ * @data_buf_len (RX ONLY): This value indicates the length of
+ * the assigned data buffer
+ * @next_gpd: Physical address of the next GPD
+ * @buffer: Physical address of the data buffer
+ * @buf_len:
+ * (TX): This value indicates the length of the assigned data buffer
+ * (RX): The total length of data received
+ * @ext_len: reserved
+ * @ext_flag:
+ * bit5 (TX ONLY): Zero Length Packet (ZLP),
+ */
+struct qmu_gpd {
+ __u8 flag;
+ __u8 chksum;
+ __le16 data_buf_len;
+ __le32 next_gpd;
+ __le32 buffer;
+ __le16 buf_len;
+ __u8 ext_len;
+ __u8 ext_flag;
+} __packed;
+
+/**
+ * dma: physical base address of GPD segment
+ * start: virtual base address of GPD segment
+ * end: the last GPD element
+ * enqueue: the first empty GPD to use
+ * dequeue: the first completed GPD serviced by ISR
+ * NOTE: the size of GPD ring should be >= 2
+ */
+struct mtu3_gpd_ring {
+ dma_addr_t dma;
+ struct qmu_gpd *start;
+ struct qmu_gpd *end;
+ struct qmu_gpd *enqueue;
+ struct qmu_gpd *dequeue;
+};
+
+/**
+ * @fifo_size: it is (@slot + 1) * @fifo_seg_size
+ * @fifo_seg_size: it is roundup_pow_of_two(@maxp)
+ */
+struct mtu3_ep {
+ struct usb_ep ep;
+ char name[12];
+ struct mtu3 *mtu;
+ u8 epnum;
+ u8 type;
+ u8 is_in;
+ u16 maxp;
+ int slot;
+ u32 fifo_size;
+ u32 fifo_addr;
+ u32 fifo_seg_size;
+ struct mtu3_fifo_info *fifo;
+
+ struct list_head req_list;
+ struct mtu3_gpd_ring gpd_ring;
+ const struct usb_ss_ep_comp_descriptor *comp_desc;
+ const struct usb_endpoint_descriptor *desc;
+
+ int flags;
+};
+
+struct mtu3_request {
+ struct usb_request request;
+ struct list_head list;
+ struct mtu3_ep *mep;
+ struct mtu3 *mtu;
+ struct qmu_gpd *gpd;
+ int epnum;
+};
+
+static inline struct ssusb_mtk *dev_to_ssusb(struct udevice *dev)
+{
+ return dev_get_priv(dev);
+}
+
+/**
+ * struct mtu3 - device driver instance data.
+ * @slot: MTU3_U2_IP_SLOT_DEFAULT for U2 IP only,
+ * MTU3_U3_IP_SLOT_DEFAULT for U3 IP
+ * @may_wakeup: means device's remote wakeup is enabled
+ * @is_self_powered: is reported in device status and the config descriptor
+ * @delayed_status: true when function drivers ask for delayed status
+ * @gen2cp: compatible with USB3 Gen2 IP
+ * @ep0_req: dummy request used while handling standard USB requests
+ * for GET_STATUS and SET_SEL
+ * @setup_buf: ep0 response buffer for GET_STATUS and SET_SEL requests
+ */
+struct mtu3 {
+ spinlock_t lock;
+ struct ssusb_mtk *ssusb;
+ struct udevice *dev;
+ void __iomem *mac_base;
+ void __iomem *ippc_base;
+ int irq;
+
+ struct mtu3_fifo_info tx_fifo;
+ struct mtu3_fifo_info rx_fifo;
+
+ struct mtu3_ep *ep_array;
+ struct mtu3_ep *in_eps;
+ struct mtu3_ep *out_eps;
+ struct mtu3_ep *ep0;
+ int num_eps;
+ int slot;
+ int active_ep;
+
+ enum mtu3_g_ep0_state ep0_state;
+ struct usb_gadget g; /* the gadget */
+ struct usb_gadget_driver *gadget_driver;
+ struct mtu3_request ep0_req;
+ u8 setup_buf[EP0_RESPONSE_BUF];
+ enum usb_device_speed max_speed;
+ enum usb_device_speed speed;
+
+ unsigned is_active:1;
+ unsigned may_wakeup:1;
+ unsigned is_self_powered:1;
+ unsigned test_mode:1;
+ unsigned softconnect:1;
+ unsigned u1_enable:1;
+ unsigned u2_enable:1;
+ unsigned is_u3_ip:1;
+ unsigned delayed_status:1;
+ unsigned gen2cp:1;
+ unsigned force_vbus:1;
+
+ u8 address;
+ u8 test_mode_nr;
+ u32 hw_version;
+};
+
+static inline struct mtu3 *gadget_to_mtu3(struct usb_gadget *g)
+{
+ return container_of(g, struct mtu3, g);
+}
+
+static inline int is_first_entry(const struct list_head *list,
+ const struct list_head *head)
+{
+ return list_is_last(head, list);
+}
+
+static inline struct mtu3_request *to_mtu3_request(struct usb_request *req)
+{
+ return req ? container_of(req, struct mtu3_request, request) : NULL;
+}
+
+static inline struct mtu3_ep *to_mtu3_ep(struct usb_ep *ep)
+{
+ return ep ? container_of(ep, struct mtu3_ep, ep) : NULL;
+}
+
+static inline struct mtu3_request *next_request(struct mtu3_ep *mep)
+{
+ if (list_empty(&mep->req_list))
+ return NULL;
+
+ return list_first_entry(&mep->req_list, struct mtu3_request, list);
+}
+
+static inline void mtu3_writel(void __iomem *base, u32 offset, u32 data)
+{
+ writel(data, base + offset);
+}
+
+static inline u32 mtu3_readl(void __iomem *base, u32 offset)
+{
+ return readl(base + offset);
+}
+
+static inline void mtu3_setbits(void __iomem *base, u32 offset, u32 bits)
+{
+ void __iomem *addr = base + offset;
+ u32 tmp = readl(addr);
+
+ writel((tmp | (bits)), addr);
+}
+
+static inline void mtu3_clrbits(void __iomem *base, u32 offset, u32 bits)
+{
+ void __iomem *addr = base + offset;
+ u32 tmp = readl(addr);
+
+ writel((tmp & ~(bits)), addr);
+}
+
+int ssusb_check_clocks(struct ssusb_mtk *ssusb, u32 ex_clks);
+struct usb_request *mtu3_alloc_request(struct usb_ep *ep, gfp_t gfp_flags);
+void mtu3_free_request(struct usb_ep *ep, struct usb_request *req);
+void mtu3_req_complete(struct mtu3_ep *mep,
+ struct usb_request *req, int status);
+
+int mtu3_config_ep(struct mtu3 *mtu, struct mtu3_ep *mep,
+ int interval, int burst, int mult);
+void mtu3_deconfig_ep(struct mtu3 *mtu, struct mtu3_ep *mep);
+void mtu3_ep_stall_set(struct mtu3_ep *mep, bool set);
+void mtu3_ep0_setup(struct mtu3 *mtu);
+void mtu3_start(struct mtu3 *mtu);
+void mtu3_stop(struct mtu3 *mtu);
+void mtu3_dev_on_off(struct mtu3 *mtu, int is_on);
+void mtu3_set_speed(struct mtu3 *mtu, enum usb_device_speed speed);
+
+int mtu3_gadget_setup(struct mtu3 *mtu);
+void mtu3_gadget_cleanup(struct mtu3 *mtu);
+void mtu3_gadget_reset(struct mtu3 *mtu);
+void mtu3_gadget_suspend(struct mtu3 *mtu);
+void mtu3_gadget_resume(struct mtu3 *mtu);
+void mtu3_gadget_disconnect(struct mtu3 *mtu);
+
+irqreturn_t mtu3_ep0_isr(struct mtu3 *mtu);
+extern const struct usb_ep_ops mtu3_ep0_ops;
+
+#endif
diff --git a/drivers/usb/mtu3/mtu3_core.c b/drivers/usb/mtu3/mtu3_core.c
new file mode 100644
index 00000000000..28136f88f45
--- /dev/null
+++ b/drivers/usb/mtu3/mtu3_core.c
@@ -0,0 +1,838 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * mtu3_core.c - hardware access layer and gadget init/exit of
+ * MediaTek usb3 Dual-Role Controller Driver
+ *
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * Author: Chunfeng Yun <chunfeng.yun@mediatek.com>
+ */
+
+#include <linux/log2.h>
+#include <linux/bitmap.h>
+
+#include "mtu3.h"
+#include "mtu3_dr.h"
+
+static int ep_fifo_alloc(struct mtu3_ep *mep, u32 seg_size)
+{
+ struct mtu3_fifo_info *fifo = mep->fifo;
+ struct mtu3 *mtu = mep->mtu;
+ u32 fz_bit;
+
+ mep->fifo_seg_size = mtu->is_u3_ip ? USB_SS_MAXP : USB_HS_MAXP;
+
+ fz_bit = find_first_zero_bit(fifo->bitmap, fifo->limit);
+ if (fz_bit >= fifo->limit)
+ return -EOVERFLOW;
+
+ mep->fifo_size = mep->fifo_seg_size * (mep->slot + 1);
+ mep->fifo_addr = fifo->base + mep->fifo_size * fz_bit;
+ generic_set_bit(fz_bit, fifo->bitmap);
+
+ dev_dbg(mep->mtu->dev, "%s fifo:%#x/%#x, bit: %d\n",
+ __func__, mep->fifo_seg_size, mep->fifo_size, fz_bit);
+
+ return mep->fifo_addr;
+}
+
+static void ep_fifo_free(struct mtu3_ep *mep)
+{
+ struct mtu3_fifo_info *fifo = mep->fifo;
+ u32 addr = mep->fifo_addr;
+ u32 bit;
+
+ if (unlikely(addr < fifo->base))
+ return;
+
+ bit = (addr - fifo->base) / mep->fifo_size;
+ generic_clear_bit(bit, fifo->bitmap);
+ mep->fifo_size = 0;
+ mep->fifo_seg_size = 0;
+
+ dev_dbg(mep->mtu->dev, "%s size:%#x/%#x, bit: %d\n",
+ __func__, mep->fifo_seg_size, mep->fifo_size, bit);
+}
+
+/* enable/disable U3D SS function */
+static inline void mtu3_ss_func_set(struct mtu3 *mtu, bool enable)
+{
+ /* If usb3_en==0, LTSSM will go to SS.Disable state */
+ if (enable)
+ mtu3_setbits(mtu->mac_base, U3D_USB3_CONFIG, USB3_EN);
+ else
+ mtu3_clrbits(mtu->mac_base, U3D_USB3_CONFIG, USB3_EN);
+
+ dev_dbg(mtu->dev, "USB3_EN = %d\n", !!enable);
+}
+
+/* set/clear U3D HS device soft connect */
+static inline void mtu3_hs_softconn_set(struct mtu3 *mtu, bool enable)
+{
+ if (enable) {
+ mtu3_setbits(mtu->mac_base, U3D_POWER_MANAGEMENT,
+ SOFT_CONN | SUSPENDM_ENABLE);
+ } else {
+ mtu3_clrbits(mtu->mac_base, U3D_POWER_MANAGEMENT,
+ SOFT_CONN | SUSPENDM_ENABLE);
+ }
+ dev_dbg(mtu->dev, "SOFTCONN = %d\n", !!enable);
+}
+
+/* only port0 of U2/U3 supports device mode */
+static int mtu3_device_enable(struct mtu3 *mtu)
+{
+ void __iomem *ibase = mtu->ippc_base;
+ u32 check_clk = 0;
+
+ mtu3_clrbits(ibase, U3D_SSUSB_IP_PW_CTRL2, SSUSB_IP_DEV_PDN);
+
+ if (mtu->is_u3_ip) {
+ check_clk = SSUSB_U3_MAC_RST_B_STS;
+ mtu3_clrbits(ibase, SSUSB_U3_CTRL(0),
+ (SSUSB_U3_PORT_DIS | SSUSB_U3_PORT_PDN |
+ SSUSB_U3_PORT_HOST_SEL));
+ }
+ mtu3_clrbits(ibase, SSUSB_U2_CTRL(0),
+ (SSUSB_U2_PORT_DIS | SSUSB_U2_PORT_PDN |
+ SSUSB_U2_PORT_HOST_SEL));
+
+ return ssusb_check_clocks(mtu->ssusb, check_clk);
+}
+
+static void mtu3_device_disable(struct mtu3 *mtu)
+{
+ void __iomem *ibase = mtu->ippc_base;
+
+ if (mtu->is_u3_ip)
+ mtu3_setbits(ibase, SSUSB_U3_CTRL(0),
+ (SSUSB_U3_PORT_DIS | SSUSB_U3_PORT_PDN));
+
+ mtu3_setbits(ibase, SSUSB_U2_CTRL(0),
+ SSUSB_U2_PORT_DIS | SSUSB_U2_PORT_PDN);
+
+ mtu3_setbits(ibase, U3D_SSUSB_IP_PW_CTRL2, SSUSB_IP_DEV_PDN);
+}
+
+/* reset U3D's device module. */
+static void mtu3_device_reset(struct mtu3 *mtu)
+{
+ void __iomem *ibase = mtu->ippc_base;
+
+ mtu3_setbits(ibase, U3D_SSUSB_DEV_RST_CTRL, SSUSB_DEV_SW_RST);
+ udelay(1);
+ mtu3_clrbits(ibase, U3D_SSUSB_DEV_RST_CTRL, SSUSB_DEV_SW_RST);
+}
+
+static void mtu3_intr_status_clear(struct mtu3 *mtu)
+{
+ void __iomem *mbase = mtu->mac_base;
+
+ /* Clear EP0 and Tx/Rx EPn interrupts status */
+ mtu3_writel(mbase, U3D_EPISR, ~0x0);
+ /* Clear U2 USB common interrupts status */
+ mtu3_writel(mbase, U3D_COMMON_USB_INTR, ~0x0);
+ /* Clear U3 LTSSM interrupts status */
+ mtu3_writel(mbase, U3D_LTSSM_INTR, ~0x0);
+ /* Clear speed change interrupt status */
+ mtu3_writel(mbase, U3D_DEV_LINK_INTR, ~0x0);
+ /* Clear QMU interrupt status */
+ mtu3_writel(mbase, U3D_QISAR0, ~0x0);
+}
+
+/* disable all interrupts */
+static void mtu3_intr_disable(struct mtu3 *mtu)
+{
+ /* Disable level 1 interrupts */
+ mtu3_writel(mtu->mac_base, U3D_LV1IECR, ~0x0);
+ /* Disable endpoint interrupts */
+ mtu3_writel(mtu->mac_base, U3D_EPIECR, ~0x0);
+ mtu3_intr_status_clear(mtu);
+}
+
+/* enable system global interrupt */
+static void mtu3_intr_enable(struct mtu3 *mtu)
+{
+ void __iomem *mbase = mtu->mac_base;
+ u32 value;
+
+ /*Enable level 1 interrupts (BMU, QMU, MAC3, DMA, MAC2, EPCTL) */
+ value = BMU_INTR | QMU_INTR | MAC3_INTR | MAC2_INTR | EP_CTRL_INTR;
+ mtu3_writel(mbase, U3D_LV1IESR, value);
+
+ /* Enable U2 common USB interrupts */
+ value = SUSPEND_INTR | RESUME_INTR | RESET_INTR;
+ mtu3_writel(mbase, U3D_COMMON_USB_INTR_ENABLE, value);
+
+ if (mtu->is_u3_ip) {
+ /* Enable U3 LTSSM interrupts */
+ value = HOT_RST_INTR | WARM_RST_INTR |
+ ENTER_U3_INTR | EXIT_U3_INTR;
+ mtu3_writel(mbase, U3D_LTSSM_INTR_ENABLE, value);
+ }
+
+ /* Enable QMU interrupts. */
+ value = TXQ_CSERR_INT | TXQ_LENERR_INT | RXQ_CSERR_INT |
+ RXQ_LENERR_INT | RXQ_ZLPERR_INT;
+ mtu3_writel(mbase, U3D_QIESR1, value);
+
+ /* Enable speed change interrupt */
+ mtu3_writel(mbase, U3D_DEV_LINK_INTR_ENABLE, SSUSB_DEV_SPEED_CHG_INTR);
+}
+
+void mtu3_set_speed(struct mtu3 *mtu, enum usb_device_speed speed)
+{
+ void __iomem *mbase = mtu->mac_base;
+
+ if (speed > mtu->max_speed)
+ speed = mtu->max_speed;
+
+ switch (speed) {
+ case USB_SPEED_FULL:
+ /* disable U3 SS function */
+ mtu3_clrbits(mbase, U3D_USB3_CONFIG, USB3_EN);
+ /* disable HS function */
+ mtu3_clrbits(mbase, U3D_POWER_MANAGEMENT, HS_ENABLE);
+ break;
+ case USB_SPEED_HIGH:
+ mtu3_clrbits(mbase, U3D_USB3_CONFIG, USB3_EN);
+ /* HS/FS detected by HW */
+ mtu3_setbits(mbase, U3D_POWER_MANAGEMENT, HS_ENABLE);
+ break;
+ case USB_SPEED_SUPER:
+ mtu3_clrbits(mtu->ippc_base, SSUSB_U3_CTRL(0),
+ SSUSB_U3_PORT_SSP_SPEED);
+ break;
+ case USB_SPEED_SUPER_PLUS:
+ mtu3_setbits(mtu->ippc_base, SSUSB_U3_CTRL(0),
+ SSUSB_U3_PORT_SSP_SPEED);
+ break;
+ default:
+ dev_err(mtu->dev, "invalid speed: %d\n", speed);
+ return;
+ }
+
+ mtu->speed = speed;
+ dev_dbg(mtu->dev, "set speed: %s\n", usb_speed_string(mtu->speed));
+}
+
+/* reset: u2 - data toggle, u3 - SeqN, flow control status etc */
+static void mtu3_ep_reset(struct mtu3_ep *mep)
+{
+ struct mtu3 *mtu = mep->mtu;
+ u32 rst_bit = EP_RST(mep->is_in, mep->epnum);
+
+ mtu3_setbits(mtu->mac_base, U3D_EP_RST, rst_bit);
+ mtu3_clrbits(mtu->mac_base, U3D_EP_RST, rst_bit);
+}
+
+/* set/clear the stall and toggle bits for non-ep0 */
+void mtu3_ep_stall_set(struct mtu3_ep *mep, bool set)
+{
+ struct mtu3 *mtu = mep->mtu;
+ void __iomem *mbase = mtu->mac_base;
+ u8 epnum = mep->epnum;
+ u32 csr;
+
+ if (mep->is_in) { /* TX */
+ csr = mtu3_readl(mbase, MU3D_EP_TXCR0(epnum)) & TX_W1C_BITS;
+ if (set)
+ csr |= TX_SENDSTALL;
+ else
+ csr = (csr & (~TX_SENDSTALL)) | TX_SENTSTALL;
+ mtu3_writel(mbase, MU3D_EP_TXCR0(epnum), csr);
+ } else { /* RX */
+ csr = mtu3_readl(mbase, MU3D_EP_RXCR0(epnum)) & RX_W1C_BITS;
+ if (set)
+ csr |= RX_SENDSTALL;
+ else
+ csr = (csr & (~RX_SENDSTALL)) | RX_SENTSTALL;
+ mtu3_writel(mbase, MU3D_EP_RXCR0(epnum), csr);
+ }
+
+ if (!set) {
+ mtu3_ep_reset(mep);
+ mep->flags &= ~MTU3_EP_STALL;
+ } else {
+ mep->flags |= MTU3_EP_STALL;
+ }
+
+ dev_dbg(mtu->dev, "%s: %s\n", mep->name,
+ set ? "SEND STALL" : "CLEAR STALL, with EP RESET");
+}
+
+void mtu3_dev_on_off(struct mtu3 *mtu, int is_on)
+{
+ if (mtu->is_u3_ip && mtu->speed >= USB_SPEED_SUPER)
+ mtu3_ss_func_set(mtu, is_on);
+ else
+ mtu3_hs_softconn_set(mtu, is_on);
+
+ dev_info(mtu->dev, "gadget (%s) pullup D%s\n",
+ usb_speed_string(mtu->speed), is_on ? "+" : "-");
+}
+
+void mtu3_start(struct mtu3 *mtu)
+{
+ void __iomem *mbase = mtu->mac_base;
+
+ dev_dbg(mtu->dev, "%s devctl 0x%x\n", __func__,
+ mtu3_readl(mbase, U3D_DEVICE_CONTROL));
+
+ /* Initialize the default interrupts */
+ mtu3_intr_enable(mtu);
+ mtu->is_active = 1;
+
+ if (mtu->softconnect)
+ mtu3_dev_on_off(mtu, 1);
+}
+
+void mtu3_stop(struct mtu3 *mtu)
+{
+ dev_dbg(mtu->dev, "%s\n", __func__);
+
+ mtu3_intr_disable(mtu);
+
+ if (mtu->softconnect)
+ mtu3_dev_on_off(mtu, 0);
+
+ mtu->is_active = 0;
+}
+
+/* for non-ep0 */
+int mtu3_config_ep(struct mtu3 *mtu, struct mtu3_ep *mep,
+ int interval, int burst, int mult)
+{
+ void __iomem *mbase = mtu->mac_base;
+ bool gen2cp = mtu->gen2cp;
+ int epnum = mep->epnum;
+ u32 csr0, csr1, csr2;
+ int fifo_sgsz, fifo_addr;
+ int num_pkts;
+
+ fifo_addr = ep_fifo_alloc(mep, mep->maxp);
+ if (fifo_addr < 0) {
+ dev_err(mtu->dev, "alloc ep fifo failed(%d)\n", mep->maxp);
+ return -ENOMEM;
+ }
+ fifo_sgsz = ilog2(mep->fifo_seg_size);
+ dev_dbg(mtu->dev, "%s fifosz: %x(%x/%x)\n", __func__, fifo_sgsz,
+ mep->fifo_seg_size, mep->fifo_size);
+
+ if (mep->is_in) {
+ csr0 = TX_TXMAXPKTSZ(mep->maxp);
+ csr0 |= TX_DMAREQEN;
+
+ num_pkts = (burst + 1) * (mult + 1) - 1;
+ csr1 = TX_SS_BURST(burst) | TX_SLOT(mep->slot);
+ csr1 |= TX_MAX_PKT(gen2cp, num_pkts) | TX_MULT(gen2cp, mult);
+
+ csr2 = TX_FIFOADDR(fifo_addr >> 4);
+ csr2 |= TX_FIFOSEGSIZE(fifo_sgsz);
+
+ switch (mep->type) {
+ case USB_ENDPOINT_XFER_BULK:
+ csr1 |= TX_TYPE(TYPE_BULK);
+ break;
+ case USB_ENDPOINT_XFER_ISOC:
+ csr1 |= TX_TYPE(TYPE_ISO);
+ csr2 |= TX_BINTERVAL(interval);
+ break;
+ case USB_ENDPOINT_XFER_INT:
+ csr1 |= TX_TYPE(TYPE_INT);
+ csr2 |= TX_BINTERVAL(interval);
+ break;
+ }
+
+ /* Enable QMU Done interrupt */
+ mtu3_setbits(mbase, U3D_QIESR0, QMU_TX_DONE_INT(epnum));
+
+ mtu3_writel(mbase, MU3D_EP_TXCR0(epnum), csr0);
+ mtu3_writel(mbase, MU3D_EP_TXCR1(epnum), csr1);
+ mtu3_writel(mbase, MU3D_EP_TXCR2(epnum), csr2);
+
+ dev_dbg(mtu->dev, "U3D_TX%d CSR0:%#x, CSR1:%#x, CSR2:%#x\n",
+ epnum, mtu3_readl(mbase, MU3D_EP_TXCR0(epnum)),
+ mtu3_readl(mbase, MU3D_EP_TXCR1(epnum)),
+ mtu3_readl(mbase, MU3D_EP_TXCR2(epnum)));
+ } else {
+ csr0 = RX_RXMAXPKTSZ(mep->maxp);
+ csr0 |= RX_DMAREQEN;
+
+ num_pkts = (burst + 1) * (mult + 1) - 1;
+ csr1 = RX_SS_BURST(burst) | RX_SLOT(mep->slot);
+ csr1 |= RX_MAX_PKT(gen2cp, num_pkts) | RX_MULT(gen2cp, mult);
+
+ csr2 = RX_FIFOADDR(fifo_addr >> 4);
+ csr2 |= RX_FIFOSEGSIZE(fifo_sgsz);
+
+ switch (mep->type) {
+ case USB_ENDPOINT_XFER_BULK:
+ csr1 |= RX_TYPE(TYPE_BULK);
+ break;
+ case USB_ENDPOINT_XFER_ISOC:
+ csr1 |= RX_TYPE(TYPE_ISO);
+ csr2 |= RX_BINTERVAL(interval);
+ break;
+ case USB_ENDPOINT_XFER_INT:
+ csr1 |= RX_TYPE(TYPE_INT);
+ csr2 |= RX_BINTERVAL(interval);
+ break;
+ }
+
+ /*Enable QMU Done interrupt */
+ mtu3_setbits(mbase, U3D_QIESR0, QMU_RX_DONE_INT(epnum));
+
+ mtu3_writel(mbase, MU3D_EP_RXCR0(epnum), csr0);
+ mtu3_writel(mbase, MU3D_EP_RXCR1(epnum), csr1);
+ mtu3_writel(mbase, MU3D_EP_RXCR2(epnum), csr2);
+
+ dev_dbg(mtu->dev, "U3D_RX%d CSR0:%#x, CSR1:%#x, CSR2:%#x\n",
+ epnum, mtu3_readl(mbase, MU3D_EP_RXCR0(epnum)),
+ mtu3_readl(mbase, MU3D_EP_RXCR1(epnum)),
+ mtu3_readl(mbase, MU3D_EP_RXCR2(epnum)));
+ }
+
+ dev_dbg(mtu->dev, "csr0:%#x, csr1:%#x, csr2:%#x\n", csr0, csr1, csr2);
+ dev_dbg(mtu->dev, "%s: %s, fifo-addr:%#x, fifo-size:%#x(%#x/%#x)\n",
+ __func__, mep->name, mep->fifo_addr, mep->fifo_size,
+ fifo_sgsz, mep->fifo_seg_size);
+
+ return 0;
+}
+
+/* for non-ep0 */
+void mtu3_deconfig_ep(struct mtu3 *mtu, struct mtu3_ep *mep)
+{
+ void __iomem *mbase = mtu->mac_base;
+ int epnum = mep->epnum;
+
+ if (mep->is_in) {
+ mtu3_writel(mbase, MU3D_EP_TXCR0(epnum), 0);
+ mtu3_writel(mbase, MU3D_EP_TXCR1(epnum), 0);
+ mtu3_writel(mbase, MU3D_EP_TXCR2(epnum), 0);
+ mtu3_setbits(mbase, U3D_QIECR0, QMU_TX_DONE_INT(epnum));
+ } else {
+ mtu3_writel(mbase, MU3D_EP_RXCR0(epnum), 0);
+ mtu3_writel(mbase, MU3D_EP_RXCR1(epnum), 0);
+ mtu3_writel(mbase, MU3D_EP_RXCR2(epnum), 0);
+ mtu3_setbits(mbase, U3D_QIECR0, QMU_RX_DONE_INT(epnum));
+ }
+
+ mtu3_ep_reset(mep);
+ ep_fifo_free(mep);
+
+ dev_dbg(mtu->dev, "%s: %s\n", __func__, mep->name);
+}
+
+/*
+ * Two scenarios:
+ * 1. when device IP supports SS, the fifo of EP0, TX EPs, RX EPs
+ * are separated;
+ * 2. when supports only HS, the fifo is shared for all EPs, and
+ * the capability registers of @EPNTXFFSZ or @EPNRXFFSZ indicate
+ * the total fifo size of non-ep0, and ep0's is fixed to 64B,
+ * so the total fifo size is 64B + @EPNTXFFSZ;
+ * Due to the first 64B should be reserved for EP0, non-ep0's fifo
+ * starts from offset 64 and are divided into two equal parts for
+ * TX or RX EPs for simplification.
+ */
+static void get_ep_fifo_config(struct mtu3 *mtu)
+{
+ struct mtu3_fifo_info *tx_fifo;
+ struct mtu3_fifo_info *rx_fifo;
+ u32 fifosize;
+
+ if (mtu->is_u3_ip) {
+ fifosize = mtu3_readl(mtu->mac_base, U3D_CAP_EPNTXFFSZ);
+ tx_fifo = &mtu->tx_fifo;
+ tx_fifo->base = 0;
+ tx_fifo->limit = fifosize / MTU3_U3IP_EP_FIFO_UNIT;
+ bitmap_zero(tx_fifo->bitmap, MTU3_FIFO_BIT_SIZE);
+
+ fifosize = mtu3_readl(mtu->mac_base, U3D_CAP_EPNRXFFSZ);
+ rx_fifo = &mtu->rx_fifo;
+ rx_fifo->base = 0;
+ rx_fifo->limit = fifosize / MTU3_U3IP_EP_FIFO_UNIT;
+ bitmap_zero(rx_fifo->bitmap, MTU3_FIFO_BIT_SIZE);
+ mtu->slot = MTU3_U3_IP_SLOT_DEFAULT;
+ } else {
+ fifosize = mtu3_readl(mtu->mac_base, U3D_CAP_EPNTXFFSZ);
+ tx_fifo = &mtu->tx_fifo;
+ tx_fifo->base = MTU3_U2_IP_EP0_FIFO_SIZE;
+ tx_fifo->limit = (fifosize / MTU3_U2IP_EP_FIFO_UNIT) >> 1;
+ bitmap_zero(tx_fifo->bitmap, MTU3_FIFO_BIT_SIZE);
+
+ rx_fifo = &mtu->rx_fifo;
+ rx_fifo->base = tx_fifo->base +
+ tx_fifo->limit * MTU3_U2IP_EP_FIFO_UNIT;
+ rx_fifo->limit = tx_fifo->limit;
+ bitmap_zero(rx_fifo->bitmap, MTU3_FIFO_BIT_SIZE);
+ mtu->slot = MTU3_U2_IP_SLOT_DEFAULT;
+ }
+
+ dev_dbg(mtu->dev, "%s, TX: base-%d, limit-%d; RX: base-%d, limit-%d\n",
+ __func__, tx_fifo->base, tx_fifo->limit,
+ rx_fifo->base, rx_fifo->limit);
+}
+
+void mtu3_ep0_setup(struct mtu3 *mtu)
+{
+ u32 maxpacket = mtu->g.ep0->maxpacket;
+ u32 csr;
+
+ dev_dbg(mtu->dev, "%s maxpacket: %d\n", __func__, maxpacket);
+
+ csr = mtu3_readl(mtu->mac_base, U3D_EP0CSR);
+ csr &= ~EP0_MAXPKTSZ_MSK;
+ csr |= EP0_MAXPKTSZ(maxpacket);
+ csr &= EP0_W1C_BITS;
+ mtu3_writel(mtu->mac_base, U3D_EP0CSR, csr);
+
+ /* Enable EP0 interrupt */
+ mtu3_writel(mtu->mac_base, U3D_EPIESR, EP0ISR | SETUPENDISR);
+}
+
+static int mtu3_mem_alloc(struct mtu3 *mtu)
+{
+ void __iomem *mbase = mtu->mac_base;
+ struct mtu3_ep *ep_array;
+ int in_ep_num, out_ep_num;
+ u32 cap_epinfo;
+ int i;
+
+ cap_epinfo = mtu3_readl(mbase, U3D_CAP_EPINFO);
+ in_ep_num = CAP_TX_EP_NUM(cap_epinfo);
+ out_ep_num = CAP_RX_EP_NUM(cap_epinfo);
+
+ dev_info(mtu->dev, "fifosz/epnum: Tx=%#x/%d, Rx=%#x/%d\n",
+ mtu3_readl(mbase, U3D_CAP_EPNTXFFSZ), in_ep_num,
+ mtu3_readl(mbase, U3D_CAP_EPNRXFFSZ), out_ep_num);
+
+ /* one for ep0, another is reserved */
+ mtu->num_eps = min(in_ep_num, out_ep_num) + 1;
+ ep_array = kcalloc(mtu->num_eps * 2, sizeof(*ep_array), GFP_KERNEL);
+ if (!ep_array)
+ return -ENOMEM;
+
+ mtu->ep_array = ep_array;
+ mtu->in_eps = ep_array;
+ mtu->out_eps = &ep_array[mtu->num_eps];
+ /* ep0 uses in_eps[0], out_eps[0] is reserved */
+ mtu->ep0 = mtu->in_eps;
+ mtu->ep0->mtu = mtu;
+ mtu->ep0->epnum = 0;
+
+ for (i = 1; i < mtu->num_eps; i++) {
+ struct mtu3_ep *mep = mtu->in_eps + i;
+
+ mep->fifo = &mtu->tx_fifo;
+ mep = mtu->out_eps + i;
+ mep->fifo = &mtu->rx_fifo;
+ }
+
+ get_ep_fifo_config(mtu);
+ mtu3_qmu_init(mtu);
+
+ return 0;
+}
+
+static void mtu3_mem_free(struct mtu3 *mtu)
+{
+ mtu3_qmu_exit(mtu);
+ kfree(mtu->ep_array);
+}
+
+static void mtu3_regs_init(struct mtu3 *mtu)
+{
+ void __iomem *mbase = mtu->mac_base;
+
+ /* be sure interrupts are disabled before registration of ISR */
+ mtu3_intr_disable(mtu);
+
+ if (mtu->is_u3_ip) {
+ /* disable LGO_U1/U2 by default */
+ mtu3_clrbits(mbase, U3D_LINK_POWER_CONTROL,
+ SW_U1_REQUEST_ENABLE | SW_U2_REQUEST_ENABLE);
+ /* enable accept LGO_U1/U2 link command from host */
+ mtu3_setbits(mbase, U3D_LINK_POWER_CONTROL,
+ SW_U1_ACCEPT_ENABLE | SW_U2_ACCEPT_ENABLE);
+ /* device responses to u3_exit from host automatically */
+ mtu3_clrbits(mbase, U3D_LTSSM_CTRL, SOFT_U3_EXIT_EN);
+ /* automatically build U2 link when U3 detect fail */
+ mtu3_setbits(mbase, U3D_USB2_TEST_MODE, U2U3_AUTO_SWITCH);
+ /* auto clear SOFT_CONN when clear USB3_EN if work as HS */
+ mtu3_setbits(mbase, U3D_U3U2_SWITCH_CTRL, SOFTCON_CLR_AUTO_EN);
+ }
+
+ /* delay about 0.1us from detecting reset to send chirp-K */
+ mtu3_clrbits(mbase, U3D_LINK_RESET_INFO, WTCHRP_MSK);
+ /* U2/U3 detected by HW */
+ mtu3_writel(mbase, U3D_DEVICE_CONF, 0);
+ /* enable automatical HWRW from L1 */
+ mtu3_setbits(mbase, U3D_POWER_MANAGEMENT, LPM_HRWE);
+
+ mtu3_set_speed(mtu, mtu->max_speed);
+ ssusb_set_force_mode(mtu->ssusb, MTU3_DR_FORCE_DEVICE);
+
+ if (mtu->force_vbus)
+ mtu3_setbits(mbase, U3D_MISC_CTRL, VBUS_FRC_EN | VBUS_ON);
+ else /* vbus detected by HW */
+ mtu3_clrbits(mbase, U3D_MISC_CTRL, VBUS_FRC_EN | VBUS_ON);
+}
+
+static irqreturn_t mtu3_link_isr(struct mtu3 *mtu)
+{
+ void __iomem *mbase = mtu->mac_base;
+ enum usb_device_speed udev_speed;
+ u32 maxpkt = 64;
+ u32 link;
+ u32 speed;
+
+ link = mtu3_readl(mbase, U3D_DEV_LINK_INTR);
+ link &= mtu3_readl(mbase, U3D_DEV_LINK_INTR_ENABLE);
+ mtu3_writel(mbase, U3D_DEV_LINK_INTR, link); /* W1C */
+ dev_dbg(mtu->dev, "=== LINK[%x] ===\n", link);
+
+ if (!(link & SSUSB_DEV_SPEED_CHG_INTR))
+ return IRQ_NONE;
+
+ speed = SSUSB_DEV_SPEED(mtu3_readl(mbase, U3D_DEVICE_CONF));
+
+ switch (speed) {
+ case MTU3_SPEED_FULL:
+ udev_speed = USB_SPEED_FULL;
+ /*BESLCK = 4 < BESLCK_U3 = 10 < BESLDCK = 15 */
+ mtu3_writel(mbase, U3D_USB20_LPM_PARAMETER, LPM_BESLDCK(0xf)
+ | LPM_BESLCK(4) | LPM_BESLCK_U3(0xa));
+ mtu3_setbits(mbase, U3D_POWER_MANAGEMENT,
+ LPM_BESL_STALL | LPM_BESLD_STALL);
+ break;
+ case MTU3_SPEED_HIGH:
+ udev_speed = USB_SPEED_HIGH;
+ /*BESLCK = 4 < BESLCK_U3 = 10 < BESLDCK = 15 */
+ mtu3_writel(mbase, U3D_USB20_LPM_PARAMETER, LPM_BESLDCK(0xf)
+ | LPM_BESLCK(4) | LPM_BESLCK_U3(0xa));
+ mtu3_setbits(mbase, U3D_POWER_MANAGEMENT,
+ LPM_BESL_STALL | LPM_BESLD_STALL);
+ break;
+ case MTU3_SPEED_SUPER:
+ udev_speed = USB_SPEED_SUPER;
+ maxpkt = 512;
+ break;
+ case MTU3_SPEED_SUPER_PLUS:
+ udev_speed = USB_SPEED_SUPER_PLUS;
+ maxpkt = 512;
+ break;
+ default:
+ udev_speed = USB_SPEED_UNKNOWN;
+ break;
+ }
+ dev_dbg(mtu->dev, "%s: %s\n", __func__, usb_speed_string(udev_speed));
+
+ mtu->g.speed = udev_speed;
+ mtu->g.ep0->maxpacket = maxpkt;
+ mtu->ep0_state = MU3D_EP0_STATE_SETUP;
+
+ if (udev_speed == USB_SPEED_UNKNOWN)
+ mtu3_gadget_disconnect(mtu);
+ else
+ mtu3_ep0_setup(mtu);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t mtu3_u3_ltssm_isr(struct mtu3 *mtu)
+{
+ void __iomem *mbase = mtu->mac_base;
+ u32 ltssm;
+
+ ltssm = mtu3_readl(mbase, U3D_LTSSM_INTR);
+ ltssm &= mtu3_readl(mbase, U3D_LTSSM_INTR_ENABLE);
+ mtu3_writel(mbase, U3D_LTSSM_INTR, ltssm); /* W1C */
+ dev_dbg(mtu->dev, "=== LTSSM[%x] ===\n", ltssm);
+
+ if (ltssm & (HOT_RST_INTR | WARM_RST_INTR))
+ mtu3_gadget_reset(mtu);
+
+ if (ltssm & VBUS_FALL_INTR) {
+ mtu3_ss_func_set(mtu, false);
+ mtu3_gadget_reset(mtu);
+ }
+
+ if (ltssm & VBUS_RISE_INTR)
+ mtu3_ss_func_set(mtu, true);
+
+ if (ltssm & EXIT_U3_INTR)
+ mtu3_gadget_resume(mtu);
+
+ if (ltssm & ENTER_U3_INTR)
+ mtu3_gadget_suspend(mtu);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t mtu3_u2_common_isr(struct mtu3 *mtu)
+{
+ void __iomem *mbase = mtu->mac_base;
+ u32 u2comm;
+
+ u2comm = mtu3_readl(mbase, U3D_COMMON_USB_INTR);
+ u2comm &= mtu3_readl(mbase, U3D_COMMON_USB_INTR_ENABLE);
+ mtu3_writel(mbase, U3D_COMMON_USB_INTR, u2comm); /* W1C */
+ dev_dbg(mtu->dev, "=== U2COMM[%x] ===\n", u2comm);
+
+ if (u2comm & SUSPEND_INTR)
+ mtu3_gadget_suspend(mtu);
+
+ if (u2comm & RESUME_INTR)
+ mtu3_gadget_resume(mtu);
+
+ if (u2comm & RESET_INTR)
+ mtu3_gadget_reset(mtu);
+
+ return IRQ_HANDLED;
+}
+
+irqreturn_t mtu3_irq(int irq, void *data)
+{
+ struct mtu3 *mtu = (struct mtu3 *)data;
+ unsigned long flags;
+ u32 level1;
+
+ spin_lock_irqsave(&mtu->lock, flags);
+
+ /* U3D_LV1ISR is RU */
+ level1 = mtu3_readl(mtu->mac_base, U3D_LV1ISR);
+ level1 &= mtu3_readl(mtu->mac_base, U3D_LV1IER);
+
+ if (level1 & EP_CTRL_INTR)
+ mtu3_link_isr(mtu);
+
+ if (level1 & MAC2_INTR)
+ mtu3_u2_common_isr(mtu);
+
+ if (level1 & MAC3_INTR)
+ mtu3_u3_ltssm_isr(mtu);
+
+ if (level1 & BMU_INTR)
+ mtu3_ep0_isr(mtu);
+
+ if (level1 & QMU_INTR)
+ mtu3_qmu_isr(mtu);
+
+ spin_unlock_irqrestore(&mtu->lock, flags);
+
+ return IRQ_HANDLED;
+}
+
+static void mtu3_check_params(struct mtu3 *mtu)
+{
+ /* check the max_speed parameter */
+ switch (mtu->max_speed) {
+ case USB_SPEED_FULL:
+ case USB_SPEED_HIGH:
+ case USB_SPEED_SUPER:
+ case USB_SPEED_SUPER_PLUS:
+ break;
+ default:
+ dev_err(mtu->dev, "invalid max_speed: %d\n", mtu->max_speed);
+ /* fall through */
+ case USB_SPEED_UNKNOWN:
+ /* default as SS */
+ mtu->max_speed = USB_SPEED_SUPER;
+ break;
+ }
+
+ if (!mtu->is_u3_ip && (mtu->max_speed > USB_SPEED_HIGH))
+ mtu->max_speed = USB_SPEED_HIGH;
+
+ mtu->speed = mtu->max_speed;
+
+ dev_info(mtu->dev, "max_speed: %s\n", usb_speed_string(mtu->speed));
+}
+
+static int mtu3_hw_init(struct mtu3 *mtu)
+{
+ u32 value;
+ int ret;
+
+ value = mtu3_readl(mtu->ippc_base, U3D_SSUSB_IP_TRUNK_VERS);
+ mtu->hw_version = IP_TRUNK_VERS(value);
+ mtu->gen2cp = !!(mtu->hw_version >= MTU3_TRUNK_VERS_1003);
+
+ value = mtu3_readl(mtu->ippc_base, U3D_SSUSB_IP_DEV_CAP);
+ mtu->is_u3_ip = !!SSUSB_IP_DEV_U3_PORT_NUM(value);
+
+ dev_info(mtu->dev, "IP version 0x%x(%s IP)\n", mtu->hw_version,
+ mtu->is_u3_ip ? "U3" : "U2");
+
+ mtu3_check_params(mtu);
+
+ mtu3_device_reset(mtu);
+
+ ret = mtu3_device_enable(mtu);
+ if (ret) {
+ dev_err(mtu->dev, "device enable failed %d\n", ret);
+ return ret;
+ }
+
+ ret = mtu3_mem_alloc(mtu);
+ if (ret)
+ return ret;
+
+ mtu3_regs_init(mtu);
+
+ return 0;
+}
+
+static void mtu3_hw_exit(struct mtu3 *mtu)
+{
+ mtu3_device_disable(mtu);
+ mtu3_mem_free(mtu);
+}
+
+int ssusb_gadget_init(struct ssusb_mtk *ssusb)
+{
+ struct mtu3 *mtu = ssusb->u3d;
+ struct udevice *dev = mtu->dev;
+ int ret = -ENOMEM;
+
+ spin_lock_init(&mtu->lock);
+ mtu->ippc_base = ssusb->ippc_base;
+ mtu->mac_base = ssusb->mac_base;
+ mtu->ssusb = ssusb;
+ mtu->max_speed = usb_get_maximum_speed(dev->node);
+ mtu->force_vbus = dev_read_bool(dev, "mediatek,force-vbus");
+
+ ret = mtu3_hw_init(mtu);
+ if (ret) {
+ dev_err(dev, "mtu3 hw init failed:%d\n", ret);
+ return ret;
+ }
+
+ ret = mtu3_gadget_setup(mtu);
+ if (ret) {
+ dev_err(dev, "mtu3 gadget init failed:%d\n", ret);
+ goto gadget_err;
+ }
+
+ dev_info(dev, "%s() done...\n", __func__);
+
+ return 0;
+
+gadget_err:
+ mtu3_hw_exit(mtu);
+ ssusb->u3d = NULL;
+ dev_err(dev, "%s() fail...\n", __func__);
+
+ return ret;
+}
+
+void ssusb_gadget_exit(struct ssusb_mtk *ssusb)
+{
+ struct mtu3 *mtu = ssusb->u3d;
+
+ mtu3_gadget_cleanup(mtu);
+ mtu3_hw_exit(mtu);
+}
diff --git a/drivers/usb/mtu3/mtu3_dr.h b/drivers/usb/mtu3/mtu3_dr.h
new file mode 100644
index 00000000000..ec0e50c04ca
--- /dev/null
+++ b/drivers/usb/mtu3/mtu3_dr.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * mtu3_dr.h - dual role switch and host glue layer header
+ *
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * Author: Chunfeng Yun <chunfeng.yun@mediatek.com>
+ */
+
+#ifndef _MTU3_DR_H_
+#define _MTU3_DR_H_
+
+#if IS_ENABLED(CONFIG_USB_MTU3_HOST)
+
+int ssusb_host_init(struct ssusb_mtk *ssusb);
+void ssusb_host_exit(struct ssusb_mtk *ssusb);
+
+#else
+
+static inline int ssusb_host_init(struct ssusb_mtk *ssusb)
+{
+ return 0;
+}
+
+static inline void ssusb_host_exit(struct ssusb_mtk *ssusb)
+{}
+
+#endif
+
+#if IS_ENABLED(CONFIG_USB_MTU3_GADGET)
+int ssusb_gadget_init(struct ssusb_mtk *ssusb);
+void ssusb_gadget_exit(struct ssusb_mtk *ssusb);
+irqreturn_t mtu3_irq(int irq, void *data);
+#else
+static inline int ssusb_gadget_init(struct ssusb_mtk *ssusb)
+{
+ return 0;
+}
+
+static inline void ssusb_gadget_exit(struct ssusb_mtk *ssusb)
+{}
+
+static inline irqreturn_t mtu3_irq(int irq, void *data)
+{
+ return IRQ_NONE;
+}
+#endif
+
+void ssusb_set_force_mode(struct ssusb_mtk *ssusb,
+ enum mtu3_dr_force_mode mode);
+
+#endif /* _MTU3_DR_H_ */
diff --git a/drivers/usb/mtu3/mtu3_gadget.c b/drivers/usb/mtu3/mtu3_gadget.c
new file mode 100644
index 00000000000..027b7e61113
--- /dev/null
+++ b/drivers/usb/mtu3/mtu3_gadget.c
@@ -0,0 +1,686 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * mtu3_gadget.c - MediaTek usb3 DRD peripheral support
+ *
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * Author: Chunfeng Yun <chunfeng.yun@mediatek.com>
+ */
+
+#include "mtu3.h"
+
+void mtu3_req_complete(struct mtu3_ep *mep,
+ struct usb_request *req, int status)
+__releases(mep->mtu->lock)
+__acquires(mep->mtu->lock)
+{
+ struct mtu3_request *mreq = to_mtu3_request(req);
+ struct mtu3 *mtu = mreq->mtu;
+
+ list_del(&mreq->list);
+ if (req->status == -EINPROGRESS)
+ req->status = status;
+
+ spin_unlock(&mtu->lock);
+
+ /* ep0 makes use of PIO, needn't unmap it */
+ if (mep->epnum)
+ usb_gadget_unmap_request(&mtu->g, req, mep->is_in);
+
+ dev_dbg(mtu->dev, "%s complete req: %p, sts %d, %d/%d\n",
+ mep->name, req, req->status, req->actual, req->length);
+
+ usb_gadget_giveback_request(&mep->ep, req);
+ spin_lock(&mtu->lock);
+}
+
+static void nuke(struct mtu3_ep *mep, const int status)
+{
+ struct mtu3_request *mreq = NULL;
+
+ if (list_empty(&mep->req_list))
+ return;
+
+ dev_dbg(mep->mtu->dev, "abort %s's req: sts %d\n", mep->name, status);
+
+ /* exclude EP0 */
+ if (mep->epnum)
+ mtu3_qmu_flush(mep);
+
+ while (!list_empty(&mep->req_list)) {
+ mreq = list_first_entry(&mep->req_list,
+ struct mtu3_request, list);
+ mtu3_req_complete(mep, &mreq->request, status);
+ }
+}
+
+static int mtu3_ep_enable(struct mtu3_ep *mep)
+{
+ const struct usb_endpoint_descriptor *desc;
+ const struct usb_ss_ep_comp_descriptor *comp_desc;
+ struct mtu3 *mtu = mep->mtu;
+ u32 interval = 0;
+ u32 mult = 0;
+ u32 burst = 0;
+ int max_packet;
+ int ret;
+
+ desc = mep->desc;
+ comp_desc = mep->comp_desc;
+ mep->type = usb_endpoint_type(desc);
+ max_packet = usb_endpoint_maxp(desc);
+ mep->maxp = max_packet & GENMASK(10, 0);
+
+ switch (mtu->g.speed) {
+ case USB_SPEED_SUPER:
+ case USB_SPEED_SUPER_PLUS:
+ if (usb_endpoint_xfer_int(desc) ||
+ usb_endpoint_xfer_isoc(desc)) {
+ interval = desc->bInterval;
+ interval = clamp_val(interval, 1, 16) - 1;
+ if (usb_endpoint_xfer_isoc(desc) && comp_desc)
+ mult = comp_desc->bmAttributes;
+ }
+ if (comp_desc)
+ burst = comp_desc->bMaxBurst;
+
+ break;
+ case USB_SPEED_HIGH:
+ if (usb_endpoint_xfer_isoc(desc) ||
+ usb_endpoint_xfer_int(desc)) {
+ interval = desc->bInterval;
+ interval = clamp_val(interval, 1, 16) - 1;
+ burst = (max_packet & GENMASK(12, 11)) >> 11;
+ }
+ break;
+ default:
+ break; /*others are ignored */
+ }
+
+ dev_dbg(mtu->dev, "%s maxp:%d, interval:%d, burst:%d, mult:%d\n",
+ __func__, mep->maxp, interval, burst, mult);
+
+ mep->ep.maxpacket = mep->maxp;
+ mep->ep.desc = desc;
+ mep->ep.comp_desc = comp_desc;
+ mep->slot = mtu->slot;
+
+ ret = mtu3_config_ep(mtu, mep, interval, burst, mult);
+ if (ret < 0)
+ return ret;
+
+ ret = mtu3_gpd_ring_alloc(mep);
+ if (ret < 0) {
+ mtu3_deconfig_ep(mtu, mep);
+ return ret;
+ }
+
+ mtu3_qmu_start(mep);
+
+ return 0;
+}
+
+static int mtu3_ep_disable(struct mtu3_ep *mep)
+{
+ struct mtu3 *mtu = mep->mtu;
+
+ mtu3_qmu_stop(mep);
+
+ /* abort all pending requests */
+ nuke(mep, -ESHUTDOWN);
+ mtu3_deconfig_ep(mtu, mep);
+ mtu3_gpd_ring_free(mep);
+
+ mep->desc = NULL;
+ mep->ep.desc = NULL;
+ mep->comp_desc = NULL;
+ mep->type = 0;
+ mep->flags = 0;
+
+ return 0;
+}
+
+static int mtu3_gadget_ep_enable(struct usb_ep *ep,
+ const struct usb_endpoint_descriptor *desc)
+{
+ struct mtu3_ep *mep;
+ struct mtu3 *mtu;
+ unsigned long flags;
+ int ret = -EINVAL;
+
+ if (!ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT) {
+ pr_debug("%s invalid parameters\n", __func__);
+ return -EINVAL;
+ }
+
+ if (!desc->wMaxPacketSize) {
+ pr_debug("%s missing wMaxPacketSize\n", __func__);
+ return -EINVAL;
+ }
+ mep = to_mtu3_ep(ep);
+ mtu = mep->mtu;
+
+ /* check ep number and direction against endpoint */
+ if (usb_endpoint_num(desc) != mep->epnum)
+ return -EINVAL;
+
+ if (!!usb_endpoint_dir_in(desc) ^ !!mep->is_in)
+ return -EINVAL;
+
+ dev_dbg(mtu->dev, "%s %s\n", __func__, ep->name);
+
+ if (mep->flags & MTU3_EP_ENABLED) {
+ dev_warn(mtu->dev, "%s is already enabled\n", mep->name);
+ return 0;
+ }
+
+ spin_lock_irqsave(&mtu->lock, flags);
+ mep->desc = desc;
+ mep->comp_desc = ep->comp_desc;
+
+ ret = mtu3_ep_enable(mep);
+ if (ret)
+ goto error;
+
+ mep->flags = MTU3_EP_ENABLED;
+ mtu->active_ep++;
+
+error:
+ spin_unlock_irqrestore(&mtu->lock, flags);
+
+ dev_dbg(mtu->dev, "%s active_ep=%d\n", __func__, mtu->active_ep);
+
+ return ret;
+}
+
+static int mtu3_gadget_ep_disable(struct usb_ep *ep)
+{
+ struct mtu3_ep *mep = to_mtu3_ep(ep);
+ struct mtu3 *mtu = mep->mtu;
+ unsigned long flags;
+
+ dev_dbg(mtu->dev, "%s %s\n", __func__, mep->name);
+
+ if (!(mep->flags & MTU3_EP_ENABLED)) {
+ dev_warn(mtu->dev, "%s is already disabled\n", mep->name);
+ return 0;
+ }
+
+ spin_lock_irqsave(&mtu->lock, flags);
+ mtu3_ep_disable(mep);
+ mep->flags = 0;
+ mtu->active_ep--;
+ spin_unlock_irqrestore(&mtu->lock, flags);
+
+ dev_dbg(mtu->dev, "%s active_ep=%d, mtu3 is_active=%d\n",
+ __func__, mtu->active_ep, mtu->is_active);
+
+ return 0;
+}
+
+struct usb_request *mtu3_alloc_request(struct usb_ep *ep, gfp_t gfp_flags)
+{
+ struct mtu3_ep *mep = to_mtu3_ep(ep);
+ struct mtu3_request *mreq;
+
+ mreq = kzalloc(sizeof(*mreq), gfp_flags);
+ if (!mreq)
+ return NULL;
+
+ mreq->request.dma = DMA_ADDR_INVALID;
+ mreq->epnum = mep->epnum;
+ mreq->mep = mep;
+
+ return &mreq->request;
+}
+
+void mtu3_free_request(struct usb_ep *ep, struct usb_request *req)
+{
+ struct mtu3_request *mreq = to_mtu3_request(req);
+
+ kfree(mreq);
+}
+
+static int mtu3_gadget_queue(struct usb_ep *ep,
+ struct usb_request *req, gfp_t gfp_flags)
+{
+ struct mtu3_ep *mep = to_mtu3_ep(ep);
+ struct mtu3_request *mreq = to_mtu3_request(req);
+ struct mtu3 *mtu = mep->mtu;
+ unsigned long flags;
+ int ret = 0;
+
+ if (!req->buf)
+ return -ENODATA;
+
+ if (mreq->mep != mep)
+ return -EINVAL;
+
+ dev_dbg(mtu->dev, "%s %s EP%d(%s), req=%p, maxp=%d, len#%d\n",
+ __func__, mep->is_in ? "TX" : "RX", mreq->epnum, ep->name,
+ mreq, ep->maxpacket, mreq->request.length);
+
+ if (req->length > GPD_BUF_SIZE) {
+ dev_warn(mtu->dev,
+ "req length > supported MAX:%d requested:%d\n",
+ GPD_BUF_SIZE, req->length);
+ return -EOPNOTSUPP;
+ }
+
+ /* don't queue if the ep is down */
+ if (!mep->desc) {
+ dev_dbg(mtu->dev, "req=%p queued to %s while it's disabled\n",
+ req, ep->name);
+ return -ESHUTDOWN;
+ }
+
+ mreq->mtu = mtu;
+ mreq->request.actual = 0;
+ mreq->request.status = -EINPROGRESS;
+
+ ret = usb_gadget_map_request(&mtu->g, req, mep->is_in);
+ if (ret) {
+ dev_err(mtu->dev, "dma mapping failed\n");
+ return ret;
+ }
+
+ spin_lock_irqsave(&mtu->lock, flags);
+
+ if (mtu3_prepare_transfer(mep)) {
+ ret = -EAGAIN;
+ goto error;
+ }
+
+ list_add_tail(&mreq->list, &mep->req_list);
+ mtu3_insert_gpd(mep, mreq);
+ mtu3_qmu_resume(mep);
+
+error:
+ spin_unlock_irqrestore(&mtu->lock, flags);
+
+ return ret;
+}
+
+static int mtu3_gadget_dequeue(struct usb_ep *ep, struct usb_request *req)
+{
+ struct mtu3_ep *mep = to_mtu3_ep(ep);
+ struct mtu3_request *mreq = to_mtu3_request(req);
+ struct mtu3_request *r;
+ struct mtu3 *mtu = mep->mtu;
+ unsigned long flags;
+ int ret = 0;
+
+ if (mreq->mep != mep)
+ return -EINVAL;
+
+ dev_dbg(mtu->dev, "%s : req=%p\n", __func__, req);
+
+ spin_lock_irqsave(&mtu->lock, flags);
+
+ list_for_each_entry(r, &mep->req_list, list) {
+ if (r == mreq)
+ break;
+ }
+ if (r != mreq) {
+ dev_dbg(mtu->dev, "req=%p not queued to %s\n", req, ep->name);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ mtu3_qmu_flush(mep); /* REVISIT: set BPS ?? */
+ mtu3_req_complete(mep, req, -ECONNRESET);
+ mtu3_qmu_start(mep);
+
+done:
+ spin_unlock_irqrestore(&mtu->lock, flags);
+
+ return ret;
+}
+
+/*
+ * Set or clear the halt bit of an EP.
+ * A halted EP won't TX/RX any data but will queue requests.
+ */
+static int mtu3_gadget_ep_set_halt(struct usb_ep *ep, int value)
+{
+ struct mtu3_ep *mep = to_mtu3_ep(ep);
+ struct mtu3 *mtu = mep->mtu;
+ struct mtu3_request *mreq;
+ unsigned long flags = 0;
+ int ret = 0;
+
+ dev_dbg(mtu->dev, "%s : %s...", __func__, ep->name);
+
+ spin_lock_irqsave(&mtu->lock, flags);
+
+ if (mep->type == USB_ENDPOINT_XFER_ISOC) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ mreq = next_request(mep);
+ if (value) {
+ /*
+ * If there is not request for TX-EP, QMU will not transfer
+ * data to TX-FIFO, so no need check whether TX-FIFO
+ * holds bytes or not here
+ */
+ if (mreq) {
+ dev_dbg(mtu->dev, "req in progress, cannot halt %s\n",
+ ep->name);
+ ret = -EAGAIN;
+ goto done;
+ }
+ } else {
+ mep->flags &= ~MTU3_EP_WEDGE;
+ }
+
+ dev_dbg(mtu->dev, "%s %s stall\n", ep->name, value ? "set" : "clear");
+
+ mtu3_ep_stall_set(mep, value);
+
+done:
+ spin_unlock_irqrestore(&mtu->lock, flags);
+
+ return ret;
+}
+
+/* Sets the halt feature with the clear requests ignored */
+static int mtu3_gadget_ep_set_wedge(struct usb_ep *ep)
+{
+ struct mtu3_ep *mep = to_mtu3_ep(ep);
+
+ mep->flags |= MTU3_EP_WEDGE;
+
+ return usb_ep_set_halt(ep);
+}
+
+static const struct usb_ep_ops mtu3_ep_ops = {
+ .enable = mtu3_gadget_ep_enable,
+ .disable = mtu3_gadget_ep_disable,
+ .alloc_request = mtu3_alloc_request,
+ .free_request = mtu3_free_request,
+ .queue = mtu3_gadget_queue,
+ .dequeue = mtu3_gadget_dequeue,
+ .set_halt = mtu3_gadget_ep_set_halt,
+ .set_wedge = mtu3_gadget_ep_set_wedge,
+};
+
+static int mtu3_gadget_get_frame(struct usb_gadget *gadget)
+{
+ struct mtu3 *mtu = gadget_to_mtu3(gadget);
+
+ return (int)mtu3_readl(mtu->mac_base, U3D_USB20_FRAME_NUM);
+}
+
+static int mtu3_gadget_wakeup(struct usb_gadget *gadget)
+{
+ struct mtu3 *mtu = gadget_to_mtu3(gadget);
+ unsigned long flags;
+
+ dev_dbg(mtu->dev, "%s\n", __func__);
+
+ /* remote wakeup feature is not enabled by host */
+ if (!mtu->may_wakeup)
+ return -EOPNOTSUPP;
+
+ spin_lock_irqsave(&mtu->lock, flags);
+ if (mtu->g.speed >= USB_SPEED_SUPER) {
+ mtu3_setbits(mtu->mac_base, U3D_LINK_POWER_CONTROL, UX_EXIT);
+ } else {
+ mtu3_setbits(mtu->mac_base, U3D_POWER_MANAGEMENT, RESUME);
+ spin_unlock_irqrestore(&mtu->lock, flags);
+ mdelay(10);
+ spin_lock_irqsave(&mtu->lock, flags);
+ mtu3_clrbits(mtu->mac_base, U3D_POWER_MANAGEMENT, RESUME);
+ }
+ spin_unlock_irqrestore(&mtu->lock, flags);
+ return 0;
+}
+
+static int mtu3_gadget_set_self_powered(struct usb_gadget *gadget,
+ int is_selfpowered)
+{
+ struct mtu3 *mtu = gadget_to_mtu3(gadget);
+
+ mtu->is_self_powered = !!is_selfpowered;
+ return 0;
+}
+
+static int mtu3_gadget_pullup(struct usb_gadget *gadget, int is_on)
+{
+ struct mtu3 *mtu = gadget_to_mtu3(gadget);
+ unsigned long flags;
+
+ dev_dbg(mtu->dev, "%s (%s) for %sactive device\n", __func__,
+ is_on ? "on" : "off", mtu->is_active ? "" : "in");
+
+ /* we'd rather not pullup unless the device is active. */
+ spin_lock_irqsave(&mtu->lock, flags);
+
+ is_on = !!is_on;
+ if (!mtu->is_active) {
+ /* save it for mtu3_start() to process the request */
+ mtu->softconnect = is_on;
+ } else if (is_on != mtu->softconnect) {
+ mtu->softconnect = is_on;
+ mtu3_dev_on_off(mtu, is_on);
+ }
+
+ spin_unlock_irqrestore(&mtu->lock, flags);
+
+ return 0;
+}
+
+static int mtu3_gadget_start(struct usb_gadget *gadget,
+ struct usb_gadget_driver *driver)
+{
+ struct mtu3 *mtu = gadget_to_mtu3(gadget);
+ unsigned long flags;
+
+ if (mtu->gadget_driver) {
+ dev_err(mtu->dev, "%s is already bound to %s\n",
+ mtu->g.name, mtu->gadget_driver->function);
+ return -EBUSY;
+ }
+
+ dev_dbg(mtu->dev, "bind driver %s\n", driver->function);
+
+ spin_lock_irqsave(&mtu->lock, flags);
+
+ mtu->softconnect = 0;
+ mtu->gadget_driver = driver;
+ mtu3_start(mtu);
+
+ spin_unlock_irqrestore(&mtu->lock, flags);
+
+ return 0;
+}
+
+static void stop_activity(struct mtu3 *mtu)
+{
+ int i;
+
+ mtu->g.speed = USB_SPEED_UNKNOWN;
+
+ /* deactivate the hardware */
+ if (mtu->softconnect) {
+ mtu->softconnect = 0;
+ mtu3_dev_on_off(mtu, 0);
+ }
+
+ /*
+ * killing any outstanding requests will quiesce the driver;
+ * then report disconnect
+ */
+ nuke(mtu->ep0, -ESHUTDOWN);
+ for (i = 1; i < mtu->num_eps; i++) {
+ nuke(mtu->in_eps + i, -ESHUTDOWN);
+ nuke(mtu->out_eps + i, -ESHUTDOWN);
+ }
+}
+
+static int mtu3_gadget_stop(struct usb_gadget *g)
+{
+ struct mtu3 *mtu = gadget_to_mtu3(g);
+ unsigned long flags;
+
+ dev_dbg(mtu->dev, "%s\n", __func__);
+
+ spin_lock_irqsave(&mtu->lock, flags);
+
+ stop_activity(mtu);
+ mtu->gadget_driver = NULL;
+ mtu3_stop(mtu);
+
+ spin_unlock_irqrestore(&mtu->lock, flags);
+
+ return 0;
+}
+
+static void
+mtu3_gadget_set_speed(struct usb_gadget *g, enum usb_device_speed speed)
+{
+ struct mtu3 *mtu = gadget_to_mtu3(g);
+ unsigned long flags;
+
+ dev_dbg(mtu->dev, "%s %d\n", __func__, speed);
+
+ spin_lock_irqsave(&mtu->lock, flags);
+ mtu3_set_speed(mtu, speed);
+ spin_unlock_irqrestore(&mtu->lock, flags);
+}
+
+static const struct usb_gadget_ops mtu3_gadget_ops = {
+ .get_frame = mtu3_gadget_get_frame,
+ .wakeup = mtu3_gadget_wakeup,
+ .set_selfpowered = mtu3_gadget_set_self_powered,
+ .pullup = mtu3_gadget_pullup,
+ .udc_start = mtu3_gadget_start,
+ .udc_stop = mtu3_gadget_stop,
+ .udc_set_speed = mtu3_gadget_set_speed,
+};
+
+static void mtu3_state_reset(struct mtu3 *mtu)
+{
+ mtu->address = 0;
+ mtu->ep0_state = MU3D_EP0_STATE_SETUP;
+ mtu->may_wakeup = 0;
+ mtu->u1_enable = 0;
+ mtu->u2_enable = 0;
+ mtu->delayed_status = false;
+ mtu->test_mode = false;
+}
+
+static void init_hw_ep(struct mtu3 *mtu, struct mtu3_ep *mep,
+ u32 epnum, u32 is_in)
+{
+ mep->epnum = epnum;
+ mep->mtu = mtu;
+ mep->is_in = is_in;
+
+ INIT_LIST_HEAD(&mep->req_list);
+
+ sprintf(mep->name, "ep%d%s", epnum,
+ !epnum ? "" : (is_in ? "in" : "out"));
+
+ mep->ep.name = mep->name;
+ INIT_LIST_HEAD(&mep->ep.ep_list);
+
+ /* initialize maxpacket as SS */
+ if (!epnum) {
+ usb_ep_set_maxpacket_limit(&mep->ep, USB_HS_MAXP);
+ mep->ep.ops = &mtu3_ep0_ops;
+ mtu->g.ep0 = &mep->ep;
+ } else {
+ usb_ep_set_maxpacket_limit(&mep->ep, USB_SS_MAXP);
+ mep->ep.ops = &mtu3_ep_ops;
+ list_add_tail(&mep->ep.ep_list, &mtu->g.ep_list);
+ }
+
+ dev_dbg(mtu->dev, "%s, name=%s, maxp=%d\n", __func__, mep->ep.name,
+ mep->ep.maxpacket);
+}
+
+static void mtu3_gadget_init_eps(struct mtu3 *mtu)
+{
+ u8 epnum;
+
+ /* initialize endpoint list just once */
+ INIT_LIST_HEAD(&mtu->g.ep_list);
+
+ dev_dbg(mtu->dev, "%s num_eps(1 for a pair of tx&rx ep)=%d\n",
+ __func__, mtu->num_eps);
+
+ init_hw_ep(mtu, mtu->ep0, 0, 0);
+ for (epnum = 1; epnum < mtu->num_eps; epnum++) {
+ init_hw_ep(mtu, mtu->in_eps + epnum, epnum, 1);
+ init_hw_ep(mtu, mtu->out_eps + epnum, epnum, 0);
+ }
+}
+
+int mtu3_gadget_setup(struct mtu3 *mtu)
+{
+ mtu->g.ops = &mtu3_gadget_ops;
+ mtu->g.max_speed = mtu->max_speed;
+ mtu->g.speed = USB_SPEED_UNKNOWN;
+ mtu->g.is_dualspeed = 1;
+ mtu->g.name = MTU3_DRIVER_NAME;
+ mtu->is_active = 0;
+ mtu->delayed_status = false;
+
+ mtu3_gadget_init_eps(mtu);
+
+ return usb_add_gadget_udc((struct device *)mtu->dev, &mtu->g);
+}
+
+void mtu3_gadget_cleanup(struct mtu3 *mtu)
+{
+ usb_del_gadget_udc(&mtu->g);
+}
+
+void mtu3_gadget_resume(struct mtu3 *mtu)
+{
+ dev_dbg(mtu->dev, "gadget RESUME\n");
+ if (mtu->gadget_driver && mtu->gadget_driver->resume) {
+ spin_unlock(&mtu->lock);
+ mtu->gadget_driver->resume(&mtu->g);
+ spin_lock(&mtu->lock);
+ }
+}
+
+/* called when SOF packets stop for 3+ msec or enters U3 */
+void mtu3_gadget_suspend(struct mtu3 *mtu)
+{
+ dev_dbg(mtu->dev, "gadget SUSPEND\n");
+ if (mtu->gadget_driver && mtu->gadget_driver->suspend) {
+ spin_unlock(&mtu->lock);
+ mtu->gadget_driver->suspend(&mtu->g);
+ spin_lock(&mtu->lock);
+ }
+}
+
+/* called when VBUS drops below session threshold, and in other cases */
+void mtu3_gadget_disconnect(struct mtu3 *mtu)
+{
+ dev_dbg(mtu->dev, "gadget DISCONNECT\n");
+ if (mtu->gadget_driver && mtu->gadget_driver->disconnect) {
+ spin_unlock(&mtu->lock);
+ mtu->gadget_driver->disconnect(&mtu->g);
+ spin_lock(&mtu->lock);
+ }
+
+ mtu3_state_reset(mtu);
+ usb_gadget_set_state(&mtu->g, USB_STATE_NOTATTACHED);
+}
+
+void mtu3_gadget_reset(struct mtu3 *mtu)
+{
+ dev_dbg(mtu->dev, "gadget RESET\n");
+
+ /* report disconnect, if we didn't flush EP state */
+ if (mtu->g.speed != USB_SPEED_UNKNOWN)
+ mtu3_gadget_disconnect(mtu);
+ else
+ mtu3_state_reset(mtu);
+}
diff --git a/drivers/usb/mtu3/mtu3_gadget_ep0.c b/drivers/usb/mtu3/mtu3_gadget_ep0.c
new file mode 100644
index 00000000000..4b0bc5f02d1
--- /dev/null
+++ b/drivers/usb/mtu3/mtu3_gadget_ep0.c
@@ -0,0 +1,933 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * mtu3_gadget_ep0.c - MediaTek USB3 DRD peripheral driver ep0 handling
+ *
+ * Copyright (c) 2016 MediaTek Inc.
+ *
+ * Author: Chunfeng.Yun <chunfeng.yun@mediatek.com>
+ */
+
+#include <linux/iopoll.h>
+#include <linux/usb/composite.h>
+
+#include "mtu3.h"
+
+/* ep0 is always mtu3->in_eps[0] */
+#define next_ep0_request(mtu) next_request((mtu)->ep0)
+
+/* for high speed test mode; see USB 2.0 spec 7.1.20 */
+static const u8 mtu3_test_packet[53] = {
+ /* implicit SYNC then DATA0 to start */
+
+ /* JKJKJKJK x9 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* JJKKJJKK x8 */
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ /* JJJJKKKK x8 */
+ 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
+ /* JJJJJJJKKKKKKK x8 */
+ 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ /* JJJJJJJK x8 */
+ 0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd,
+ /* JKKKKKKK x10, JK */
+ 0xfc, 0x7e, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0x7e,
+ /* implicit CRC16 then EOP to end */
+};
+
+static char *decode_ep0_state(struct mtu3 *mtu)
+{
+ switch (mtu->ep0_state) {
+ case MU3D_EP0_STATE_SETUP:
+ return "SETUP";
+ case MU3D_EP0_STATE_TX:
+ return "IN";
+ case MU3D_EP0_STATE_RX:
+ return "OUT";
+ case MU3D_EP0_STATE_TX_END:
+ return "TX-END";
+ case MU3D_EP0_STATE_STALL:
+ return "STALL";
+ default:
+ return "??";
+ }
+}
+
+static void ep0_req_giveback(struct mtu3 *mtu, struct usb_request *req)
+{
+ mtu3_req_complete(mtu->ep0, req, 0);
+}
+
+static int
+forward_to_driver(struct mtu3 *mtu, const struct usb_ctrlrequest *setup)
+__releases(mtu->lock)
+__acquires(mtu->lock)
+{
+ int ret;
+
+ if (!mtu->gadget_driver)
+ return -EOPNOTSUPP;
+
+ spin_unlock(&mtu->lock);
+ ret = mtu->gadget_driver->setup(&mtu->g, setup);
+ spin_lock(&mtu->lock);
+
+ dev_dbg(mtu->dev, "%s ret %d\n", __func__, ret);
+ return ret;
+}
+
+static inline void writel_rep(volatile void *addr, const void *buffer,
+ unsigned int count)
+{
+ if (count) {
+ const u32 *buf = buffer;
+
+ do {
+ writel(*buf++, addr);
+ } while (--count);
+ }
+}
+
+static inline void readl_rep(const volatile void *addr, void *buffer,
+ unsigned int count)
+{
+ if (count) {
+ u32 *buf = buffer;
+
+ do {
+ u32 x = readl(addr);
+ *buf++ = x;
+ } while (--count);
+ }
+}
+
+static void ep0_write_fifo(struct mtu3_ep *mep, const u8 *src, u16 len)
+{
+ void __iomem *fifo = mep->mtu->mac_base + U3D_FIFO0;
+ u16 index = 0;
+
+ dev_dbg(mep->mtu->dev, "%s: ep%din, len=%d, buf=%p\n",
+ __func__, mep->epnum, len, src);
+
+ if (len >= 4) {
+ writel_rep(fifo, src, len >> 2);
+ index = len & ~0x03;
+ }
+ if (len & 0x02) {
+ writew(*(u16 *)&src[index], fifo);
+ index += 2;
+ }
+ if (len & 0x01)
+ writeb(src[index], fifo);
+}
+
+static void ep0_read_fifo(struct mtu3_ep *mep, u8 *dst, u16 len)
+{
+ void __iomem *fifo = mep->mtu->mac_base + U3D_FIFO0;
+ u32 value;
+ u16 index = 0;
+
+ dev_dbg(mep->mtu->dev, "%s: ep%dout len=%d buf=%p\n",
+ __func__, mep->epnum, len, dst);
+
+ if (len >= 4) {
+ readl_rep(fifo, dst, len >> 2);
+ index = len & ~0x03;
+ }
+ if (len & 0x3) {
+ value = readl(fifo);
+ memcpy(&dst[index], &value, len & 0x3);
+ }
+}
+
+static void ep0_load_test_packet(struct mtu3 *mtu)
+{
+ /*
+ * because the length of test packet is less than max packet of HS ep0,
+ * write it into fifo directly.
+ */
+ ep0_write_fifo(mtu->ep0, mtu3_test_packet, sizeof(mtu3_test_packet));
+}
+
+/*
+ * A. send STALL for setup transfer without data stage:
+ * set SENDSTALL and SETUPPKTRDY at the same time;
+ * B. send STALL for other cases:
+ * set SENDSTALL only.
+ */
+static void ep0_stall_set(struct mtu3_ep *mep0, bool set, u32 pktrdy)
+{
+ struct mtu3 *mtu = mep0->mtu;
+ void __iomem *mbase = mtu->mac_base;
+ u32 csr;
+
+ /* EP0_SENTSTALL is W1C */
+ csr = mtu3_readl(mbase, U3D_EP0CSR) & EP0_W1C_BITS;
+ if (set)
+ csr |= EP0_SENDSTALL | pktrdy;
+ else
+ csr = (csr & ~EP0_SENDSTALL) | EP0_SENTSTALL;
+ mtu3_writel(mtu->mac_base, U3D_EP0CSR, csr);
+
+ mtu->delayed_status = false;
+ mtu->ep0_state = MU3D_EP0_STATE_SETUP;
+
+ dev_dbg(mtu->dev, "ep0: %s STALL, ep0_state: %s\n",
+ set ? "SEND" : "CLEAR", decode_ep0_state(mtu));
+}
+
+static void ep0_do_status_stage(struct mtu3 *mtu)
+{
+ void __iomem *mbase = mtu->mac_base;
+ u32 value;
+
+ value = mtu3_readl(mbase, U3D_EP0CSR) & EP0_W1C_BITS;
+ mtu3_writel(mbase, U3D_EP0CSR, value | EP0_SETUPPKTRDY | EP0_DATAEND);
+}
+
+static int ep0_queue(struct mtu3_ep *mep0, struct mtu3_request *mreq);
+
+static void ep0_dummy_complete(struct usb_ep *ep, struct usb_request *req)
+{}
+
+static void ep0_set_sel_complete(struct usb_ep *ep, struct usb_request *req)
+{
+ struct mtu3_request *mreq;
+ struct mtu3 *mtu;
+ struct usb_set_sel_req sel;
+
+ memcpy(&sel, req->buf, sizeof(sel));
+
+ mreq = to_mtu3_request(req);
+ mtu = mreq->mtu;
+ dev_dbg(mtu->dev, "u1sel:%d, u1pel:%d, u2sel:%d, u2pel:%d\n",
+ sel.u1_sel, sel.u1_pel, sel.u2_sel, sel.u2_pel);
+}
+
+/* queue data stage to handle 6 byte SET_SEL request */
+static int ep0_set_sel(struct mtu3 *mtu, struct usb_ctrlrequest *setup)
+{
+ int ret;
+ u16 length = le16_to_cpu(setup->wLength);
+
+ if (unlikely(length != 6)) {
+ dev_err(mtu->dev, "%s wrong wLength:%d\n",
+ __func__, length);
+ return -EINVAL;
+ }
+
+ mtu->ep0_req.mep = mtu->ep0;
+ mtu->ep0_req.request.length = 6;
+ mtu->ep0_req.request.buf = mtu->setup_buf;
+ mtu->ep0_req.request.complete = ep0_set_sel_complete;
+ ret = ep0_queue(mtu->ep0, &mtu->ep0_req);
+
+ return ret < 0 ? ret : 1;
+}
+
+static int
+ep0_get_status(struct mtu3 *mtu, const struct usb_ctrlrequest *setup)
+{
+ struct mtu3_ep *mep = NULL;
+ int handled = 1;
+ u8 result[2] = {0, 0};
+ u8 epnum = 0;
+ int is_in;
+
+ switch (setup->bRequestType & USB_RECIP_MASK) {
+ case USB_RECIP_DEVICE:
+ result[0] = mtu->is_self_powered << USB_DEVICE_SELF_POWERED;
+ result[0] |= mtu->may_wakeup << USB_DEVICE_REMOTE_WAKEUP;
+
+ if (mtu->g.speed >= USB_SPEED_SUPER) {
+ result[0] |= mtu->u1_enable << USB_DEV_STAT_U1_ENABLED;
+ result[0] |= mtu->u2_enable << USB_DEV_STAT_U2_ENABLED;
+ }
+
+ dev_dbg(mtu->dev, "%s result=%x, U1=%x, U2=%x\n", __func__,
+ result[0], mtu->u1_enable, mtu->u2_enable);
+
+ break;
+ case USB_RECIP_INTERFACE:
+ break;
+ case USB_RECIP_ENDPOINT:
+ epnum = (u8)le16_to_cpu(setup->wIndex);
+ is_in = epnum & USB_DIR_IN;
+ epnum &= USB_ENDPOINT_NUMBER_MASK;
+
+ if (epnum >= mtu->num_eps) {
+ handled = -EINVAL;
+ break;
+ }
+ if (!epnum)
+ break;
+
+ mep = (is_in ? mtu->in_eps : mtu->out_eps) + epnum;
+ if (!mep->desc) {
+ handled = -EINVAL;
+ break;
+ }
+ if (mep->flags & MTU3_EP_STALL)
+ result[0] |= 1 << USB_ENDPOINT_HALT;
+
+ break;
+ default:
+ /* class, vendor, etc ... delegate */
+ handled = 0;
+ break;
+ }
+
+ if (handled > 0) {
+ int ret;
+
+ /* prepare a data stage for GET_STATUS */
+ dev_dbg(mtu->dev, "get_status=%x\n", *(u16 *)result);
+ memcpy(mtu->setup_buf, result, sizeof(result));
+ mtu->ep0_req.mep = mtu->ep0;
+ mtu->ep0_req.request.length = 2;
+ mtu->ep0_req.request.buf = &mtu->setup_buf;
+ mtu->ep0_req.request.complete = ep0_dummy_complete;
+ ret = ep0_queue(mtu->ep0, &mtu->ep0_req);
+ if (ret < 0)
+ handled = ret;
+ }
+ return handled;
+}
+
+static int handle_test_mode(struct mtu3 *mtu, struct usb_ctrlrequest *setup)
+{
+ void __iomem *mbase = mtu->mac_base;
+ int handled = 1;
+ u32 value = 0;
+
+ switch (le16_to_cpu(setup->wIndex) >> 8) {
+ case TEST_J:
+ dev_dbg(mtu->dev, "TEST_J\n");
+ mtu->test_mode_nr = TEST_J_MODE;
+ break;
+ case TEST_K:
+ dev_dbg(mtu->dev, "TEST_K\n");
+ mtu->test_mode_nr = TEST_K_MODE;
+ break;
+ case TEST_SE0_NAK:
+ dev_dbg(mtu->dev, "TEST_SE0_NAK\n");
+ mtu->test_mode_nr = TEST_SE0_NAK_MODE;
+ break;
+ case TEST_PACKET:
+ dev_dbg(mtu->dev, "TEST_PACKET\n");
+ mtu->test_mode_nr = TEST_PACKET_MODE;
+ break;
+ default:
+ handled = -EINVAL;
+ goto out;
+ }
+
+ mtu->test_mode = true;
+
+ /* no TX completion interrupt, and need restart platform after test */
+ if (mtu->test_mode_nr == TEST_PACKET_MODE)
+ ep0_load_test_packet(mtu);
+
+ /* send status before entering test mode. */
+ ep0_do_status_stage(mtu);
+
+ /* wait for ACK status sent by host */
+ readl_poll_timeout(mbase + U3D_EP0CSR, value,
+ !(value & EP0_DATAEND), 5000);
+
+ mtu3_writel(mbase, U3D_USB2_TEST_MODE, mtu->test_mode_nr);
+
+ mtu->ep0_state = MU3D_EP0_STATE_SETUP;
+
+out:
+ return handled;
+}
+
+static int ep0_handle_feature_dev(struct mtu3 *mtu,
+ struct usb_ctrlrequest *setup, bool set)
+{
+ void __iomem *mbase = mtu->mac_base;
+ int handled = -EINVAL;
+ u32 lpc;
+
+ switch (le16_to_cpu(setup->wValue)) {
+ case USB_DEVICE_REMOTE_WAKEUP:
+ mtu->may_wakeup = !!set;
+ handled = 1;
+ break;
+ case USB_DEVICE_TEST_MODE:
+ if (!set || (mtu->g.speed != USB_SPEED_HIGH) ||
+ (le16_to_cpu(setup->wIndex) & 0xff))
+ break;
+
+ handled = handle_test_mode(mtu, setup);
+ break;
+ case USB_DEVICE_U1_ENABLE:
+ if (mtu->g.speed < USB_SPEED_SUPER ||
+ mtu->g.state != USB_STATE_CONFIGURED)
+ break;
+
+ lpc = mtu3_readl(mbase, U3D_LINK_POWER_CONTROL);
+ if (set)
+ lpc |= SW_U1_REQUEST_ENABLE;
+ else
+ lpc &= ~SW_U1_REQUEST_ENABLE;
+ mtu3_writel(mbase, U3D_LINK_POWER_CONTROL, lpc);
+
+ mtu->u1_enable = !!set;
+ handled = 1;
+ break;
+ case USB_DEVICE_U2_ENABLE:
+ if (mtu->g.speed < USB_SPEED_SUPER ||
+ mtu->g.state != USB_STATE_CONFIGURED)
+ break;
+
+ lpc = mtu3_readl(mbase, U3D_LINK_POWER_CONTROL);
+ if (set)
+ lpc |= SW_U2_REQUEST_ENABLE;
+ else
+ lpc &= ~SW_U2_REQUEST_ENABLE;
+ mtu3_writel(mbase, U3D_LINK_POWER_CONTROL, lpc);
+
+ mtu->u2_enable = !!set;
+ handled = 1;
+ break;
+ default:
+ handled = -EINVAL;
+ break;
+ }
+ return handled;
+}
+
+static int ep0_handle_feature(struct mtu3 *mtu,
+ struct usb_ctrlrequest *setup, bool set)
+{
+ struct mtu3_ep *mep;
+ int handled = -EINVAL;
+ int is_in;
+ u16 value;
+ u16 index;
+ u8 epnum;
+
+ value = le16_to_cpu(setup->wValue);
+ index = le16_to_cpu(setup->wIndex);
+
+ switch (setup->bRequestType & USB_RECIP_MASK) {
+ case USB_RECIP_DEVICE:
+ handled = ep0_handle_feature_dev(mtu, setup, set);
+ break;
+ case USB_RECIP_INTERFACE:
+ /* superspeed only */
+ if (value == USB_INTRF_FUNC_SUSPEND &&
+ mtu->g.speed >= USB_SPEED_SUPER) {
+ /*
+ * forward the request because function drivers
+ * should handle it
+ */
+ handled = 0;
+ }
+ break;
+ case USB_RECIP_ENDPOINT:
+ epnum = index & USB_ENDPOINT_NUMBER_MASK;
+ if (epnum == 0 || epnum >= mtu->num_eps ||
+ value != USB_ENDPOINT_HALT)
+ break;
+
+ is_in = index & USB_DIR_IN;
+ mep = (is_in ? mtu->in_eps : mtu->out_eps) + epnum;
+ if (!mep->desc)
+ break;
+
+ handled = 1;
+ /* ignore request if endpoint is wedged */
+ if (mep->flags & MTU3_EP_WEDGE)
+ break;
+
+ mtu3_ep_stall_set(mep, set);
+ break;
+ default:
+ /* class, vendor, etc ... delegate */
+ handled = 0;
+ break;
+ }
+ return handled;
+}
+
+/*
+ * handle all control requests can be handled
+ * returns:
+ * negative errno - error happened
+ * zero - need delegate SETUP to gadget driver
+ * positive - already handled
+ */
+static int handle_standard_request(struct mtu3 *mtu,
+ struct usb_ctrlrequest *setup)
+{
+ void __iomem *mbase = mtu->mac_base;
+ enum usb_device_state state = mtu->g.state;
+ int handled = -EINVAL;
+ u32 dev_conf;
+ u16 value;
+
+ value = le16_to_cpu(setup->wValue);
+
+ /* the gadget driver handles everything except what we must handle */
+ switch (setup->bRequest) {
+ case USB_REQ_SET_ADDRESS:
+ /* change it after the status stage */
+ mtu->address = (u8)(value & 0x7f);
+ dev_dbg(mtu->dev, "set address to 0x%x\n", mtu->address);
+
+ dev_conf = mtu3_readl(mbase, U3D_DEVICE_CONF);
+ dev_conf &= ~DEV_ADDR_MSK;
+ dev_conf |= DEV_ADDR(mtu->address);
+ mtu3_writel(mbase, U3D_DEVICE_CONF, dev_conf);
+
+ if (mtu->address)
+ usb_gadget_set_state(&mtu->g, USB_STATE_ADDRESS);
+ else
+ usb_gadget_set_state(&mtu->g, USB_STATE_DEFAULT);
+
+ handled = 1;
+ break;
+ case USB_REQ_SET_CONFIGURATION:
+ if (state == USB_STATE_ADDRESS) {
+ usb_gadget_set_state(&mtu->g,
+ USB_STATE_CONFIGURED);
+ } else if (state == USB_STATE_CONFIGURED) {
+ /*
+ * USB2 spec sec 9.4.7, if wValue is 0 then dev
+ * is moved to addressed state
+ */
+ if (!value)
+ usb_gadget_set_state(&mtu->g,
+ USB_STATE_ADDRESS);
+ }
+ handled = 0;
+ break;
+ case USB_REQ_CLEAR_FEATURE:
+ handled = ep0_handle_feature(mtu, setup, 0);
+ break;
+ case USB_REQ_SET_FEATURE:
+ handled = ep0_handle_feature(mtu, setup, 1);
+ break;
+ case USB_REQ_GET_STATUS:
+ handled = ep0_get_status(mtu, setup);
+ break;
+ case USB_REQ_SET_SEL:
+ handled = ep0_set_sel(mtu, setup);
+ break;
+ case USB_REQ_SET_ISOCH_DELAY:
+ handled = 1;
+ break;
+ default:
+ /* delegate SET_CONFIGURATION, etc */
+ handled = 0;
+ }
+
+ return handled;
+}
+
+/* receive an data packet (OUT) */
+static void ep0_rx_state(struct mtu3 *mtu)
+{
+ struct mtu3_request *mreq;
+ struct usb_request *req;
+ void __iomem *mbase = mtu->mac_base;
+ u32 maxp;
+ u32 csr;
+ u16 count = 0;
+
+ dev_dbg(mtu->dev, "%s\n", __func__);
+
+ csr = mtu3_readl(mbase, U3D_EP0CSR) & EP0_W1C_BITS;
+ mreq = next_ep0_request(mtu);
+ req = &mreq->request;
+
+ /* read packet and ack; or stall because of gadget driver bug */
+ if (req) {
+ void *buf = req->buf + req->actual;
+ unsigned int len = req->length - req->actual;
+
+ /* read the buffer */
+ count = mtu3_readl(mbase, U3D_RXCOUNT0);
+ if (count > len) {
+ req->status = -EOVERFLOW;
+ count = len;
+ }
+ ep0_read_fifo(mtu->ep0, buf, count);
+ req->actual += count;
+ csr |= EP0_RXPKTRDY;
+
+ maxp = mtu->g.ep0->maxpacket;
+ if (count < maxp || req->actual == req->length) {
+ mtu->ep0_state = MU3D_EP0_STATE_SETUP;
+ dev_dbg(mtu->dev, "ep0 state: %s\n",
+ decode_ep0_state(mtu));
+
+ csr |= EP0_DATAEND;
+ } else {
+ req = NULL;
+ }
+ } else {
+ csr |= EP0_RXPKTRDY | EP0_SENDSTALL;
+ dev_dbg(mtu->dev, "%s: SENDSTALL\n", __func__);
+ }
+
+ mtu3_writel(mbase, U3D_EP0CSR, csr);
+
+ /* give back the request if have received all data */
+ if (req)
+ ep0_req_giveback(mtu, req);
+}
+
+/* transmitting to the host (IN) */
+static void ep0_tx_state(struct mtu3 *mtu)
+{
+ struct mtu3_request *mreq = next_ep0_request(mtu);
+ struct usb_request *req;
+ u32 csr;
+ u8 *src;
+ u32 count;
+ u32 maxp;
+
+ dev_dbg(mtu->dev, "%s\n", __func__);
+
+ if (!mreq)
+ return;
+
+ maxp = mtu->g.ep0->maxpacket;
+ req = &mreq->request;
+
+ /* load the data */
+ src = (u8 *)req->buf + req->actual;
+ count = min(maxp, req->length - req->actual);
+ if (count)
+ ep0_write_fifo(mtu->ep0, src, count);
+
+ dev_dbg(mtu->dev, "%s act=%d, len=%d, cnt=%d, maxp=%d zero=%d\n",
+ __func__, req->actual, req->length, count, maxp, req->zero);
+
+ req->actual += count;
+
+ if ((count < maxp) ||
+ ((req->actual == req->length) && !req->zero))
+ mtu->ep0_state = MU3D_EP0_STATE_TX_END;
+
+ /* send it out, triggering a "txpktrdy cleared" irq */
+ csr = mtu3_readl(mtu->mac_base, U3D_EP0CSR) & EP0_W1C_BITS;
+ mtu3_writel(mtu->mac_base, U3D_EP0CSR, csr | EP0_TXPKTRDY);
+
+ dev_dbg(mtu->dev, "%s ep0csr=0x%x\n", __func__,
+ mtu3_readl(mtu->mac_base, U3D_EP0CSR));
+}
+
+static void ep0_read_setup(struct mtu3 *mtu, struct usb_ctrlrequest *setup)
+{
+ struct mtu3_request *mreq;
+ u32 count;
+ u32 csr;
+
+ csr = mtu3_readl(mtu->mac_base, U3D_EP0CSR) & EP0_W1C_BITS;
+ count = mtu3_readl(mtu->mac_base, U3D_RXCOUNT0);
+
+ ep0_read_fifo(mtu->ep0, (u8 *)setup, count);
+
+ dev_dbg(mtu->dev, "SETUP req%02x.%02x v%04x i%04x l%04x\n",
+ setup->bRequestType, setup->bRequest,
+ le16_to_cpu(setup->wValue), le16_to_cpu(setup->wIndex),
+ le16_to_cpu(setup->wLength));
+
+ /* clean up any leftover transfers */
+ mreq = next_ep0_request(mtu);
+ if (mreq)
+ ep0_req_giveback(mtu, &mreq->request);
+
+ if (le16_to_cpu(setup->wLength) == 0) {
+ ; /* no data stage, nothing to do */
+ } else if (setup->bRequestType & USB_DIR_IN) {
+ mtu3_writel(mtu->mac_base, U3D_EP0CSR,
+ csr | EP0_SETUPPKTRDY | EP0_DPHTX);
+ mtu->ep0_state = MU3D_EP0_STATE_TX;
+ } else {
+ mtu3_writel(mtu->mac_base, U3D_EP0CSR,
+ (csr | EP0_SETUPPKTRDY) & (~EP0_DPHTX));
+ mtu->ep0_state = MU3D_EP0_STATE_RX;
+ }
+}
+
+static int ep0_handle_setup(struct mtu3 *mtu)
+__releases(mtu->lock)
+__acquires(mtu->lock)
+{
+ struct usb_ctrlrequest setup;
+ struct mtu3_request *mreq;
+ int handled = 0;
+
+ ep0_read_setup(mtu, &setup);
+
+ if ((setup.bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD)
+ handled = handle_standard_request(mtu, &setup);
+
+ dev_dbg(mtu->dev, "handled %d, ep0_state: %s\n",
+ handled, decode_ep0_state(mtu));
+
+ if (handled < 0)
+ goto stall;
+ else if (handled > 0)
+ goto finish;
+
+ handled = forward_to_driver(mtu, &setup);
+ if (handled < 0) {
+stall:
+ dev_dbg(mtu->dev, "%s stall (%d)\n", __func__, handled);
+
+ ep0_stall_set(mtu->ep0, true,
+ le16_to_cpu(setup.wLength) ? 0 : EP0_SETUPPKTRDY);
+
+ return 0;
+ }
+
+finish:
+ if (mtu->test_mode) {
+ ; /* nothing to do */
+ } else if (handled == USB_GADGET_DELAYED_STATUS) {
+
+ mreq = next_ep0_request(mtu);
+ if (mreq) {
+ /* already asked us to continue delayed status */
+ ep0_do_status_stage(mtu);
+ ep0_req_giveback(mtu, &mreq->request);
+ } else {
+ /* do delayed STATUS stage till receive ep0_queue */
+ mtu->delayed_status = true;
+ }
+ } else if (le16_to_cpu(setup.wLength) == 0) { /* no data stage */
+
+ ep0_do_status_stage(mtu);
+ /* complete zlp request directly */
+ mreq = next_ep0_request(mtu);
+ if (mreq && !mreq->request.length)
+ ep0_req_giveback(mtu, &mreq->request);
+ }
+
+ return 0;
+}
+
+irqreturn_t mtu3_ep0_isr(struct mtu3 *mtu)
+{
+ void __iomem *mbase = mtu->mac_base;
+ struct mtu3_request *mreq;
+ u32 int_status;
+ irqreturn_t ret = IRQ_NONE;
+ u32 csr;
+ u32 len;
+
+ int_status = mtu3_readl(mbase, U3D_EPISR);
+ int_status &= mtu3_readl(mbase, U3D_EPIER);
+ mtu3_writel(mbase, U3D_EPISR, int_status); /* W1C */
+
+ /* only handle ep0's */
+ if (!(int_status & (EP0ISR | SETUPENDISR)))
+ return IRQ_NONE;
+
+ /* abort current SETUP, and process new one */
+ if (int_status & SETUPENDISR)
+ mtu->ep0_state = MU3D_EP0_STATE_SETUP;
+
+ csr = mtu3_readl(mbase, U3D_EP0CSR);
+
+ dev_dbg(mtu->dev, "%s csr=0x%x\n", __func__, csr);
+
+ /* we sent a stall.. need to clear it now.. */
+ if (csr & EP0_SENTSTALL) {
+ ep0_stall_set(mtu->ep0, false, 0);
+ csr = mtu3_readl(mbase, U3D_EP0CSR);
+ ret = IRQ_HANDLED;
+ }
+ dev_dbg(mtu->dev, "ep0_state: %s\n", decode_ep0_state(mtu));
+
+ switch (mtu->ep0_state) {
+ case MU3D_EP0_STATE_TX:
+ /* irq on clearing txpktrdy */
+ if ((csr & EP0_FIFOFULL) == 0) {
+ ep0_tx_state(mtu);
+ ret = IRQ_HANDLED;
+ }
+ break;
+ case MU3D_EP0_STATE_RX:
+ /* irq on set rxpktrdy */
+ if (csr & EP0_RXPKTRDY) {
+ ep0_rx_state(mtu);
+ ret = IRQ_HANDLED;
+ }
+ break;
+ case MU3D_EP0_STATE_TX_END:
+ mtu3_writel(mbase, U3D_EP0CSR,
+ (csr & EP0_W1C_BITS) | EP0_DATAEND);
+
+ mreq = next_ep0_request(mtu);
+ if (mreq)
+ ep0_req_giveback(mtu, &mreq->request);
+
+ mtu->ep0_state = MU3D_EP0_STATE_SETUP;
+ ret = IRQ_HANDLED;
+ dev_dbg(mtu->dev, "ep0_state: %s\n", decode_ep0_state(mtu));
+ break;
+ case MU3D_EP0_STATE_SETUP:
+ if (!(csr & EP0_SETUPPKTRDY))
+ break;
+
+ len = mtu3_readl(mbase, U3D_RXCOUNT0);
+ if (len != 8) {
+ dev_err(mtu->dev, "SETUP packet len %d != 8 ?\n", len);
+ break;
+ }
+
+ ep0_handle_setup(mtu);
+ ret = IRQ_HANDLED;
+ break;
+ default:
+ /* can't happen */
+ ep0_stall_set(mtu->ep0, true, 0);
+ WARN_ON(1);
+ break;
+ }
+
+ return ret;
+}
+
+static int mtu3_ep0_enable(struct usb_ep *ep,
+ const struct usb_endpoint_descriptor *desc)
+{
+ /* always enabled */
+ return -EINVAL;
+}
+
+static int mtu3_ep0_disable(struct usb_ep *ep)
+{
+ /* always enabled */
+ return -EINVAL;
+}
+
+static int ep0_queue(struct mtu3_ep *mep, struct mtu3_request *mreq)
+{
+ struct mtu3 *mtu = mep->mtu;
+
+ mreq->mtu = mtu;
+ mreq->request.actual = 0;
+ mreq->request.status = -EINPROGRESS;
+
+ dev_dbg(mtu->dev, "%s %s (ep0_state: %s), len#%d\n", __func__,
+ mep->name, decode_ep0_state(mtu), mreq->request.length);
+
+ switch (mtu->ep0_state) {
+ case MU3D_EP0_STATE_SETUP:
+ case MU3D_EP0_STATE_RX: /* control-OUT data */
+ case MU3D_EP0_STATE_TX: /* control-IN data */
+ break;
+ default:
+ dev_err(mtu->dev, "%s, error in ep0 state %s\n", __func__,
+ decode_ep0_state(mtu));
+ return -EINVAL;
+ }
+
+ if (mtu->delayed_status) {
+ mtu->delayed_status = false;
+ ep0_do_status_stage(mtu);
+ /* needn't giveback the request for handling delay STATUS */
+ return 0;
+ }
+
+ if (!list_empty(&mep->req_list))
+ return -EBUSY;
+
+ list_add_tail(&mreq->list, &mep->req_list);
+
+ /* sequence #1, IN ... start writing the data */
+ if (mtu->ep0_state == MU3D_EP0_STATE_TX)
+ ep0_tx_state(mtu);
+
+ return 0;
+}
+
+static int mtu3_ep0_queue(struct usb_ep *ep,
+ struct usb_request *req, gfp_t gfp)
+{
+ struct mtu3_ep *mep;
+ struct mtu3_request *mreq;
+ struct mtu3 *mtu;
+ unsigned long flags;
+ int ret = 0;
+
+ if (!ep || !req)
+ return -EINVAL;
+
+ mep = to_mtu3_ep(ep);
+ mtu = mep->mtu;
+ mreq = to_mtu3_request(req);
+
+ spin_lock_irqsave(&mtu->lock, flags);
+ ret = ep0_queue(mep, mreq);
+ spin_unlock_irqrestore(&mtu->lock, flags);
+ return ret;
+}
+
+static int mtu3_ep0_dequeue(struct usb_ep *ep, struct usb_request *req)
+{
+ /* we just won't support this */
+ return -EINVAL;
+}
+
+static int mtu3_ep0_halt(struct usb_ep *ep, int value)
+{
+ struct mtu3_ep *mep;
+ struct mtu3 *mtu;
+ unsigned long flags;
+ int ret = 0;
+
+ if (!ep || !value)
+ return -EINVAL;
+
+ mep = to_mtu3_ep(ep);
+ mtu = mep->mtu;
+
+ dev_dbg(mtu->dev, "%s\n", __func__);
+
+ spin_lock_irqsave(&mtu->lock, flags);
+
+ if (!list_empty(&mep->req_list)) {
+ ret = -EBUSY;
+ goto cleanup;
+ }
+
+ switch (mtu->ep0_state) {
+ /*
+ * stalls are usually issued after parsing SETUP packet, either
+ * directly in irq context from setup() or else later.
+ */
+ case MU3D_EP0_STATE_TX:
+ case MU3D_EP0_STATE_TX_END:
+ case MU3D_EP0_STATE_RX:
+ case MU3D_EP0_STATE_SETUP:
+ ep0_stall_set(mtu->ep0, true, 0);
+ break;
+ default:
+ dev_dbg(mtu->dev, "ep0 can't halt in state %s\n",
+ decode_ep0_state(mtu));
+ ret = -EINVAL;
+ }
+
+cleanup:
+ spin_unlock_irqrestore(&mtu->lock, flags);
+ return ret;
+}
+
+const struct usb_ep_ops mtu3_ep0_ops = {
+ .enable = mtu3_ep0_enable,
+ .disable = mtu3_ep0_disable,
+ .alloc_request = mtu3_alloc_request,
+ .free_request = mtu3_free_request,
+ .queue = mtu3_ep0_queue,
+ .dequeue = mtu3_ep0_dequeue,
+ .set_halt = mtu3_ep0_halt,
+};
diff --git a/drivers/usb/mtu3/mtu3_host.c b/drivers/usb/mtu3/mtu3_host.c
new file mode 100644
index 00000000000..8001fc2d9bd
--- /dev/null
+++ b/drivers/usb/mtu3/mtu3_host.c
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * mtu3_dr.c - dual role switch and host glue layer
+ *
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * Author: Chunfeng Yun <chunfeng.yun@mediatek.com>
+ */
+
+#include <dm/lists.h>
+#include <linux/iopoll.h>
+
+#include "mtu3.h"
+#include "mtu3_dr.h"
+
+static void host_ports_num_get(struct mtu3_host *u3h)
+{
+ u32 xhci_cap;
+
+ xhci_cap = mtu3_readl(u3h->ippc_base, U3D_SSUSB_IP_XHCI_CAP);
+ u3h->u2_ports = SSUSB_IP_XHCI_U2_PORT_NUM(xhci_cap);
+ u3h->u3_ports = SSUSB_IP_XHCI_U3_PORT_NUM(xhci_cap);
+
+ dev_dbg(u3h->dev, "host - u2_ports:%d, u3_ports:%d\n",
+ u3h->u2_ports, u3h->u3_ports);
+}
+
+/* only configure ports will be used later */
+static int ssusb_host_enable(struct mtu3_host *u3h)
+{
+ void __iomem *ibase = u3h->ippc_base;
+ int num_u3p = u3h->u3_ports;
+ int num_u2p = u3h->u2_ports;
+ int u3_ports_disabed;
+ u32 check_clk;
+ u32 value;
+ int i;
+
+ /* power on host ip */
+ mtu3_clrbits(ibase, U3D_SSUSB_IP_PW_CTRL1, SSUSB_IP_HOST_PDN);
+
+ /* power on and enable u3 ports except skipped ones */
+ u3_ports_disabed = 0;
+ for (i = 0; i < num_u3p; i++) {
+ if ((0x1 << i) & u3h->u3p_dis_msk) {
+ u3_ports_disabed++;
+ continue;
+ }
+
+ value = mtu3_readl(ibase, SSUSB_U3_CTRL(i));
+ value &= ~(SSUSB_U3_PORT_PDN | SSUSB_U3_PORT_DIS);
+ value |= SSUSB_U3_PORT_HOST_SEL;
+ mtu3_writel(ibase, SSUSB_U3_CTRL(i), value);
+ }
+
+ /* power on and enable all u2 ports */
+ for (i = 0; i < num_u2p; i++) {
+ value = mtu3_readl(ibase, SSUSB_U2_CTRL(i));
+ value &= ~(SSUSB_U2_PORT_PDN | SSUSB_U2_PORT_DIS);
+ value |= SSUSB_U2_PORT_HOST_SEL;
+ mtu3_writel(ibase, SSUSB_U2_CTRL(i), value);
+ }
+
+ check_clk = SSUSB_XHCI_RST_B_STS;
+ if (num_u3p > u3_ports_disabed)
+ check_clk = SSUSB_U3_MAC_RST_B_STS;
+
+ return ssusb_check_clocks(u3h->ssusb, check_clk);
+}
+
+static void ssusb_host_disable(struct mtu3_host *u3h)
+{
+ void __iomem *ibase = u3h->ippc_base;
+ int num_u3p = u3h->u3_ports;
+ int num_u2p = u3h->u2_ports;
+ u32 value;
+ int i;
+
+ /* power down and disable u3 ports except skipped ones */
+ for (i = 0; i < num_u3p; i++) {
+ if ((0x1 << i) & u3h->u3p_dis_msk)
+ continue;
+
+ value = mtu3_readl(ibase, SSUSB_U3_CTRL(i));
+ value |= SSUSB_U3_PORT_PDN | SSUSB_U3_PORT_DIS;
+ mtu3_writel(ibase, SSUSB_U3_CTRL(i), value);
+ }
+
+ /* power down and disable all u2 ports */
+ for (i = 0; i < num_u2p; i++) {
+ value = mtu3_readl(ibase, SSUSB_U2_CTRL(i));
+ value |= SSUSB_U2_PORT_PDN | SSUSB_U2_PORT_DIS;
+ mtu3_writel(ibase, SSUSB_U2_CTRL(i), value);
+ }
+
+ /* power down host ip */
+ mtu3_setbits(ibase, U3D_SSUSB_IP_PW_CTRL1, SSUSB_IP_HOST_PDN);
+}
+
+/*
+ * If host supports multiple ports, the VBUSes(5V) of ports except port0
+ * which supports OTG are better to be enabled by default in DTS.
+ * Because the host driver will keep link with devices attached when system
+ * enters suspend mode, so no need to control VBUSes after initialization.
+ */
+int ssusb_host_init(struct ssusb_mtk *ssusb)
+{
+ struct mtu3_host *u3h = ssusb->u3h;
+ struct udevice *dev = u3h->dev;
+ int ret;
+
+ u3h->ssusb = ssusb;
+ u3h->hcd = ssusb->mac_base;
+ u3h->ippc_base = ssusb->ippc_base;
+
+ /* optional property, ignore the error */
+ dev_read_u32(dev, "mediatek,u3p-dis-msk", &u3h->u3p_dis_msk);
+
+ host_ports_num_get(u3h);
+ ret = ssusb_host_enable(u3h);
+ if (ret)
+ return ret;
+
+ ssusb_set_force_mode(ssusb, MTU3_DR_FORCE_HOST);
+
+ ret = regulator_set_enable(ssusb->vbus_supply, true);
+ if (ret < 0 && ret != -ENOSYS) {
+ dev_err(dev, "failed to enable vbus %d!\n", ret);
+ return ret;
+ }
+
+ dev_info(dev, "%s done...\n", __func__);
+
+ return 0;
+}
+
+void ssusb_host_exit(struct ssusb_mtk *ssusb)
+{
+ regulator_set_enable(ssusb->vbus_supply, false);
+ ssusb_host_disable(ssusb->u3h);
+}
diff --git a/drivers/usb/mtu3/mtu3_hw_regs.h b/drivers/usb/mtu3/mtu3_hw_regs.h
new file mode 100644
index 00000000000..9c2a7e1f466
--- /dev/null
+++ b/drivers/usb/mtu3/mtu3_hw_regs.h
@@ -0,0 +1,515 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * mtu3_hw_regs.h - MediaTek USB3 DRD register and field definitions
+ *
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * Author: Chunfeng Yun <chunfeng.yun@mediatek.com>
+ */
+
+#ifndef _SSUSB_HW_REGS_H_
+#define _SSUSB_HW_REGS_H_
+
+/* segment offset of MAC register */
+#define SSUSB_XCHI_BASE 0x0000
+#define SSUSB_DEV_BASE 0x1000
+#define SSUSB_EPCTL_CSR_BASE 0x1800
+#define SSUSB_USB3_MAC_CSR_BASE 0x2400
+#define SSUSB_USB3_SYS_CSR_BASE 0x2400
+#define SSUSB_USB2_CSR_BASE 0x3400
+
+/* IPPC register in Infra */
+#define SSUSB_SIFSLV_IPPC_BASE 0x0000
+
+/* --------------- SSUSB_DEV REGISTER DEFINITION --------------- */
+
+#define U3D_LV1ISR (SSUSB_DEV_BASE + 0x0000)
+#define U3D_LV1IER (SSUSB_DEV_BASE + 0x0004)
+#define U3D_LV1IESR (SSUSB_DEV_BASE + 0x0008)
+#define U3D_LV1IECR (SSUSB_DEV_BASE + 0x000C)
+
+#define U3D_EPISR (SSUSB_DEV_BASE + 0x0080)
+#define U3D_EPIER (SSUSB_DEV_BASE + 0x0084)
+#define U3D_EPIESR (SSUSB_DEV_BASE + 0x0088)
+#define U3D_EPIECR (SSUSB_DEV_BASE + 0x008C)
+
+#define U3D_EP0CSR (SSUSB_DEV_BASE + 0x0100)
+#define U3D_RXCOUNT0 (SSUSB_DEV_BASE + 0x0108)
+#define U3D_RESERVED (SSUSB_DEV_BASE + 0x010C)
+#define U3D_TX1CSR0 (SSUSB_DEV_BASE + 0x0110)
+#define U3D_TX1CSR1 (SSUSB_DEV_BASE + 0x0114)
+#define U3D_TX1CSR2 (SSUSB_DEV_BASE + 0x0118)
+
+#define U3D_RX1CSR0 (SSUSB_DEV_BASE + 0x0210)
+#define U3D_RX1CSR1 (SSUSB_DEV_BASE + 0x0214)
+#define U3D_RX1CSR2 (SSUSB_DEV_BASE + 0x0218)
+
+#define U3D_FIFO0 (SSUSB_DEV_BASE + 0x0300)
+
+#define U3D_QCR0 (SSUSB_DEV_BASE + 0x0400)
+#define U3D_QCR1 (SSUSB_DEV_BASE + 0x0404)
+#define U3D_QCR2 (SSUSB_DEV_BASE + 0x0408)
+#define U3D_QCR3 (SSUSB_DEV_BASE + 0x040C)
+#define U3D_QFCR (SSUSB_DEV_BASE + 0x0428)
+
+#define U3D_TXQCSR1 (SSUSB_DEV_BASE + 0x0510)
+#define U3D_TXQSAR1 (SSUSB_DEV_BASE + 0x0514)
+#define U3D_TXQCPR1 (SSUSB_DEV_BASE + 0x0518)
+
+#define U3D_RXQCSR1 (SSUSB_DEV_BASE + 0x0610)
+#define U3D_RXQSAR1 (SSUSB_DEV_BASE + 0x0614)
+#define U3D_RXQCPR1 (SSUSB_DEV_BASE + 0x0618)
+#define U3D_RXQLDPR1 (SSUSB_DEV_BASE + 0x061C)
+
+#define U3D_QISAR0 (SSUSB_DEV_BASE + 0x0700)
+#define U3D_QIER0 (SSUSB_DEV_BASE + 0x0704)
+#define U3D_QIESR0 (SSUSB_DEV_BASE + 0x0708)
+#define U3D_QIECR0 (SSUSB_DEV_BASE + 0x070C)
+#define U3D_QISAR1 (SSUSB_DEV_BASE + 0x0710)
+#define U3D_QIER1 (SSUSB_DEV_BASE + 0x0714)
+#define U3D_QIESR1 (SSUSB_DEV_BASE + 0x0718)
+#define U3D_QIECR1 (SSUSB_DEV_BASE + 0x071C)
+
+#define U3D_TQERRIR0 (SSUSB_DEV_BASE + 0x0780)
+#define U3D_TQERRIER0 (SSUSB_DEV_BASE + 0x0784)
+#define U3D_TQERRIESR0 (SSUSB_DEV_BASE + 0x0788)
+#define U3D_TQERRIECR0 (SSUSB_DEV_BASE + 0x078C)
+#define U3D_RQERRIR0 (SSUSB_DEV_BASE + 0x07C0)
+#define U3D_RQERRIER0 (SSUSB_DEV_BASE + 0x07C4)
+#define U3D_RQERRIESR0 (SSUSB_DEV_BASE + 0x07C8)
+#define U3D_RQERRIECR0 (SSUSB_DEV_BASE + 0x07CC)
+#define U3D_RQERRIR1 (SSUSB_DEV_BASE + 0x07D0)
+#define U3D_RQERRIER1 (SSUSB_DEV_BASE + 0x07D4)
+#define U3D_RQERRIESR1 (SSUSB_DEV_BASE + 0x07D8)
+#define U3D_RQERRIECR1 (SSUSB_DEV_BASE + 0x07DC)
+
+#define U3D_CAP_EP0FFSZ (SSUSB_DEV_BASE + 0x0C04)
+#define U3D_CAP_EPNTXFFSZ (SSUSB_DEV_BASE + 0x0C08)
+#define U3D_CAP_EPNRXFFSZ (SSUSB_DEV_BASE + 0x0C0C)
+#define U3D_CAP_EPINFO (SSUSB_DEV_BASE + 0x0C10)
+#define U3D_MISC_CTRL (SSUSB_DEV_BASE + 0x0C84)
+
+/*---------------- SSUSB_DEV FIELD DEFINITION ---------------*/
+
+/* U3D_LV1ISR */
+#define EP_CTRL_INTR BIT(5)
+#define MAC2_INTR BIT(4)
+#define DMA_INTR BIT(3)
+#define MAC3_INTR BIT(2)
+#define QMU_INTR BIT(1)
+#define BMU_INTR BIT(0)
+
+/* U3D_LV1IECR */
+#define LV1IECR_MSK GENMASK(31, 0)
+
+/* U3D_EPISR */
+#define EPRISR(x) (BIT(16) << (x))
+#define SETUPENDISR BIT(16)
+#define EPTISR(x) (BIT(0) << (x))
+#define EP0ISR BIT(0)
+
+/* U3D_EP0CSR */
+#define EP0_SENDSTALL BIT(25)
+#define EP0_FIFOFULL BIT(23)
+#define EP0_SENTSTALL BIT(22)
+#define EP0_DPHTX BIT(20)
+#define EP0_DATAEND BIT(19)
+#define EP0_TXPKTRDY BIT(18)
+#define EP0_SETUPPKTRDY BIT(17)
+#define EP0_RXPKTRDY BIT(16)
+#define EP0_MAXPKTSZ_MSK GENMASK(9, 0)
+#define EP0_MAXPKTSZ(x) ((x) & EP0_MAXPKTSZ_MSK)
+#define EP0_W1C_BITS (~(EP0_RXPKTRDY | EP0_SETUPPKTRDY | EP0_SENTSTALL))
+
+/* U3D_TX1CSR0 */
+#define TX_DMAREQEN BIT(29)
+#define TX_FIFOFULL BIT(25)
+#define TX_FIFOEMPTY BIT(24)
+#define TX_SENTSTALL BIT(22)
+#define TX_SENDSTALL BIT(21)
+#define TX_TXPKTRDY BIT(16)
+#define TX_TXMAXPKTSZ_MSK GENMASK(10, 0)
+#define TX_TXMAXPKTSZ(x) ((x) & TX_TXMAXPKTSZ_MSK)
+#define TX_W1C_BITS (~(TX_SENTSTALL))
+
+/* U3D_TX1CSR1 */
+#define TX_MAX_PKT_G2(x) (((x) & 0xff) << 24)
+#define TX_MULT_G2(x) (((x) & 0x7) << 21)
+#define TX_MULT_OG(x) (((x) & 0x3) << 22)
+#define TX_MAX_PKT_OG(x) (((x) & 0x3f) << 16)
+#define TX_SLOT(x) (((x) & 0x3f) << 8)
+#define TX_TYPE(x) (((x) & 0x3) << 4)
+#define TX_SS_BURST(x) (((x) & 0xf) << 0)
+#define TX_MULT(g2c, x) \
+({ \
+ typeof(x) x_ = (x); \
+ (g2c) ? TX_MULT_G2(x_) : TX_MULT_OG(x_); \
+})
+#define TX_MAX_PKT(g2c, x) \
+({ \
+ typeof(x) x_ = (x); \
+ (g2c) ? TX_MAX_PKT_G2(x_) : TX_MAX_PKT_OG(x_); \
+})
+
+/* for TX_TYPE & RX_TYPE */
+#define TYPE_BULK (0x0)
+#define TYPE_INT (0x1)
+#define TYPE_ISO (0x2)
+#define TYPE_MASK (0x3)
+
+/* U3D_TX1CSR2 */
+#define TX_BINTERVAL(x) (((x) & 0xff) << 24)
+#define TX_FIFOSEGSIZE(x) (((x) & 0xf) << 16)
+#define TX_FIFOADDR(x) (((x) & 0x1fff) << 0)
+
+/* U3D_RX1CSR0 */
+#define RX_DMAREQEN BIT(29)
+#define RX_SENTSTALL BIT(22)
+#define RX_SENDSTALL BIT(21)
+#define RX_RXPKTRDY BIT(16)
+#define RX_RXMAXPKTSZ_MSK GENMASK(10, 0)
+#define RX_RXMAXPKTSZ(x) ((x) & RX_RXMAXPKTSZ_MSK)
+#define RX_W1C_BITS (~(RX_SENTSTALL | RX_RXPKTRDY))
+
+/* U3D_RX1CSR1 */
+#define RX_MAX_PKT_G2(x) (((x) & 0xff) << 24)
+#define RX_MULT_G2(x) (((x) & 0x7) << 21)
+#define RX_MULT_OG(x) (((x) & 0x3) << 22)
+#define RX_MAX_PKT_OG(x) (((x) & 0x3f) << 16)
+#define RX_SLOT(x) (((x) & 0x3f) << 8)
+#define RX_TYPE(x) (((x) & 0x3) << 4)
+#define RX_SS_BURST(x) (((x) & 0xf) << 0)
+#define RX_MULT(g2c, x) \
+({ \
+ typeof(x) x_ = (x); \
+ (g2c) ? RX_MULT_G2(x_) : RX_MULT_OG(x_); \
+})
+#define RX_MAX_PKT(g2c, x) \
+({ \
+ typeof(x) x_ = (x); \
+ (g2c) ? RX_MAX_PKT_G2(x_) : RX_MAX_PKT_OG(x_); \
+})
+
+/* U3D_RX1CSR2 */
+#define RX_BINTERVAL(x) (((x) & 0xff) << 24)
+#define RX_FIFOSEGSIZE(x) (((x) & 0xf) << 16)
+#define RX_FIFOADDR(x) (((x) & 0x1fff) << 0)
+
+/* U3D_QCR0 */
+#define QMU_RX_CS_EN(x) (BIT(16) << (x))
+#define QMU_TX_CS_EN(x) (BIT(0) << (x))
+#define QMU_CS16B_EN BIT(0)
+
+/* U3D_QCR1 */
+#define QMU_TX_ZLP(x) (BIT(0) << (x))
+
+/* U3D_QCR3 */
+#define QMU_RX_COZ(x) (BIT(16) << (x))
+#define QMU_RX_ZLP(x) (BIT(0) << (x))
+
+/* U3D_TXQCSR1 */
+/* U3D_RXQCSR1 */
+#define QMU_Q_ACTIVE BIT(15)
+#define QMU_Q_STOP BIT(2)
+#define QMU_Q_RESUME BIT(1)
+#define QMU_Q_START BIT(0)
+
+/* U3D_QISAR0, U3D_QIER0, U3D_QIESR0, U3D_QIECR0 */
+#define QMU_RX_DONE_INT(x) (BIT(16) << (x))
+#define QMU_TX_DONE_INT(x) (BIT(0) << (x))
+
+/* U3D_QISAR1, U3D_QIER1, U3D_QIESR1, U3D_QIECR1 */
+#define RXQ_ZLPERR_INT BIT(20)
+#define RXQ_LENERR_INT BIT(18)
+#define RXQ_CSERR_INT BIT(17)
+#define RXQ_EMPTY_INT BIT(16)
+#define TXQ_LENERR_INT BIT(2)
+#define TXQ_CSERR_INT BIT(1)
+#define TXQ_EMPTY_INT BIT(0)
+
+/* U3D_TQERRIR0, U3D_TQERRIER0, U3D_TQERRIESR0, U3D_TQERRIECR0 */
+#define QMU_TX_LEN_ERR(x) (BIT(16) << (x))
+#define QMU_TX_CS_ERR(x) (BIT(0) << (x))
+
+/* U3D_RQERRIR0, U3D_RQERRIER0, U3D_RQERRIESR0, U3D_RQERRIECR0 */
+#define QMU_RX_LEN_ERR(x) (BIT(16) << (x))
+#define QMU_RX_CS_ERR(x) (BIT(0) << (x))
+
+/* U3D_RQERRIR1, U3D_RQERRIER1, U3D_RQERRIESR1, U3D_RQERRIECR1 */
+#define QMU_RX_ZLP_ERR(n) (BIT(16) << (n))
+
+/* U3D_CAP_EPINFO */
+#define CAP_RX_EP_NUM(x) (((x) >> 8) & 0x1f)
+#define CAP_TX_EP_NUM(x) ((x) & 0x1f)
+
+/* U3D_MISC_CTRL */
+#define VBUS_ON BIT(1)
+#define VBUS_FRC_EN BIT(0)
+
+/*---------------- SSUSB_EPCTL_CSR REGISTER DEFINITION ----------------*/
+
+#define U3D_DEVICE_CONF (SSUSB_EPCTL_CSR_BASE + 0x0000)
+#define U3D_EP_RST (SSUSB_EPCTL_CSR_BASE + 0x0004)
+
+#define U3D_DEV_LINK_INTR_ENABLE (SSUSB_EPCTL_CSR_BASE + 0x0050)
+#define U3D_DEV_LINK_INTR (SSUSB_EPCTL_CSR_BASE + 0x0054)
+
+/*---------------- SSUSB_EPCTL_CSR FIELD DEFINITION ----------------*/
+
+/* U3D_DEVICE_CONF */
+#define DEV_ADDR_MSK GENMASK(30, 24)
+#define DEV_ADDR(x) ((0x7f & (x)) << 24)
+#define HW_USB2_3_SEL BIT(18)
+#define SW_USB2_3_SEL_EN BIT(17)
+#define SW_USB2_3_SEL BIT(16)
+#define SSUSB_DEV_SPEED(x) ((x) & 0x7)
+
+/* U3D_EP_RST */
+#define EP1_IN_RST BIT(17)
+#define EP1_OUT_RST BIT(1)
+#define EP_RST(is_in, epnum) (((is_in) ? BIT(16) : BIT(0)) << (epnum))
+#define EP0_RST BIT(0)
+
+/* U3D_DEV_LINK_INTR_ENABLE */
+/* U3D_DEV_LINK_INTR */
+#define SSUSB_DEV_SPEED_CHG_INTR BIT(0)
+
+/*---------------- SSUSB_USB3_MAC_CSR REGISTER DEFINITION ----------------*/
+
+#define U3D_LTSSM_CTRL (SSUSB_USB3_MAC_CSR_BASE + 0x0010)
+#define U3D_USB3_CONFIG (SSUSB_USB3_MAC_CSR_BASE + 0x001C)
+
+#define U3D_LINK_STATE_MACHINE (SSUSB_USB3_MAC_CSR_BASE + 0x0134)
+#define U3D_LTSSM_INTR_ENABLE (SSUSB_USB3_MAC_CSR_BASE + 0x013C)
+#define U3D_LTSSM_INTR (SSUSB_USB3_MAC_CSR_BASE + 0x0140)
+
+#define U3D_U3U2_SWITCH_CTRL (SSUSB_USB3_MAC_CSR_BASE + 0x0170)
+
+/*---------------- SSUSB_USB3_MAC_CSR FIELD DEFINITION ----------------*/
+
+/* U3D_LTSSM_CTRL */
+#define FORCE_POLLING_FAIL BIT(4)
+#define FORCE_RXDETECT_FAIL BIT(3)
+#define SOFT_U3_EXIT_EN BIT(2)
+#define COMPLIANCE_EN BIT(1)
+#define U1_GO_U2_EN BIT(0)
+
+/* U3D_USB3_CONFIG */
+#define USB3_EN BIT(0)
+
+/* U3D_LINK_STATE_MACHINE */
+#define LTSSM_STATE(x) ((x) & 0x1f)
+
+/* U3D_LTSSM_INTR_ENABLE */
+/* U3D_LTSSM_INTR */
+#define U3_RESUME_INTR BIT(18)
+#define U3_LFPS_TMOUT_INTR BIT(17)
+#define VBUS_FALL_INTR BIT(16)
+#define VBUS_RISE_INTR BIT(15)
+#define RXDET_SUCCESS_INTR BIT(14)
+#define EXIT_U3_INTR BIT(13)
+#define EXIT_U2_INTR BIT(12)
+#define EXIT_U1_INTR BIT(11)
+#define ENTER_U3_INTR BIT(10)
+#define ENTER_U2_INTR BIT(9)
+#define ENTER_U1_INTR BIT(8)
+#define ENTER_U0_INTR BIT(7)
+#define RECOVERY_INTR BIT(6)
+#define WARM_RST_INTR BIT(5)
+#define HOT_RST_INTR BIT(4)
+#define LOOPBACK_INTR BIT(3)
+#define COMPLIANCE_INTR BIT(2)
+#define SS_DISABLE_INTR BIT(1)
+#define SS_INACTIVE_INTR BIT(0)
+
+/* U3D_U3U2_SWITCH_CTRL */
+#define SOFTCON_CLR_AUTO_EN BIT(0)
+
+/*---------------- SSUSB_USB3_SYS_CSR REGISTER DEFINITION ----------------*/
+
+#define U3D_LINK_UX_INACT_TIMER (SSUSB_USB3_SYS_CSR_BASE + 0x020C)
+#define U3D_LINK_POWER_CONTROL (SSUSB_USB3_SYS_CSR_BASE + 0x0210)
+#define U3D_LINK_ERR_COUNT (SSUSB_USB3_SYS_CSR_BASE + 0x0214)
+
+/*---------------- SSUSB_USB3_SYS_CSR FIELD DEFINITION ----------------*/
+
+/* U3D_LINK_UX_INACT_TIMER */
+#define DEV_U2_INACT_TIMEOUT_MSK GENMASK(23, 16)
+#define DEV_U2_INACT_TIMEOUT_VALUE(x) (((x) & 0xff) << 16)
+#define U2_INACT_TIMEOUT_MSK GENMASK(15, 8)
+#define U1_INACT_TIMEOUT_MSK GENMASK(7, 0)
+#define U1_INACT_TIMEOUT_VALUE(x) ((x) & 0xff)
+
+/* U3D_LINK_POWER_CONTROL */
+#define SW_U2_ACCEPT_ENABLE BIT(9)
+#define SW_U1_ACCEPT_ENABLE BIT(8)
+#define UX_EXIT BIT(5)
+#define LGO_U3 BIT(4)
+#define LGO_U2 BIT(3)
+#define LGO_U1 BIT(2)
+#define SW_U2_REQUEST_ENABLE BIT(1)
+#define SW_U1_REQUEST_ENABLE BIT(0)
+
+/* U3D_LINK_ERR_COUNT */
+#define CLR_LINK_ERR_CNT BIT(16)
+#define LINK_ERROR_COUNT GENMASK(15, 0)
+
+/*---------------- SSUSB_USB2_CSR REGISTER DEFINITION ----------------*/
+
+#define U3D_POWER_MANAGEMENT (SSUSB_USB2_CSR_BASE + 0x0004)
+#define U3D_DEVICE_CONTROL (SSUSB_USB2_CSR_BASE + 0x000C)
+#define U3D_USB2_TEST_MODE (SSUSB_USB2_CSR_BASE + 0x0014)
+#define U3D_COMMON_USB_INTR_ENABLE (SSUSB_USB2_CSR_BASE + 0x0018)
+#define U3D_COMMON_USB_INTR (SSUSB_USB2_CSR_BASE + 0x001C)
+#define U3D_LINK_RESET_INFO (SSUSB_USB2_CSR_BASE + 0x0024)
+#define U3D_USB20_FRAME_NUM (SSUSB_USB2_CSR_BASE + 0x003C)
+#define U3D_USB20_LPM_PARAMETER (SSUSB_USB2_CSR_BASE + 0x0044)
+#define U3D_USB20_MISC_CONTROL (SSUSB_USB2_CSR_BASE + 0x004C)
+#define U3D_USB20_OPSTATE (SSUSB_USB2_CSR_BASE + 0x0060)
+
+/*---------------- SSUSB_USB2_CSR FIELD DEFINITION ----------------*/
+
+/* U3D_POWER_MANAGEMENT */
+#define LPM_BESL_STALL BIT(14)
+#define LPM_BESLD_STALL BIT(13)
+#define LPM_RWP BIT(11)
+#define LPM_HRWE BIT(10)
+#define LPM_MODE(x) (((x) & 0x3) << 8)
+#define ISO_UPDATE BIT(7)
+#define SOFT_CONN BIT(6)
+#define HS_ENABLE BIT(5)
+#define RESUME BIT(2)
+#define SUSPENDM_ENABLE BIT(0)
+
+/* U3D_DEVICE_CONTROL */
+#define DC_HOSTREQ BIT(1)
+#define DC_SESSION BIT(0)
+
+/* U3D_USB2_TEST_MODE */
+#define U2U3_AUTO_SWITCH BIT(10)
+#define LPM_FORCE_STALL BIT(8)
+#define FIFO_ACCESS BIT(6)
+#define FORCE_FS BIT(5)
+#define FORCE_HS BIT(4)
+#define TEST_PACKET_MODE BIT(3)
+#define TEST_K_MODE BIT(2)
+#define TEST_J_MODE BIT(1)
+#define TEST_SE0_NAK_MODE BIT(0)
+
+/* U3D_COMMON_USB_INTR_ENABLE */
+/* U3D_COMMON_USB_INTR */
+#define LPM_RESUME_INTR BIT(9)
+#define LPM_INTR BIT(8)
+#define DISCONN_INTR BIT(5)
+#define CONN_INTR BIT(4)
+#define SOF_INTR BIT(3)
+#define RESET_INTR BIT(2)
+#define RESUME_INTR BIT(1)
+#define SUSPEND_INTR BIT(0)
+
+/* U3D_LINK_RESET_INFO */
+#define WTCHRP_MSK GENMASK(19, 16)
+
+/* U3D_USB20_LPM_PARAMETER */
+#define LPM_BESLCK_U3(x) (((x) & 0xf) << 12)
+#define LPM_BESLCK(x) (((x) & 0xf) << 8)
+#define LPM_BESLDCK(x) (((x) & 0xf) << 4)
+#define LPM_BESL GENMASK(3, 0)
+
+/* U3D_USB20_MISC_CONTROL */
+#define LPM_U3_ACK_EN BIT(0)
+
+/*---------------- SSUSB_SIFSLV_IPPC REGISTER DEFINITION ----------------*/
+
+#define U3D_SSUSB_IP_PW_CTRL0 (SSUSB_SIFSLV_IPPC_BASE + 0x0000)
+#define U3D_SSUSB_IP_PW_CTRL1 (SSUSB_SIFSLV_IPPC_BASE + 0x0004)
+#define U3D_SSUSB_IP_PW_CTRL2 (SSUSB_SIFSLV_IPPC_BASE + 0x0008)
+#define U3D_SSUSB_IP_PW_CTRL3 (SSUSB_SIFSLV_IPPC_BASE + 0x000C)
+#define U3D_SSUSB_IP_PW_STS1 (SSUSB_SIFSLV_IPPC_BASE + 0x0010)
+#define U3D_SSUSB_IP_PW_STS2 (SSUSB_SIFSLV_IPPC_BASE + 0x0014)
+#define U3D_SSUSB_OTG_STS (SSUSB_SIFSLV_IPPC_BASE + 0x0018)
+#define U3D_SSUSB_OTG_STS_CLR (SSUSB_SIFSLV_IPPC_BASE + 0x001C)
+#define U3D_SSUSB_IP_XHCI_CAP (SSUSB_SIFSLV_IPPC_BASE + 0x0024)
+#define U3D_SSUSB_IP_DEV_CAP (SSUSB_SIFSLV_IPPC_BASE + 0x0028)
+#define U3D_SSUSB_OTG_INT_EN (SSUSB_SIFSLV_IPPC_BASE + 0x002C)
+#define U3D_SSUSB_U3_CTRL_0P (SSUSB_SIFSLV_IPPC_BASE + 0x0030)
+#define U3D_SSUSB_U2_CTRL_0P (SSUSB_SIFSLV_IPPC_BASE + 0x0050)
+#define U3D_SSUSB_REF_CK_CTRL (SSUSB_SIFSLV_IPPC_BASE + 0x008C)
+#define U3D_SSUSB_DEV_RST_CTRL (SSUSB_SIFSLV_IPPC_BASE + 0x0098)
+#define U3D_SSUSB_HW_ID (SSUSB_SIFSLV_IPPC_BASE + 0x00A0)
+#define U3D_SSUSB_HW_SUB_ID (SSUSB_SIFSLV_IPPC_BASE + 0x00A4)
+#define U3D_SSUSB_IP_TRUNK_VERS (U3D_SSUSB_HW_SUB_ID)
+#define U3D_SSUSB_PRB_CTRL0 (SSUSB_SIFSLV_IPPC_BASE + 0x00B0)
+#define U3D_SSUSB_PRB_CTRL1 (SSUSB_SIFSLV_IPPC_BASE + 0x00B4)
+#define U3D_SSUSB_PRB_CTRL2 (SSUSB_SIFSLV_IPPC_BASE + 0x00B8)
+#define U3D_SSUSB_PRB_CTRL3 (SSUSB_SIFSLV_IPPC_BASE + 0x00BC)
+#define U3D_SSUSB_PRB_CTRL4 (SSUSB_SIFSLV_IPPC_BASE + 0x00C0)
+#define U3D_SSUSB_PRB_CTRL5 (SSUSB_SIFSLV_IPPC_BASE + 0x00C4)
+#define U3D_SSUSB_IP_SPARE0 (SSUSB_SIFSLV_IPPC_BASE + 0x00C8)
+
+/*---------------- SSUSB_SIFSLV_IPPC FIELD DEFINITION ----------------*/
+
+/* U3D_SSUSB_IP_PW_CTRL0 */
+#define SSUSB_IP_SW_RST BIT(0)
+
+/* U3D_SSUSB_IP_PW_CTRL1 */
+#define SSUSB_IP_HOST_PDN BIT(0)
+
+/* U3D_SSUSB_IP_PW_CTRL2 */
+#define SSUSB_IP_DEV_PDN BIT(0)
+
+/* U3D_SSUSB_IP_PW_CTRL3 */
+#define SSUSB_IP_PCIE_PDN BIT(0)
+
+/* U3D_SSUSB_IP_PW_STS1 */
+#define SSUSB_IP_SLEEP_STS BIT(30)
+#define SSUSB_U3_MAC_RST_B_STS BIT(16)
+#define SSUSB_XHCI_RST_B_STS BIT(11)
+#define SSUSB_SYS125_RST_B_STS BIT(10)
+#define SSUSB_REF_RST_B_STS BIT(8)
+#define SSUSB_SYSPLL_STABLE BIT(0)
+
+/* U3D_SSUSB_IP_PW_STS2 */
+#define SSUSB_U2_MAC_SYS_RST_B_STS BIT(0)
+
+/* U3D_SSUSB_OTG_STS */
+#define SSUSB_VBUS_VALID BIT(9)
+
+/* U3D_SSUSB_OTG_STS_CLR */
+#define SSUSB_VBUS_INTR_CLR BIT(6)
+
+/* U3D_SSUSB_IP_XHCI_CAP */
+#define SSUSB_IP_XHCI_U2_PORT_NUM(x) (((x) >> 8) & 0xff)
+#define SSUSB_IP_XHCI_U3_PORT_NUM(x) ((x) & 0xff)
+
+/* U3D_SSUSB_IP_DEV_CAP */
+#define SSUSB_IP_DEV_U3_PORT_NUM(x) ((x) & 0xff)
+
+/* U3D_SSUSB_OTG_INT_EN */
+#define SSUSB_VBUS_CHG_INT_A_EN BIT(7)
+#define SSUSB_VBUS_CHG_INT_B_EN BIT(6)
+
+/* U3D_SSUSB_U3_CTRL_0P */
+#define SSUSB_U3_PORT_SSP_SPEED BIT(9)
+#define SSUSB_U3_PORT_DUAL_MODE BIT(7)
+#define SSUSB_U3_PORT_HOST_SEL BIT(2)
+#define SSUSB_U3_PORT_PDN BIT(1)
+#define SSUSB_U3_PORT_DIS BIT(0)
+
+/* U3D_SSUSB_U2_CTRL_0P */
+#define SSUSB_U2_PORT_RG_IDDIG BIT(12)
+#define SSUSB_U2_PORT_FORCE_IDDIG BIT(11)
+#define SSUSB_U2_PORT_VBUSVALID BIT(9)
+#define SSUSB_U2_PORT_OTG_SEL BIT(7)
+#define SSUSB_U2_PORT_HOST BIT(2)
+#define SSUSB_U2_PORT_PDN BIT(1)
+#define SSUSB_U2_PORT_DIS BIT(0)
+#define SSUSB_U2_PORT_HOST_SEL (SSUSB_U2_PORT_VBUSVALID | SSUSB_U2_PORT_HOST)
+
+/* U3D_SSUSB_DEV_RST_CTRL */
+#define SSUSB_DEV_SW_RST BIT(0)
+
+/* U3D_SSUSB_IP_TRUNK_VERS */
+#define IP_TRUNK_VERS(x) (((x) >> 16) & 0xffff)
+
+#endif /* _SSUSB_HW_REGS_H_ */
diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c
new file mode 100644
index 00000000000..3795e695e87
--- /dev/null
+++ b/drivers/usb/mtu3/mtu3_plat.c
@@ -0,0 +1,369 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * Author: Chunfeng Yun <chunfeng.yun@mediatek.com>
+ */
+
+#include <common.h>
+#include <dm/lists.h>
+#include <linux/iopoll.h>
+
+#include "mtu3.h"
+#include "mtu3_dr.h"
+
+void ssusb_set_force_mode(struct ssusb_mtk *ssusb,
+ enum mtu3_dr_force_mode mode)
+{
+ u32 value;
+
+ value = mtu3_readl(ssusb->ippc_base, SSUSB_U2_CTRL(0));
+ switch (mode) {
+ case MTU3_DR_FORCE_DEVICE:
+ value |= SSUSB_U2_PORT_FORCE_IDDIG | SSUSB_U2_PORT_RG_IDDIG;
+ break;
+ case MTU3_DR_FORCE_HOST:
+ value |= SSUSB_U2_PORT_FORCE_IDDIG;
+ value &= ~SSUSB_U2_PORT_RG_IDDIG;
+ break;
+ case MTU3_DR_FORCE_NONE:
+ value &= ~(SSUSB_U2_PORT_FORCE_IDDIG | SSUSB_U2_PORT_RG_IDDIG);
+ break;
+ default:
+ return;
+ }
+ mtu3_writel(ssusb->ippc_base, SSUSB_U2_CTRL(0), value);
+}
+
+/* u2-port0 should be powered on and enabled; */
+int ssusb_check_clocks(struct ssusb_mtk *ssusb, u32 ex_clks)
+{
+ void __iomem *ibase = ssusb->ippc_base;
+ u32 value, check_val;
+ int ret;
+
+ check_val = ex_clks | SSUSB_SYS125_RST_B_STS | SSUSB_SYSPLL_STABLE |
+ SSUSB_REF_RST_B_STS;
+
+ ret = readl_poll_timeout(ibase + U3D_SSUSB_IP_PW_STS1, value,
+ ((value & check_val) == check_val), 10000);
+ if (ret) {
+ dev_err(ssusb->dev, "clks of sts1 are not stable!\n");
+ return ret;
+ }
+
+ ret = readl_poll_timeout(ibase + U3D_SSUSB_IP_PW_STS2, value,
+ (value & SSUSB_U2_MAC_SYS_RST_B_STS), 10000);
+ if (ret) {
+ dev_err(ssusb->dev, "mac2 clock is not stable\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+int ssusb_phy_setup(struct ssusb_mtk *ssusb)
+{
+ struct udevice *dev = ssusb->dev;
+ struct phy_bulk *phys = &ssusb->phys;
+ int ret;
+
+ ret = generic_phy_get_bulk(dev, phys);
+ if (ret)
+ return ret;
+
+ ret = generic_phy_init_bulk(phys);
+ if (ret)
+ return ret;
+
+ ret = generic_phy_power_on_bulk(phys);
+ if (ret)
+ generic_phy_exit_bulk(phys);
+
+ return ret;
+}
+
+void ssusb_phy_shutdown(struct ssusb_mtk *ssusb)
+{
+ generic_phy_power_off_bulk(&ssusb->phys);
+ generic_phy_exit_bulk(&ssusb->phys);
+}
+
+static int ssusb_rscs_init(struct ssusb_mtk *ssusb)
+{
+ int ret = 0;
+
+ ret = regulator_set_enable(ssusb->vusb33_supply, true);
+ if (ret < 0 && ret != -ENOSYS) {
+ dev_err(ssusb->dev, "failed to enable vusb33\n");
+ goto vusb33_err;
+ }
+
+ ret = clk_enable_bulk(&ssusb->clks);
+ if (ret)
+ goto clks_err;
+
+ ret = ssusb_phy_setup(ssusb);
+ if (ret) {
+ dev_err(ssusb->dev, "failed to setup phy\n");
+ goto phy_err;
+ }
+
+ return 0;
+
+phy_err:
+ clk_disable_bulk(&ssusb->clks);
+clks_err:
+ regulator_set_enable(ssusb->vusb33_supply, false);
+vusb33_err:
+ return ret;
+}
+
+static void ssusb_rscs_exit(struct ssusb_mtk *ssusb)
+{
+ clk_disable_bulk(&ssusb->clks);
+ regulator_set_enable(ssusb->vusb33_supply, false);
+ ssusb_phy_shutdown(ssusb);
+}
+
+static void ssusb_ip_sw_reset(struct ssusb_mtk *ssusb)
+{
+ /* reset whole ip (xhci & u3d) */
+ mtu3_setbits(ssusb->ippc_base, U3D_SSUSB_IP_PW_CTRL0, SSUSB_IP_SW_RST);
+ udelay(1);
+ mtu3_clrbits(ssusb->ippc_base, U3D_SSUSB_IP_PW_CTRL0, SSUSB_IP_SW_RST);
+}
+
+static int get_ssusb_rscs(struct udevice *dev, struct ssusb_mtk *ssusb)
+{
+ struct udevice *child;
+ int ret;
+
+ ret = device_get_supply_regulator(dev, "vusb33-supply",
+ &ssusb->vusb33_supply);
+ if (ret) /* optional, ignore error */
+ dev_warn(dev, "can't get optional vusb33 %d\n", ret);
+
+ ret = device_get_supply_regulator(dev, "vbus-supply",
+ &ssusb->vbus_supply);
+ if (ret) /* optional, ignore error */
+ dev_warn(dev, "can't get optional vbus regulator %d!\n", ret);
+
+ ret = clk_get_bulk(dev, &ssusb->clks);
+ if (ret) {
+ dev_err(dev, "failed to get clocks %d!\n", ret);
+ return ret;
+ }
+
+ ssusb->ippc_base = devfdt_remap_addr_name(dev, "ippc");
+ if (!ssusb->ippc_base) {
+ dev_err(dev, "error mapping memory for ippc\n");
+ return -ENODEV;
+ }
+
+ ret = device_find_first_child(dev, &child);
+ if (ret || !child) {
+ dev_err(dev, "failed to get child %d!\n", ret);
+ return ret;
+ }
+
+ ssusb->mac_base = devfdt_remap_addr_name(child, "mac");
+ if (!ssusb->mac_base) {
+ dev_err(dev, "error mapping memory for mac\n");
+ return -ENODEV;
+ }
+
+ ssusb->dr_mode = usb_get_dr_mode(child->node);
+
+ if (ssusb->dr_mode == USB_DR_MODE_UNKNOWN ||
+ ssusb->dr_mode == USB_DR_MODE_OTG)
+ ssusb->dr_mode = USB_DR_MODE_PERIPHERAL;
+
+ if (IS_ENABLED(CONFIG_USB_MTU3_GADGET))
+ ssusb->dr_mode = USB_DR_MODE_PERIPHERAL;
+ else if (IS_ENABLED(CONFIG_USB_MTU3_HOST))
+ ssusb->dr_mode = USB_DR_MODE_HOST;
+
+ dev_info(dev, "dr_mode: %d, ippc: 0x%p, mac: 0x%p\n",
+ ssusb->dr_mode, ssusb->ippc_base, ssusb->mac_base);
+
+ return 0;
+}
+
+static int mtu3_probe(struct udevice *dev)
+{
+ struct ssusb_mtk *ssusb = dev_get_priv(dev);
+ int ret = -ENOMEM;
+
+ ssusb->dev = dev;
+
+ ret = get_ssusb_rscs(dev, ssusb);
+ if (ret)
+ return ret;
+
+ ret = ssusb_rscs_init(ssusb);
+ if (ret)
+ return ret;
+
+ ssusb_ip_sw_reset(ssusb);
+
+ return 0;
+}
+
+static int mtu3_remove(struct udevice *dev)
+{
+ struct ssusb_mtk *ssusb = dev_to_ssusb(dev);
+
+ ssusb_rscs_exit(ssusb);
+ return 0;
+}
+
+static const struct udevice_id ssusb_of_match[] = {
+ {.compatible = "mediatek,ssusb",},
+ {},
+};
+
+#if CONFIG_IS_ENABLED(DM_USB_GADGET)
+int dm_usb_gadget_handle_interrupts(struct udevice *dev)
+{
+ struct mtu3 *mtu = dev_get_priv(dev);
+
+ mtu3_irq(0, mtu);
+
+ return 0;
+}
+
+static int mtu3_gadget_probe(struct udevice *dev)
+{
+ struct ssusb_mtk *ssusb = dev_to_ssusb(dev->parent);
+ struct mtu3 *mtu = dev_get_priv(dev);
+
+ mtu->dev = dev;
+ ssusb->u3d = mtu;
+ return ssusb_gadget_init(ssusb);
+}
+
+static int mtu3_gadget_remove(struct udevice *dev)
+{
+ struct mtu3 *mtu = dev_get_priv(dev);
+
+ ssusb_gadget_exit(mtu->ssusb);
+ return 0;
+}
+
+U_BOOT_DRIVER(mtu3_peripheral) = {
+ .name = "mtu3-peripheral",
+ .id = UCLASS_USB_GADGET_GENERIC,
+ .of_match = ssusb_of_match,
+ .probe = mtu3_gadget_probe,
+ .remove = mtu3_gadget_remove,
+ .priv_auto_alloc_size = sizeof(struct mtu3),
+};
+#endif
+
+#if defined(CONFIG_SPL_USB_HOST_SUPPORT) || \
+ (!defined(CONFIG_SPL_BUILD) && defined(CONFIG_USB_HOST))
+static int mtu3_host_probe(struct udevice *dev)
+{
+ struct ssusb_mtk *ssusb = dev_to_ssusb(dev->parent);
+ struct mtu3_host *u3h = dev_get_priv(dev);
+ struct xhci_hcor *hcor;
+ int rc;
+
+ u3h->dev = dev;
+ ssusb->u3h = u3h;
+ rc = ssusb_host_init(ssusb);
+ if (rc)
+ return rc;
+
+ u3h->ctrl.quirks = XHCI_MTK_HOST;
+ hcor = (struct xhci_hcor *)((uintptr_t)u3h->hcd +
+ HC_LENGTH(xhci_readl(&u3h->hcd->cr_capbase)));
+
+ return xhci_register(dev, u3h->hcd, hcor);
+}
+
+static int mtu3_host_remove(struct udevice *dev)
+{
+ struct mtu3_host *u3h = dev_get_priv(dev);
+
+ xhci_deregister(dev);
+ ssusb_host_exit(u3h->ssusb);
+ return 0;
+}
+
+U_BOOT_DRIVER(mtu3_host) = {
+ .name = "mtu3-host",
+ .id = UCLASS_USB,
+ .of_match = ssusb_of_match,
+ .probe = mtu3_host_probe,
+ .remove = mtu3_host_remove,
+ .priv_auto_alloc_size = sizeof(struct mtu3_host),
+ .ops = &xhci_usb_ops,
+ .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
+#endif
+
+static int mtu3_glue_bind(struct udevice *parent)
+{
+ struct udevice *dev;
+ enum usb_dr_mode dr_mode;
+ const char *driver;
+ const char *name;
+ ofnode node;
+ int ret;
+
+ node = ofnode_by_compatible(parent->node, "mediatek,ssusb");
+ if (!ofnode_valid(node))
+ return -ENODEV;
+
+ name = ofnode_get_name(node);
+ dr_mode = usb_get_dr_mode(node);
+
+ switch (dr_mode) {
+#if CONFIG_IS_ENABLED(DM_USB_GADGET)
+ case USB_DR_MODE_PERIPHERAL:
+ case USB_DR_MODE_OTG:
+ dev_dbg(parent, "%s: dr_mode: peripheral\n", __func__);
+ driver = "mtu3-peripheral";
+ break;
+#endif
+
+#if defined(CONFIG_SPL_USB_HOST_SUPPORT) || \
+ (!defined(CONFIG_SPL_BUILD) && defined(CONFIG_USB_HOST))
+ case USB_DR_MODE_HOST:
+ dev_dbg(parent, "%s: dr_mode: host\n", __func__);
+ driver = "mtu3-host";
+ break;
+#endif
+ default:
+ dev_err(parent, "%s: unsupported dr_mode %d\n",
+ __func__, dr_mode);
+ return -ENODEV;
+ };
+
+ dev_dbg(parent, "%s: node name: %s, driver %s, dr_mode %d\n",
+ __func__, name, driver, dr_mode);
+
+ ret = device_bind_driver_to_node(parent, driver, name, node, &dev);
+ if (ret)
+ dev_err(parent, "%s: not able to bind usb device mode\n",
+ __func__);
+
+ return ret;
+}
+
+static const struct udevice_id mtu3_of_match[] = {
+ {.compatible = "mediatek,mtu3",},
+ {},
+};
+
+U_BOOT_DRIVER(mtu3) = {
+ .name = "mtu3",
+ .id = UCLASS_NOP,
+ .of_match = mtu3_of_match,
+ .bind = mtu3_glue_bind,
+ .probe = mtu3_probe,
+ .remove = mtu3_remove,
+ .priv_auto_alloc_size = sizeof(struct ssusb_mtk),
+};
diff --git a/drivers/usb/mtu3/mtu3_qmu.c b/drivers/usb/mtu3/mtu3_qmu.c
new file mode 100644
index 00000000000..801c2bc416d
--- /dev/null
+++ b/drivers/usb/mtu3/mtu3_qmu.c
@@ -0,0 +1,505 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * mtu3_qmu.c - Queue Management Unit driver for device controller
+ *
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * Author: Chunfeng Yun <chunfeng.yun@mediatek.com>
+ */
+
+/*
+ * Queue Management Unit (QMU) is designed to unload SW effort
+ * to serve DMA interrupts.
+ * By preparing General Purpose Descriptor (GPD) and Buffer Descriptor (BD),
+ * SW links data buffers and triggers QMU to send / receive data to
+ * host / from device at a time.
+ * And now only GPD is supported.
+ *
+ * For more detailed information, please refer to QMU Programming Guide
+ */
+
+#include <asm/cache.h>
+#include <cpu_func.h>
+#include <linux/iopoll.h>
+#include <linux/types.h>
+
+#include "mtu3.h"
+
+#define QMU_CHECKSUM_LEN 16
+
+#define GPD_FLAGS_HWO BIT(0)
+#define GPD_FLAGS_BDP BIT(1)
+#define GPD_FLAGS_BPS BIT(2)
+#define GPD_FLAGS_IOC BIT(7)
+
+#define GPD_EXT_FLAG_ZLP BIT(5)
+
+#define DCACHELINE_SIZE CONFIG_SYS_CACHELINE_SIZE
+
+void mtu3_flush_cache(uintptr_t addr, u32 len)
+{
+ WARN_ON(!(void *)addr || len == 0);
+
+ flush_dcache_range(addr & ~(DCACHELINE_SIZE - 1),
+ ALIGN(addr + len, DCACHELINE_SIZE));
+}
+
+void mtu3_inval_cache(uintptr_t addr, u32 len)
+{
+ WARN_ON(!(void *)addr || len == 0);
+
+ invalidate_dcache_range(addr & ~(DCACHELINE_SIZE - 1),
+ ALIGN(addr + len, DCACHELINE_SIZE));
+}
+
+static struct qmu_gpd *gpd_dma_to_virt(struct mtu3_gpd_ring *ring,
+ dma_addr_t dma_addr)
+{
+ dma_addr_t dma_base = ring->dma;
+ struct qmu_gpd *gpd_head = ring->start;
+ u32 offset = (dma_addr - dma_base) / sizeof(*gpd_head);
+
+ if (offset >= MAX_GPD_NUM)
+ return NULL;
+
+ return gpd_head + offset;
+}
+
+static dma_addr_t gpd_virt_to_dma(struct mtu3_gpd_ring *ring,
+ struct qmu_gpd *gpd)
+{
+ dma_addr_t dma_base = ring->dma;
+ struct qmu_gpd *gpd_head = ring->start;
+ u32 offset;
+
+ offset = gpd - gpd_head;
+ if (offset >= MAX_GPD_NUM)
+ return 0;
+
+ return dma_base + (offset * sizeof(*gpd));
+}
+
+static void gpd_ring_init(struct mtu3_gpd_ring *ring, struct qmu_gpd *gpd)
+{
+ ring->start = gpd;
+ ring->enqueue = gpd;
+ ring->dequeue = gpd;
+ ring->end = gpd + MAX_GPD_NUM - 1;
+}
+
+static void reset_gpd_list(struct mtu3_ep *mep)
+{
+ struct mtu3_gpd_ring *ring = &mep->gpd_ring;
+ struct qmu_gpd *gpd = ring->start;
+
+ if (gpd) {
+ gpd->flag &= ~GPD_FLAGS_HWO;
+ gpd_ring_init(ring, gpd);
+ mtu3_flush_cache((uintptr_t)gpd, sizeof(*gpd));
+ }
+}
+
+int mtu3_gpd_ring_alloc(struct mtu3_ep *mep)
+{
+ struct qmu_gpd *gpd;
+ struct mtu3_gpd_ring *ring = &mep->gpd_ring;
+
+ /* software own all gpds as default */
+ gpd = memalign(DCACHELINE_SIZE, QMU_GPD_RING_SIZE);
+ if (!gpd)
+ return -ENOMEM;
+
+ memset(gpd, 0, QMU_GPD_RING_SIZE);
+ ring->dma = (dma_addr_t)gpd;
+ gpd_ring_init(ring, gpd);
+
+ return 0;
+}
+
+void mtu3_gpd_ring_free(struct mtu3_ep *mep)
+{
+ struct mtu3_gpd_ring *ring = &mep->gpd_ring;
+
+ kfree(ring->start);
+ memset(ring, 0, sizeof(*ring));
+}
+
+void mtu3_qmu_resume(struct mtu3_ep *mep)
+{
+ struct mtu3 *mtu = mep->mtu;
+ void __iomem *mbase = mtu->mac_base;
+ int epnum = mep->epnum;
+ u32 offset;
+
+ offset = mep->is_in ? USB_QMU_TQCSR(epnum) : USB_QMU_RQCSR(epnum);
+
+ mtu3_writel(mbase, offset, QMU_Q_RESUME);
+ if (!(mtu3_readl(mbase, offset) & QMU_Q_ACTIVE))
+ mtu3_writel(mbase, offset, QMU_Q_RESUME);
+}
+
+static struct qmu_gpd *advance_enq_gpd(struct mtu3_gpd_ring *ring)
+{
+ if (ring->enqueue < ring->end)
+ ring->enqueue++;
+ else
+ ring->enqueue = ring->start;
+
+ return ring->enqueue;
+}
+
+static struct qmu_gpd *advance_deq_gpd(struct mtu3_gpd_ring *ring)
+{
+ if (ring->dequeue < ring->end)
+ ring->dequeue++;
+ else
+ ring->dequeue = ring->start;
+
+ return ring->dequeue;
+}
+
+/* check if a ring is emtpy */
+static int gpd_ring_empty(struct mtu3_gpd_ring *ring)
+{
+ struct qmu_gpd *enq = ring->enqueue;
+ struct qmu_gpd *next;
+
+ if (ring->enqueue < ring->end)
+ next = enq + 1;
+ else
+ next = ring->start;
+
+ /* one gpd is reserved to simplify gpd preparation */
+ return next == ring->dequeue;
+}
+
+int mtu3_prepare_transfer(struct mtu3_ep *mep)
+{
+ return gpd_ring_empty(&mep->gpd_ring);
+}
+
+static int mtu3_prepare_tx_gpd(struct mtu3_ep *mep, struct mtu3_request *mreq)
+{
+ struct qmu_gpd *enq;
+ struct mtu3_gpd_ring *ring = &mep->gpd_ring;
+ struct qmu_gpd *gpd = ring->enqueue;
+ struct usb_request *req = &mreq->request;
+
+ /* set all fields to zero as default value */
+ memset(gpd, 0, sizeof(*gpd));
+
+ gpd->buffer = cpu_to_le32((u32)req->dma);
+ gpd->buf_len = cpu_to_le16(req->length);
+
+ /* get the next GPD */
+ enq = advance_enq_gpd(ring);
+ dev_dbg(mep->mtu->dev, "TX-EP%d queue gpd=%p, enq=%p\n",
+ mep->epnum, gpd, enq);
+
+ enq->flag &= ~GPD_FLAGS_HWO;
+ gpd->next_gpd = cpu_to_le32((u32)gpd_virt_to_dma(ring, enq));
+
+ if (req->zero)
+ gpd->ext_flag |= GPD_EXT_FLAG_ZLP;
+
+ gpd->flag |= GPD_FLAGS_IOC | GPD_FLAGS_HWO;
+
+ mreq->gpd = gpd;
+
+ if (req->length)
+ mtu3_flush_cache((uintptr_t)req->buf, req->length);
+
+ mtu3_flush_cache((uintptr_t)gpd, sizeof(*gpd));
+
+ return 0;
+}
+
+static int mtu3_prepare_rx_gpd(struct mtu3_ep *mep, struct mtu3_request *mreq)
+{
+ struct qmu_gpd *enq;
+ struct mtu3_gpd_ring *ring = &mep->gpd_ring;
+ struct qmu_gpd *gpd = ring->enqueue;
+ struct usb_request *req = &mreq->request;
+
+ /* set all fields to zero as default value */
+ memset(gpd, 0, sizeof(*gpd));
+
+ gpd->buffer = cpu_to_le32((u32)req->dma);
+ gpd->data_buf_len = cpu_to_le16(req->length);
+
+ /* get the next GPD */
+ enq = advance_enq_gpd(ring);
+ dev_dbg(mep->mtu->dev, "RX-EP%d queue gpd=%p, enq=%p\n",
+ mep->epnum, gpd, enq);
+
+ enq->flag &= ~GPD_FLAGS_HWO;
+ gpd->next_gpd = cpu_to_le32((u32)gpd_virt_to_dma(ring, enq));
+ gpd->flag |= GPD_FLAGS_IOC | GPD_FLAGS_HWO;
+
+ mreq->gpd = gpd;
+
+ mtu3_inval_cache((uintptr_t)req->buf, req->length);
+ mtu3_flush_cache((uintptr_t)gpd, sizeof(*gpd));
+
+ return 0;
+}
+
+void mtu3_insert_gpd(struct mtu3_ep *mep, struct mtu3_request *mreq)
+{
+ if (mep->is_in)
+ mtu3_prepare_tx_gpd(mep, mreq);
+ else
+ mtu3_prepare_rx_gpd(mep, mreq);
+}
+
+int mtu3_qmu_start(struct mtu3_ep *mep)
+{
+ struct mtu3 *mtu = mep->mtu;
+ void __iomem *mbase = mtu->mac_base;
+ struct mtu3_gpd_ring *ring = &mep->gpd_ring;
+ u8 epnum = mep->epnum;
+
+ if (mep->is_in) {
+ /* set QMU start address */
+ mtu3_writel(mbase, USB_QMU_TQSAR(epnum), ring->dma);
+ mtu3_setbits(mbase, MU3D_EP_TXCR0(epnum), TX_DMAREQEN);
+ /* send zero length packet according to ZLP flag in GPD */
+ mtu3_setbits(mbase, U3D_QCR1, QMU_TX_ZLP(epnum));
+ mtu3_writel(mbase, U3D_TQERRIESR0,
+ QMU_TX_LEN_ERR(epnum) | QMU_TX_CS_ERR(epnum));
+
+ if (mtu3_readl(mbase, USB_QMU_TQCSR(epnum)) & QMU_Q_ACTIVE) {
+ dev_warn(mtu->dev, "Tx %d Active Now!\n", epnum);
+ return 0;
+ }
+ mtu3_writel(mbase, USB_QMU_TQCSR(epnum), QMU_Q_START);
+
+ } else {
+ mtu3_writel(mbase, USB_QMU_RQSAR(epnum), ring->dma);
+ mtu3_setbits(mbase, MU3D_EP_RXCR0(epnum), RX_DMAREQEN);
+ /* don't expect ZLP */
+ mtu3_clrbits(mbase, U3D_QCR3, QMU_RX_ZLP(epnum));
+ /* move to next GPD when receive ZLP */
+ mtu3_setbits(mbase, U3D_QCR3, QMU_RX_COZ(epnum));
+ mtu3_writel(mbase, U3D_RQERRIESR0,
+ QMU_RX_LEN_ERR(epnum) | QMU_RX_CS_ERR(epnum));
+ mtu3_writel(mbase, U3D_RQERRIESR1, QMU_RX_ZLP_ERR(epnum));
+
+ if (mtu3_readl(mbase, USB_QMU_RQCSR(epnum)) & QMU_Q_ACTIVE) {
+ dev_warn(mtu->dev, "Rx %d Active Now!\n", epnum);
+ return 0;
+ }
+ mtu3_writel(mbase, USB_QMU_RQCSR(epnum), QMU_Q_START);
+ }
+
+ return 0;
+}
+
+/* may called in atomic context */
+void mtu3_qmu_stop(struct mtu3_ep *mep)
+{
+ struct mtu3 *mtu = mep->mtu;
+ void __iomem *mbase = mtu->mac_base;
+ int epnum = mep->epnum;
+ u32 value = 0;
+ u32 qcsr;
+ int ret;
+
+ qcsr = mep->is_in ? USB_QMU_TQCSR(epnum) : USB_QMU_RQCSR(epnum);
+
+ if (!(mtu3_readl(mbase, qcsr) & QMU_Q_ACTIVE)) {
+ dev_dbg(mtu->dev, "%s's qmu is inactive now!\n", mep->name);
+ return;
+ }
+ mtu3_writel(mbase, qcsr, QMU_Q_STOP);
+
+ ret = readl_poll_timeout(mbase + qcsr, value,
+ !(value & QMU_Q_ACTIVE), 1000);
+ if (ret) {
+ dev_err(mtu->dev, "stop %s's qmu failed\n", mep->name);
+ return;
+ }
+
+ dev_dbg(mtu->dev, "%s's qmu stop now!\n", mep->name);
+}
+
+void mtu3_qmu_flush(struct mtu3_ep *mep)
+{
+ dev_dbg(mep->mtu->dev, "%s flush QMU %s\n", __func__,
+ ((mep->is_in) ? "TX" : "RX"));
+
+ /*Stop QMU */
+ mtu3_qmu_stop(mep);
+ reset_gpd_list(mep);
+}
+
+/*
+ * NOTE: request list maybe is already empty as following case:
+ * queue_tx --> qmu_interrupt(clear interrupt pending, schedule tasklet)-->
+ * queue_tx --> process_tasklet(meanwhile, the second one is transferred,
+ * tasklet process both of them)-->qmu_interrupt for second one.
+ * To avoid upper case, put qmu_done_tx in ISR directly to process it.
+ */
+static void qmu_done_tx(struct mtu3 *mtu, u8 epnum)
+{
+ struct mtu3_ep *mep = mtu->in_eps + epnum;
+ struct mtu3_gpd_ring *ring = &mep->gpd_ring;
+ void __iomem *mbase = mtu->mac_base;
+ struct qmu_gpd *gpd = ring->dequeue;
+ struct qmu_gpd *gpd_current = NULL;
+ struct usb_request *req = NULL;
+ struct mtu3_request *mreq;
+ dma_addr_t cur_gpd_dma;
+
+ /*transfer phy address got from QMU register to virtual address */
+ cur_gpd_dma = mtu3_readl(mbase, USB_QMU_TQCPR(epnum));
+ gpd_current = gpd_dma_to_virt(ring, cur_gpd_dma);
+ mtu3_inval_cache((uintptr_t)gpd, sizeof(*gpd));
+
+ dev_dbg(mtu->dev, "%s EP%d, last=%p, current=%p, enq=%p\n",
+ __func__, epnum, gpd, gpd_current, ring->enqueue);
+
+ while (gpd != gpd_current && !(gpd->flag & GPD_FLAGS_HWO)) {
+ mreq = next_request(mep);
+
+ if (!mreq || mreq->gpd != gpd) {
+ dev_err(mtu->dev, "no correct TX req is found\n");
+ break;
+ }
+
+ req = &mreq->request;
+ req->actual = le16_to_cpu(gpd->buf_len);
+ mtu3_req_complete(mep, req, 0);
+
+ gpd = advance_deq_gpd(ring);
+ mtu3_inval_cache((uintptr_t)gpd, sizeof(*gpd));
+ }
+
+ dev_dbg(mtu->dev, "%s EP%d, deq=%p, enq=%p, complete\n",
+ __func__, epnum, ring->dequeue, ring->enqueue);
+}
+
+static void qmu_done_rx(struct mtu3 *mtu, u8 epnum)
+{
+ struct mtu3_ep *mep = mtu->out_eps + epnum;
+ struct mtu3_gpd_ring *ring = &mep->gpd_ring;
+ void __iomem *mbase = mtu->mac_base;
+ struct qmu_gpd *gpd = ring->dequeue;
+ struct qmu_gpd *gpd_current = NULL;
+ struct usb_request *req = NULL;
+ struct mtu3_request *mreq;
+ dma_addr_t cur_gpd_dma;
+
+ cur_gpd_dma = mtu3_readl(mbase, USB_QMU_RQCPR(epnum));
+ gpd_current = gpd_dma_to_virt(ring, cur_gpd_dma);
+ mtu3_inval_cache((uintptr_t)gpd, sizeof(*gpd));
+
+ dev_dbg(mtu->dev, "%s EP%d, last=%p, current=%p, enq=%p\n",
+ __func__, epnum, gpd, gpd_current, ring->enqueue);
+
+ while (gpd != gpd_current && !(gpd->flag & GPD_FLAGS_HWO)) {
+ mreq = next_request(mep);
+
+ if (!mreq || mreq->gpd != gpd) {
+ dev_err(mtu->dev, "no correct RX req is found\n");
+ break;
+ }
+ req = &mreq->request;
+
+ req->actual = le16_to_cpu(gpd->buf_len);
+ mtu3_req_complete(mep, req, 0);
+
+ gpd = advance_deq_gpd(ring);
+ mtu3_inval_cache((uintptr_t)gpd, sizeof(*gpd));
+ }
+
+ dev_dbg(mtu->dev, "%s EP%d, deq=%p, enq=%p, complete\n",
+ __func__, epnum, ring->dequeue, ring->enqueue);
+}
+
+static void qmu_done_isr(struct mtu3 *mtu, u32 done_status)
+{
+ int i;
+
+ for (i = 1; i < mtu->num_eps; i++) {
+ if (done_status & QMU_RX_DONE_INT(i))
+ qmu_done_rx(mtu, i);
+ if (done_status & QMU_TX_DONE_INT(i))
+ qmu_done_tx(mtu, i);
+ }
+}
+
+static void qmu_exception_isr(struct mtu3 *mtu, u32 qmu_status)
+{
+ void __iomem *mbase = mtu->mac_base;
+ u32 errval;
+ int i;
+
+ if ((qmu_status & RXQ_CSERR_INT) || (qmu_status & RXQ_LENERR_INT)) {
+ errval = mtu3_readl(mbase, U3D_RQERRIR0);
+ for (i = 1; i < mtu->num_eps; i++) {
+ if (errval & QMU_RX_CS_ERR(i))
+ dev_err(mtu->dev, "Rx %d CS error!\n", i);
+
+ if (errval & QMU_RX_LEN_ERR(i))
+ dev_err(mtu->dev, "RX %d Length error\n", i);
+ }
+ mtu3_writel(mbase, U3D_RQERRIR0, errval);
+ }
+
+ if (qmu_status & RXQ_ZLPERR_INT) {
+ errval = mtu3_readl(mbase, U3D_RQERRIR1);
+ for (i = 1; i < mtu->num_eps; i++) {
+ if (errval & QMU_RX_ZLP_ERR(i))
+ dev_dbg(mtu->dev, "RX EP%d Recv ZLP\n", i);
+ }
+ mtu3_writel(mbase, U3D_RQERRIR1, errval);
+ }
+
+ if ((qmu_status & TXQ_CSERR_INT) || (qmu_status & TXQ_LENERR_INT)) {
+ errval = mtu3_readl(mbase, U3D_TQERRIR0);
+ for (i = 1; i < mtu->num_eps; i++) {
+ if (errval & QMU_TX_CS_ERR(i))
+ dev_err(mtu->dev, "Tx %d checksum error!\n", i);
+
+ if (errval & QMU_TX_LEN_ERR(i))
+ dev_err(mtu->dev, "Tx %d zlp error!\n", i);
+ }
+ mtu3_writel(mbase, U3D_TQERRIR0, errval);
+ }
+}
+
+irqreturn_t mtu3_qmu_isr(struct mtu3 *mtu)
+{
+ void __iomem *mbase = mtu->mac_base;
+ u32 qmu_status;
+ u32 qmu_done_status;
+
+ /* U3D_QISAR1 is read update */
+ qmu_status = mtu3_readl(mbase, U3D_QISAR1);
+ qmu_status &= mtu3_readl(mbase, U3D_QIER1);
+
+ qmu_done_status = mtu3_readl(mbase, U3D_QISAR0);
+ qmu_done_status &= mtu3_readl(mbase, U3D_QIER0);
+ mtu3_writel(mbase, U3D_QISAR0, qmu_done_status); /* W1C */
+ dev_dbg(mtu->dev, "=== QMUdone[tx=%x, rx=%x] QMUexp[%x] ===\n",
+ (qmu_done_status & 0xFFFF), qmu_done_status >> 16,
+ qmu_status);
+
+ if (qmu_done_status)
+ qmu_done_isr(mtu, qmu_done_status);
+
+ if (qmu_status)
+ qmu_exception_isr(mtu, qmu_status);
+
+ return IRQ_HANDLED;
+}
+
+void mtu3_qmu_init(struct mtu3 *mtu)
+{
+ compiletime_assert(QMU_GPD_SIZE == 16, "QMU_GPD size SHOULD be 16B");
+}
+
+void mtu3_qmu_exit(struct mtu3 *mtu)
+{
+}
diff --git a/drivers/usb/mtu3/mtu3_qmu.h b/drivers/usb/mtu3/mtu3_qmu.h
new file mode 100644
index 00000000000..ba8a3aa309b
--- /dev/null
+++ b/drivers/usb/mtu3/mtu3_qmu.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * mtu3_qmu.h - Queue Management Unit driver header
+ *
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * Author: Chunfeng Yun <chunfeng.yun@mediatek.com>
+ */
+
+#ifndef __MTK_QMU_H__
+#define __MTK_QMU_H__
+
+#define MAX_GPD_NUM 16
+#define QMU_GPD_SIZE (sizeof(struct qmu_gpd))
+#define QMU_GPD_RING_SIZE (MAX_GPD_NUM * QMU_GPD_SIZE)
+
+#define GPD_BUF_SIZE 65532
+
+void mtu3_flush_cache(uintptr_t addr, u32 len);
+void mtu3_inval_cache(uintptr_t addr, u32 len);
+
+void mtu3_qmu_stop(struct mtu3_ep *mep);
+int mtu3_qmu_start(struct mtu3_ep *mep);
+void mtu3_qmu_resume(struct mtu3_ep *mep);
+void mtu3_qmu_flush(struct mtu3_ep *mep);
+
+void mtu3_insert_gpd(struct mtu3_ep *mep, struct mtu3_request *mreq);
+int mtu3_prepare_transfer(struct mtu3_ep *mep);
+
+int mtu3_gpd_ring_alloc(struct mtu3_ep *mep);
+void mtu3_gpd_ring_free(struct mtu3_ep *mep);
+
+irqreturn_t mtu3_qmu_isr(struct mtu3 *mtu);
+void mtu3_qmu_init(struct mtu3 *mtu);
+void mtu3_qmu_exit(struct mtu3 *mtu);
+
+#endif
diff --git a/drivers/usb/musb-new/musb_dsps.c b/drivers/usb/musb-new/musb_dsps.c
index 236bab3dc1e..d55a920ae59 100644
--- a/drivers/usb/musb-new/musb_dsps.c
+++ b/drivers/usb/musb-new/musb_dsps.c
@@ -340,7 +340,7 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
* Also, DRVVBUS pulses for SRP (but not at 5V) ...
*/
if ((usbintr & MUSB_INTR_BABBLE) && is_host_enabled(musb))
- pr_info("CAUTION: musb: Babble Interrupt Occured\n");
+ pr_info("CAUTION: musb: Babble Interrupt Occurred\n");
if (usbintr & ((1 << wrp->drvvbus) << wrp->usb_shift)) {
int drvvbus = dsps_readl(reg_base, wrp->status);
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index e2e1f9c476b..b1cb745d59e 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -939,4 +939,37 @@ config SPLASH_SOURCE
In case the environment variable "splashfile" is not defined the
default name 'splash.bmp' will be used.
+config VIDEO_BMP_GZIP
+ bool "Gzip compressed BMP image support"
+ depends on CMD_BMP || SPLASH_SCREEN
+ help
+ If this option is set, additionally to standard BMP
+ images, gzipped BMP images can be displayed via the
+ splashscreen support or the bmp command.
+
+config VIDEO_BMP_RLE8
+ bool "Run length encoded BMP image (RLE8) support"
+ depends on DM_VIDEO || CFB_CONSOLE
+ help
+ If this option is set, the 8-bit RLE compressed BMP images
+ is supported.
+
+config BMP_16BPP
+ bool "16-bit-per-pixel BMP image support"
+ depends on DM_VIDEO || LCD
+ help
+ Support display of bitmaps file with 16-bit-per-pixel
+
+config BMP_24BPP
+ bool "24-bit-per-pixel BMP image support"
+ depends on DM_VIDEO || LCD
+ help
+ Support display of bitmaps file with 24-bit-per-pixel.
+
+config BMP_32BPP
+ bool "32-bit-per-pixel BMP image support"
+ depends on DM_VIDEO || LCD
+ help
+ Support display of bitmaps file with 32-bit-per-pixel.
+
endmenu
diff --git a/drivers/video/dw_mipi_dsi.c b/drivers/video/dw_mipi_dsi.c
index 2743836fb4c..4055ef49b6e 100644
--- a/drivers/video/dw_mipi_dsi.c
+++ b/drivers/video/dw_mipi_dsi.c
@@ -485,15 +485,27 @@ static void dw_mipi_dsi_set_mode(struct dw_mipi_dsi *dsi,
static void dw_mipi_dsi_init_pll(struct dw_mipi_dsi *dsi)
{
+ const struct mipi_dsi_phy_ops *phy_ops = dsi->phy_ops;
+ unsigned int esc_rate;
+ u32 esc_clk_division;
+
/*
* The maximum permitted escape clock is 20MHz and it is derived from
- * lanebyteclk, which is running at "lane_mbps / 8". Thus we want:
+ * lanebyteclk, which is running at "lane_mbps / 8".
+ */
+ if (phy_ops->get_esc_clk_rate)
+ phy_ops->get_esc_clk_rate(dsi->device, &esc_rate);
+ else
+ esc_rate = 20; /* Default to 20MHz */
+
+ /*
+ * We want:
*
- * (lane_mbps >> 3) / esc_clk_division < 20
+ * (lane_mbps >> 3) / esc_clk_division < X
* which is:
- * (lane_mbps >> 3) / 20 > esc_clk_division
+ * (lane_mbps >> 3) / X > esc_clk_division
*/
- u32 esc_clk_division = (dsi->lane_mbps >> 3) / 20 + 1;
+ esc_clk_division = (dsi->lane_mbps >> 3) / esc_rate + 1;
dsi_write(dsi, DSI_PWR_UP, RESET);
@@ -645,8 +657,13 @@ static void dw_mipi_dsi_vertical_timing_config(struct dw_mipi_dsi *dsi,
static void dw_mipi_dsi_dphy_timing_config(struct dw_mipi_dsi *dsi)
{
+ const struct mipi_dsi_phy_ops *phy_ops = dsi->phy_ops;
+ struct mipi_dsi_phy_timing timing = {0x40, 0x40, 0x40, 0x40};
u32 hw_version;
+ if (phy_ops->get_timing)
+ phy_ops->get_timing(dsi->device, dsi->lane_mbps, &timing);
+
/*
* TODO dw drv improvements
* data & clock lane timers should be computed according to panel
@@ -658,16 +675,16 @@ static void dw_mipi_dsi_dphy_timing_config(struct dw_mipi_dsi *dsi)
hw_version = dsi_read(dsi, DSI_VERSION) & VERSION;
if (hw_version >= HWVER_131) {
- dsi_write(dsi, DSI_PHY_TMR_CFG, PHY_HS2LP_TIME_V131(0x40) |
- PHY_LP2HS_TIME_V131(0x40));
+ dsi_write(dsi, DSI_PHY_TMR_CFG, PHY_HS2LP_TIME_V131(timing.data_hs2lp) |
+ PHY_LP2HS_TIME_V131(timing.data_lp2hs));
dsi_write(dsi, DSI_PHY_TMR_RD_CFG, MAX_RD_TIME_V131(10000));
} else {
- dsi_write(dsi, DSI_PHY_TMR_CFG, PHY_HS2LP_TIME(0x40) |
- PHY_LP2HS_TIME(0x40) | MAX_RD_TIME(10000));
+ dsi_write(dsi, DSI_PHY_TMR_CFG, PHY_HS2LP_TIME(timing.data_hs2lp) |
+ PHY_LP2HS_TIME(timing.data_lp2hs) | MAX_RD_TIME(10000));
}
- dsi_write(dsi, DSI_PHY_TMR_LPCLK_CFG, PHY_CLKHS2LP_TIME(0x40)
- | PHY_CLKLP2HS_TIME(0x40));
+ dsi_write(dsi, DSI_PHY_TMR_LPCLK_CFG, PHY_CLKHS2LP_TIME(timing.clk_hs2lp)
+ | PHY_CLKLP2HS_TIME(timing.clk_lp2hs));
}
static void dw_mipi_dsi_dphy_interface_config(struct dw_mipi_dsi *dsi)
diff --git a/drivers/video/pwm_backlight.c b/drivers/video/pwm_backlight.c
index 468a5703bdb..9519180ceb3 100644
--- a/drivers/video/pwm_backlight.c
+++ b/drivers/video/pwm_backlight.c
@@ -33,7 +33,7 @@
* @cur_level: Current level for the backlight (index or value)
* @default_level: Default level for the backlight (index or value)
* @min_level: Minimum level of the backlight (full off)
- * @min_level: Maximum level of the backlight (full on)
+ * @max_level: Maximum level of the backlight (full on)
* @enabled: true if backlight is enabled
*/
struct pwm_backlight_priv {
@@ -63,7 +63,7 @@ static int set_pwm(struct pwm_backlight_priv *priv)
int ret;
duty_cycle = priv->period_ns * (priv->cur_level - priv->min_level) /
- (priv->max_level - priv->min_level + 1);
+ (priv->max_level - priv->min_level);
ret = pwm_set_config(priv->pwm, priv->channel, priv->period_ns,
duty_cycle);
if (ret)
diff --git a/include/configs/advantech_dms-ba16.h b/include/configs/advantech_dms-ba16.h
index 07d804cbcbf..1ecb7c9df89 100644
--- a/include/configs/advantech_dms-ba16.h
+++ b/include/configs/advantech_dms-ba16.h
@@ -197,8 +197,6 @@
#define CONFIG_SYS_FSL_USDHC_NUM 3
/* Framebuffer */
-#define CONFIG_VIDEO_BMP_RLE8
-#define CONFIG_BMP_16BPP
#define CONFIG_VIDEO_LOGO
#define CONFIG_VIDEO_BMP_LOGO
#define CONFIG_IMX_HDMI
diff --git a/include/configs/apalis_imx6.h b/include/configs/apalis_imx6.h
index 4cffc7f887d..0e81ef94d37 100644
--- a/include/configs/apalis_imx6.h
+++ b/include/configs/apalis_imx6.h
@@ -67,8 +67,6 @@
/* Framebuffer and LCD */
#define CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE
-#define CONFIG_VIDEO_BMP_RLE8
-#define CONFIG_BMP_16BPP
#define CONFIG_VIDEO_LOGO
#define CONFIG_VIDEO_BMP_LOGO
#define CONFIG_IMX_HDMI
diff --git a/include/configs/aristainetos2.h b/include/configs/aristainetos2.h
index fd28f44ae31..6e8595caad8 100644
--- a/include/configs/aristainetos2.h
+++ b/include/configs/aristainetos2.h
@@ -441,8 +441,6 @@
#define CONFIG_IMX_VIDEO_SKIP
#define CONFIG_VIDEO_LOGO
#define CONFIG_VIDEO_BMP_LOGO
-#define CONFIG_BMP_16BPP
-#define CONFIG_VIDEO_BMP_RLE8
#define CONFIG_IMX6_PWM_PER_CLK 66000000
diff --git a/include/configs/cgtqmx6eval.h b/include/configs/cgtqmx6eval.h
index 9d0f516b7dc..2ef6bfdba86 100644
--- a/include/configs/cgtqmx6eval.h
+++ b/include/configs/cgtqmx6eval.h
@@ -60,8 +60,6 @@
#define CONFIG_USBD_HS
/* Framebuffer */
-#define CONFIG_VIDEO_BMP_RLE8
-#define CONFIG_BMP_16BPP
#define CONFIG_VIDEO_LOGO
#define CONFIG_VIDEO_BMP_LOGO
#define CONFIG_IMX_HDMI
diff --git a/include/configs/cm_fx6.h b/include/configs/cm_fx6.h
index 6915dcb6615..72eb19b581c 100644
--- a/include/configs/cm_fx6.h
+++ b/include/configs/cm_fx6.h
@@ -204,8 +204,6 @@
/* Display */
#define CONFIG_IMX_HDMI
-#define CONFIG_VIDEO_BMP_RLE8
-
#define CONFIG_VIDEO_LOGO
#define CONFIG_VIDEO_BMP_LOGO
diff --git a/include/configs/colibri-imx6ull.h b/include/configs/colibri-imx6ull.h
index 63b3fef34c5..d373fda0168 100644
--- a/include/configs/colibri-imx6ull.h
+++ b/include/configs/colibri-imx6ull.h
@@ -152,8 +152,6 @@
#define CONFIG_VIDEO_MXS
#define MXS_LCDIF_BASE MX6UL_LCDIF1_BASE_ADDR
#define CONFIG_VIDEO_LOGO
-#define CONFIG_BMP_16BPP
-#define CONFIG_VIDEO_BMP_RLE8
#define CONFIG_VIDEO_BMP_LOGO
#endif
diff --git a/include/configs/colibri_imx6.h b/include/configs/colibri_imx6.h
index 097e620de4a..c014d6b2d5f 100644
--- a/include/configs/colibri_imx6.h
+++ b/include/configs/colibri_imx6.h
@@ -55,8 +55,6 @@
/* Framebuffer and LCD */
#define CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE
-#define CONFIG_VIDEO_BMP_RLE8
-#define CONFIG_BMP_16BPP
#define CONFIG_VIDEO_LOGO
#define CONFIG_VIDEO_BMP_LOGO
#define CONFIG_IMX_HDMI
diff --git a/include/configs/colibri_imx7.h b/include/configs/colibri_imx7.h
index 76088d53a3b..b3601abe2cb 100644
--- a/include/configs/colibri_imx7.h
+++ b/include/configs/colibri_imx7.h
@@ -215,8 +215,6 @@
#if defined(CONFIG_VIDEO) || defined(CONFIG_DM_VIDEO)
#define CONFIG_VIDEO_MXS
#define CONFIG_VIDEO_LOGO
-#define CONFIG_BMP_16BPP
-#define CONFIG_VIDEO_BMP_RLE8
#define CONFIG_VIDEO_BMP_LOGO
#endif
diff --git a/include/configs/embestmx6boards.h b/include/configs/embestmx6boards.h
index ef4ea9a29bf..b18db76d2f1 100644
--- a/include/configs/embestmx6boards.h
+++ b/include/configs/embestmx6boards.h
@@ -72,8 +72,6 @@
#endif
/* Framebuffer */
-#define CONFIG_VIDEO_BMP_RLE8
-#define CONFIG_BMP_16BPP
#define CONFIG_VIDEO_LOGO
#define CONFIG_VIDEO_BMP_LOGO
#define CONFIG_IMX_HDMI
diff --git a/include/configs/imx6-engicam.h b/include/configs/imx6-engicam.h
index 13cd54a8dc1..bfe83b8cba5 100644
--- a/include/configs/imx6-engicam.h
+++ b/include/configs/imx6-engicam.h
@@ -165,8 +165,6 @@
#ifdef CONFIG_VIDEO_IPUV3
# define CONFIG_IMX_VIDEO_SKIP
-# define CONFIG_BMP_16BPP
-# define CONFIG_VIDEO_BMP_RLE8
# define CONFIG_VIDEO_LOGO
# define CONFIG_VIDEO_BMP_LOGO
#endif
diff --git a/include/configs/imxrt1050-evk.h b/include/configs/imxrt1050-evk.h
index 559e6880b7d..c8d661fb3ee 100644
--- a/include/configs/imxrt1050-evk.h
+++ b/include/configs/imxrt1050-evk.h
@@ -31,8 +31,6 @@
#ifdef CONFIG_DM_VIDEO
#define CONFIG_VIDEO_MXS
#define CONFIG_VIDEO_LOGO
-#define CONFIG_BMP_16BPP
-#define CONFIG_VIDEO_BMP_RLE8
#define CONFIG_VIDEO_BMP_LOGO
#define CONFIG_EXTRA_ENV_SETTINGS \
diff --git a/include/configs/m53menlo.h b/include/configs/m53menlo.h
index c15e7d22bc8..52c95de5231 100644
--- a/include/configs/m53menlo.h
+++ b/include/configs/m53menlo.h
@@ -126,9 +126,6 @@
/*
* LCD
*/
-#define CONFIG_VIDEO_BMP_RLE8
-#define CONFIG_VIDEO_BMP_GZIP
-#define CONFIG_BMP_16BPP
#define CONFIG_VIDEO_LOGO
#define CONFIG_SYS_VIDEO_LOGO_MAX_SIZE (2 << 20)
diff --git a/include/configs/meson64.h b/include/configs/meson64.h
index c895a24eca3..cee69006802 100644
--- a/include/configs/meson64.h
+++ b/include/configs/meson64.h
@@ -18,10 +18,6 @@
/* For splashscreen */
#ifdef CONFIG_DM_VIDEO
-#define CONFIG_VIDEO_BMP_RLE8
-#define CONFIG_BMP_16BPP
-#define CONFIG_BMP_24BPP
-#define CONFIG_BMP_32BPP
#define STDOUT_CFG "vidconsole,serial"
#else
#define STDOUT_CFG "serial"
diff --git a/include/configs/mx23evk.h b/include/configs/mx23evk.h
index 8f170b25297..3f13e60531c 100644
--- a/include/configs/mx23evk.h
+++ b/include/configs/mx23evk.h
@@ -31,9 +31,6 @@
/* Framebuffer support */
#ifdef CONFIG_VIDEO
#define CONFIG_VIDEO_LOGO
-#define CONFIG_BMP_16BPP
-#define CONFIG_VIDEO_BMP_RLE8
-#define CONFIG_VIDEO_BMP_GZIP
#define CONFIG_SYS_VIDEO_LOGO_MAX_SIZE (512 << 10)
#endif
diff --git a/include/configs/mx28evk.h b/include/configs/mx28evk.h
index d65f6a900f9..a65df486081 100644
--- a/include/configs/mx28evk.h
+++ b/include/configs/mx28evk.h
@@ -52,9 +52,6 @@
/* Framebuffer support */
#ifdef CONFIG_VIDEO
#define CONFIG_VIDEO_LOGO
-#define CONFIG_BMP_16BPP
-#define CONFIG_VIDEO_BMP_RLE8
-#define CONFIG_VIDEO_BMP_GZIP
#define CONFIG_SYS_VIDEO_LOGO_MAX_SIZE (512 << 10)
#endif
diff --git a/include/configs/mx51evk.h b/include/configs/mx51evk.h
index 58712926b4d..49f88c27dcd 100644
--- a/include/configs/mx51evk.h
+++ b/include/configs/mx51evk.h
@@ -65,8 +65,6 @@
#define CONFIG_MXC_USB_FLAGS MXC_EHCI_POWER_PINS_ENABLED
/* Framebuffer and LCD */
-#define CONFIG_VIDEO_BMP_RLE8
-#define CONFIG_BMP_16BPP
#define CONFIG_VIDEO_LOGO
#define CONFIG_ETHPRIME "FEC0"
diff --git a/include/configs/mx53loco.h b/include/configs/mx53loco.h
index 90d800cd254..a0dd33aecd3 100644
--- a/include/configs/mx53loco.h
+++ b/include/configs/mx53loco.h
@@ -176,8 +176,6 @@
#endif
/* Framebuffer and LCD */
-#define CONFIG_VIDEO_BMP_RLE8
-#define CONFIG_BMP_16BPP
#define CONFIG_VIDEO_LOGO
#endif /* __CONFIG_H */
diff --git a/include/configs/mx6cuboxi.h b/include/configs/mx6cuboxi.h
index 20b757e621b..cfab9a7fc02 100644
--- a/include/configs/mx6cuboxi.h
+++ b/include/configs/mx6cuboxi.h
@@ -29,8 +29,6 @@
#endif
/* Framebuffer */
-#define CONFIG_VIDEO_BMP_RLE8
-#define CONFIG_BMP_16BPP
#define CONFIG_VIDEO_LOGO
#define CONFIG_VIDEO_BMP_LOGO
#define CONFIG_IMX_HDMI
diff --git a/include/configs/mx6sabre_common.h b/include/configs/mx6sabre_common.h
index ecf4681c1f7..c4e34e9cbc7 100644
--- a/include/configs/mx6sabre_common.h
+++ b/include/configs/mx6sabre_common.h
@@ -169,8 +169,6 @@
/* Environment organization */
/* Framebuffer */
-#define CONFIG_VIDEO_BMP_RLE8
-#define CONFIG_BMP_16BPP
#define CONFIG_VIDEO_LOGO
#define CONFIG_VIDEO_BMP_LOGO
#define CONFIG_IMX_HDMI
diff --git a/include/configs/mx6sxsabresd.h b/include/configs/mx6sxsabresd.h
index 441ea3d4df5..42feb140197 100644
--- a/include/configs/mx6sxsabresd.h
+++ b/include/configs/mx6sxsabresd.h
@@ -176,8 +176,6 @@
#ifdef CONFIG_VIDEO
#define CONFIG_VIDEO_MXS
#define CONFIG_VIDEO_LOGO
-#define CONFIG_BMP_16BPP
-#define CONFIG_VIDEO_BMP_RLE8
#define CONFIG_VIDEO_BMP_LOGO
#define MXS_LCDIF_BASE MX6SX_LCDIF1_BASE_ADDR
#endif
diff --git a/include/configs/mx6ul_14x14_evk.h b/include/configs/mx6ul_14x14_evk.h
index 68e1db52c73..fa6b303dd4a 100644
--- a/include/configs/mx6ul_14x14_evk.h
+++ b/include/configs/mx6ul_14x14_evk.h
@@ -183,8 +183,6 @@
#if defined(CONFIG_DM_VIDEO)
#define CONFIG_VIDEO_MXS
#define CONFIG_VIDEO_LOGO
-#define CONFIG_BMP_16BPP
-#define CONFIG_VIDEO_BMP_RLE8
#define CONFIG_VIDEO_BMP_LOGO
#define MXS_LCDIF_BASE MX6UL_LCDIF1_BASE_ADDR
#endif
diff --git a/include/configs/mx7dsabresd.h b/include/configs/mx7dsabresd.h
index 16b8c07f324..51a7a5f4a0e 100644
--- a/include/configs/mx7dsabresd.h
+++ b/include/configs/mx7dsabresd.h
@@ -141,8 +141,6 @@
#ifdef CONFIG_VIDEO
#define CONFIG_VIDEO_MXS
#define CONFIG_VIDEO_LOGO
-#define CONFIG_BMP_16BPP
-#define CONFIG_VIDEO_BMP_RLE8
#define CONFIG_VIDEO_BMP_LOGO
#endif
diff --git a/include/configs/nitrogen6x.h b/include/configs/nitrogen6x.h
index f1780b2391a..6448ea891f8 100644
--- a/include/configs/nitrogen6x.h
+++ b/include/configs/nitrogen6x.h
@@ -56,10 +56,7 @@
#define CONFIG_MXC_USB_FLAGS 0
/* Framebuffer and LCD */
-#define CONFIG_VIDEO_BMP_RLE8
-#define CONFIG_VIDEO_BMP_GZIP
#define CONFIG_SYS_VIDEO_LOGO_MAX_SIZE (6 * 1024 * 1024)
-#define CONFIG_BMP_16BPP
#define CONFIG_IMX_HDMI
#define CONFIG_IMX_VIDEO_SKIP
diff --git a/include/configs/novena.h b/include/configs/novena.h
index b648c7bc868..2b0a7631c8c 100644
--- a/include/configs/novena.h
+++ b/include/configs/novena.h
@@ -101,8 +101,6 @@
#endif
/* Video output */
-#define CONFIG_VIDEO_BMP_RLE8
-#define CONFIG_BMP_16BPP
#define CONFIG_VIDEO_LOGO
#define CONFIG_IMX_HDMI
#define CONFIG_IMX_VIDEO_SKIP
diff --git a/include/configs/opos6uldev.h b/include/configs/opos6uldev.h
index 8dfd5bede3c..2fb1634a7de 100644
--- a/include/configs/opos6uldev.h
+++ b/include/configs/opos6uldev.h
@@ -45,11 +45,7 @@
#ifndef CONFIG_SPL_BUILD
#ifdef CONFIG_DM_VIDEO
#define CONFIG_VIDEO_LOGO
-#define CONFIG_VIDEO_BMP_RLE8
#define CONFIG_VIDEO_BMP_LOGO
-#define CONFIG_BMP_16BPP
-#define CONFIG_BMP_24BPP
-#define CONFIG_BMP_32BPP
#define CONFIG_VIDEO_MXS
#define MXS_LCDIF_BASE MX6UL_LCDIF1_BASE_ADDR
#endif
diff --git a/include/configs/pico-imx6.h b/include/configs/pico-imx6.h
index 289c1cac669..19c8aeb71b6 100644
--- a/include/configs/pico-imx6.h
+++ b/include/configs/pico-imx6.h
@@ -143,8 +143,6 @@
#define CONFIG_FEC_MXC_PHYADDR 1
/* Framebuffer */
-#define CONFIG_VIDEO_BMP_RLE8
-#define CONFIG_BMP_16BPP
#define CONFIG_VIDEO_LOGO
#define CONFIG_VIDEO_BMP_LOGO
#define CONFIG_IMX_HDMI
diff --git a/include/configs/pico-imx6ul.h b/include/configs/pico-imx6ul.h
index 5211970a83c..747ef09f37d 100644
--- a/include/configs/pico-imx6ul.h
+++ b/include/configs/pico-imx6ul.h
@@ -147,8 +147,6 @@
#ifdef CONFIG_VIDEO
#define CONFIG_VIDEO_MXS
#define CONFIG_VIDEO_LOGO
-#define CONFIG_BMP_16BPP
-#define CONFIG_VIDEO_BMP_RLE8
#define CONFIG_VIDEO_BMP_LOGO
#define MXS_LCDIF_BASE MX6UL_LCDIF1_BASE_ADDR
#endif
diff --git a/include/configs/pico-imx7d.h b/include/configs/pico-imx7d.h
index 12417dfeded..51b7359cad9 100644
--- a/include/configs/pico-imx7d.h
+++ b/include/configs/pico-imx7d.h
@@ -143,8 +143,6 @@
#ifdef CONFIG_DM_VIDEO
#define CONFIG_VIDEO_MXS
#define CONFIG_VIDEO_LOGO
-#define CONFIG_BMP_16BPP
-#define CONFIG_VIDEO_BMP_RLE8
#define CONFIG_VIDEO_BMP_LOGO
#endif
diff --git a/include/configs/puma_rk3399.h b/include/configs/puma_rk3399.h
index 5714437a001..f52ea014b5d 100644
--- a/include/configs/puma_rk3399.h
+++ b/include/configs/puma_rk3399.h
@@ -12,8 +12,4 @@
#define CONFIG_SERIAL_TAG
-#define CONFIG_BMP_16BPP
-#define CONFIG_BMP_24BPP
-#define CONFIG_BMP_32BPP
-
#endif
diff --git a/include/configs/pxm2.h b/include/configs/pxm2.h
index 588eb282a17..4673390c1a7 100644
--- a/include/configs/pxm2.h
+++ b/include/configs/pxm2.h
@@ -115,7 +115,6 @@
#if defined(CONFIG_VIDEO)
#define CONFIG_VIDEO_DA8XX
#define CONFIG_VIDEO_LOGO
-#define CONFIG_VIDEO_BMP_RLE8
#define CONFIG_VIDEO_BMP_LOGO
#define DA8XX_LCD_CNTL_BASE LCD_CNTL_BASE
#define PWM_TICKS 0x1388
diff --git a/include/configs/rut.h b/include/configs/rut.h
index 7e1e8f428eb..66940033ab9 100644
--- a/include/configs/rut.h
+++ b/include/configs/rut.h
@@ -108,7 +108,6 @@
#if defined(CONFIG_VIDEO)
#define CONFIG_VIDEO_DA8XX
#define CONFIG_VIDEO_LOGO
-#define CONFIG_VIDEO_BMP_RLE8
#define CONFIG_VIDEO_BMP_LOGO
#define DA8XX_LCD_CNTL_BASE LCD_CNTL_BASE
diff --git a/include/configs/s5p4418_nanopi2.h b/include/configs/s5p4418_nanopi2.h
index 8577729d654..6dd1f3bc049 100644
--- a/include/configs/s5p4418_nanopi2.h
+++ b/include/configs/s5p4418_nanopi2.h
@@ -153,11 +153,6 @@
#define CONFIG_VIDEO_LOGO
#ifdef CONFIG_VIDEO_LOGO
-
-#ifdef CONFIG_DM_VIDEO
-#define CONFIG_BMP_24BPP
-#endif
-
#ifdef CONFIG_SPLASH_SCREEN
#define SPLASH_FILE logo.bmp
#endif
diff --git a/include/configs/s5pc210_universal.h b/include/configs/s5pc210_universal.h
index da6ed975c36..86c90d990b3 100644
--- a/include/configs/s5pc210_universal.h
+++ b/include/configs/s5pc210_universal.h
@@ -158,9 +158,7 @@ int universal_spi_read(void);
/*
* LCD Settings
*/
-#define CONFIG_BMP_16BPP
#define CONFIG_LD9040
-#define CONFIG_VIDEO_BMP_GZIP
#define CONFIG_SYS_VIDEO_LOGO_MAX_SIZE ((500 * 160 * 4) + 54)
#endif /* __CONFIG_H */
diff --git a/include/configs/sam9x60ek.h b/include/configs/sam9x60ek.h
index 19714402ca4..6a6f1de41d1 100644
--- a/include/configs/sam9x60ek.h
+++ b/include/configs/sam9x60ek.h
@@ -40,7 +40,8 @@
#define CONFIG_SYS_SDRAM_SIZE 0x10000000 /* 256 megs */
#define CONFIG_SYS_INIT_SP_ADDR \
- (CONFIG_SYS_SDRAM_BASE + 16 * 1024 - GENERATED_GBL_DATA_SIZE)
+ (CONFIG_SYS_SDRAM_BASE + 16 * 1024 + CONFIG_SYS_MALLOC_F_LEN - \
+ GENERATED_GBL_DATA_SIZE)
/* NAND flash */
#ifdef CONFIG_CMD_NAND
diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
index 5554313810c..e0708fe5739 100644
--- a/include/configs/sandbox.h
+++ b/include/configs/sandbox.h
@@ -80,7 +80,6 @@
#ifdef CONFIG_SANDBOX_SDL
#define LCD_BPP LCD_COLOR16
#define CONFIG_LCD_BMP_RLE8
-#define CONFIG_VIDEO_BMP_RLE8
#define CONFIG_KEYBOARD
diff --git a/include/configs/stm32f746-disco.h b/include/configs/stm32f746-disco.h
index 74abf95ce93..08d050adfa5 100644
--- a/include/configs/stm32f746-disco.h
+++ b/include/configs/stm32f746-disco.h
@@ -76,11 +76,5 @@
/* For SPL ends */
/* For splashcreen */
-#ifdef CONFIG_DM_VIDEO
-#define CONFIG_VIDEO_BMP_RLE8
-#define CONFIG_BMP_16BPP
-#define CONFIG_BMP_24BPP
-#define CONFIG_BMP_32BPP
-#endif
#endif /* __CONFIG_H */
diff --git a/include/configs/stm32mp1.h b/include/configs/stm32mp1.h
index b937233797f..1aa7514ac79 100644
--- a/include/configs/stm32mp1.h
+++ b/include/configs/stm32mp1.h
@@ -75,13 +75,6 @@
#define CONFIG_SYS_AUTOLOAD "no"
#endif
-#ifdef CONFIG_DM_VIDEO
-#define CONFIG_VIDEO_BMP_RLE8
-#define CONFIG_BMP_16BPP
-#define CONFIG_BMP_24BPP
-#define CONFIG_BMP_32BPP
-#endif
-
/*****************************************************************************/
#ifdef CONFIG_DISTRO_DEFAULTS
/*****************************************************************************/
diff --git a/include/configs/tbs2910.h b/include/configs/tbs2910.h
index b05034945e5..01c1143e43c 100644
--- a/include/configs/tbs2910.h
+++ b/include/configs/tbs2910.h
@@ -36,7 +36,6 @@
#define CONFIG_MXC_UART_BASE UART1_BASE /* select UART1/UART2 */
/* Framebuffer */
-#define CONFIG_VIDEO_BMP_RLE8
#define CONFIG_IMX_HDMI
#define CONFIG_IMX_VIDEO_SKIP
diff --git a/include/configs/theadorable-x86-common.h b/include/configs/theadorable-x86-common.h
index 141d4d61f84..193c6c3bb5c 100644
--- a/include/configs/theadorable-x86-common.h
+++ b/include/configs/theadorable-x86-common.h
@@ -19,7 +19,6 @@
#define VIDEO_IO_OFFSET 0
#define CONFIG_X86EMU_RAW_IO
-#define CONFIG_BMP_16BPP
/* Environment settings */
diff --git a/include/configs/theadorable.h b/include/configs/theadorable.h
index 85ab34c0834..587b134a1b3 100644
--- a/include/configs/theadorable.h
+++ b/include/configs/theadorable.h
@@ -51,10 +51,6 @@
/* Enable LCD and reserve 512KB from top of memory*/
#define CONFIG_SYS_MEM_TOP_HIDE 0x80000
-#define CONFIG_BMP_16BPP
-#define CONFIG_BMP_24BPP
-#define CONFIG_BMP_32BPP
-
/* FPGA programming support */
#define CONFIG_FPGA_STRATIX_V
diff --git a/include/configs/trats.h b/include/configs/trats.h
index 3202627a7db..3c71f08ea4b 100644
--- a/include/configs/trats.h
+++ b/include/configs/trats.h
@@ -178,10 +178,8 @@
#define LCD_BPP LCD_COLOR16
/* LCD */
-#define CONFIG_BMP_16BPP
#define CONFIG_FB_ADDR 0x52504000
#define CONFIG_EXYNOS_MIPI_DSIM
-#define CONFIG_VIDEO_BMP_GZIP
#define CONFIG_SYS_VIDEO_LOGO_MAX_SIZE ((500 * 160 * 4) + 54)
#endif /* __CONFIG_H */
diff --git a/include/configs/trats2.h b/include/configs/trats2.h
index 14549dd1a0c..d53b855023d 100644
--- a/include/configs/trats2.h
+++ b/include/configs/trats2.h
@@ -161,10 +161,8 @@
#define LCD_BPP LCD_COLOR16
/* LCD */
-#define CONFIG_BMP_16BPP
#define CONFIG_FB_ADDR 0x52504000
#define CONFIG_EXYNOS_MIPI_DSIM
-#define CONFIG_VIDEO_BMP_GZIP
#define CONFIG_SYS_VIDEO_LOGO_MAX_SIZE ((500 * 160 * 4) + 54)
#endif /* __CONFIG_H */
diff --git a/include/configs/wandboard.h b/include/configs/wandboard.h
index 5506c1a028a..bd64893fc77 100644
--- a/include/configs/wandboard.h
+++ b/include/configs/wandboard.h
@@ -37,8 +37,6 @@
#define CONFIG_MXC_USB_FLAGS 0
/* Framebuffer */
-#define CONFIG_VIDEO_BMP_RLE8
-#define CONFIG_BMP_16BPP
#define CONFIG_VIDEO_LOGO
#define CONFIG_VIDEO_BMP_LOGO
#define CONFIG_IMX_HDMI
diff --git a/include/dt-bindings/clock/r8a774c0-cpg-mssr.h b/include/dt-bindings/clock/r8a774c0-cpg-mssr.h
new file mode 100644
index 00000000000..9db5c76e23f
--- /dev/null
+++ b/include/dt-bindings/clock/r8a774c0-cpg-mssr.h
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 Renesas Electronics Corp.
+ */
+#ifndef __DT_BINDINGS_CLOCK_R8A774C0_CPG_MSSR_H__
+#define __DT_BINDINGS_CLOCK_R8A774C0_CPG_MSSR_H__
+
+#include <dt-bindings/clock/renesas-cpg-mssr.h>
+
+/* r8a774c0 CPG Core Clocks */
+#define R8A774C0_CLK_Z2 0
+#define R8A774C0_CLK_ZG 1
+#define R8A774C0_CLK_ZTR 2
+#define R8A774C0_CLK_ZT 3
+#define R8A774C0_CLK_ZX 4
+#define R8A774C0_CLK_S0D1 5
+#define R8A774C0_CLK_S0D3 6
+#define R8A774C0_CLK_S0D6 7
+#define R8A774C0_CLK_S0D12 8
+#define R8A774C0_CLK_S0D24 9
+#define R8A774C0_CLK_S1D1 10
+#define R8A774C0_CLK_S1D2 11
+#define R8A774C0_CLK_S1D4 12
+#define R8A774C0_CLK_S2D1 13
+#define R8A774C0_CLK_S2D2 14
+#define R8A774C0_CLK_S2D4 15
+#define R8A774C0_CLK_S3D1 16
+#define R8A774C0_CLK_S3D2 17
+#define R8A774C0_CLK_S3D4 18
+#define R8A774C0_CLK_S0D6C 19
+#define R8A774C0_CLK_S3D1C 20
+#define R8A774C0_CLK_S3D2C 21
+#define R8A774C0_CLK_S3D4C 22
+#define R8A774C0_CLK_LB 23
+#define R8A774C0_CLK_CL 24
+#define R8A774C0_CLK_ZB3 25
+#define R8A774C0_CLK_ZB3D2 26
+#define R8A774C0_CLK_CR 27
+#define R8A774C0_CLK_CRD2 28
+#define R8A774C0_CLK_SD0H 29
+#define R8A774C0_CLK_SD0 30
+#define R8A774C0_CLK_SD1H 31
+#define R8A774C0_CLK_SD1 32
+#define R8A774C0_CLK_SD3H 33
+#define R8A774C0_CLK_SD3 34
+#define R8A774C0_CLK_RPC 35
+#define R8A774C0_CLK_RPCD2 36
+#define R8A774C0_CLK_ZA2 37
+#define R8A774C0_CLK_ZA8 38
+#define R8A774C0_CLK_Z2D 39
+#define R8A774C0_CLK_MSO 40
+#define R8A774C0_CLK_R 41
+#define R8A774C0_CLK_OSC 42
+#define R8A774C0_CLK_LV0 43
+#define R8A774C0_CLK_LV1 44
+#define R8A774C0_CLK_CSI0 45
+#define R8A774C0_CLK_CP 46
+#define R8A774C0_CLK_CPEX 47
+#define R8A774C0_CLK_CANFD 48
+
+#endif /* __DT_BINDINGS_CLOCK_R8A774C0_CPG_MSSR_H__ */
diff --git a/include/dt-bindings/power/r8a774c0-sysc.h b/include/dt-bindings/power/r8a774c0-sysc.h
new file mode 100644
index 00000000000..dd0cd656d90
--- /dev/null
+++ b/include/dt-bindings/power/r8a774c0-sysc.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2020 Renesas Electronics Corp.
+ */
+#ifndef __DT_BINDINGS_POWER_R8A774C0_SYSC_H__
+#define __DT_BINDINGS_POWER_R8A774C0_SYSC_H__
+
+/*
+ * These power domain indices match the numbers of the interrupt bits
+ * representing the power areas in the various Interrupt Registers
+ * (e.g. SYSCISR, Interrupt Status Register)
+ */
+
+#define R8A774C0_PD_CA53_CPU0 5
+#define R8A774C0_PD_CA53_CPU1 6
+#define R8A774C0_PD_A3VC 14
+#define R8A774C0_PD_3DG_A 17
+#define R8A774C0_PD_3DG_B 18
+#define R8A774C0_PD_CA53_SCU 21
+#define R8A774C0_PD_A2VC1 26
+
+/* Always-on power area */
+#define R8A774C0_PD_ALWAYS_ON 32
+
+#endif /* __DT_BINDINGS_POWER_R8A774C0_SYSC_H__ */
diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h
index 989a5fcbd96..a8fa5d74490 100644
--- a/include/linux/usb/ch9.h
+++ b/include/linux/usb/ch9.h
@@ -956,10 +956,9 @@ enum usb_device_speed {
USB_SPEED_HIGH, /* usb 2.0 */
USB_SPEED_WIRELESS, /* wireless (usb 2.5) */
USB_SPEED_SUPER, /* usb 3.0 */
+ USB_SPEED_SUPER_PLUS, /* usb 3.1 */
};
-#ifdef __KERNEL__
-
/**
* usb_speed_string() - Returns human readable-name of the speed.
* @speed: The speed to return human-readable name for. If it's not
@@ -968,8 +967,6 @@ enum usb_device_speed {
*/
extern const char *usb_speed_string(enum usb_device_speed speed);
-#endif
-
enum usb_device_state {
/* NOTATTACHED isn't in the USB spec, and this state acts
* the same as ATTACHED ... but it's clearer this way.
diff --git a/include/mipi_dsi.h b/include/mipi_dsi.h
index c8a7d3daefa..4ca05f71e29 100644
--- a/include/mipi_dsi.h
+++ b/include/mipi_dsi.h
@@ -97,6 +97,20 @@ struct mipi_dsi_host_ops {
};
/**
+ * struct mipi_dsi_phy_timing - DSI host phy timings
+ * @data_hs2lp: High Speed to Low Speed Data Transition Time
+ * @data_lp2hs: Low Speed to High Speed Data Transition Time
+ * @clk_hs2lp: High Speed to Low Speed Clock Transition Time
+ * @clk_lp2hs: Low Speed to High Speed Clock Transition Time
+ */
+struct mipi_dsi_phy_timing {
+ u16 data_hs2lp;
+ u16 data_lp2hs;
+ u16 clk_hs2lp;
+ u16 clk_lp2hs;
+};
+
+/**
* struct mipi_dsi_phy_ops - DSI host physical operations
* @init: initialized host physical part
* @get_lane_mbps: get lane bitrate per lane (mbps)
@@ -107,6 +121,9 @@ struct mipi_dsi_phy_ops {
int (*get_lane_mbps)(void *priv_data, struct display_timing *timings,
u32 lanes, u32 format, unsigned int *lane_mbps);
void (*post_set_mode)(void *priv_data, unsigned long mode_flags);
+ int (*get_timing)(void *priv_data, unsigned int lane_mbps,
+ struct mipi_dsi_phy_timing *timing);
+ void (*get_esc_clk_rate)(void *priv_data, unsigned int *esc_clk_rate);
};
/**
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index 12f1209aa8f..dc4f0b050c9 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -101,9 +101,6 @@ CONFIG_BL1_OFFSET
CONFIG_BL1_SIZE
CONFIG_BL2_OFFSET
CONFIG_BL2_SIZE
-CONFIG_BMP_16BPP
-CONFIG_BMP_24BPP
-CONFIG_BMP_32BPP
CONFIG_BOARDDIR
CONFIG_BOARDNAME
CONFIG_BOARDNAME_LOCAL
@@ -4061,9 +4058,7 @@ CONFIG_VEXPRESS_EXTENDED_MEMORY_MAP
CONFIG_VEXPRESS_ORIGINAL_MEMORY_MAP
CONFIG_VID
CONFIG_VIDEO_BCM2835
-CONFIG_VIDEO_BMP_GZIP
CONFIG_VIDEO_BMP_LOGO
-CONFIG_VIDEO_BMP_RLE8
CONFIG_VIDEO_CORALP
CONFIG_VIDEO_DA8XX
CONFIG_VIDEO_FONT_4X6
diff --git a/test/dm/panel.c b/test/dm/panel.c
index a840fb4951d..49f5ac7169d 100644
--- a/test/dm/panel.c
+++ b/test/dm/panel.c
@@ -40,7 +40,7 @@ static int dm_test_panel(struct unit_test_state *uts)
ut_assertok(sandbox_pwm_get_config(pwm, 0, &period_ns, &duty_ns,
&enable, &polarity));
ut_asserteq(1000, period_ns);
- ut_asserteq(170 * 1000 / 256, duty_ns);
+ ut_asserteq(170 * 1000 / 255, duty_ns);
ut_asserteq(true, enable);
ut_asserteq(false, polarity);
ut_asserteq(1, sandbox_gpio_get_value(gpio, 1));
@@ -49,29 +49,29 @@ static int dm_test_panel(struct unit_test_state *uts)
ut_assertok(panel_set_backlight(dev, 40));
ut_assertok(sandbox_pwm_get_config(pwm, 0, &period_ns, &duty_ns,
&enable, &polarity));
- ut_asserteq(64 * 1000 / 256, duty_ns);
+ ut_asserteq(64 * 1000 / 255, duty_ns);
ut_assertok(panel_set_backlight(dev, BACKLIGHT_MAX));
ut_assertok(sandbox_pwm_get_config(pwm, 0, &period_ns, &duty_ns,
&enable, &polarity));
- ut_asserteq(255 * 1000 / 256, duty_ns);
+ ut_asserteq(255 * 1000 / 255, duty_ns);
ut_assertok(panel_set_backlight(dev, BACKLIGHT_MIN));
ut_assertok(sandbox_pwm_get_config(pwm, 0, &period_ns, &duty_ns,
&enable, &polarity));
- ut_asserteq(0 * 1000 / 256, duty_ns);
+ ut_asserteq(0 * 1000 / 255, duty_ns);
ut_asserteq(1, sandbox_gpio_get_value(gpio, 1));
ut_assertok(panel_set_backlight(dev, BACKLIGHT_DEFAULT));
ut_assertok(sandbox_pwm_get_config(pwm, 0, &period_ns, &duty_ns,
&enable, &polarity));
ut_asserteq(true, enable);
- ut_asserteq(170 * 1000 / 256, duty_ns);
+ ut_asserteq(170 * 1000 / 255, duty_ns);
ut_assertok(panel_set_backlight(dev, BACKLIGHT_OFF));
ut_assertok(sandbox_pwm_get_config(pwm, 0, &period_ns, &duty_ns,
&enable, &polarity));
- ut_asserteq(0 * 1000 / 256, duty_ns);
+ ut_asserteq(0 * 1000 / 255, duty_ns);
ut_asserteq(0, sandbox_gpio_get_value(gpio, 1));
ut_asserteq(false, regulator_get_enable(reg));