diff --git a/package/boot/uboot-rockchip/Makefile b/package/boot/uboot-rockchip/Makefile index 4f8c7f1029..e5c49d00bb 100644 --- a/package/boot/uboot-rockchip/Makefile +++ b/package/boot/uboot-rockchip/Makefile @@ -20,15 +20,8 @@ define U-Boot/Default HIDDEN:=1 endef -define U-Boot/rockpro64-rk3399 - BUILD_SUBTARGET:=armv8 - NAME:=RockPro64 - BUILD_DEVICES:= \ - pine64_rockpro64 - DEPENDS:=+PACKAGE_u-boot-rockpro64-rk3399:arm-trusted-firmware-rockchip - PKG_BUILD_DEPENDS:=arm-trusted-firmware-rockchip - ATF:=rk3399_bl31.elf -endef + +# RK3328 boards define U-Boot/nanopi-r2s-rk3328 BUILD_SUBTARGET:=armv8 @@ -41,6 +34,19 @@ define U-Boot/nanopi-r2s-rk3328 OF_PLATDATA:=$(1) endef + +# RK3399 boards + +define U-Boot/rockpro64-rk3399 + BUILD_SUBTARGET:=armv8 + NAME:=RockPro64 + BUILD_DEVICES:= \ + pine64_rockpro64 + DEPENDS:=+PACKAGE_u-boot-rockpro64-rk3399:arm-trusted-firmware-rockchip + PKG_BUILD_DEPENDS:=arm-trusted-firmware-rockchip + ATF:=rk3399_bl31.elf +endef + UBOOT_TARGETS := \ rockpro64-rk3399 \ nanopi-r2s-rk3328 diff --git a/package/boot/uboot-rockchip/patches/100-rockchip-rk3328-Add-support-for-FriendlyARM-NanoPi-R.patch b/package/boot/uboot-rockchip/patches/100-rockchip-rk3328-Add-support-for-FriendlyARM-NanoPi-R.patch index bcdf16389f..7e38db03e1 100644 --- a/package/boot/uboot-rockchip/patches/100-rockchip-rk3328-Add-support-for-FriendlyARM-NanoPi-R.patch +++ b/package/boot/uboot-rockchip/patches/100-rockchip-rk3328-Add-support-for-FriendlyARM-NanoPi-R.patch @@ -1,4 +1,4 @@ -From 42e21846e8faa537f2eda0297e1faa7d8a0abddb Mon Sep 17 00:00:00 2001 +From bd067ecdb13efb78e0f166b53837dc141ca47380 Mon Sep 17 00:00:00 2001 From: David Bauer Date: Fri, 10 Jul 2020 14:58:30 +0200 Subject: [PATCH] rockchip: rk3328: Add support for FriendlyARM NanoPi R2S @@ -18,17 +18,19 @@ Signed-off-by: David Bauer --- arch/arm/dts/Makefile | 1 + arch/arm/dts/rk3328-nanopi-r2s-u-boot.dtsi | 34 +++ - arch/arm/dts/rk3328-nanopi-r2s.dts | 317 +++++++++++++++++++++ + arch/arm/dts/rk3328-nanopi-r2s.dts | 323 +++++++++++++++++++++ board/rockchip/evb_rk3328/MAINTAINERS | 7 + configs/nanopi-r2s-rk3328_defconfig | 99 +++++++ - 5 files changed, 458 insertions(+) + 5 files changed, 464 insertions(+) create mode 100644 arch/arm/dts/rk3328-nanopi-r2s-u-boot.dtsi create mode 100644 arch/arm/dts/rk3328-nanopi-r2s.dts create mode 100644 configs/nanopi-r2s-rk3328_defconfig +diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile +index cee10f533f..a6bd8ea0d8 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile -@@ -106,6 +106,7 @@ dtb-$(CONFIG_ROCKCHIP_RK3308) += \ +@@ -107,6 +107,7 @@ dtb-$(CONFIG_ROCKCHIP_RK3308) += \ dtb-$(CONFIG_ROCKCHIP_RK3328) += \ rk3328-evb.dtb \ @@ -36,6 +38,9 @@ Signed-off-by: David Bauer rk3328-roc-cc.dtb \ rk3328-rock64.dtb \ rk3328-rock-pi-e.dtb +diff --git a/arch/arm/dts/rk3328-nanopi-r2s-u-boot.dtsi b/arch/arm/dts/rk3328-nanopi-r2s-u-boot.dtsi +new file mode 100644 +index 0000000000..4159348402 --- /dev/null +++ b/arch/arm/dts/rk3328-nanopi-r2s-u-boot.dtsi @@ -0,0 +1,34 @@ @@ -73,9 +78,12 @@ Signed-off-by: David Bauer +&vcc_sd { + u-boot,dm-spl; +}; +diff --git a/arch/arm/dts/rk3328-nanopi-r2s.dts b/arch/arm/dts/rk3328-nanopi-r2s.dts +new file mode 100644 +index 0000000000..073cfd7bb2 --- /dev/null +++ b/arch/arm/dts/rk3328-nanopi-r2s.dts -@@ -0,0 +1,317 @@ +@@ -0,0 +1,323 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2020 David Bauer @@ -113,6 +121,23 @@ Signed-off-by: David Bauer + vin-supply = <&vcc_io>; + }; + ++ vcc_sdio: sdmmcio-regulator { ++ compatible = "regulator-gpio"; ++ gpios = <&gpio1 RK_PD4 GPIO_ACTIVE_HIGH>; ++ enable-active-high; ++ states = <1800000 0x1 ++ 3300000 0x0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdio_vcc_pin>; ++ regulator-always-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vcc_sdio"; ++ regulator-settling-time-us = <5000>; ++ regulator-type = "voltage"; ++ vin-supply = <&vcc_io>; ++ }; ++ + vcc_sys: vcc-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc_sys"; @@ -122,18 +147,6 @@ Signed-off-by: David Bauer + regulator-max-microvolt = <5000000>; + }; + -+ vcc_rtl8153: vcc-rtl8153-regulator { -+ compatible = "regulator-fixed"; -+ gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&rtl8153_en_drv>; -+ regulator-always-on; -+ regulator-name = "vcc_rtl8153"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ enable-active-high; -+ }; -+ + leds { + compatible = "gpio-leds"; + @@ -321,7 +334,7 @@ Signed-off-by: David Bauer + + vccio1-supply = <&vcc_io>; + vccio2-supply = <&vcc18_emmc>; -+ vccio3-supply = <&vcc_io>; ++ vccio3-supply = <&vcc_sdio>; + vccio4-supply = <&vcc_18>; + vccio5-supply = <&vcc_io>; + vccio6-supply = <&vcc_io>; @@ -330,7 +343,7 @@ Signed-off-by: David Bauer + +&pinctrl { + leds { -+ led_pins: led_pins { ++ led_pins: led-pins { + rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>, + <2 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>, + <2 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; @@ -338,7 +351,7 @@ Signed-off-by: David Bauer + }; + + button { -+ button_pins: button_pins { ++ button_pins: button-pins { + rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; @@ -349,9 +362,9 @@ Signed-off-by: David Bauer + }; + }; + -+ usb { -+ rtl8153_en_drv: rtl8153-en-drv { -+ rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; ++ sd { ++ sdio_vcc_pin: sdio-vcc-pin { ++ rockchip,pins = <1 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; @@ -365,6 +378,7 @@ Signed-off-by: David Bauer + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; + vmmc-supply = <&vcc_sd>; ++ vqmmc-supply = <&vcc_sdio>; + status = "okay"; +}; + @@ -393,6 +407,8 @@ Signed-off-by: David Bauer +&usb_host0_ohci { + status = "okay"; +}; +diff --git a/board/rockchip/evb_rk3328/MAINTAINERS b/board/rockchip/evb_rk3328/MAINTAINERS +index e7dd59ff4e..14fda46e8f 100644 --- a/board/rockchip/evb_rk3328/MAINTAINERS +++ b/board/rockchip/evb_rk3328/MAINTAINERS @@ -5,6 +5,13 @@ F: board/rockchip/evb_rk3328 @@ -409,6 +425,9 @@ Signed-off-by: David Bauer ROC-RK3328-CC M: Loic Devulder M: Chen-Yu Tsai +diff --git a/configs/nanopi-r2s-rk3328_defconfig b/configs/nanopi-r2s-rk3328_defconfig +new file mode 100644 +index 0000000000..2c028e9d0b --- /dev/null +++ b/configs/nanopi-r2s-rk3328_defconfig @@ -0,0 +1,99 @@ @@ -511,3 +530,6 @@ Signed-off-by: David Bauer +CONFIG_TPL_TINY_MEMSET=y +CONFIG_ERRNO_STR=y +CONFIG_SMBIOS_MANUFACTURER="pine64" +-- +2.27.0 + diff --git a/package/boot/uboot-rockchip/src/of-platdata/nanopi-r2s-rk3328/dt-platdata.c b/package/boot/uboot-rockchip/src/of-platdata/nanopi-r2s-rk3328/dt-platdata.c index bfcb290db2..226c85b6a4 100644 --- a/package/boot/uboot-rockchip/src/of-platdata/nanopi-r2s-rk3328/dt-platdata.c +++ b/package/boot/uboot-rockchip/src/of-platdata/nanopi-r2s-rk3328/dt-platdata.c @@ -19,7 +19,7 @@ U_BOOT_DEVICE(syscon_at_ff100000) = { static const struct dtd_rockchip_rk3328_cru dtv_clock_controller_at_ff440000 = { .reg = {0xff440000, 0x1000}, - .rockchip_grf = 0x39, + .rockchip_grf = 0x3a, }; U_BOOT_DEVICE(clock_controller_at_ff440000) = { .name = "rockchip_rk3328_cru", @@ -35,7 +35,7 @@ static const struct dtd_rockchip_rk3328_uart dtv_serial_at_ff130000 = { .dma_names = {"tx", "rx"}, .dmas = {0x10, 0x6, 0x10, 0x7}, .interrupts = {0x0, 0x39, 0x4}, - .pinctrl_0 = 0x25, + .pinctrl_0 = 0x26, .pinctrl_names = "default", .reg = {0xff130000, 0x100}, .reg_io_width = 0x4, @@ -60,11 +60,12 @@ static const struct dtd_rockchip_rk3328_dw_mshc dtv_mmc_at_ff500000 = { .fifo_depth = 0x100, .interrupts = {0x0, 0xc, 0x4}, .max_frequency = 0x8f0d180, - .pinctrl_0 = {0x46, 0x47, 0x48, 0x49}, + .pinctrl_0 = {0x47, 0x48, 0x49, 0x4a}, .pinctrl_names = "default", .reg = {0xff500000, 0x4000}, .u_boot_spl_fifo_mode = true, - .vmmc_supply = 0x4a, + .vmmc_supply = 0x4b, + .vqmmc_supply = 0x1e, }; U_BOOT_DEVICE(mmc_at_ff500000) = { .name = "rockchip_rk3328_dw_mshc", @@ -74,7 +75,7 @@ U_BOOT_DEVICE(mmc_at_ff500000) = { static const struct dtd_rockchip_rk3328_pinctrl dtv_pinctrl = { .ranges = true, - .rockchip_grf = 0x39, + .rockchip_grf = 0x3a, }; U_BOOT_DEVICE(pinctrl) = { .name = "rockchip_rk3328_pinctrl", @@ -97,8 +98,8 @@ U_BOOT_DEVICE(gpio0_at_ff210000) = { }; static const struct dtd_regulator_fixed dtv_sdmmc_regulator = { - .gpio = {0x5e, 0x1e, 0x1}, - .pinctrl_0 = 0x5f, + .gpio = {0x5f, 0x1e, 0x1}, + .pinctrl_0 = 0x60, .pinctrl_names = "default", .regulator_max_microvolt = 0x325aa0, .regulator_min_microvolt = 0x325aa0, diff --git a/package/boot/uboot-rockchip/src/of-platdata/nanopi-r2s-rk3328/dt-structs-gen.h b/package/boot/uboot-rockchip/src/of-platdata/nanopi-r2s-rk3328/dt-structs-gen.h index 37a0cf5c6c..88291627b8 100644 --- a/package/boot/uboot-rockchip/src/of-platdata/nanopi-r2s-rk3328/dt-structs-gen.h +++ b/package/boot/uboot-rockchip/src/of-platdata/nanopi-r2s-rk3328/dt-structs-gen.h @@ -44,6 +44,7 @@ struct dtd_rockchip_rk3328_dw_mshc { fdt64_t reg[2]; bool u_boot_spl_fifo_mode; fdt32_t vmmc_supply; + fdt32_t vqmmc_supply; }; struct dtd_rockchip_rk3328_grf { fdt64_t reg[2]; diff --git a/target/linux/rockchip/patches-5.4/001-rockchip-rk3328-Add-support-for-FriendlyARM-NanoPi-R.patch b/target/linux/rockchip/patches-5.4/001-rockchip-rk3328-Add-support-for-FriendlyARM-NanoPi-R.patch index 256d08f1a8..a1b6caebfa 100644 --- a/target/linux/rockchip/patches-5.4/001-rockchip-rk3328-Add-support-for-FriendlyARM-NanoPi-R.patch +++ b/target/linux/rockchip/patches-5.4/001-rockchip-rk3328-Add-support-for-FriendlyARM-NanoPi-R.patch @@ -1,9 +1,9 @@ -From 7e772d77a4ac5174803c1524598c5eb677360aec Mon Sep 17 00:00:00 2001 +From c222b8b15193f3ed15562fe7e06f3573aac05b70 Mon Sep 17 00:00:00 2001 From: David Bauer Date: Fri, 10 Jul 2020 15:57:46 +0200 Subject: [PATCH] rockchip: rk3328: Add support for FriendlyARM NanoPi R2S -This adds support for the NanoPi R2S from FriendlyArm. +This adds support for the NanoPi R2S from FriendlyARM. Rockchip RK3328 SoC 1GB DDR4 RAM @@ -17,8 +17,8 @@ WAN - LAN - SYS LED Signed-off-by: David Bauer --- arch/arm64/boot/dts/rockchip/Makefile | 1 + - .../boot/dts/rockchip/rk3328-nanopi-r2s.dts | 299 ++++++++++++++++++ - 2 files changed, 300 insertions(+) + .../boot/dts/rockchip/rk3328-nanopi-r2s.dts | 323 ++++++++++++++++++ + 2 files changed, 324 insertions(+) create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts --- a/arch/arm64/boot/dts/rockchip/Makefile @@ -33,7 +33,7 @@ Signed-off-by: David Bauer dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-evb-act8846.dtb --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts -@@ -0,0 +1,299 @@ +@@ -0,0 +1,323 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2020 David Bauer @@ -71,6 +71,23 @@ Signed-off-by: David Bauer + vin-supply = <&vcc_io>; + }; + ++ vcc_sdio: sdmmcio-regulator { ++ compatible = "regulator-gpio"; ++ gpios = <&gpio1 RK_PD4 GPIO_ACTIVE_HIGH>; ++ enable-active-high; ++ states = <1800000 0x1 ++ 3300000 0x0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdio_vcc_pin>; ++ regulator-always-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vcc_sdio"; ++ regulator-settling-time-us = <5000>; ++ regulator-type = "voltage"; ++ vin-supply = <&vcc_io>; ++ }; ++ + vcc_sys: vcc-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc_sys"; @@ -267,7 +284,7 @@ Signed-off-by: David Bauer + + vccio1-supply = <&vcc_io>; + vccio2-supply = <&vcc18_emmc>; -+ vccio3-supply = <&vcc_io>; ++ vccio3-supply = <&vcc_sdio>; + vccio4-supply = <&vcc_18>; + vccio5-supply = <&vcc_io>; + vccio6-supply = <&vcc_io>; @@ -276,7 +293,7 @@ Signed-off-by: David Bauer + +&pinctrl { + leds { -+ led_pins: led_pins { ++ led_pins: led-pins { + rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>, + <2 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>, + <2 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; @@ -284,7 +301,7 @@ Signed-off-by: David Bauer + }; + + button { -+ button_pins: button_pins { ++ button_pins: button-pins { + rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; @@ -294,6 +311,12 @@ Signed-off-by: David Bauer + rockchip,pins = <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; ++ ++ sd { ++ sdio_vcc_pin: sdio-vcc-pin { ++ rockchip,pins = <1 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; +}; + +&sdmmc { @@ -305,6 +328,7 @@ Signed-off-by: David Bauer + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; + vmmc-supply = <&vcc_sd>; ++ vqmmc-supply = <&vcc_sdio>; + status = "okay"; +}; + diff --git a/target/linux/rockchip/patches-5.4/004-rockchip-rk3328-allow-higher-frequency.patch b/target/linux/rockchip/patches-5.4/003-rockchip-rk3328-allow-higher-frequency.patch similarity index 74% rename from target/linux/rockchip/patches-5.4/004-rockchip-rk3328-allow-higher-frequency.patch rename to target/linux/rockchip/patches-5.4/003-rockchip-rk3328-allow-higher-frequency.patch index 1d203b9c97..576e462152 100644 --- a/target/linux/rockchip/patches-5.4/004-rockchip-rk3328-allow-higher-frequency.patch +++ b/target/linux/rockchip/patches-5.4/003-rockchip-rk3328-allow-higher-frequency.patch @@ -1,9 +1,7 @@ From: QiuSimons -diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -index 8dabc6e29..d58c893a6 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -@@ -125,6 +125,16 @@ +@@ -123,6 +123,16 @@ opp-microvolt = <1300000>; clock-latency-ns = <40000>; }; diff --git a/target/linux/rockchip/patches-5.4/004-net-usb-r8152-add-LED-configuration-from-OF.patch b/target/linux/rockchip/patches-5.4/004-net-usb-r8152-add-LED-configuration-from-OF.patch new file mode 100644 index 0000000000..53b6413cf3 --- /dev/null +++ b/target/linux/rockchip/patches-5.4/004-net-usb-r8152-add-LED-configuration-from-OF.patch @@ -0,0 +1,74 @@ +From 82985725e071f2a5735052f18e109a32aeac3a0b Mon Sep 17 00:00:00 2001 +From: David Bauer +Date: Sun, 26 Jul 2020 02:38:31 +0200 +Subject: [PATCH] net: usb: r8152: add LED configuration from OF + +This adds the ability to configure the LED configuration register using +OF. This way, the correct value for board specific LED configuration can +be determined. + +Signed-off-by: David Bauer +--- + drivers/net/usb/r8152.c | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -4363,6 +4364,22 @@ static void rtl_tally_reset(struct r8152 + ocp_write_word(tp, MCU_TYPE_PLA, PLA_RSTTALLY, ocp_data); + } + ++static int r8152_led_configuration(struct r8152 *tp) ++{ ++ u32 led_data; ++ int ret; ++ ++ ret = of_property_read_u32(tp->udev->dev.of_node, "realtek,led-data", ++ &led_data); ++ ++ if (ret) ++ return ret; ++ ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_LEDSEL, led_data); ++ ++ return 0; ++} ++ + static void r8152b_init(struct r8152 *tp) + { + u32 ocp_data; +@@ -4404,6 +4421,8 @@ static void r8152b_init(struct r8152 *tp + ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); + ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN); + ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); ++ ++ r8152_led_configuration(tp); + } + + static void r8153_init(struct r8152 *tp) +@@ -4533,6 +4552,8 @@ static void r8153_init(struct r8152 *tp) + tp->coalesce = COALESCE_SLOW; + break; + } ++ ++ r8152_led_configuration(tp); + } + + static void r8153b_init(struct r8152 *tp) +@@ -4609,6 +4630,8 @@ static void r8153b_init(struct r8152 *tp + rtl_tally_reset(tp); + + tp->coalesce = 15000; /* 15 us */ ++ ++ r8152_led_configuration(tp); + } + + static int rtl8152_pre_reset(struct usb_interface *intf) diff --git a/target/linux/rockchip/patches-5.4/005-dt-bindings-net-add-RTL8152-binding-documentation.patch b/target/linux/rockchip/patches-5.4/005-dt-bindings-net-add-RTL8152-binding-documentation.patch new file mode 100644 index 0000000000..be262b993c --- /dev/null +++ b/target/linux/rockchip/patches-5.4/005-dt-bindings-net-add-RTL8152-binding-documentation.patch @@ -0,0 +1,54 @@ +From 3ee05f4aa64fc86af3be5bc176ba5808de9260a7 Mon Sep 17 00:00:00 2001 +From: David Bauer +Date: Sun, 26 Jul 2020 15:30:33 +0200 +Subject: [PATCH] dt-bindings: net: add RTL8152 binding documentation + +Add binding documentation for the Realtek RTL8152 / RTL8153 USB ethernet +adapters. + +Signed-off-by: David Bauer +--- + .../bindings/net/realtek,rtl8152.yaml | 36 +++++++++++++++++++ + 1 file changed, 36 insertions(+) + create mode 100644 Documentation/devicetree/bindings/net/realtek,rtl8152.yaml + +--- /dev/null ++++ b/Documentation/devicetree/bindings/net/realtek,rtl8152.yaml +@@ -0,0 +1,36 @@ ++# SPDX-License-Identifier: GPL-2.0 ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/net/realtek,rtl8152.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Realtek RTL8152/RTL8153 series USB ethernet ++ ++maintainers: ++ - David Bauer ++ ++properties: ++ compatible: ++ oneOf: ++ - items: ++ - enum: ++ - realtek,rtl8152 ++ - realtek,rtl8153 ++ ++ reg: ++ description: The device number on the USB bus ++ ++ realtek,led-data: ++ description: Value to be written to the LED configuration register. ++ ++required: ++ - compatible ++ - reg ++ ++examples: ++ - | ++ usb-eth@2 { ++ compatible = "realtek,rtl8153"; ++ reg = <2>; ++ realtek,led-data = <0x87>; ++ }; +\ No newline at end of file diff --git a/target/linux/rockchip/patches-5.4/005-rockchip-rk3328-add-idle-state.patch b/target/linux/rockchip/patches-5.4/005-rockchip-rk3328-add-idle-state.patch deleted file mode 100644 index 07c09dfb7f..0000000000 --- a/target/linux/rockchip/patches-5.4/005-rockchip-rk3328-add-idle-state.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Robin Murphy -Date: Sun, 29 Dec 2019 20:16:17 +0000 -Subject: [PATCH] arm64: dts: rockchip: Add RK3328 idle state - -Downstream RK3328 DTBs describe a CPU idle state matching that present -on other SoCs like RK3399. This works with upstream Trusted Firmware-A -too, so let's add it here. - -Signed-off-by: Robin Murphy -Link: https://lore.kernel.org/r/a8c83e705d387446ea8121516d410e38b2d9c57b.1577640736.git.robin.murphy@arm.com -Signed-off-by: Heiko Stuebner ---- - arch/arm64/boot/dts/rockchip/rk3328.dtsi | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -index 91306ebed4da..c9ff1188bd7b 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -@@ -41,6 +41,7 @@ - reg = <0x0 0x0>; - clocks = <&cru ARMCLK>; - #cooling-cells = <2>; -+ cpu-idle-states = <&CPU_SLEEP>; - dynamic-power-coefficient = <120>; - enable-method = "psci"; - next-level-cache = <&l2>; -@@ -53,6 +54,7 @@ - reg = <0x0 0x1>; - clocks = <&cru ARMCLK>; - #cooling-cells = <2>; -+ cpu-idle-states = <&CPU_SLEEP>; - dynamic-power-coefficient = <120>; - enable-method = "psci"; - next-level-cache = <&l2>; -@@ -65,6 +67,7 @@ - reg = <0x0 0x2>; - clocks = <&cru ARMCLK>; - #cooling-cells = <2>; -+ cpu-idle-states = <&CPU_SLEEP>; - dynamic-power-coefficient = <120>; - enable-method = "psci"; - next-level-cache = <&l2>; -@@ -77,12 +80,26 @@ - reg = <0x0 0x3>; - clocks = <&cru ARMCLK>; - #cooling-cells = <2>; -+ cpu-idle-states = <&CPU_SLEEP>; - dynamic-power-coefficient = <120>; - enable-method = "psci"; - next-level-cache = <&l2>; - operating-points-v2 = <&cpu0_opp_table>; - }; - -+ idle-states { -+ entry-method = "psci"; -+ -+ CPU_SLEEP: cpu-sleep { -+ compatible = "arm,idle-state"; -+ local-timer-stop; -+ arm,psci-suspend-param = <0x0010000>; -+ entry-latency-us = <120>; -+ exit-latency-us = <250>; -+ min-residency-us = <900>; -+ }; -+ }; -+ - l2: l2-cache0 { - compatible = "cache"; - }; diff --git a/target/linux/rockchip/patches-5.4/100-rockchip-use-system-LED-for-OpenWrt.patch b/target/linux/rockchip/patches-5.4/100-rockchip-use-system-LED-for-OpenWrt.patch index 382f89b134..1250dbcd9b 100644 --- a/target/linux/rockchip/patches-5.4/100-rockchip-use-system-LED-for-OpenWrt.patch +++ b/target/linux/rockchip/patches-5.4/100-rockchip-use-system-LED-for-OpenWrt.patch @@ -29,7 +29,7 @@ Signed-off-by: David Bauer gmac_clkin: external-gmac-clock { compatible = "fixed-clock"; clock-frequency = <125000000>; -@@ -50,7 +57,7 @@ +@@ -67,7 +74,7 @@ pinctrl-names = "default"; pinctrl-0 = <&led_pins>; diff --git a/target/linux/rockchip/patches-5.4/101-dts-rockchip-add-usb3-controller-node-for-RK3328-SoCs.patch b/target/linux/rockchip/patches-5.4/101-dts-rockchip-add-usb3-controller-node-for-RK3328-SoCs.patch new file mode 100644 index 0000000000..316f7c01d3 --- /dev/null +++ b/target/linux/rockchip/patches-5.4/101-dts-rockchip-add-usb3-controller-node-for-RK3328-SoCs.patch @@ -0,0 +1,62 @@ +From: William Wu + +RK3328 has one USB 3.0 OTG controller which uses DWC_USB3 +core's general architecture. It can act as static xHCI host +controller, static device controller, USB 3.0/2.0 OTG basing +on ID of USB3.0 PHY. + +Signed-off-by: William Wu +Signed-off-by: Leonidas P. Papadakos + +--- + +NOTE: This binding still has issues. From the original thread: + +the rk3328 usb3-phy has an issue with detecting any plugin events +after a previous device got removed - see the inno-usb3-phy driver +in the vendor kernel. + +The current state is good-enough for enabling the USB3 attached LAN +port of the NanoPi R2S. However, it might explode depending on your +use-case. You've been warned. + +--- + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 27 ++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -936,6 +936,33 @@ + status = "disabled"; + }; + ++ usbdrd3: usb@ff600000 { ++ compatible = "rockchip,rk3328-dwc3", "rockchip,rk3399-dwc3"; ++ clocks = <&cru SCLK_USB3OTG_REF>, <&cru SCLK_USB3OTG_SUSPEND>, ++ <&cru ACLK_USB3OTG>; ++ clock-names = "ref_clk", "suspend_clk", ++ "bus_clk"; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ status = "disabled"; ++ ++ usbdrd_dwc3: dwc3@ff600000 { ++ compatible = "snps,dwc3"; ++ reg = <0x0 0xff600000 0x0 0x100000>; ++ interrupts = ; ++ dr_mode = "otg"; ++ phy_type = "utmi_wide"; ++ snps,dis_enblslpm_quirk; ++ snps,dis-u2-freeclk-exists-quirk; ++ snps,dis_u2_susphy_quirk; ++ snps,dis_u3_susphy_quirk; ++ snps,dis-del-phy-power-chg-quirk; ++ snps,dis-tx-ipgap-linecheck-quirk; ++ status = "disabled"; ++ }; ++ }; ++ + gic: interrupt-controller@ff811000 { + compatible = "arm,gic-400"; + #interrupt-cells = <3>; diff --git a/target/linux/rockchip/patches-5.4/101-rockchip-rework-rtl8152-LEDs-for-FriendlyARM-NanoPi-R2S.patch b/target/linux/rockchip/patches-5.4/101-rockchip-rework-rtl8152-LEDs-for-FriendlyARM-NanoPi-R2S.patch deleted file mode 100644 index b01b8d87a3..0000000000 --- a/target/linux/rockchip/patches-5.4/101-rockchip-rework-rtl8152-LEDs-for-FriendlyARM-NanoPi-R2S.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 2d4f786f94b331904682c24a792462726d474007 Mon Sep 17 00:00:00 2001 -From: hmz007 -Date: Mon, 23 Dec 2019 13:10:06 +0800 -Subject: [PATCH] r8152: Add module param for customized LEDs - -Signed-off-by: hmz007 ---- - drivers/net/usb/r8152.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c -index eb78f6d9390c..ec737fffcded 100644 ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -37,6 +37,11 @@ - #define DRIVER_DESC "Realtek RTL8152/RTL8153 Based USB Ethernet Adapters" - #define MODULENAME "r8152" - -+/* LED0: Activity, LED1: Link */ -+static int ledsel = 0x78; -+module_param(ledsel, int, 0); -+MODULE_PARM_DESC(ledsel, "Override default LED configuration"); -+ - #define R8152_PHY_ID 32 - - #define PLA_IDR 0xc000 -@@ -4545,6 +4550,9 @@ static void r8153b_init(struct r8152 *tp) - ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN); - ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); - -+ /* set customized led */ -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_LEDSEL, ledsel); -+ - rtl_tally_reset(tp); - - tp->coalesce = 15000; /* 15 us */ diff --git a/target/linux/rockchip/patches-5.4/102-rockchip-add-usb3-controller-driver-for-RK3328-SoCs.patch b/target/linux/rockchip/patches-5.4/102-rockchip-add-usb3-controller-driver-for-RK3328-SoCs.patch deleted file mode 100644 index 5a523c1392..0000000000 --- a/target/linux/rockchip/patches-5.4/102-rockchip-add-usb3-controller-driver-for-RK3328-SoCs.patch +++ /dev/null @@ -1,1432 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Geis -Date: Mon, 17 Sep 2001 00:00:00 +0000 -Subject: [PATCH] rockchip: add rockchip innosilicon usb3 phy driver - -Add the rockchip innosilicon usb3 phy driver, supporting devices such as the rk3328. -Pulled from: -https://github.com/rockchip-linux/kernel/blob/develop-4.4/drivers/phy/rockchip/phy-rockchip-inno-usb3.c - -Signed-off-by: Peter Geis ---- - .../bindings/phy/phy-rockchip-inno-usb3.yaml | 157 +++ - .../devicetree/bindings/soc/rockchip/grf.txt | 2 + - arch/arm64/boot/dts/rockchip/rk3328.dtsi | 69 + - drivers/phy/rockchip/Kconfig | 9 + - drivers/phy/rockchip/Makefile | 1 + - drivers/phy/rockchip/phy-rockchip-inno-usb3.c | 1107 +++++++++++++++++ - 6 files changed, 1345 insertions(+) - create mode 100644 Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb3.yaml - create mode 100644 drivers/phy/rockchip/phy-rockchip-inno-usb3.c - -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 000000000..f4f286251 ---- /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.txt b/Documentation/devicetree/bindings/soc/rockchip/grf.txt -index 46e27cd69..ab1265c82 100644 ---- a/Documentation/devicetree/bindings/soc/rockchip/grf.txt -+++ b/Documentation/devicetree/bindings/soc/rockchip/grf.txt -@@ -33,6 +33,8 @@ Required Properties: - - "rockchip,rk3328-usb2phy-grf", "syscon": for rk3328 - - compatible: USBGRF should be one of the following - - "rockchip,rv1108-usbgrf", "syscon": for rv1108 -+- compatible: USB3PHYGRF should be one of the following: -+ - "rockchip,u3phy-grf", "syscon" - - reg: physical base address of the controller and length of memory mapped - region. - -diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -index 31cc1541f..032a3d7a6 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: dwmmc@ff500000 { - compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc"; - reg = <0x0 0xff500000 0x0 0x4000>; -@@ -936,6 +977,34 @@ - status = "disabled"; - }; - -+ usbdrd3: usb@ff600000 { -+ compatible = "rockchip,rk3328-dwc3", "rockchip,rk3399-dwc3"; -+ clocks = <&cru SCLK_USB3OTG_REF>, <&cru ACLK_USB3OTG>, -+ <&cru SCLK_USB3OTG_SUSPEND>; -+ clock-names = "ref", "bus_early", -+ "suspend"; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ ranges; -+ clock-ranges; -+ status = "disabled"; -+ -+ usbdrd_dwc3: dwc3@ff600000 { -+ compatible = "snps,dwc3"; -+ reg = <0x0 0xff600000 0x0 0x100000>; -+ interrupts = ; -+ dr_mode = "otg"; -+ phy_type = "utmi_wide"; -+ snps,dis_enblslpm_quirk; -+ snps,dis-u2-freeclk-exists-quirk; -+ snps,dis_u2_susphy_quirk; -+ snps,dis_u3_susphy_quirk; -+ snps,dis-del-phy-power-chg-quirk; -+ snps,dis-tx-ipgap-linecheck-quirk; -+ status = "disabled"; -+ }; -+ }; -+ - gic: interrupt-controller@ff811000 { - compatible = "arm,gic-400"; - #interrupt-cells = <3>; -diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig -index c454c90cd..766407939 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 fd21cbaf4..d7b3d16c1 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_EMMC) += phy-rockchip-emmc.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_PCIE) += phy-rockchip-pcie.o - obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o - obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.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 000000000..31fee8f3a ---- /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"); --- -2.20.1 - diff --git a/target/linux/rockchip/patches-5.4/003-rockchip-rk3328-enable-LAN-port-on-NanoPi-R2S.patch b/target/linux/rockchip/patches-5.4/102-rockchip-enable-LAN-port-on-NanoPi-R2S.patch similarity index 83% rename from target/linux/rockchip/patches-5.4/003-rockchip-rk3328-enable-LAN-port-on-NanoPi-R2S.patch rename to target/linux/rockchip/patches-5.4/102-rockchip-enable-LAN-port-on-NanoPi-R2S.patch index ea70a3e467..1b52de231e 100644 --- a/target/linux/rockchip/patches-5.4/003-rockchip-rk3328-enable-LAN-port-on-NanoPi-R2S.patch +++ b/target/linux/rockchip/patches-5.4/102-rockchip-enable-LAN-port-on-NanoPi-R2S.patch @@ -1,7 +1,7 @@ -From 6636512096c0749514b27d492db71858150b6e9c Mon Sep 17 00:00:00 2001 +From 0fc3b9b7619c4878f73a6a7989863f0d1a3fd392 Mon Sep 17 00:00:00 2001 From: David Bauer Date: Fri, 10 Jul 2020 21:12:16 +0200 -Subject: [PATCH] rockchip: enable LAN port on NanoPi R2S +Subject: [PATCH] rockchip: enabled LAN port on NanoPi R2S Enable the USB3 port on the FriendlyARM NanoPi R2S. This is required for the USB3 attached LAN port to work. @@ -13,7 +13,7 @@ Signed-off-by: David Bauer --- a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts -@@ -51,6 +51,18 @@ +@@ -68,6 +68,18 @@ regulator-max-microvolt = <5000000>; }; @@ -32,8 +32,8 @@ Signed-off-by: David Bauer leds { compatible = "gpio-leds"; -@@ -265,6 +277,12 @@ - rockchip,pins = <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; +@@ -288,6 +300,12 @@ + rockchip,pins = <1 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>; }; }; + @@ -45,7 +45,7 @@ Signed-off-by: David Bauer }; &sdmmc { -@@ -304,3 +322,12 @@ +@@ -328,3 +346,12 @@ &usb_host0_ohci { status = "okay"; }; diff --git a/target/linux/rockchip/patches-5.4/103-arm64-rockchip-add-OF-node-for-USB-eth-on-NanoPi-R2S.patch b/target/linux/rockchip/patches-5.4/103-arm64-rockchip-add-OF-node-for-USB-eth-on-NanoPi-R2S.patch new file mode 100644 index 0000000000..96c7566095 --- /dev/null +++ b/target/linux/rockchip/patches-5.4/103-arm64-rockchip-add-OF-node-for-USB-eth-on-NanoPi-R2S.patch @@ -0,0 +1,28 @@ +From 2795c8b31a686bdb8338f9404d18ef7a154f0d75 Mon Sep 17 00:00:00 2001 +From: David Bauer +Date: Sun, 26 Jul 2020 13:32:59 +0200 +Subject: [PATCH] arm64: rockchip: add OF node for USB eth on NanoPi R2S + +This adds the OF node for the USB3 ethernet adapter on the FriendlyARM +NanoPi R2S. Add the correct value for the RTL8153 LED configuration +register to match the blink behavior of the other port on the device. + +Signed-off-by: David Bauer +--- + arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts +@@ -354,4 +354,11 @@ + &usbdrd_dwc3 { + dr_mode = "host"; + status = "okay"; ++ ++ usb-eth@2 { ++ compatible = "realtek,rtl8153"; ++ reg = <2>; ++ ++ realtek,led-data = <0x87>; ++ }; + }; diff --git a/target/linux/rockchip/patches-5.4/103-rockchip-add-hwmon-support-for-SoCs-and-GPUs.patch b/target/linux/rockchip/patches-5.4/104-rockchip-add-hwmon-support-for-SoCs-and-GPUs.patch similarity index 100% rename from target/linux/rockchip/patches-5.4/103-rockchip-add-hwmon-support-for-SoCs-and-GPUs.patch rename to target/linux/rockchip/patches-5.4/104-rockchip-add-hwmon-support-for-SoCs-and-GPUs.patch