diff --git a/config/kernel/linux-rockchip64-edge.config b/config/kernel/linux-rockchip64-edge.config index 46527bfb95..e7b23e8498 100644 --- a/config/kernel/linux-rockchip64-edge.config +++ b/config/kernel/linux-rockchip64-edge.config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm64 5.18.3 Kernel Configuration +# Linux/arm64 5.18.12 Kernel Configuration # CONFIG_CC_VERSION_TEXT="aarch64-linux-gnu-gcc (GNU Toolchain for the A-profile Architecture 8.3-2019.03 (arm-rel-8.36)) 8.3.0" CONFIG_CC_IS_GCC=y @@ -165,6 +165,7 @@ CONFIG_GENERIC_SCHED_CLOCK=y CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y CONFIG_CC_HAS_INT128=y CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" +CONFIG_GCC12_NO_ARRAY_BOUNDS=y CONFIG_ARCH_SUPPORTS_INT128=y CONFIG_NUMA_BALANCING=y CONFIG_NUMA_BALANCING_DEFAULT_ENABLED=y @@ -645,6 +646,7 @@ CONFIG_JUMP_LABEL=y # CONFIG_STATIC_KEYS_SELFTEST is not set CONFIG_UPROBES=y CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_KRETPROBES=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y @@ -8583,7 +8585,6 @@ CONFIG_PHY_ROCKCHIP_INNO_USB2=y CONFIG_PHY_ROCKCHIP_INNO_CSIDPHY=m CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY=m CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY=y -CONFIG_PHY_ROCKCHIP_INNO_USB3=m CONFIG_PHY_ROCKCHIP_PCIE=y CONFIG_PHY_ROCKCHIP_SNPS_PCIE3=y CONFIG_PHY_ROCKCHIP_TYPEC=y @@ -9435,6 +9436,7 @@ CONFIG_CRYPTO_LIB_SM3=m CONFIG_CRYPTO_LIB_SM4=m # end of Crypto library routines +CONFIG_LIB_MEMNEQ=y CONFIG_CRC_CCITT=y CONFIG_CRC16=y CONFIG_CRC_T10DIF=y @@ -9785,10 +9787,12 @@ CONFIG_FTRACE=y CONFIG_BRANCH_PROFILE_NONE=y # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set # CONFIG_BLK_DEV_IO_TRACE is not set +CONFIG_KPROBE_EVENTS=y CONFIG_UPROBE_EVENTS=y CONFIG_BPF_EVENTS=y CONFIG_DYNAMIC_EVENTS=y CONFIG_PROBE_EVENTS=y +# CONFIG_BPF_KPROBE_OVERRIDE is not set # CONFIG_SYNTH_EVENTS is not set # CONFIG_HIST_TRIGGERS is not set # CONFIG_TRACE_EVENT_INJECT is not set @@ -9798,6 +9802,7 @@ CONFIG_PROBE_EVENTS=y # CONFIG_RING_BUFFER_STARTUP_TEST is not set # CONFIG_RING_BUFFER_VALIDATE_TIME_DELTAS is not set # CONFIG_PREEMPTIRQ_DELAY_TEST is not set +# CONFIG_KPROBE_EVENT_GEN_TEST is not set # CONFIG_SAMPLES is not set CONFIG_STRICT_DEVMEM=y # CONFIG_IO_STRICT_DEVMEM is not set @@ -9819,6 +9824,7 @@ CONFIG_KUNIT=m # CONFIG_KUNIT_EXAMPLE_TEST is not set # CONFIG_KUNIT_ALL_TESTS is not set # CONFIG_NOTIFIER_ERROR_INJECTION is not set +CONFIG_FUNCTION_ERROR_INJECTION=y # CONFIG_FAULT_INJECTION is not set CONFIG_ARCH_HAS_KCOV=y CONFIG_CC_HAS_SANCOV_TRACE_PC=y @@ -9828,6 +9834,7 @@ CONFIG_RUNTIME_TESTING_MENU=y # CONFIG_TEST_MIN_HEAP is not set # CONFIG_TEST_SORT is not set CONFIG_TEST_DIV64=m +# CONFIG_KPROBES_SANITY_TEST is not set CONFIG_BACKTRACE_SELF_TEST=m CONFIG_TEST_REF_TRACKER=m CONFIG_RBTREE_TEST=m diff --git a/patch/kernel/archive/rockchip64-5.18/add-board-rk3328-roc-pc-as-station-m1.patch b/patch/kernel/archive/rockchip64-5.18/add-board-rk3328-roc-pc-as-station-m1.patch deleted file mode 100644 index 9551ba43d0..0000000000 --- a/patch/kernel/archive/rockchip64-5.18/add-board-rk3328-roc-pc-as-station-m1.patch +++ /dev/null @@ -1,498 +0,0 @@ ---- /dev/null 2020-12-23 11:47:50.044000030 +0200 -+++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-pc.dts 2020-12-30 16:15:50.808198411 +0200 -@@ -0,0 +1,495 @@ -+/* -+ * SPDX-License-Identifier: (GPL-2.0+ or MIT) -+ * Copyright (c) 2016 Fuzhou Rockchip Electronics Co., Ltd -+ */ -+ -+/dts-v1/; -+#include "rk3328.dtsi" -+#include -+ -+/ { -+ model = "Firefly roc-rk3328-pc"; -+ compatible = "firefly,roc-rk3328-pc", "rockchip,rk3328"; -+ -+ aliases { -+ mmc0 = &sdmmc; -+ mmc1 = &emmc; /* MMC boot device */ -+ }; -+ -+ gmac_clkin: external-gmac-clock { -+ compatible = "fixed-clock"; -+ clock-frequency = <125000000>; -+ clock-output-names = "gmac_clkin"; -+ #clock-cells = <0>; -+ }; -+ -+ sound { -+ compatible = "simple-audio-card"; -+ simple-audio-card,format = "i2s"; -+ simple-audio-card,mclk-fs = <256>; -+ simple-audio-card,name = "rockchip,rk3328"; -+ simple-audio-card,cpu { -+ sound-dai = <&i2s1>; -+ }; -+ simple-audio-card,codec { -+ sound-dai = <&codec>; -+ }; -+ }; -+ -+ hdmi-sound { -+ compatible = "simple-audio-card"; -+ simple-audio-card,format = "i2s"; -+ simple-audio-card,mclk-fs = <128>; -+ simple-audio-card,name = "rockchip,hdmi"; -+ simple-audio-card,cpu { -+ sound-dai = <&i2s0>; -+ }; -+ simple-audio-card,codec { -+ sound-dai = <&hdmi>; -+ }; -+ }; -+ -+ vcc_host_5v: vcc-host-5v-regulator { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&usb30_host_drv>; -+ regulator-name = "vcc_host_5v"; -+ regulator-always-on; -+ regulator-boot-on; -+ vin-supply = <&vcc_sys>; -+ }; -+ -+ vcc_host1_5v: vcc_otg_5v: vcc-host1-5v-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc_phy"; -+ regulator-always-on; -+ regulator-boot-on; -+ }; -+ -+ vcc_phy: vcc-phy-regulator { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&usb20_host_drv>; -+ regulator-name = "vcc_host1_5v"; -+ regulator-always-on; -+ regulator-boot-on; -+ vin-supply = <&vcc_sys>; -+ }; -+ -+ vcc_sd: sdmmc-regulator { -+ compatible = "regulator-fixed"; -+ gpio = <&gpio0 30 GPIO_ACTIVE_LOW>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdmmc0m1_pin>; -+ regulator-name = "vcc_sd"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <&vcc_io>; -+ }; -+ -+ vcc_sys: vcc-sys { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc_sys"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ }; -+ -+ xin32k: xin32k { -+ compatible = "fixed-clock"; -+ clock-frequency = <32768>; -+ clock-output-names = "xin32k"; -+ #clock-cells = <0>; -+ }; -+ -+ leds { -+ compatible = "gpio-leds"; -+ -+ power_led: led-0 { -+ label = "firefly:blue:power"; -+ linux,default-trigger = "heartbeat"; -+ gpios = <&rk805 1 GPIO_ACTIVE_LOW>; -+ default-state = "on"; -+ mode = <0x23>; -+ }; -+ -+ user_led: led-1 { -+ label = "firefly:yellow:user"; -+ linux,default-trigger = "mmc1"; -+ gpios = <&rk805 0 GPIO_ACTIVE_LOW>; -+ default-state = "off"; -+ mode = <0x05>; -+ }; -+ }; -+}; -+ -+&io_domains { -+ status = "okay"; -+ -+ vccio1-supply = <&vcc_io>; -+ vccio2-supply = <&vcc_18emmc>; -+ vccio3-supply = <&vcc_io>; -+ vccio4-supply = <&vcc_io>; -+ vccio5-supply = <&vcc_io>; -+ vccio6-supply = <&vcc_io>; -+ pmuio-supply = <&vcc_io>; -+}; -+ -+&cpu0 { -+ cpu-supply = <&vdd_arm>; -+}; -+ -+&gpu { -+ status = "okay"; -+ mali-supply = <&vdd_logic>; -+}; -+ -+&gmac2phy { -+ phy-supply = <&vcc_phy>; -+ clock_in_out = "output"; -+ assigned-clocks = <&cru SCLK_MAC2PHY_SRC>; -+ assigned-clock-rate = <50000000>; -+ assigned-clocks = <&cru SCLK_MAC2PHY>; -+ assigned-clock-parents = <&cru SCLK_MAC2PHY_SRC>; -+ status = "disabled"; -+}; -+ -+&gmac2io { -+ phy-supply = <&vcc_io>; -+ phy-mode = "rgmii"; -+ clock_in_out = "input"; -+ snps,reset-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; -+ snps,reset-active-low; -+ snps,reset-delays-us = <0 10000 50000>; -+ assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>; -+ assigned-clock-parents = <&gmac_clkin>, <&gmac_clkin>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&rgmiim1_pins>; -+ snps,aal; -+ snps,rxpbl = <0x4>; -+ snps,txpbl = <0x4>; -+ tx_delay = <0x24>; -+ rx_delay = <0x18>; -+ status = "okay"; -+}; -+ -+&display_subsystem { -+ status = "okay"; -+}; -+ -+&hdmi { -+ #sound-dai-cells = <0>; -+ ddc-i2c-scl-high-time-ns = <9625>; -+ ddc-i2c-scl-low-time-ns = <10000>; -+ status = "okay"; -+}; -+ -+&hdmiphy { -+ status = "okay"; -+}; -+ -+&hdmi_sound { -+ status = "okay"; -+}; -+ -+/*&h265e { -+ status = "okay"; -+}; -+ -+&rkvdec { -+ status = "okay"; -+}; -+ -+&vepu { -+ status = "okay"; -+};*/ -+ -+&vop { -+ status = "okay"; -+}; -+ -+&vop_mmu { -+ status = "okay"; -+}; -+ -+/*&vpu_service { -+ status = "okay"; -+};*/ -+ -+&i2s0 { -+ #sound-dai-cells = <0>; -+ rockchip,bclk-fs = <128>; -+ status = "okay"; -+}; -+ -+&i2s1 { -+ #sound-dai-cells = <0>; -+ status = "okay"; -+}; -+ -+&codec { -+ #sound-dai-cells = <0>; -+ status = "okay"; -+}; -+ -+&emmc { -+ bus-width = <8>; -+ cap-mmc-highspeed; -+ mmc-hs200-1_8v; -+ supports-emmc; -+ disable-wp; -+ non-removable; -+ num-slots = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; -+ status = "okay"; -+}; -+ -+&sdmmc { -+ bus-width = <4>; -+ cap-mmc-highspeed; -+ cap-sd-highspeed; -+ disable-wp; -+ max-frequency = <150000000>; -+ num-slots = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; -+ supports-sd; -+ status = "okay"; -+ vmmc-supply = <&vcc_sd>; -+}; -+ -+&i2c1 { -+ status = "okay"; -+ -+ rk805: rk805@18 { -+ compatible = "rockchip,rk805"; -+ status = "okay"; -+ reg = <0x18>; -+ interrupt-parent = <&gpio2>; -+ interrupts = <24 IRQ_TYPE_LEVEL_LOW>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pmic_int_l>; -+ rockchip,system-power-controller; -+ wakeup-source; -+ gpio-controller; -+ #gpio-cells = <2>; -+ #clock-cells = <1>; -+ clock-output-names = "xin32k", "rk805-clkout2"; -+ -+ vcc1-supply = <&vcc_sys>; -+ vcc2-supply = <&vcc_sys>; -+ vcc3-supply = <&vcc_sys>; -+ vcc4-supply = <&vcc_sys>; -+ vcc5-supply = <&vcc_io>; -+ vcc6-supply = <&vcc_io>; -+ -+ rtc { -+ status = "okay"; -+ }; -+ -+ pwrkey { -+ status = "okay"; -+ }; -+ -+ gpio { -+ status = "okay"; -+ }; -+ -+ regulators { -+ compatible = "rk805-regulator"; -+ status = "okay"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ vdd_logic: DCDC_REG1 { -+ regulator-name = "vdd_logic"; -+ regulator-min-microvolt = <712500>; -+ regulator-max-microvolt = <1450000>; -+ regulator-ramp-delay = <12500>; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1000000>; -+ }; -+ }; -+ -+ vdd_arm: DCDC_REG2 { -+ regulator-name = "vdd_arm"; -+ regulator-min-microvolt = <712500>; -+ regulator-max-microvolt = <1450000>; -+ regulator-ramp-delay = <12500>; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <950000>; -+ }; -+ }; -+ -+ vcc_ddr: DCDC_REG3 { -+ regulator-name = "vcc_ddr"; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vcc_io: DCDC_REG4 { -+ regulator-name = "vcc_io"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3300000>; -+ }; -+ }; -+ -+ vdd_18: LDO_REG1 { -+ regulator-name = "vdd_18"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vcc_18emmc: LDO_REG2 { -+ regulator-name = "vcc_18emmc"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vdd_11: LDO_REG3 { -+ regulator-name = "vdd_11"; -+ regulator-min-microvolt = <1100000>; -+ regulator-max-microvolt = <1100000>; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1100000>; -+ }; -+ }; -+ }; -+ }; -+}; -+ -+&pinctrl { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&clk_32k_out>; -+ -+ clk_32k { -+ clk_32k_out: clk-32k-out { -+ rockchip,pins = -+ <1 RK_PD4 1 &pcfg_pull_none>; -+ }; -+ }; -+ -+ pmic { -+ pmic_int_l: pmic-int-l { -+ rockchip,pins = -+ <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; /* gpio2_a6 */ -+ }; -+ }; -+ -+ sdio-pwrseq { -+ wifi_enable_h: wifi-enable-h { -+ rockchip,pins = <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>, -+ <3 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none_4ma>, -+ <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>, -+ <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ usb2 { -+ usb20_host_drv: usb20-host-drv { -+ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ usb3 { -+ usb30_host_drv: usb30-host-drv { -+ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+}; -+ -+&u2phy { -+ status = "okay"; -+}; -+ -+&u2phy_host { -+ status = "okay"; -+}; -+ -+&u2phy_otg { -+ status = "okay"; -+}; -+ -+&u3phy { -+ status = "okay"; -+}; -+ -+&u3phy_utmi { -+ status = "okay"; -+}; -+ -+&u3phy_pipe { -+ status = "okay"; -+}; -+ -+&uart2 { -+ status = "okay"; -+}; -+ -+&usb20_otg { -+ dr_mode = "host"; -+ status = "okay"; -+}; -+ -+&usb_host0_ehci { -+ status = "okay"; -+}; -+ -+&usb_host0_ohci { -+ status = "okay"; -+}; -+ -+&usbdrd3 { -+ dr_mode = "host"; -+ status = "okay"; -+}; -+ -+&wdt { -+ status = "okay"; -+}; -+ -+&saradc { -+ status = "okay"; -+ vref-supply = <&vdd_18>; -+}; -+ -+&tsadc { -+ status = "okay"; -+ rockchip,hw-tshut-mode = <1>; /* tshut mode 0:CRU 1:GPIO */ -+ rockchip,hw-tshut-polarity = <1>; /* tshut polarity 0:LOW 1:HIGH */ -+}; diff --git a/patch/kernel/archive/rockchip64-5.18/board-rk3328-roc-pc-dts-enable-dmc.patch b/patch/kernel/archive/rockchip64-5.18/add-board-roc-pc.patch similarity index 98% rename from patch/kernel/archive/rockchip64-5.18/board-rk3328-roc-pc-dts-enable-dmc.patch rename to patch/kernel/archive/rockchip64-5.18/add-board-roc-pc.patch index fd473df3c7..f9c5e0588d 100644 --- a/patch/kernel/archive/rockchip64-5.18/board-rk3328-roc-pc-dts-enable-dmc.patch +++ b/patch/kernel/archive/rockchip64-5.18/add-board-roc-pc.patch @@ -13,7 +13,7 @@ new file mode 100644 index 000000000..08d77c694 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-pc.dts -@@ -0,0 +1,529 @@ +@@ -0,0 +1,517 @@ +/* + * SPDX-License-Identifier: (GPL-2.0+ or MIT) + * Copyright (c) 2016 Fuzhou Rockchip Electronics Co., Ltd @@ -495,18 +495,6 @@ index 000000000..08d77c694 + status = "okay"; +}; + -+&u3phy { -+ status = "okay"; -+}; -+ -+&u3phy_utmi { -+ status = "okay"; -+}; -+ -+&u3phy_pipe { -+ status = "okay"; -+}; -+ +&uart2 { + status = "okay"; +}; diff --git a/patch/kernel/archive/rockchip64-5.18/add-rk3328-usb3-phy-driver.patch b/patch/kernel/archive/rockchip64-5.18/add-rk3328-usb3-phy-driver.patch deleted file mode 100644 index 1a74d6c25c..0000000000 --- a/patch/kernel/archive/rockchip64-5.18/add-rk3328-usb3-phy-driver.patch +++ /dev/null @@ -1,1456 +0,0 @@ -Add the rockchip innosilicon usb3 phy driver, supporting devices such as the rk3328. -Pulled from: -https://github.com/FireflyTeam/kernel/blob/roc-rk3328-cc/drivers/phy/rockchip/phy-rockchip-inno-usb3.c - -Signed-off-by: Peter Geis ---- - drivers/phy/rockchip/Kconfig | 9 + - drivers/phy/rockchip/Makefile | 1 + - drivers/phy/rockchip/phy-rockchip-inno-usb3.c | 1107 +++++++++++++++++ - 3 files changed, 1117 insertions(+) - create mode 100644 drivers/phy/rockchip/phy-rockchip-inno-usb3.c - -diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig -index c454c90cd99e..766407939d4a 100644 ---- a/drivers/phy/rockchip/Kconfig -+++ b/drivers/phy/rockchip/Kconfig -@@ -35,6 +35,15 @@ config PHY_ROCKCHIP_INNO_USB2 - help - Support for Rockchip USB2.0 PHY with Innosilicon IP block. - -+config PHY_ROCKCHIP_INNO_USB3 -+ tristate "Rockchip INNO USB 3.0 PHY Driver" -+ depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF -+ depends on USB_SUPPORT -+ select GENERIC_PHY -+ select USB_PHY -+ help -+ Support for Rockchip USB 3.0 PHY with Innosilicon IP block. -+ - config PHY_ROCKCHIP_PCIE - tristate "Rockchip PCIe PHY Driver" - depends on (ARCH_ROCKCHIP && OF) || COMPILE_TEST -diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile -index fd21cbaf40dd..d7b3d16c19ae 100644 ---- a/drivers/phy/rockchip/Makefile -+++ b/drivers/phy/rockchip/Makefile -@@ -3,6 +3,7 @@ obj-$(CONFIG_PHY_ROCKCHIP_DP) += phy-rockchip-dp.o - obj-$(CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY) += phy-rockchip-inno-dsidphy.o - obj-$(CONFIG_PHY_ROCKCHIP_INNO_HDMI) += phy-rockchip-inno-hdmi.o - obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o -+obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB3) += phy-rockchip-inno-usb3.o - obj-$(CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY) += phy-rockchip-naneng-combphy.o - obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o - obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o -diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb3.c b/drivers/phy/rockchip/phy-rockchip-inno-usb3.c -new file mode 100644 -index 000000000000..31fee8f3a705 ---- /dev/null -+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb3.c -@@ -0,0 +1,1107 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * Rockchip USB 3.0 PHY with Innosilicon IP block driver -+ * -+ * Copyright (C) 2016 Fuzhou Rockchip Electronics Co., Ltd -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define U3PHY_PORT_NUM 2 -+#define BIT_WRITEABLE_SHIFT 16 -+#define SCHEDULE_DELAY (60 * HZ) -+ -+#define U3PHY_APB_RST BIT(0) -+#define U3PHY_POR_RST BIT(1) -+#define U3PHY_MAC_RST BIT(2) -+ -+struct rockchip_u3phy; -+struct rockchip_u3phy_port; -+ -+enum rockchip_u3phy_type { -+ U3PHY_TYPE_PIPE, -+ U3PHY_TYPE_UTMI, -+}; -+ -+enum rockchip_u3phy_pipe_pwr { -+ PIPE_PWR_P0 = 0, -+ PIPE_PWR_P1 = 1, -+ PIPE_PWR_P2 = 2, -+ PIPE_PWR_P3 = 3, -+ PIPE_PWR_MAX = 4, -+}; -+ -+enum rockchip_u3phy_rest_req { -+ U3_POR_RSTN = 0, -+ U2_POR_RSTN = 1, -+ PIPE_MAC_RSTN = 2, -+ UTMI_MAC_RSTN = 3, -+ PIPE_APB_RSTN = 4, -+ UTMI_APB_RSTN = 5, -+ U3PHY_RESET_MAX = 6, -+}; -+ -+enum rockchip_u3phy_utmi_state { -+ PHY_UTMI_HS_ONLINE = 0, -+ PHY_UTMI_DISCONNECT = 1, -+ PHY_UTMI_CONNECT = 2, -+ PHY_UTMI_FS_LS_ONLINE = 4, -+}; -+ -+/* -+ * @rvalue: reset value -+ * @dvalue: desired value -+ */ -+struct u3phy_reg { -+ unsigned int offset; -+ unsigned int bitend; -+ unsigned int bitstart; -+ unsigned int rvalue; -+ unsigned int dvalue; -+}; -+ -+struct rockchip_u3phy_grfcfg { -+ struct u3phy_reg um_suspend; -+ struct u3phy_reg ls_det_en; -+ struct u3phy_reg ls_det_st; -+ struct u3phy_reg um_ls; -+ struct u3phy_reg um_hstdct; -+ struct u3phy_reg u2_only_ctrl; -+ struct u3phy_reg u3_disable; -+ struct u3phy_reg pp_pwr_st; -+ struct u3phy_reg pp_pwr_en[PIPE_PWR_MAX]; -+}; -+ -+/** -+ * struct rockchip_u3phy_apbcfg: usb3-phy apb configuration. -+ * @u2_pre_emp: usb2-phy pre-emphasis tuning. -+ * @u2_pre_emp_sth: usb2-phy pre-emphasis strength tuning. -+ * @u2_odt_tuning: usb2-phy odt 45ohm tuning. -+ */ -+struct rockchip_u3phy_apbcfg { -+ unsigned int u2_pre_emp; -+ unsigned int u2_pre_emp_sth; -+ unsigned int u2_odt_tuning; -+}; -+ -+struct rockchip_u3phy_cfg { -+ unsigned int reg; -+ const struct rockchip_u3phy_grfcfg grfcfg; -+ -+ int (*phy_pipe_power)(struct rockchip_u3phy *u3phy, -+ struct rockchip_u3phy_port *u3phy_port, -+ bool on); -+ int (*phy_tuning)(struct rockchip_u3phy *u3phy, -+ struct rockchip_u3phy_port *u3phy_port, -+ struct device_node *child_np); -+}; -+ -+struct rockchip_u3phy_port { -+ struct phy *phy; -+ void __iomem *base; -+ unsigned int index; -+ unsigned char type; -+ bool suspended; -+ bool refclk_25m_quirk; -+ struct mutex mutex; /* mutex for updating register */ -+ struct delayed_work um_sm_work; -+}; -+ -+struct rockchip_u3phy { -+ struct device *dev; -+ struct regmap *u3phy_grf; -+ struct regmap *grf; -+ int um_ls_irq; -+ struct clk **clks; -+ int num_clocks; -+ struct dentry *root; -+ struct gpio_desc *vbus_drv_gpio; -+ struct reset_control *rsts[U3PHY_RESET_MAX]; -+ struct rockchip_u3phy_apbcfg apbcfg; -+ const struct rockchip_u3phy_cfg *cfgs; -+ struct rockchip_u3phy_port ports[U3PHY_PORT_NUM]; -+ struct usb_phy usb_phy; -+}; -+ -+static inline int param_write(void __iomem *base, -+ const struct u3phy_reg *reg, bool desired) -+{ -+ unsigned int val, mask; -+ unsigned int tmp = desired ? reg->dvalue : reg->rvalue; -+ int ret = 0; -+ -+ mask = GENMASK(reg->bitend, reg->bitstart); -+ val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT); -+ ret = regmap_write(base, reg->offset, val); -+ -+ return ret; -+} -+ -+static inline bool param_exped(void __iomem *base, -+ const struct u3phy_reg *reg, -+ unsigned int value) -+{ -+ int ret; -+ unsigned int tmp, orig; -+ unsigned int mask = GENMASK(reg->bitend, reg->bitstart); -+ -+ ret = regmap_read(base, reg->offset, &orig); -+ if (ret) -+ return false; -+ -+ tmp = (orig & mask) >> reg->bitstart; -+ return tmp == value; -+} -+ -+static int rockchip_u3phy_usb2_only_show(struct seq_file *s, void *unused) -+{ -+ struct rockchip_u3phy *u3phy = s->private; -+ -+ if (param_exped(u3phy->u3phy_grf, &u3phy->cfgs->grfcfg.u2_only_ctrl, 1)) -+ dev_info(u3phy->dev, "u2\n"); -+ else -+ dev_info(u3phy->dev, "u3\n"); -+ -+ return 0; -+} -+ -+static int rockchip_u3phy_usb2_only_open(struct inode *inode, -+ struct file *file) -+{ -+ return single_open(file, rockchip_u3phy_usb2_only_show, -+ inode->i_private); -+} -+ -+static ssize_t rockchip_u3phy_usb2_only_write(struct file *file, -+ const char __user *ubuf, -+ size_t count, loff_t *ppos) -+{ -+ struct seq_file *s = file->private_data; -+ struct rockchip_u3phy *u3phy = s->private; -+ struct rockchip_u3phy_port *u3phy_port; -+ char buf[32]; -+ u8 index; -+ -+ if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) -+ return -EFAULT; -+ -+ if (!strncmp(buf, "u3", 2) && -+ param_exped(u3phy->u3phy_grf, -+ &u3phy->cfgs->grfcfg.u2_only_ctrl, 1)) { -+ dev_info(u3phy->dev, "Set usb3.0 and usb2.0 mode successfully\n"); -+ -+ gpiod_set_value_cansleep(u3phy->vbus_drv_gpio, 0); -+ -+ param_write(u3phy->grf, -+ &u3phy->cfgs->grfcfg.u3_disable, false); -+ param_write(u3phy->u3phy_grf, -+ &u3phy->cfgs->grfcfg.u2_only_ctrl, false); -+ -+ for (index = 0; index < U3PHY_PORT_NUM; index++) { -+ u3phy_port = &u3phy->ports[index]; -+ /* enable u3 rx termimation */ -+ if (u3phy_port->type == U3PHY_TYPE_PIPE) -+ writel(0x30, u3phy_port->base + 0xd8); -+ } -+ -+ atomic_notifier_call_chain(&u3phy->usb_phy.notifier, 0, NULL); -+ -+ gpiod_set_value_cansleep(u3phy->vbus_drv_gpio, 1); -+ } else if (!strncmp(buf, "u2", 2) && -+ param_exped(u3phy->u3phy_grf, -+ &u3phy->cfgs->grfcfg.u2_only_ctrl, 0)) { -+ dev_info(u3phy->dev, "Set usb2.0 only mode successfully\n"); -+ -+ gpiod_set_value_cansleep(u3phy->vbus_drv_gpio, 0); -+ -+ param_write(u3phy->grf, -+ &u3phy->cfgs->grfcfg.u3_disable, true); -+ param_write(u3phy->u3phy_grf, -+ &u3phy->cfgs->grfcfg.u2_only_ctrl, true); -+ -+ for (index = 0; index < U3PHY_PORT_NUM; index++) { -+ u3phy_port = &u3phy->ports[index]; -+ /* disable u3 rx termimation */ -+ if (u3phy_port->type == U3PHY_TYPE_PIPE) -+ writel(0x20, u3phy_port->base + 0xd8); -+ } -+ -+ atomic_notifier_call_chain(&u3phy->usb_phy.notifier, 0, NULL); -+ -+ gpiod_set_value_cansleep(u3phy->vbus_drv_gpio, 1); -+ } else { -+ dev_info(u3phy->dev, "Same or illegal mode\n"); -+ } -+ -+ return count; -+} -+ -+static const struct file_operations rockchip_u3phy_usb2_only_fops = { -+ .open = rockchip_u3phy_usb2_only_open, -+ .write = rockchip_u3phy_usb2_only_write, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release, -+}; -+ -+int rockchip_u3phy_debugfs_init(struct rockchip_u3phy *u3phy) -+{ -+ struct dentry *root; -+ struct dentry *file; -+ int ret; -+ -+ root = debugfs_create_dir(dev_name(u3phy->dev), NULL); -+ if (!root) { -+ ret = -ENOMEM; -+ goto err0; -+ } -+ -+ u3phy->root = root; -+ -+ file = debugfs_create_file("u3phy_mode", 0644, root, -+ u3phy, &rockchip_u3phy_usb2_only_fops); -+ if (!file) { -+ ret = -ENOMEM; -+ goto err1; -+ } -+ return 0; -+ -+err1: -+ debugfs_remove_recursive(root); -+err0: -+ return ret; -+} -+ -+static const char *get_rest_name(enum rockchip_u3phy_rest_req rst) -+{ -+ switch (rst) { -+ case U2_POR_RSTN: -+ return "u3phy-u2-por"; -+ case U3_POR_RSTN: -+ return "u3phy-u3-por"; -+ case PIPE_MAC_RSTN: -+ return "u3phy-pipe-mac"; -+ case UTMI_MAC_RSTN: -+ return "u3phy-utmi-mac"; -+ case UTMI_APB_RSTN: -+ return "u3phy-utmi-apb"; -+ case PIPE_APB_RSTN: -+ return "u3phy-pipe-apb"; -+ default: -+ return "invalid"; -+ } -+} -+ -+static void rockchip_u3phy_rest_deassert(struct rockchip_u3phy *u3phy, -+ unsigned int flag) -+{ -+ int rst; -+ -+ if (flag & U3PHY_APB_RST) { -+ dev_dbg(u3phy->dev, "deassert APB bus interface reset\n"); -+ for (rst = PIPE_APB_RSTN; rst <= UTMI_APB_RSTN; rst++) { -+ if (u3phy->rsts[rst]) -+ reset_control_deassert(u3phy->rsts[rst]); -+ } -+ } -+ -+ if (flag & U3PHY_POR_RST) { -+ usleep_range(12, 15); -+ dev_dbg(u3phy->dev, "deassert u2 and u3 phy power on reset\n"); -+ for (rst = U3_POR_RSTN; rst <= U2_POR_RSTN; rst++) { -+ if (u3phy->rsts[rst]) -+ reset_control_deassert(u3phy->rsts[rst]); -+ } -+ } -+ -+ if (flag & U3PHY_MAC_RST) { -+ usleep_range(1200, 1500); -+ dev_dbg(u3phy->dev, "deassert pipe and utmi MAC reset\n"); -+ for (rst = PIPE_MAC_RSTN; rst <= UTMI_MAC_RSTN; rst++) -+ if (u3phy->rsts[rst]) -+ reset_control_deassert(u3phy->rsts[rst]); -+ } -+} -+ -+static void rockchip_u3phy_rest_assert(struct rockchip_u3phy *u3phy) -+{ -+ int rst; -+ -+ dev_dbg(u3phy->dev, "assert u3phy reset\n"); -+ for (rst = 0; rst < U3PHY_RESET_MAX; rst++) -+ if (u3phy->rsts[rst]) -+ reset_control_assert(u3phy->rsts[rst]); -+} -+ -+static int rockchip_u3phy_clk_enable(struct rockchip_u3phy *u3phy) -+{ -+ int ret, clk; -+ -+ for (clk = 0; clk < u3phy->num_clocks && u3phy->clks[clk]; clk++) { -+ ret = clk_prepare_enable(u3phy->clks[clk]); -+ if (ret) -+ goto err_disable_clks; -+ } -+ return 0; -+ -+err_disable_clks: -+ while (--clk >= 0) -+ clk_disable_unprepare(u3phy->clks[clk]); -+ return ret; -+} -+ -+static void rockchip_u3phy_clk_disable(struct rockchip_u3phy *u3phy) -+{ -+ int clk; -+ -+ for (clk = u3phy->num_clocks - 1; clk >= 0; clk--) -+ if (u3phy->clks[clk]) -+ clk_disable_unprepare(u3phy->clks[clk]); -+} -+ -+static int rockchip_u3phy_init(struct phy *phy) -+{ -+ return 0; -+} -+ -+static int rockchip_u3phy_exit(struct phy *phy) -+{ -+ return 0; -+} -+ -+static int rockchip_u3phy_power_on(struct phy *phy) -+{ -+ struct rockchip_u3phy_port *u3phy_port = phy_get_drvdata(phy); -+ struct rockchip_u3phy *u3phy = dev_get_drvdata(phy->dev.parent); -+ int ret; -+ -+ dev_info(&u3phy_port->phy->dev, "u3phy %s power on\n", -+ (u3phy_port->type == U3PHY_TYPE_UTMI) ? "u2" : "u3"); -+ -+ if (!u3phy_port->suspended) -+ return 0; -+ -+ ret = rockchip_u3phy_clk_enable(u3phy); -+ if (ret) -+ return ret; -+ -+ if (u3phy_port->type == U3PHY_TYPE_UTMI) { -+ param_write(u3phy->u3phy_grf, -+ &u3phy->cfgs->grfcfg.um_suspend, false); -+ } else { -+ /* current in p2 ? */ -+ if (param_exped(u3phy->u3phy_grf, -+ &u3phy->cfgs->grfcfg.pp_pwr_st, PIPE_PWR_P2)) -+ goto done; -+ -+ if (u3phy->cfgs->phy_pipe_power) { -+ dev_dbg(u3phy->dev, "do pipe power up\n"); -+ u3phy->cfgs->phy_pipe_power(u3phy, u3phy_port, true); -+ } -+ -+ /* exit to p0 */ -+ param_write(u3phy->u3phy_grf, -+ &u3phy->cfgs->grfcfg.pp_pwr_en[PIPE_PWR_P0], true); -+ usleep_range(90, 100); -+ -+ /* enter to p2 from p0 */ -+ param_write(u3phy->u3phy_grf, -+ &u3phy->cfgs->grfcfg.pp_pwr_en[PIPE_PWR_P2], -+ false); -+ udelay(3); -+ } -+ -+done: -+ u3phy_port->suspended = false; -+ return 0; -+} -+ -+static int rockchip_u3phy_power_off(struct phy *phy) -+{ -+ struct rockchip_u3phy_port *u3phy_port = phy_get_drvdata(phy); -+ struct rockchip_u3phy *u3phy = dev_get_drvdata(phy->dev.parent); -+ -+ dev_info(&u3phy_port->phy->dev, "u3phy %s power off\n", -+ (u3phy_port->type == U3PHY_TYPE_UTMI) ? "u2" : "u3"); -+ -+ if (u3phy_port->suspended) -+ return 0; -+ -+ if (u3phy_port->type == U3PHY_TYPE_UTMI) { -+ param_write(u3phy->u3phy_grf, -+ &u3phy->cfgs->grfcfg.um_suspend, true); -+ } else { -+ /* current in p3 ? */ -+ if (param_exped(u3phy->u3phy_grf, -+ &u3phy->cfgs->grfcfg.pp_pwr_st, PIPE_PWR_P3)) -+ goto done; -+ -+ /* exit to p0 */ -+ param_write(u3phy->u3phy_grf, -+ &u3phy->cfgs->grfcfg.pp_pwr_en[PIPE_PWR_P0], true); -+ udelay(2); -+ -+ /* enter to p3 from p0 */ -+ param_write(u3phy->u3phy_grf, -+ &u3phy->cfgs->grfcfg.pp_pwr_en[PIPE_PWR_P3], true); -+ udelay(6); -+ -+ if (u3phy->cfgs->phy_pipe_power) { -+ dev_dbg(u3phy->dev, "do pipe power down\n"); -+ u3phy->cfgs->phy_pipe_power(u3phy, u3phy_port, false); -+ } -+ } -+ -+done: -+ rockchip_u3phy_clk_disable(u3phy); -+ u3phy_port->suspended = true; -+ return 0; -+} -+ -+static __maybe_unused -+struct phy *rockchip_u3phy_xlate(struct device *dev, -+ struct of_phandle_args *args) -+{ -+ struct rockchip_u3phy *u3phy = dev_get_drvdata(dev); -+ struct rockchip_u3phy_port *u3phy_port = NULL; -+ struct device_node *phy_np = args->np; -+ int index; -+ -+ if (args->args_count != 1) { -+ dev_err(dev, "invalid number of cells in 'phy' property\n"); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ for (index = 0; index < U3PHY_PORT_NUM; index++) { -+ if (phy_np == u3phy->ports[index].phy->dev.of_node) { -+ u3phy_port = &u3phy->ports[index]; -+ break; -+ } -+ } -+ -+ if (!u3phy_port) { -+ dev_err(dev, "failed to find appropriate phy\n"); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ return u3phy_port->phy; -+} -+ -+static struct phy_ops rockchip_u3phy_ops = { -+ .init = rockchip_u3phy_init, -+ .exit = rockchip_u3phy_exit, -+ .power_on = rockchip_u3phy_power_on, -+ .power_off = rockchip_u3phy_power_off, -+ .owner = THIS_MODULE, -+}; -+ -+/* -+ * The function manage host-phy port state and suspend/resume phy port -+ * to save power automatically. -+ * -+ * we rely on utmi_linestate and utmi_hostdisconnect to identify whether -+ * devices is disconnect or not. Besides, we do not need care it is FS/LS -+ * disconnected or HS disconnected, actually, we just only need get the -+ * device is disconnected at last through rearm the delayed work, -+ * to suspend the phy port in _PHY_STATE_DISCONNECT_ case. -+ */ -+static void rockchip_u3phy_um_sm_work(struct work_struct *work) -+{ -+ struct rockchip_u3phy_port *u3phy_port = -+ container_of(work, struct rockchip_u3phy_port, um_sm_work.work); -+ struct rockchip_u3phy *u3phy = -+ dev_get_drvdata(u3phy_port->phy->dev.parent); -+ unsigned int sh = u3phy->cfgs->grfcfg.um_hstdct.bitend - -+ u3phy->cfgs->grfcfg.um_hstdct.bitstart + 1; -+ unsigned int ul, uhd, state; -+ unsigned int ul_mask, uhd_mask; -+ int ret; -+ -+ mutex_lock(&u3phy_port->mutex); -+ -+ ret = regmap_read(u3phy->u3phy_grf, -+ u3phy->cfgs->grfcfg.um_ls.offset, &ul); -+ if (ret < 0) -+ goto next_schedule; -+ -+ ret = regmap_read(u3phy->u3phy_grf, -+ u3phy->cfgs->grfcfg.um_hstdct.offset, &uhd); -+ if (ret < 0) -+ goto next_schedule; -+ -+ uhd_mask = GENMASK(u3phy->cfgs->grfcfg.um_hstdct.bitend, -+ u3phy->cfgs->grfcfg.um_hstdct.bitstart); -+ ul_mask = GENMASK(u3phy->cfgs->grfcfg.um_ls.bitend, -+ u3phy->cfgs->grfcfg.um_ls.bitstart); -+ -+ /* stitch on um_ls and um_hstdct as phy state */ -+ state = ((uhd & uhd_mask) >> u3phy->cfgs->grfcfg.um_hstdct.bitstart) | -+ (((ul & ul_mask) >> u3phy->cfgs->grfcfg.um_ls.bitstart) << sh); -+ -+ switch (state) { -+ case PHY_UTMI_HS_ONLINE: -+ dev_dbg(&u3phy_port->phy->dev, "HS online\n"); -+ break; -+ case PHY_UTMI_FS_LS_ONLINE: -+ /* -+ * For FS/LS device, the online state share with connect state -+ * from um_ls and um_hstdct register, so we distinguish -+ * them via suspended flag. -+ * -+ * Plus, there are two cases, one is D- Line pull-up, and D+ -+ * line pull-down, the state is 4; another is D+ line pull-up, -+ * and D- line pull-down, the state is 2. -+ */ -+ if (!u3phy_port->suspended) { -+ /* D- line pull-up, D+ line pull-down */ -+ dev_dbg(&u3phy_port->phy->dev, "FS/LS online\n"); -+ break; -+ } -+ /* fall through */ -+ case PHY_UTMI_CONNECT: -+ if (u3phy_port->suspended) { -+ dev_dbg(&u3phy_port->phy->dev, "Connected\n"); -+ rockchip_u3phy_power_on(u3phy_port->phy); -+ u3phy_port->suspended = false; -+ } else { -+ /* D+ line pull-up, D- line pull-down */ -+ dev_dbg(&u3phy_port->phy->dev, "FS/LS online\n"); -+ } -+ break; -+ case PHY_UTMI_DISCONNECT: -+ if (!u3phy_port->suspended) { -+ dev_dbg(&u3phy_port->phy->dev, "Disconnected\n"); -+ rockchip_u3phy_power_off(u3phy_port->phy); -+ u3phy_port->suspended = true; -+ } -+ -+ /* -+ * activate the linestate detection to get the next device -+ * plug-in irq. -+ */ -+ param_write(u3phy->u3phy_grf, -+ &u3phy->cfgs->grfcfg.ls_det_st, true); -+ param_write(u3phy->u3phy_grf, -+ &u3phy->cfgs->grfcfg.ls_det_en, true); -+ -+ /* -+ * we don't need to rearm the delayed work when the phy port -+ * is suspended. -+ */ -+ mutex_unlock(&u3phy_port->mutex); -+ return; -+ default: -+ dev_dbg(&u3phy_port->phy->dev, "unknown phy state\n"); -+ break; -+ } -+ -+next_schedule: -+ mutex_unlock(&u3phy_port->mutex); -+ schedule_delayed_work(&u3phy_port->um_sm_work, SCHEDULE_DELAY); -+} -+ -+static irqreturn_t rockchip_u3phy_um_ls_irq(int irq, void *data) -+{ -+ struct rockchip_u3phy_port *u3phy_port = data; -+ struct rockchip_u3phy *u3phy = -+ dev_get_drvdata(u3phy_port->phy->dev.parent); -+ -+ if (!param_exped(u3phy->u3phy_grf, -+ &u3phy->cfgs->grfcfg.ls_det_st, -+ u3phy->cfgs->grfcfg.ls_det_st.dvalue)) -+ return IRQ_NONE; -+ -+ dev_dbg(u3phy->dev, "utmi linestate interrupt\n"); -+ mutex_lock(&u3phy_port->mutex); -+ -+ /* disable linestate detect irq and clear its status */ -+ param_write(u3phy->u3phy_grf, &u3phy->cfgs->grfcfg.ls_det_en, false); -+ param_write(u3phy->u3phy_grf, &u3phy->cfgs->grfcfg.ls_det_st, true); -+ -+ mutex_unlock(&u3phy_port->mutex); -+ -+ /* -+ * In this case for host phy, a new device is plugged in, meanwhile, -+ * if the phy port is suspended, we need rearm the work to resume it -+ * and mange its states; otherwise, we just return irq handled. -+ */ -+ if (u3phy_port->suspended) { -+ dev_dbg(u3phy->dev, "schedule utmi sm work\n"); -+ rockchip_u3phy_um_sm_work(&u3phy_port->um_sm_work.work); -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+static int rockchip_u3phy_parse_dt(struct rockchip_u3phy *u3phy, -+ struct platform_device *pdev) -+ -+{ -+ struct device *dev = &pdev->dev; -+ struct device_node *np = dev->of_node; -+ int ret, i, clk; -+ -+ u3phy->um_ls_irq = platform_get_irq_byname(pdev, "linestate"); -+ if (u3phy->um_ls_irq < 0) { -+ dev_err(dev, "get utmi linestate irq failed\n"); -+ return -ENXIO; -+ } -+ -+ u3phy->vbus_drv_gpio = devm_gpiod_get_optional(dev, "vbus-drv", -+ GPIOD_OUT_HIGH); -+ -+ if (!u3phy->vbus_drv_gpio) { -+ dev_warn(&pdev->dev, "vbus_drv is not assigned\n"); -+ } else if (IS_ERR(u3phy->vbus_drv_gpio)) { -+ dev_err(&pdev->dev, "failed to get vbus_drv\n"); -+ return PTR_ERR(u3phy->vbus_drv_gpio); -+ } -+ -+ u3phy->num_clocks = of_clk_get_parent_count(np); -+ if (u3phy->num_clocks == 0) -+ dev_warn(&pdev->dev, "no clks found in dt\n"); -+ -+ u3phy->clks = devm_kcalloc(dev, u3phy->num_clocks, -+ sizeof(struct clk *), GFP_KERNEL); -+ -+ for (clk = 0; clk < u3phy->num_clocks; clk++) { -+ u3phy->clks[clk] = of_clk_get(np, clk); -+ if (IS_ERR(u3phy->clks[clk])) { -+ ret = PTR_ERR(u3phy->clks[clk]); -+ if (ret == -EPROBE_DEFER) -+ goto err_put_clks; -+ dev_err(&pdev->dev, "failed to get clks, %i\n", -+ ret); -+ u3phy->clks[clk] = NULL; -+ break; -+ } -+ } -+ -+ for (i = 0; i < U3PHY_RESET_MAX; i++) { -+ u3phy->rsts[i] = devm_reset_control_get(dev, get_rest_name(i)); -+ if (IS_ERR(u3phy->rsts[i])) { -+ dev_info(dev, "no %s reset control specified\n", -+ get_rest_name(i)); -+ u3phy->rsts[i] = NULL; -+ } -+ } -+ -+ return 0; -+ -+err_put_clks: -+ while (--clk >= 0) -+ clk_put(u3phy->clks[clk]); -+ return ret; -+} -+ -+static int rockchip_u3phy_port_init(struct rockchip_u3phy *u3phy, -+ struct rockchip_u3phy_port *u3phy_port, -+ struct device_node *child_np) -+{ -+ struct resource res; -+ struct phy *phy; -+ int ret; -+ -+ dev_dbg(u3phy->dev, "u3phy port initialize\n"); -+ -+ mutex_init(&u3phy_port->mutex); -+ u3phy_port->suspended = true; /* initial status */ -+ -+ phy = devm_phy_create(u3phy->dev, child_np, &rockchip_u3phy_ops); -+ if (IS_ERR(phy)) { -+ dev_err(u3phy->dev, "failed to create phy\n"); -+ return PTR_ERR(phy); -+ } -+ -+ u3phy_port->phy = phy; -+ -+ ret = of_address_to_resource(child_np, 0, &res); -+ if (ret) { -+ dev_err(u3phy->dev, "failed to get address resource(np-%s)\n", -+ child_np->name); -+ return ret; -+ } -+ -+ u3phy_port->base = devm_ioremap_resource(&u3phy_port->phy->dev, &res); -+ if (IS_ERR(u3phy_port->base)) { -+ dev_err(u3phy->dev, "failed to remap phy regs\n"); -+ return PTR_ERR(u3phy_port->base); -+ } -+ -+ if (!of_node_cmp(child_np->name, "pipe")) { -+ u3phy_port->type = U3PHY_TYPE_PIPE; -+ u3phy_port->refclk_25m_quirk = -+ of_property_read_bool(child_np, -+ "rockchip,refclk-25m-quirk"); -+ } else { -+ u3phy_port->type = U3PHY_TYPE_UTMI; -+ INIT_DELAYED_WORK(&u3phy_port->um_sm_work, -+ rockchip_u3phy_um_sm_work); -+ -+ ret = devm_request_threaded_irq(u3phy->dev, u3phy->um_ls_irq, -+ NULL, rockchip_u3phy_um_ls_irq, -+ IRQF_ONESHOT, "rockchip_u3phy", -+ u3phy_port); -+ if (ret) { -+ dev_err(u3phy->dev, "failed to request utmi linestate irq handle\n"); -+ return ret; -+ } -+ } -+ -+ if (u3phy->cfgs->phy_tuning) { -+ dev_dbg(u3phy->dev, "do u3phy tuning\n"); -+ ret = u3phy->cfgs->phy_tuning(u3phy, u3phy_port, child_np); -+ if (ret) -+ return ret; -+ } -+ -+ phy_set_drvdata(u3phy_port->phy, u3phy_port); -+ return 0; -+} -+ -+static int rockchip_u3phy_on_init(struct usb_phy *usb_phy) -+{ -+ struct rockchip_u3phy *u3phy = -+ container_of(usb_phy, struct rockchip_u3phy, usb_phy); -+ -+ rockchip_u3phy_rest_deassert(u3phy, U3PHY_POR_RST | U3PHY_MAC_RST); -+ return 0; -+} -+ -+static void rockchip_u3phy_on_shutdown(struct usb_phy *usb_phy) -+{ -+ struct rockchip_u3phy *u3phy = -+ container_of(usb_phy, struct rockchip_u3phy, usb_phy); -+ int rst; -+ -+ for (rst = 0; rst < U3PHY_RESET_MAX; rst++) -+ if (u3phy->rsts[rst] && rst != UTMI_APB_RSTN && -+ rst != PIPE_APB_RSTN) -+ reset_control_assert(u3phy->rsts[rst]); -+ udelay(1); -+} -+ -+static int rockchip_u3phy_on_disconnect(struct usb_phy *usb_phy, -+ enum usb_device_speed speed) -+{ -+ struct rockchip_u3phy *u3phy = -+ container_of(usb_phy, struct rockchip_u3phy, usb_phy); -+ -+ dev_info(u3phy->dev, "%s device has disconnected\n", -+ (speed == USB_SPEED_SUPER) ? "U3" : "UW/U2/U1.1/U1"); -+ -+ if (speed == USB_SPEED_SUPER) -+ atomic_notifier_call_chain(&usb_phy->notifier, 0, NULL); -+ -+ return 0; -+} -+ -+static int rockchip_u3phy_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct device_node *np = dev->of_node; -+ struct device_node *child_np; -+ struct phy_provider *provider; -+ struct rockchip_u3phy *u3phy; -+ const struct rockchip_u3phy_cfg *phy_cfgs; -+ const struct of_device_id *match; -+ unsigned int reg[2]; -+ int index, ret; -+ -+ match = of_match_device(dev->driver->of_match_table, dev); -+ if (!match || !match->data) { -+ dev_err(dev, "phy-cfgs are not assigned!\n"); -+ return -EINVAL; -+ } -+ -+ u3phy = devm_kzalloc(dev, sizeof(*u3phy), GFP_KERNEL); -+ if (!u3phy) -+ return -ENOMEM; -+ -+ u3phy->u3phy_grf = -+ syscon_regmap_lookup_by_phandle(np, "rockchip,u3phygrf"); -+ if (IS_ERR(u3phy->u3phy_grf)) -+ return PTR_ERR(u3phy->u3phy_grf); -+ -+ u3phy->grf = -+ syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); -+ if (IS_ERR(u3phy->grf)) { -+ dev_err(dev, "Missing rockchip,grf property\n"); -+ return PTR_ERR(u3phy->grf); -+ } -+ -+ if (of_property_read_u32_array(np, "reg", reg, 2)) { -+ dev_err(dev, "the reg property is not assigned in %s node\n", -+ np->name); -+ return -EINVAL; -+ } -+ -+ u3phy->dev = dev; -+ phy_cfgs = match->data; -+ platform_set_drvdata(pdev, u3phy); -+ -+ /* find out a proper config which can be matched with dt. */ -+ index = 0; -+ while (phy_cfgs[index].reg) { -+ if (phy_cfgs[index].reg == reg[1]) { -+ u3phy->cfgs = &phy_cfgs[index]; -+ break; -+ } -+ -+ ++index; -+ } -+ -+ if (!u3phy->cfgs) { -+ dev_err(dev, "no phy-cfgs can be matched with %s node\n", -+ np->name); -+ return -EINVAL; -+ } -+ -+ ret = rockchip_u3phy_parse_dt(u3phy, pdev); -+ if (ret) { -+ dev_err(dev, "parse dt failed, ret(%d)\n", ret); -+ return ret; -+ } -+ -+ ret = rockchip_u3phy_clk_enable(u3phy); -+ if (ret) { -+ dev_err(dev, "clk enable failed, ret(%d)\n", ret); -+ return ret; -+ } -+ -+ rockchip_u3phy_rest_assert(u3phy); -+ rockchip_u3phy_rest_deassert(u3phy, U3PHY_APB_RST | U3PHY_POR_RST); -+ -+ index = 0; -+ for_each_available_child_of_node(np, child_np) { -+ struct rockchip_u3phy_port *u3phy_port = &u3phy->ports[index]; -+ -+ u3phy_port->index = index; -+ ret = rockchip_u3phy_port_init(u3phy, u3phy_port, child_np); -+ if (ret) { -+ dev_err(dev, "u3phy port init failed,ret(%d)\n", ret); -+ goto put_child; -+ } -+ -+ /* to prevent out of boundary */ -+ if (++index >= U3PHY_PORT_NUM) -+ break; -+ } -+ -+ provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); -+ if (IS_ERR_OR_NULL(provider)) -+ goto put_child; -+ -+ rockchip_u3phy_rest_deassert(u3phy, U3PHY_MAC_RST); -+ rockchip_u3phy_clk_disable(u3phy); -+ -+ u3phy->usb_phy.dev = dev; -+ u3phy->usb_phy.init = rockchip_u3phy_on_init; -+ u3phy->usb_phy.shutdown = rockchip_u3phy_on_shutdown; -+ u3phy->usb_phy.notify_disconnect = rockchip_u3phy_on_disconnect; -+ usb_add_phy(&u3phy->usb_phy, USB_PHY_TYPE_USB3); -+ ATOMIC_INIT_NOTIFIER_HEAD(&u3phy->usb_phy.notifier); -+ -+ rockchip_u3phy_debugfs_init(u3phy); -+ -+ dev_info(dev, "Rockchip u3phy initialized successfully\n"); -+ return 0; -+ -+put_child: -+ of_node_put(child_np); -+ return ret; -+} -+ -+static int rk3328_u3phy_pipe_power(struct rockchip_u3phy *u3phy, -+ struct rockchip_u3phy_port *u3phy_port, -+ bool on) -+{ -+ unsigned int reg; -+ -+ if (on) { -+ reg = readl(u3phy_port->base + 0x1a8); -+ reg &= ~BIT(4); /* ldo power up */ -+ writel(reg, u3phy_port->base + 0x1a8); -+ -+ reg = readl(u3phy_port->base + 0x044); -+ reg &= ~BIT(4); /* bg power on */ -+ writel(reg, u3phy_port->base + 0x044); -+ -+ reg = readl(u3phy_port->base + 0x150); -+ reg |= BIT(6); /* tx bias enable */ -+ writel(reg, u3phy_port->base + 0x150); -+ -+ reg = readl(u3phy_port->base + 0x080); -+ reg &= ~BIT(2); /* tx cm power up */ -+ writel(reg, u3phy_port->base + 0x080); -+ -+ reg = readl(u3phy_port->base + 0x0c0); -+ /* tx obs enable and rx cm enable */ -+ reg |= (BIT(3) | BIT(4)); -+ writel(reg, u3phy_port->base + 0x0c0); -+ -+ udelay(1); -+ } else { -+ reg = readl(u3phy_port->base + 0x1a8); -+ reg |= BIT(4); /* ldo power down */ -+ writel(reg, u3phy_port->base + 0x1a8); -+ -+ reg = readl(u3phy_port->base + 0x044); -+ reg |= BIT(4); /* bg power down */ -+ writel(reg, u3phy_port->base + 0x044); -+ -+ reg = readl(u3phy_port->base + 0x150); -+ reg &= ~BIT(6); /* tx bias disable */ -+ writel(reg, u3phy_port->base + 0x150); -+ -+ reg = readl(u3phy_port->base + 0x080); -+ reg |= BIT(2); /* tx cm power down */ -+ writel(reg, u3phy_port->base + 0x080); -+ -+ reg = readl(u3phy_port->base + 0x0c0); -+ /* tx obs disable and rx cm disable */ -+ reg &= ~(BIT(3) | BIT(4)); -+ writel(reg, u3phy_port->base + 0x0c0); -+ } -+ -+ return 0; -+} -+ -+static int rk3328_u3phy_tuning(struct rockchip_u3phy *u3phy, -+ struct rockchip_u3phy_port *u3phy_port, -+ struct device_node *child_np) -+{ -+ if (u3phy_port->type == U3PHY_TYPE_UTMI) { -+ /* -+ * For rk3328 SoC, pre-emphasis and pre-emphasis strength must -+ * be written as one fixed value as below. -+ * -+ * Dissimilarly, the odt 45ohm value should be flexibly tuninged -+ * for the different boards to adjust HS eye height, so its -+ * value can be assigned in DT in code design. -+ */ -+ -+ /* {bits[2:0]=111}: always enable pre-emphasis */ -+ u3phy->apbcfg.u2_pre_emp = 0x0f; -+ -+ /* {bits[5:3]=000}: pre-emphasis strength as the weakest */ -+ u3phy->apbcfg.u2_pre_emp_sth = 0x41; -+ -+ /* {bits[4:0]=10101}: odt 45ohm tuning */ -+ u3phy->apbcfg.u2_odt_tuning = 0xb5; -+ /* optional override of the odt 45ohm tuning */ -+ of_property_read_u32(child_np, "rockchip,odt-val-tuning", -+ &u3phy->apbcfg.u2_odt_tuning); -+ -+ writel(u3phy->apbcfg.u2_pre_emp, u3phy_port->base + 0x030); -+ writel(u3phy->apbcfg.u2_pre_emp_sth, u3phy_port->base + 0x040); -+ writel(u3phy->apbcfg.u2_odt_tuning, u3phy_port->base + 0x11c); -+ } else if (u3phy_port->type == U3PHY_TYPE_PIPE) { -+ if (u3phy_port->refclk_25m_quirk) { -+ dev_dbg(u3phy->dev, "switch to 25m refclk\n"); -+ /* ref clk switch to 25M */ -+ writel(0x64, u3phy_port->base + 0x11c); -+ writel(0x64, u3phy_port->base + 0x028); -+ writel(0x01, u3phy_port->base + 0x020); -+ writel(0x21, u3phy_port->base + 0x030); -+ writel(0x06, u3phy_port->base + 0x108); -+ writel(0x00, u3phy_port->base + 0x118); -+ } else { -+ /* configure for 24M ref clk */ -+ writel(0x80, u3phy_port->base + 0x10c); -+ writel(0x01, u3phy_port->base + 0x118); -+ writel(0x38, u3phy_port->base + 0x11c); -+ writel(0x83, u3phy_port->base + 0x020); -+ writel(0x02, u3phy_port->base + 0x108); -+ } -+ -+ /* Enable SSC */ -+ udelay(3); -+ writel(0x08, u3phy_port->base + 0x000); -+ writel(0x0c, u3phy_port->base + 0x120); -+ -+ /* Tuning Rx for compliance RJTL test */ -+ writel(0x70, u3phy_port->base + 0x150); -+ writel(0x12, u3phy_port->base + 0x0c8); -+ writel(0x05, u3phy_port->base + 0x148); -+ writel(0x08, u3phy_port->base + 0x068); -+ writel(0xf0, u3phy_port->base + 0x1c4); -+ writel(0xff, u3phy_port->base + 0x070); -+ writel(0x0f, u3phy_port->base + 0x06c); -+ writel(0xe0, u3phy_port->base + 0x060); -+ -+ /* -+ * Tuning Tx to increase the bias current -+ * used in TX driver and RX EQ, it can -+ * also increase the voltage of LFPS. -+ */ -+ writel(0x08, u3phy_port->base + 0x180); -+ } else { -+ dev_err(u3phy->dev, "invalid u3phy port type\n"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static const struct rockchip_u3phy_cfg rk3328_u3phy_cfgs[] = { -+ { -+ .reg = 0xff470000, -+ .grfcfg = { -+ .um_suspend = { 0x0004, 15, 0, 0x1452, 0x15d1 }, -+ .u2_only_ctrl = { 0x0020, 15, 15, 0, 1 }, -+ .um_ls = { 0x0030, 5, 4, 0, 1 }, -+ .um_hstdct = { 0x0030, 7, 7, 0, 1 }, -+ .ls_det_en = { 0x0040, 0, 0, 0, 1 }, -+ .ls_det_st = { 0x0044, 0, 0, 0, 1 }, -+ .pp_pwr_st = { 0x0034, 14, 13, 0, 0}, -+ .pp_pwr_en = { {0x0020, 14, 0, 0x0014, 0x0005}, -+ {0x0020, 14, 0, 0x0014, 0x000d}, -+ {0x0020, 14, 0, 0x0014, 0x0015}, -+ {0x0020, 14, 0, 0x0014, 0x001d} }, -+ .u3_disable = { 0x04c4, 15, 0, 0x1100, 0x101}, -+ }, -+ .phy_pipe_power = rk3328_u3phy_pipe_power, -+ .phy_tuning = rk3328_u3phy_tuning, -+ }, -+ { /* sentinel */ } -+}; -+ -+static const struct of_device_id rockchip_u3phy_dt_match[] = { -+ { .compatible = "rockchip,rk3328-u3phy", .data = &rk3328_u3phy_cfgs }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, rockchip_u3phy_dt_match); -+ -+static struct platform_driver rockchip_u3phy_driver = { -+ .probe = rockchip_u3phy_probe, -+ .driver = { -+ .name = "rockchip-u3phy", -+ .of_match_table = rockchip_u3phy_dt_match, -+ }, -+}; -+module_platform_driver(rockchip_u3phy_driver); -+ -+MODULE_AUTHOR("Frank Wang "); -+MODULE_AUTHOR("William Wu "); -+MODULE_DESCRIPTION("Rockchip USB 3.0 PHY driver"); -+MODULE_LICENSE("GPL v2"); - -diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb3.yaml b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb3.yaml -new file mode 100644 -index 000000000000..f4f28625173a ---- /dev/null -+++ b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb3.yaml -@@ -0,0 +1,157 @@ -+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) -+%YAML 1.2 -+--- -+$id: "http://devicetree.org/schemas/phy/phy-rockchip-inno-usb3.yaml#" -+$schema: "http://devicetree.org/meta-schemas/core.yaml#" -+ -+title: ROCKCHIP USB 3.0 PHY WITH INNO IP BLOCK -+ -+maintainers: -+ -+properties: -+ compatible: -+ enum: -+ - rockchip,rk3328-u3phy -+ -+ reg: -+ - description: the base address of the USB 3.0 PHY -+ -+ interrupts: -+ maxItems: 1 -+ -+ interrupt-names: -+ items: -+ - const: linestate -+ description: host/otg linestate interrupt -+ -+ clocks: -+ maxItems: 2 -+ -+ clock-names: -+ items: -+ - const: u3phy-otg -+ description: USB 3.0 PHY UTMI -+ - const: u3phy-pipe -+ description: USB 3.0 PHY Pipe -+ -+ resets: -+ maxItems: 6 -+ -+ reset-names: -+ items: -+ - const: u3phy-u2-por -+ description: USB 2.0 logic of USB 3.0 PHY -+ - const: u3phy-u3-por -+ description: USB 3.0 logic of USB 3.0 PHY -+ - const: u3phy-pipe-mac -+ description: USB 3.0 PHY pipe MAC -+ - const: u3phy-utmi-mac -+ description: USB 3.0 PHY utmi MAC -+ - const: u3phy-utmi-apb -+ description: USB 3.0 PHY utmi apb -+ - const: u3phy-pipe-apb -+ description: USB 3.0 PHY pipe apb -+ -+ "#phy-cells": -+ const: 1 -+ -+ rockchip,u3phygrf: -+ $ref: /schemas/types.yaml#/definitions/phandle-array -+ type: array -+ - description: phandle to the syscon managing the -+ "USB 3.0 PHY general register files". -+ -+ vbus-drv-gpios: -+ $ref: /schemas/types.yaml#/definitions/phandle-array -+ type: array -+ - description: phandle for gpio vbus supply -+ -+required: -+ - compatible -+ - reg -+ - interrupts -+ - interrupt-names -+ - clocks -+ - clock-names -+ - resets -+ - reset-names -+ - "#phy-cells" -+ - rockchip,u3phygrf -+ -+patternProperties: -+ "^u3phy_utmi@[0-9a-f]+$": -+ type: object -+ -+ properties: -+ - description: USB 2.0 utmi phy. -+ -+ rockchip,odt-val-tuning: -+ type: boolean -+ - description: specify 45ohm ODT tuning value. -+ -+ "phy-cells": -+ const: 0 -+ -+ required: -+ - reg -+ - "#phy-cells" -+ -+patternProperties: -+ "^u3phy_pipe@[0-9a-f]+$": -+ type: object -+ -+ properties: -+ - description: USB 3.0 pipe phy. -+ -+ rockchip,refclk-25m-quirk : -+ -+ - description: phy reference clock changed to 25m quirk. -+ -+ "phy-cells": -+ const: 0 -+ -+ required: -+ - reg -+ - "#phy-cells" -+ -+examples: -+ -+usb3phy_grf: syscon@ff460000 { -+ compatible = "rockchip,usb3phy-grf", "syscon"; -+ reg = <0x0 0xff460000 0x0 0x1000>; -+}; -+ -+... -+ -+u3phy: usb3-phy@ff470000 { -+ compatible = "rockchip,rk3328-u3phy"; -+ reg = <0x0 0xff470000 0x0 0x0>; -+ rockchip,u3phygrf = <&usb3phy_grf>; -+ interrupts = ; -+ interrupt-names = "linestate"; -+ clocks = <&cru PCLK_USB3PHY_OTG>, <&cru PCLK_USB3PHY_PIPE>; -+ clock-names = "u3phy-otg", "u3phy-pipe"; -+ resets = <&cru SRST_USB3PHY_U2>, -+ <&cru SRST_USB3PHY_U3>, -+ <&cru SRST_USB3PHY_PIPE>, -+ <&cru SRST_USB3OTG_UTMI>, -+ <&cru SRST_USB3PHY_OTG_P>, -+ <&cru SRST_USB3PHY_PIPE_P>; -+ reset-names = "u3phy-u2-por", "u3phy-u3-por", -+ "u3phy-pipe-mac", "u3phy-utmi-mac", -+ "u3phy-utmi-apb", "u3phy-pipe-apb"; -+ vbus-drv-gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ ranges; -+ -+ u3phy_utmi: utmi@ff470000 { -+ reg = <0x0 0xff470000 0x0 0x8000>; -+ #phy-cells = <0>; -+ }; -+ -+ u3phy_pipe: pipe@ff478000 { -+ reg = <0x0 0xff478000 0x0 0x8000>; -+ #phy-cells = <0>; -+ }; -+}; -diff --git a/Documentation/devicetree/bindings/soc/rockchip/grf.yaml b/Documentation/devicetree/bindings/soc/rockchip/grf.yaml -index ada5435ce2c3..5f2f19344cc7 100644 ---- a/Documentation/devicetree/bindings/soc/rockchip/grf.yaml -+++ b/Documentation/devicetree/bindings/soc/rockchip/grf.yaml -@@ -34,6 +34,7 @@ - - rockchip,rk3308-usb2phy-grf - - rockchip,rk3328-grf - - rockchip,rk3328-usb2phy-grf -+ - rockchip,rk3328-u3phy-grf - - rockchip,rk3368-grf - - rockchip,rk3368-pmugrf - - rockchip,rk3399-grf -diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -index 31cc1541f1f5..072e988ad655 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -@@ -805,6 +805,47 @@ - }; - }; - -+ usb3phy_grf: syscon@ff460000 { -+ compatible = "rockchip,usb3phy-grf", "syscon"; -+ reg = <0x0 0xff460000 0x0 0x1000>; -+ }; -+ -+ u3phy: usb3-phy@ff470000 { -+ compatible = "rockchip,rk3328-u3phy"; -+ reg = <0x0 0xff470000 0x0 0x0>; -+ rockchip,u3phygrf = <&usb3phy_grf>; -+ rockchip,grf = <&grf>; -+ interrupts = ; -+ interrupt-names = "linestate"; -+ clocks = <&cru PCLK_USB3PHY_OTG>, <&cru PCLK_USB3PHY_PIPE>; -+ clock-names = "u3phy-otg", "u3phy-pipe"; -+ resets = <&cru SRST_USB3PHY_U2>, -+ <&cru SRST_USB3PHY_U3>, -+ <&cru SRST_USB3PHY_PIPE>, -+ <&cru SRST_USB3OTG_UTMI>, -+ <&cru SRST_USB3PHY_OTG_P>, -+ <&cru SRST_USB3PHY_PIPE_P>; -+ reset-names = "u3phy-u2-por", "u3phy-u3-por", -+ "u3phy-pipe-mac", "u3phy-utmi-mac", -+ "u3phy-utmi-apb", "u3phy-pipe-apb"; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ ranges; -+ status = "disabled"; -+ -+ u3phy_utmi: utmi@ff470000 { -+ reg = <0x0 0xff470000 0x0 0x8000>; -+ #phy-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ u3phy_pipe: pipe@ff478000 { -+ reg = <0x0 0xff478000 0x0 0x8000>; -+ #phy-cells = <0>; -+ status = "disabled"; -+ }; -+ }; -+ - sdmmc: mmc@ff500000 { - compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc"; - reg = <0x0 0xff500000 0x0 0x4000>; -diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts -index bb40c163b05d..f300f3d0f02e 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts -@@ -328,6 +328,18 @@ - status = "okay"; - }; - -+&u3phy { -+ status = "okay"; -+}; -+ -+&u3phy_utmi { -+ status = "okay"; -+}; -+ -+&u3phy_pipe { -+ status = "okay"; -+}; -+ - &uart2 { - status = "okay"; - }; -@@ -344,6 +356,11 @@ - status = "okay"; - }; - -+&usbdrd3 { -+ dr_mode = "host"; -+ status = "okay"; -+}; -+ - &vop { - status = "okay"; - }; - -diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts -index 62936b432..f97446924 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts -@@ -383,6 +383,18 @@ - status = "okay"; - }; - -+&u3phy { -+ status = "okay"; -+}; -+ -+&u3phy_utmi { -+ status = "okay"; -+}; -+ -+&u3phy_pipe { -+ status = "okay"; -+}; -+ - &usb_host0_ehci { - status = "okay"; - }; -@@ -391,6 +403,11 @@ - status = "okay"; - }; - -+&usbdrd3 { -+ dr_mode = "host"; -+ status = "okay"; -+}; -+ - &vop { - status = "okay"; - };