[PATCH v4 1/5] ARM: dts: rockchip: rk3588-rock-5b-u-boot: add USB 2.0 host

Add USB 2.0 host nodes and PHYs.
Co-developed-by: William Wu william.wu@rock-chips.com Signed-off-by: William Wu william.wu@rock-chips.com Signed-off-by: Eugen Hristev eugen.hristev@collabora.com --- Changes in v4: - removed u-boot,dm-spl on regulator which was useless - moved usb nodes to rk3588s-u-boot-dtsi
Changes in v2,v3: - none
arch/arm/dts/rk3588-rock-5b-u-boot.dtsi | 82 +++++++++++++++++++++++ arch/arm/dts/rk3588s-u-boot.dtsi | 86 +++++++++++++++++++++++++ 2 files changed, 168 insertions(+)
diff --git a/arch/arm/dts/rk3588-rock-5b-u-boot.dtsi b/arch/arm/dts/rk3588-rock-5b-u-boot.dtsi index bee4c32e8965..93942b105c3d 100644 --- a/arch/arm/dts/rk3588-rock-5b-u-boot.dtsi +++ b/arch/arm/dts/rk3588-rock-5b-u-boot.dtsi @@ -4,6 +4,9 @@ */
#include "rk3588-u-boot.dtsi" +#include <dt-bindings/pinctrl/rockchip.h> +#include <dt-bindings/input/input.h> +#include <dt-bindings/gpio/gpio.h>
/ { aliases { @@ -13,6 +16,18 @@ chosen { u-boot,spl-boot-order = &sdmmc; }; + + vcc5v0_host: vcc5v0-host-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_host"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_host_en>; + vin-supply = <&vcc5v0_sys>; + }; };
&sdmmc { @@ -20,3 +35,70 @@ bootph-pre-ram; status = "okay"; }; + +&pinctrl { + usb { + vcc5v0_host_en: vcc5v0-host-en { + rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&usb_host0_ehci { + companion = <&usb_host0_ohci>; + phys = <&u2phy2_host>; + phy-names = "usb2-phy"; + status = "okay"; +}; + +&usb_host0_ohci { + phys = <&u2phy2_host>; + phy-names = "usb2-phy"; + status = "okay"; +}; + +&usb2phy2_grf { + status = "okay"; +}; + +&u2phy2 { + resets = <&cru SRST_OTGPHY_U2_0>, <&cru SRST_P_USB2PHY_U2_0_GRF0>; + reset-names = "phy", "apb"; + clock-output-names = "usb480m_phy2"; + status = "okay"; +}; + +&u2phy2_host { + phy-supply = <&vcc5v0_host>; + status = "okay"; +}; + +&usb_host1_ehci { + companion = <&usb_host1_ohci>; + phys = <&u2phy3_host>; + phy-names = "usb2-phy"; + status = "okay"; +}; + +&usb_host1_ohci { + phys = <&u2phy3_host>; + phy-names = "usb2-phy"; + status = "okay"; +}; + +&usb2phy3_grf { + status = "okay"; +}; + +&u2phy3 { + resets = <&cru SRST_OTGPHY_U2_1>, <&cru SRST_P_USB2PHY_U2_1_GRF0>; + reset-names = "phy", "apb"; + clock-output-names = "usb480m_phy3"; + status = "okay"; +}; + +&u2phy3_host { + phy-supply = <&vcc5v0_host>; + status = "okay"; +}; + diff --git a/arch/arm/dts/rk3588s-u-boot.dtsi b/arch/arm/dts/rk3588s-u-boot.dtsi index 1e225d71efc2..fb1b802fd273 100644 --- a/arch/arm/dts/rk3588s-u-boot.dtsi +++ b/arch/arm/dts/rk3588s-u-boot.dtsi @@ -12,12 +12,98 @@ status = "okay"; };
+ usb_host0_ehci: usb@fc800000 { + compatible = "generic-ehci"; + reg = <0x0 0xfc800000 0x0 0x40000>; + interrupts = <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST_ARB0>; + clock-names = "usbhost", "arbiter"; + power-domains = <&power RK3588_PD_USB>; + status = "disabled"; + }; + + usb_host0_ohci: usb@fc840000 { + compatible = "generic-ohci"; + reg = <0x0 0xfc840000 0x0 0x40000>; + interrupts = <GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST_ARB0>; + clock-names = "usbhost", "arbiter"; + power-domains = <&power RK3588_PD_USB>; + status = "disabled"; + }; + + usb_host1_ehci: usb@fc880000 { + compatible = "generic-ehci"; + reg = <0x0 0xfc880000 0x0 0x40000>; + interrupts = <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST_ARB1>; + clock-names = "usbhost", "arbiter"; + power-domains = <&power RK3588_PD_USB>; + status = "disabled"; + }; + + usb_host1_ohci: usb@fc8c0000 { + compatible = "generic-ohci"; + reg = <0x0 0xfc8c0000 0x0 0x40000>; + interrupts = <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST_ARB1>; + clock-names = "usbhost", "arbiter"; + power-domains = <&power RK3588_PD_USB>; + status = "disabled"; + }; + pmu1_grf: syscon@fd58a000 { bootph-all; compatible = "rockchip,rk3588-pmu1-grf", "syscon"; reg = <0x0 0xfd58a000 0x0 0x2000>; };
+ usb2phy2_grf: syscon@fd5d8000 { + compatible = "rockchip,rk3588-usb2phy-grf", "syscon", + "simple-mfd"; + reg = <0x0 0xfd5d8000 0x0 0x4000>; + #address-cells = <1>; + #size-cells = <1>; + + u2phy2: usb2-phy@8000 { + compatible = "rockchip,rk3588-usb2phy"; + reg = <0x8000 0x10>; + interrupts = <GIC_SPI 391 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>; + clock-names = "phyclk"; + #clock-cells = <0>; + status = "disabled"; + + u2phy2_host: host-port { + #phy-cells = <0>; + status = "disabled"; + }; + }; + }; + + usb2phy3_grf: syscon@fd5dc000 { + compatible = "rockchip,rk3588-usb2phy-grf", "syscon", + "simple-mfd"; + reg = <0x0 0xfd5dc000 0x0 0x4000>; + #address-cells = <1>; + #size-cells = <1>; + + u2phy3: usb2-phy@c000 { + compatible = "rockchip,rk3588-usb2phy"; + reg = <0xc000 0x10>; + interrupts = <GIC_SPI 392 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>; + clock-names = "phyclk"; + #clock-cells = <0>; + status = "disabled"; + + u2phy3_host: host-port { + #phy-cells = <0>; + status = "disabled"; + }; + }; + }; + sdmmc: mmc@fe2c0000 { compatible = "rockchip,rk3588-dw-mshc", "rockchip,rk3288-dw-mshc"; reg = <0x0 0xfe2c0000 0x0 0x4000>;

Enable USB command, USB drivers, PHY and regulators, for USB host operations.
Signed-off-by: Eugen Hristev eugen.hristev@collabora.com --- configs/rock5b-rk3588_defconfig | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
diff --git a/configs/rock5b-rk3588_defconfig b/configs/rock5b-rk3588_defconfig index f3026c7ea166..8d76c1eb4d42 100644 --- a/configs/rock5b-rk3588_defconfig +++ b/configs/rock5b-rk3588_defconfig @@ -41,7 +41,9 @@ CONFIG_SPL_STACK_R=y CONFIG_SPL_ATF=y CONFIG_CMD_GPT=y CONFIG_CMD_MMC=y +CONFIG_CMD_USB=y # CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_REGULATOR=y # CONFIG_SPL_DOS_PARTITION is not set CONFIG_SPL_OF_CONTROL=y CONFIG_OF_LIVE=y @@ -61,7 +63,9 @@ CONFIG_MMC_SDHCI_SDMA=y CONFIG_MMC_SDHCI_ROCKCHIP=y CONFIG_ETH_DESIGNWARE=y CONFIG_GMAC_ROCKCHIP=y +CONFIG_PHY_ROCKCHIP_INNO_USB2=y CONFIG_REGULATOR_PWM=y +CONFIG_DM_REGULATOR_FIXED=y CONFIG_PWM_ROCKCHIP=y CONFIG_SPL_RAM=y CONFIG_BAUDRATE=1500000 @@ -69,4 +73,17 @@ CONFIG_DEBUG_UART_SHIFT=2 CONFIG_DEBUG_UART_ANNOUNCE=y CONFIG_SYSRESET=y # CONFIG_BINMAN_FDT is not set +CONFIG_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_GENERIC=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_GENERIC=y +CONFIG_USB_HOST_ETHER=y +CONFIG_USB_ETHER_ASIX=y +CONFIG_USB_ETHER_ASIX88179=y +CONFIG_USB_ETHER_LAN75XX=y +CONFIG_USB_ETHER_LAN78XX=y +CONFIG_USB_ETHER_MCS7830=y +CONFIG_USB_ETHER_RTL8152=y +CONFIG_USB_ETHER_SMSC95XX=y CONFIG_ERRNO_STR=y

Some phys require a phy-supply property that is a phandle to a regulator that needs to be enabled for phy operations. Implement basic supply lookup, enable and disabling, if DM_REGULATOR is available.
Signed-off-by: Eugen Hristev eugen.hristev@collabora.com --- drivers/phy/phy-uclass.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
diff --git a/drivers/phy/phy-uclass.c b/drivers/phy/phy-uclass.c index 3fef5135a9cb..475ac285df05 100644 --- a/drivers/phy/phy-uclass.c +++ b/drivers/phy/phy-uclass.c @@ -12,6 +12,7 @@ #include <dm/devres.h> #include <generic-phy.h> #include <linux/list.h> +#include <power/regulator.h>
/** * struct phy_counts - Init and power-on counts of a single PHY port @@ -29,12 +30,14 @@ * without a matching generic_phy_exit() afterwards * @list: Handle for a linked list of these structures corresponding to * ports of the same PHY provider + * @supply: Handle to a phy-supply device */ struct phy_counts { unsigned long id; int power_on_count; int init_count; struct list_head list; + struct udevice *supply; };
static inline struct phy_ops *phy_dev_ops(struct udevice *dev) @@ -224,6 +227,12 @@ int generic_phy_init(struct phy *phy) return 0; }
+#if CONFIG_IS_ENABLED(DM_REGULATOR) + device_get_supply_regulator(phy->dev, "phy-supply", &counts->supply); + if (IS_ERR(counts->supply)) + dev_dbg(phy->dev, "no phy-supply property found\n"); +#endif + ret = ops->init(phy); if (ret) dev_err(phy->dev, "PHY: Failed to init %s: %d.\n", @@ -272,6 +281,12 @@ int generic_phy_exit(struct phy *phy) return 0; }
+#if CONFIG_IS_ENABLED(DM_REGULATOR) + if (!IS_ERR_OR_NULL(counts->supply)) { + ret = regulator_set_enable(counts->supply, false); + dev_dbg(phy->dev, "supply disable status: %d\n", ret); + } +#endif ret = ops->exit(phy); if (ret) dev_err(phy->dev, "PHY: Failed to exit %s: %d.\n", @@ -300,6 +315,13 @@ int generic_phy_power_on(struct phy *phy) return 0; }
+#if CONFIG_IS_ENABLED(DM_REGULATOR) + if (!IS_ERR_OR_NULL(counts->supply)) { + ret = regulator_set_enable(counts->supply, true); + dev_dbg(phy->dev, "supply enable status: %d\n", ret); + } +#endif + ret = ops->power_on(phy); if (ret) dev_err(phy->dev, "PHY: Failed to power on %s: %d.\n",

Hi Eugen,
On 2023-04-04 16:11, Eugen Hristev wrote:
Some phys require a phy-supply property that is a phandle to a regulator that needs to be enabled for phy operations. Implement basic supply lookup, enable and disabling, if DM_REGULATOR is available.
Thanks for looking at this, I have now had some time to test this and it turned out there was some minor issues.
First, the regulator is enabled in power_on and disabled in exit. It should probably be disabled after power_off ops has been called.
Second, the return value is ignored, this will change the meson code to continue with the call to the power_on ops, before it would have stopped and returned early with an error from the power_on ops.
Third, there seem to be a possibility that the counts in regulator core can end up uneven when any of init/exit/power_on/power_off ops is NULL.
I created "fixup! phy: add support for phy-supply" and "phy: Keep balance of counts when ops is missing" at [1] during my testing, please feel free to fixup/squash/rework any code :-)
Tested with USB (multiple usb start/reset/stop cycles) and PCIe (multiple pci enum) on RK3568 together with your "regulator: implement basic reference counter".
[1] https://github.com/Kwiboo/u-boot-rockchip/commits/rk3568-usb-v1
Regards, Jonas
Signed-off-by: Eugen Hristev eugen.hristev@collabora.com
drivers/phy/phy-uclass.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
diff --git a/drivers/phy/phy-uclass.c b/drivers/phy/phy-uclass.c index 3fef5135a9cb..475ac285df05 100644 --- a/drivers/phy/phy-uclass.c +++ b/drivers/phy/phy-uclass.c @@ -12,6 +12,7 @@ #include <dm/devres.h> #include <generic-phy.h> #include <linux/list.h> +#include <power/regulator.h>
/**
- struct phy_counts - Init and power-on counts of a single PHY port
@@ -29,12 +30,14 @@
without a matching generic_phy_exit() afterwards
- @list: Handle for a linked list of these structures corresponding to
ports of the same PHY provider
*/
- @supply: Handle to a phy-supply device
struct phy_counts { unsigned long id; int power_on_count; int init_count; struct list_head list;
- struct udevice *supply;
};
static inline struct phy_ops *phy_dev_ops(struct udevice *dev) @@ -224,6 +227,12 @@ int generic_phy_init(struct phy *phy) return 0; }
+#if CONFIG_IS_ENABLED(DM_REGULATOR)
- device_get_supply_regulator(phy->dev, "phy-supply", &counts->supply);
- if (IS_ERR(counts->supply))
dev_dbg(phy->dev, "no phy-supply property found\n");
+#endif
- ret = ops->init(phy); if (ret) dev_err(phy->dev, "PHY: Failed to init %s: %d.\n",
@@ -272,6 +281,12 @@ int generic_phy_exit(struct phy *phy) return 0; }
+#if CONFIG_IS_ENABLED(DM_REGULATOR)
- if (!IS_ERR_OR_NULL(counts->supply)) {
ret = regulator_set_enable(counts->supply, false);
dev_dbg(phy->dev, "supply disable status: %d\n", ret);
- }
+#endif ret = ops->exit(phy); if (ret) dev_err(phy->dev, "PHY: Failed to exit %s: %d.\n", @@ -300,6 +315,13 @@ int generic_phy_power_on(struct phy *phy) return 0; }
+#if CONFIG_IS_ENABLED(DM_REGULATOR)
- if (!IS_ERR_OR_NULL(counts->supply)) {
ret = regulator_set_enable(counts->supply, true);
dev_dbg(phy->dev, "supply enable status: %d\n", ret);
- }
+#endif
- ret = ops->power_on(phy); if (ret) dev_err(phy->dev, "PHY: Failed to power on %s: %d.\n",

On 4/12/23 09:53, Jonas Karlman wrote:
Hi Eugen,
On 2023-04-04 16:11, Eugen Hristev wrote:
Some phys require a phy-supply property that is a phandle to a regulator that needs to be enabled for phy operations. Implement basic supply lookup, enable and disabling, if DM_REGULATOR is available.
Thanks for looking at this, I have now had some time to test this and it turned out there was some minor issues.
First, the regulator is enabled in power_on and disabled in exit. It should probably be disabled after power_off ops has been called.
Second, the return value is ignored, this will change the meson code to continue with the call to the power_on ops, before it would have stopped and returned early with an error from the power_on ops.
While indeed there is a change, I do not want to stop when there is an error with phy supply. First, the enabling of the regulator could return EALREADY on enable, or EBUSY on disable, which is not really an error, so this has to be treated accordingly Second, all this time the code has lived without phy supply except for some few drivers, so, if now we stop and break on phy supply not working, we may break a lot of other boards which simply ignored phy supply until today. Because of that, my whole patch has treated phy supply as basically an optional property which is requested, but not mandatory to continue without.
Third, there seem to be a possibility that the counts in regulator core can end up uneven when any of init/exit/power_on/power_off ops is NULL. > I created "fixup! phy: add support for phy-supply" and "phy: Keep balance of counts when ops is missing" at [1] during my testing, please feel free to fixup/squash/rework any code :-)
do you want to add this second patch to my series ?
and squash the first into my patches with you as co-author ? but I will change a bit what you wrote, namely handling EBUSY and EALREADY e.g.
Tested with USB (multiple usb start/reset/stop cycles) and PCIe (multiple pci enum) on RK3568 together with your "regulator: implement basic reference counter".
[1] https://github.com/Kwiboo/u-boot-rockchip/commits/rk3568-usb-v1
Regards, Jonas
Signed-off-by: Eugen Hristev eugen.hristev@collabora.com
drivers/phy/phy-uclass.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
diff --git a/drivers/phy/phy-uclass.c b/drivers/phy/phy-uclass.c index 3fef5135a9cb..475ac285df05 100644 --- a/drivers/phy/phy-uclass.c +++ b/drivers/phy/phy-uclass.c @@ -12,6 +12,7 @@ #include <dm/devres.h> #include <generic-phy.h> #include <linux/list.h> +#include <power/regulator.h>
/**
- struct phy_counts - Init and power-on counts of a single PHY port
@@ -29,12 +30,14 @@
without a matching generic_phy_exit() afterwards
- @list: Handle for a linked list of these structures corresponding to
ports of the same PHY provider
- @supply: Handle to a phy-supply device
*/ struct phy_counts { unsigned long id; int power_on_count; int init_count; struct list_head list;
struct udevice *supply; };
static inline struct phy_ops *phy_dev_ops(struct udevice *dev)
@@ -224,6 +227,12 @@ int generic_phy_init(struct phy *phy) return 0; }
+#if CONFIG_IS_ENABLED(DM_REGULATOR)
- device_get_supply_regulator(phy->dev, "phy-supply", &counts->supply);
- if (IS_ERR(counts->supply))
dev_dbg(phy->dev, "no phy-supply property found\n");
+#endif
- ret = ops->init(phy); if (ret) dev_err(phy->dev, "PHY: Failed to init %s: %d.\n",
@@ -272,6 +281,12 @@ int generic_phy_exit(struct phy *phy) return 0; }
+#if CONFIG_IS_ENABLED(DM_REGULATOR)
- if (!IS_ERR_OR_NULL(counts->supply)) {
ret = regulator_set_enable(counts->supply, false);
dev_dbg(phy->dev, "supply disable status: %d\n", ret);
- }
+#endif ret = ops->exit(phy); if (ret) dev_err(phy->dev, "PHY: Failed to exit %s: %d.\n", @@ -300,6 +315,13 @@ int generic_phy_power_on(struct phy *phy) return 0; }
+#if CONFIG_IS_ENABLED(DM_REGULATOR)
- if (!IS_ERR_OR_NULL(counts->supply)) {
ret = regulator_set_enable(counts->supply, true);
dev_dbg(phy->dev, "supply enable status: %d\n", ret);
- }
+#endif
- ret = ops->power_on(phy); if (ret) dev_err(phy->dev, "PHY: Failed to power on %s: %d.\n",

Hi Eugen,
On 2023-04-12 09:45, Eugen Hristev wrote:
On 4/12/23 09:53, Jonas Karlman wrote:
Hi Eugen,
On 2023-04-04 16:11, Eugen Hristev wrote:
Some phys require a phy-supply property that is a phandle to a regulator that needs to be enabled for phy operations. Implement basic supply lookup, enable and disabling, if DM_REGULATOR is available.
Thanks for looking at this, I have now had some time to test this and it turned out there was some minor issues.
First, the regulator is enabled in power_on and disabled in exit. It should probably be disabled after power_off ops has been called.
Second, the return value is ignored, this will change the meson code to continue with the call to the power_on ops, before it would have stopped and returned early with an error from the power_on ops.
While indeed there is a change, I do not want to stop when there is an error with phy supply. First, the enabling of the regulator could return EALREADY on enable, or EBUSY on disable, which is not really an error, so this has to be treated accordingly Second, all this time the code has lived without phy supply except for some few drivers, so, if now we stop and break on phy supply not working, we may break a lot of other boards which simply ignored phy supply until today. Because of that, my whole patch has treated phy supply as basically an optional property which is requested, but not mandatory to continue without.
Understandable, and I was expecting that regulator_set_enable_if_allowed handled that, it return -ENOSYS when it is unsupported or 0 on anything that could be treated like a success and only an error if there is an error while changing the regulator.
Looking at the phy-supply defined in device trees in u-boot it is mostly used for ethernet or usb on imx, meson, rockchip and sunxi. So hopefully a relaxed error handling should not affect that much and could help keeping the regulator enable_count balanced.
Third, there seem to be a possibility that the counts in regulator core can end up uneven when any of init/exit/power_on/power_off ops is NULL. > I created "fixup! phy: add support for phy-supply" and "phy: Keep balance of counts when ops is missing" at [1] during my testing, please feel free to fixup/squash/rework any code :-)
do you want to add this second patch to my series ?
and squash the first into my patches with you as co-author ? but I will change a bit what you wrote, namely handling EBUSY and EALREADY e.g.
Please pick/squash as you see best fit, no need for co-author :-)
The counts balance change was inspired by linux drivers/phy/phy-core.c
Regards, Jonas
Tested with USB (multiple usb start/reset/stop cycles) and PCIe (multiple pci enum) on RK3568 together with your "regulator: implement basic reference counter".
[1] https://github.com/Kwiboo/u-boot-rockchip/commits/rk3568-usb-v1
Regards, Jonas
Signed-off-by: Eugen Hristev eugen.hristev@collabora.com
drivers/phy/phy-uclass.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
diff --git a/drivers/phy/phy-uclass.c b/drivers/phy/phy-uclass.c index 3fef5135a9cb..475ac285df05 100644 --- a/drivers/phy/phy-uclass.c +++ b/drivers/phy/phy-uclass.c @@ -12,6 +12,7 @@ #include <dm/devres.h> #include <generic-phy.h> #include <linux/list.h> +#include <power/regulator.h>
/**
- struct phy_counts - Init and power-on counts of a single PHY port
@@ -29,12 +30,14 @@
without a matching generic_phy_exit() afterwards
- @list: Handle for a linked list of these structures corresponding to
ports of the same PHY provider
- @supply: Handle to a phy-supply device
*/ struct phy_counts { unsigned long id; int power_on_count; int init_count; struct list_head list;
struct udevice *supply; };
static inline struct phy_ops *phy_dev_ops(struct udevice *dev)
@@ -224,6 +227,12 @@ int generic_phy_init(struct phy *phy) return 0; }
+#if CONFIG_IS_ENABLED(DM_REGULATOR)
- device_get_supply_regulator(phy->dev, "phy-supply", &counts->supply);
- if (IS_ERR(counts->supply))
dev_dbg(phy->dev, "no phy-supply property found\n");
+#endif
- ret = ops->init(phy); if (ret) dev_err(phy->dev, "PHY: Failed to init %s: %d.\n",
@@ -272,6 +281,12 @@ int generic_phy_exit(struct phy *phy) return 0; }
+#if CONFIG_IS_ENABLED(DM_REGULATOR)
- if (!IS_ERR_OR_NULL(counts->supply)) {
ret = regulator_set_enable(counts->supply, false);
dev_dbg(phy->dev, "supply disable status: %d\n", ret);
- }
+#endif ret = ops->exit(phy); if (ret) dev_err(phy->dev, "PHY: Failed to exit %s: %d.\n", @@ -300,6 +315,13 @@ int generic_phy_power_on(struct phy *phy) return 0; }
+#if CONFIG_IS_ENABLED(DM_REGULATOR)
- if (!IS_ERR_OR_NULL(counts->supply)) {
ret = regulator_set_enable(counts->supply, true);
dev_dbg(phy->dev, "supply enable status: %d\n", ret);
- }
+#endif
- ret = ops->power_on(phy); if (ret) dev_err(phy->dev, "PHY: Failed to power on %s: %d.\n",

phy-supply is now handled at uclass level. Remove it from the drivers that implement it at the driver level.
Suggested-by: Jonas Karlman jonas@kwiboo.se Signed-off-by: Eugen Hristev eugen.hristev@collabora.com --- drivers/phy/meson-g12a-usb2.c | 48 ----------------------------------- drivers/phy/meson-gxbb-usb2.c | 38 --------------------------- drivers/phy/meson-gxl-usb2.c | 30 ---------------------- 3 files changed, 116 deletions(-)
diff --git a/drivers/phy/meson-g12a-usb2.c b/drivers/phy/meson-g12a-usb2.c index 2fbba7fdae01..650b88bd1803 100644 --- a/drivers/phy/meson-g12a-usb2.c +++ b/drivers/phy/meson-g12a-usb2.c @@ -54,50 +54,12 @@
struct phy_meson_g12a_usb2_priv { struct regmap *regmap; -#if CONFIG_IS_ENABLED(DM_REGULATOR) - struct udevice *phy_supply; -#endif #if CONFIG_IS_ENABLED(CLK) struct clk clk; #endif struct reset_ctl reset; };
- -static int phy_meson_g12a_usb2_power_on(struct phy *phy) -{ -#if CONFIG_IS_ENABLED(DM_REGULATOR) - struct udevice *dev = phy->dev; - struct phy_meson_g12a_usb2_priv *priv = dev_get_priv(dev); - - if (priv->phy_supply) { - int ret = regulator_set_enable(priv->phy_supply, true); - if (ret) - return ret; - } -#endif - - return 0; -} - -static int phy_meson_g12a_usb2_power_off(struct phy *phy) -{ -#if CONFIG_IS_ENABLED(DM_REGULATOR) - struct udevice *dev = phy->dev; - struct phy_meson_g12a_usb2_priv *priv = dev_get_priv(dev); - - if (priv->phy_supply) { - int ret = regulator_set_enable(priv->phy_supply, false); - if (ret) { - pr_err("Error disabling PHY supply\n"); - return ret; - } - } -#endif - - return 0; -} - static int phy_meson_g12a_usb2_init(struct phy *phy) { struct udevice *dev = phy->dev; @@ -155,8 +117,6 @@ static int phy_meson_g12a_usb2_exit(struct phy *phy) struct phy_ops meson_g12a_usb2_phy_ops = { .init = phy_meson_g12a_usb2_init, .exit = phy_meson_g12a_usb2_exit, - .power_on = phy_meson_g12a_usb2_power_on, - .power_off = phy_meson_g12a_usb2_power_off, };
int meson_g12a_usb2_phy_probe(struct udevice *dev) @@ -193,14 +153,6 @@ int meson_g12a_usb2_phy_probe(struct udevice *dev) } #endif
-#if CONFIG_IS_ENABLED(DM_REGULATOR) - ret = device_get_supply_regulator(dev, "phy-supply", &priv->phy_supply); - if (ret && ret != -ENOENT) { - pr_err("Failed to get PHY regulator\n"); - return ret; - } -#endif - return 0; }
diff --git a/drivers/phy/meson-gxbb-usb2.c b/drivers/phy/meson-gxbb-usb2.c index 7a2e3d2739e8..70a80b863819 100644 --- a/drivers/phy/meson-gxbb-usb2.c +++ b/drivers/phy/meson-gxbb-usb2.c @@ -12,7 +12,6 @@ #include <clk.h> #include <dm.h> #include <generic-phy.h> -#include <power/regulator.h> #include <regmap.h> #include <reset.h> #include <linux/bitops.h> @@ -81,9 +80,6 @@ struct phy_meson_gxbb_usb2_priv { struct regmap *regmap; struct reset_ctl_bulk resets; -#if CONFIG_IS_ENABLED(DM_REGULATOR) - struct udevice *phy_supply; -#endif };
static int phy_meson_gxbb_usb2_power_on(struct phy *phy) @@ -92,15 +88,6 @@ static int phy_meson_gxbb_usb2_power_on(struct phy *phy) struct phy_meson_gxbb_usb2_priv *priv = dev_get_priv(dev); uint val;
-#if CONFIG_IS_ENABLED(DM_REGULATOR) - if (priv->phy_supply) { - int ret = regulator_set_enable(priv->phy_supply, true); - - if (ret) - return ret; - } -#endif - regmap_update_bits(priv->regmap, REG_CONFIG, REG_CONFIG_CLK_32k_ALTSEL, REG_CONFIG_CLK_32k_ALTSEL); @@ -140,26 +127,8 @@ static int phy_meson_gxbb_usb2_power_on(struct phy *phy) return 0; }
-static int phy_meson_gxbb_usb2_power_off(struct phy *phy) -{ -#if CONFIG_IS_ENABLED(DM_REGULATOR) - struct udevice *dev = phy->dev; - struct phy_meson_gxbb_usb2_priv *priv = dev_get_priv(dev); - - if (priv->phy_supply) { - int ret = regulator_set_enable(priv->phy_supply, false); - - if (ret) - return ret; - } -#endif - - return 0; -} - static struct phy_ops meson_gxbb_usb2_phy_ops = { .power_on = phy_meson_gxbb_usb2_power_on, - .power_off = phy_meson_gxbb_usb2_power_off, };
static int meson_gxbb_usb2_phy_probe(struct udevice *dev) @@ -192,13 +161,6 @@ static int meson_gxbb_usb2_phy_probe(struct udevice *dev) return ret; }
-#if CONFIG_IS_ENABLED(DM_REGULATOR) - ret = device_get_supply_regulator(dev, "phy-supply", &priv->phy_supply); - if (ret && ret != -ENOENT) { - pr_err("Failed to get PHY regulator\n"); - return ret; - } -#endif ret = reset_get_bulk(dev, &priv->resets); if (!ret) { ret = reset_deassert_bulk(&priv->resets); diff --git a/drivers/phy/meson-gxl-usb2.c b/drivers/phy/meson-gxl-usb2.c index 9fb376cec448..4c631310efac 100644 --- a/drivers/phy/meson-gxl-usb2.c +++ b/drivers/phy/meson-gxl-usb2.c @@ -16,7 +16,6 @@ #include <generic-phy.h> #include <regmap.h> #include <linux/delay.h> -#include <power/regulator.h> #include <clk.h> #include <linux/usb/otg.h>
@@ -101,9 +100,6 @@
struct phy_meson_gxl_usb2_priv { struct regmap *regmap; -#if CONFIG_IS_ENABLED(DM_REGULATOR) - struct udevice *phy_supply; -#endif #if CONFIG_IS_ENABLED(CLK) struct clk clk; #endif @@ -167,14 +163,6 @@ static int phy_meson_gxl_usb2_power_on(struct phy *phy)
phy_meson_gxl_usb2_set_mode(phy, USB_DR_MODE_HOST);
-#if CONFIG_IS_ENABLED(DM_REGULATOR) - if (priv->phy_supply) { - int ret = regulator_set_enable(priv->phy_supply, true); - if (ret) - return ret; - } -#endif - return 0; }
@@ -189,16 +177,6 @@ static int phy_meson_gxl_usb2_power_off(struct phy *phy) val |= U2P_R0_POWER_ON_RESET; regmap_write(priv->regmap, U2P_R0, val);
-#if CONFIG_IS_ENABLED(DM_REGULATOR) - if (priv->phy_supply) { - int ret = regulator_set_enable(priv->phy_supply, false); - if (ret) { - pr_err("Error disabling PHY supply\n"); - return ret; - } - } -#endif - return 0; }
@@ -229,14 +207,6 @@ int meson_gxl_usb2_phy_probe(struct udevice *dev) } #endif
-#if CONFIG_IS_ENABLED(DM_REGULATOR) - ret = device_get_supply_regulator(dev, "phy-supply", &priv->phy_supply); - if (ret && ret != -ENOENT) { - pr_err("Failed to get PHY regulator\n"); - return ret; - } -#endif - return 0; }

Add initial support for the rk3588 PHY variant. The lookup for the host-port reg inside the struct now does a do {} while() instead of a while() {} in order to allow a first check for reg == 0.
Co-developed-by: Frank Wang frank.wang@rock-chips.com Signed-off-by: Frank Wang frank.wang@rock-chips.com Signed-off-by: Eugen Hristev eugen.hristev@collabora.com --- Changes in v4: - moved all vbus/phy-supply to the core Changes in v3: - add handling of -EBUSY and -EALREADY for regulator return Changes in v2: - add handling of -EACCES drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 60 ++++++++++++++++++- 1 file changed, 58 insertions(+), 2 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c index 55e1dbcfef7e..22e2797eea28 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c @@ -201,14 +201,14 @@ static int rockchip_usb2phy_probe(struct udevice *dev)
/* find out a proper config which can be matched with dt. */ index = 0; - while (phy_cfgs[index].reg) { + do { if (phy_cfgs[index].reg == reg) { priv->phy_cfg = &phy_cfgs[index]; break; }
++index; - } + } while (phy_cfgs[index].reg);
if (!priv->phy_cfg) { dev_err(dev, "failed find proper phy-cfg\n"); @@ -348,6 +348,58 @@ static const struct rockchip_usb2phy_cfg rk3568_phy_cfgs[] = { { /* sentinel */ } };
+static const struct rockchip_usb2phy_cfg rk3588_phy_cfgs[] = { + { + .reg = 0x0000, + .port_cfgs = { + [USB2PHY_PORT_OTG] = { + .phy_sus = { 0x000c, 11, 11, 0, 1 }, + .ls_det_en = { 0x0080, 0, 0, 0, 1 }, + .ls_det_st = { 0x0084, 0, 0, 0, 1 }, + .ls_det_clr = { 0x0088, 0, 0, 0, 1 }, + .utmi_ls = { 0x00c0, 10, 9, 0, 1 }, + } + }, + }, + { + .reg = 0x4000, + .port_cfgs = { + [USB2PHY_PORT_OTG] = { + .phy_sus = { 0x000c, 11, 11, 0, 0 }, + .ls_det_en = { 0x0080, 0, 0, 0, 1 }, + .ls_det_st = { 0x0084, 0, 0, 0, 1 }, + .ls_det_clr = { 0x0088, 0, 0, 0, 1 }, + .utmi_ls = { 0x00c0, 10, 9, 0, 1 }, + } + }, + }, + { + .reg = 0x8000, + .port_cfgs = { + [USB2PHY_PORT_HOST] = { + .phy_sus = { 0x0008, 2, 2, 0, 1 }, + .ls_det_en = { 0x0080, 0, 0, 0, 1 }, + .ls_det_st = { 0x0084, 0, 0, 0, 1 }, + .ls_det_clr = { 0x0088, 0, 0, 0, 1 }, + .utmi_ls = { 0x00c0, 10, 9, 0, 1 }, + } + }, + }, + { + .reg = 0xc000, + .port_cfgs = { + [USB2PHY_PORT_HOST] = { + .phy_sus = { 0x0008, 2, 2, 0, 1 }, + .ls_det_en = { 0x0080, 0, 0, 0, 1 }, + .ls_det_st = { 0x0084, 0, 0, 0, 1 }, + .ls_det_clr = { 0x0088, 0, 0, 0, 1 }, + .utmi_ls = { 0x00c0, 10, 9, 0, 1 }, + } + }, + }, + { /* sentinel */ } +}; + static const struct udevice_id rockchip_usb2phy_ids[] = { { .compatible = "rockchip,rk3399-usb2phy", @@ -357,6 +409,10 @@ static const struct udevice_id rockchip_usb2phy_ids[] = { .compatible = "rockchip,rk3568-usb2phy", .data = (ulong)&rk3568_phy_cfgs, }, + { + .compatible = "rockchip,rk3588-usb2phy", + .data = (ulong)&rk3588_phy_cfgs, + }, { /* sentinel */ } };
participants (2)
-
Eugen Hristev
-
Jonas Karlman