* [PATCH v6 0/2] arm: dts: rockchip: rk3399: usb: ehci: Fix EHCI probe in rk3399 to access peripherals by USB 2.
@ 2023-06-04 8:12 Xavier Drudis Ferran
2023-06-04 8:13 ` [PATCH v6 1/2] " Xavier Drudis Ferran
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Xavier Drudis Ferran @ 2023-06-04 8:12 UTC (permalink / raw)
To: u-boot
Cc: Simon Glass, Philipp Tomsich, Kever Yang, Lukasz Majewski,
Sean Anderson, Marek Vasut, Christoph Fritz, Jagan Teki
EHCI probing in Rock pi 4 currently fails.
Add a clock driver for usb2phy so that probing EHCI does not fail when
missing one of the clocks in the bundle for usb_host0_ehci, since
usb2phy is UCLASS_PHY but not UCLASS_CLK.
Xavier Drudis Ferran (2):
arm: dts: rockchip: rk3399: usb: ehci: Fix EHCI probe in rk3399 to
access peripherals by USB 2.
arm: rk3399: usb2phy: phy-rockchip-inno-usb2.c: Implement operations
for the 480MHz usb2phy clock in rk3399.
drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 97 ++++++++++++++++++-
1 file changed, 96 insertions(+), 1 deletion(-)
Cc: Simon Glass <sjg@chromium.org>
Cc: Philipp Tomsich <philipp.tomsich@vrull.eu>
Cc: Kever Yang <kever.yang@rock-chips.com>
Cc: Lukasz Majewski <lukma@denx.de>
Cc: Sean Anderson <seanga2@gmail.com>
Cc: Marek Vasut <marex@denx.de>
Cc: Christoph Fritz <chf.fritz@googlemail.com>
Cc: Jagan Teki <jagan@amarulasolutions.com>
Signed-off-by: Xavier Drudis Ferran <xdrudis@tinet.cat>
---
Changes:
v6: just retested over current next branch and some corrections
to message and headers
(no changes to code).
v5: fixes a bug that Christoph Fritz discovered, consisting in the
wrong eror code returned when enabling or disabling the clock
because property_enable() returns an error code in linux but
the modified register value in U-Boot. This caused the clk
disable to abort before freeing the clock.
v4: move v3 to one patch in the series and add a second patch
to add operations to enable disable the usb2phy 480Mhz clock.
Also, honour clock-output-names for what is worth.
v3: implement option 5 (bind usb2phy as a clk driver too) instead
of option 1 (ehci-generic.c tolerates missing clocks).
v2: implement option 1 (ehci-generic.c tolerates missing clocks)
instead of option 3 (change dts node to remove the missing
clock).
--
2.20.1
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH v6 1/2] arm: dts: rockchip: rk3399: usb: ehci: Fix EHCI probe in rk3399 to access peripherals by USB 2. 2023-06-04 8:12 [PATCH v6 0/2] arm: dts: rockchip: rk3399: usb: ehci: Fix EHCI probe in rk3399 to access peripherals by USB 2 Xavier Drudis Ferran @ 2023-06-04 8:13 ` Xavier Drudis Ferran 2023-06-04 9:31 ` Marek Vasut 2023-06-04 8:13 ` [PATCH v6 2/2] arm: rk3399: usb2phy: phy-rockchip-inno-usb2.c: Implement operations for the 480MHz usb2phy clock in rk3399 Xavier Drudis Ferran 2023-06-05 2:41 ` [PATCH v6 0/2] arm: dts: rockchip: rk3399: usb: ehci: Fix EHCI probe in rk3399 to access peripherals by USB 2 Jagan Teki 2 siblings, 1 reply; 9+ messages in thread From: Xavier Drudis Ferran @ 2023-06-04 8:13 UTC (permalink / raw) To: u-boot Cc: Simon Glass, Philipp Tomsich, Kever Yang, Lukasz Majewski, Sean Anderson, Marek Vasut, Christoph Fritz, Jagan Teki arch/arm/dts/rk3399.dtsi has a node usb_host0_ehci: usb@fe380000 { compatible = "generic-ehci"; with clocks: clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST0_ARB>, <&u2phy0>; The first 2 refer to nodes with class UCLASS_CLK, but &u2phy0 has class UCLASS_PHY. u2phy0: usb2phy@e450 { compatible = "rockchip,rk3399-usb2phy"; Since clk_get_bulk() only looks for devices with UCLASS_CLK, it fails with -ENODEV and then ehci_usb_probe() aborts. The consequence is peripherals connected to a USB 2 port (e.g. in a Rock Pi 4 the white port, nearer the edge) not being detected. They're detected if CONFIG_USB_OHCI_GENERIC is selected in Kconfig, because ohci_usb_probe() does not abort when one clk_get_by_index() fails, but then they work in USB 1 mode. rk3399.dtsi comes from linux and the u2phy0 was added[1] to the clock list in: commit b5d1c57299734f5b54035ef2e61706b83041f20c Author: William wu <wulf@rock-chips.com> Date: Wed Dec 21 18:41:05 2016 +0800 arm64: dts: rockchip: add u2phy clock for ehci and ohci of rk3399 We found that the suspend process was blocked when it run into ehci/ohci module due to clk-480m of usb2-phy was disabled. [...] Suspend concerns don't apply to U-Boot, and the problem with U-Boot failing to probe EHCI doesn't apply to linux, because in linux rockchip_usb2phy_clk480m_register makes u2phy0 a proper clock provider when called by rockchip_usb2phy_probe(). So I can think of a few alternative solutions: 1- Change ehci_usb_probe() to make it more similar to ohci_usb_probe(), and survive failure to get one clock. Looks a little harder, and I don't know whether it could break something if it ignored a clock that was important for something else than suspend. 2- Change rk3399.dtsi effectively reverting the linux commit b5d1c57299734f5b54035ef2e61706b83041f20c. This dealigns the .dtsi from linux and seems fragile at the next synchronisation. 3- Change the clock list in rk3399-u-boot.dtsi or somewhere else. This survives .dts* sync but may survive "too much" and miss some change from linux that we might want. 4- Enable CONFIG_USB_OHCI_GENERIC and use the ports in USB 1 mode. This would need to be made for all boards using rk3399. In a simple test reading one file from USB storage it gave 769.5 KiB/s instead of 20.5 MiB/s with solution 2. 5- Trying to replicate linux and have usb2phy somehow provide a clk, or have a separate clock device for usb2phy in addition to the phy device. This patch tries to implement option 5 as Marek Vasut requested in December 5th. Options 1 and 3 didn't get through [2][3]. It just registers usb2phy as a clock driver (device_bind_driver() didn't work but device_bind_driver_to_node() did), without any specific operations, so that ehci-generic.c finds it and is happy. It worked in my tests on a Rock Pi 4 B+ (rk3399). Link: [1] https://lkml.kernel.org/lkml/1731551.Q6cHK6n5ZM@phil/T/ [2] https://patchwork.ozlabs.org/project/uboot/patch/20220701185959.GC1700@begut/ [3] https://patchwork.ozlabs.org/project/uboot/patch/Y44+ayJfUlI08ptM@localhost/ Cc: Simon Glass <sjg@chromium.org> Cc: Philipp Tomsich <philipp.tomsich@vrull.eu> Cc: Kever Yang <kever.yang@rock-chips.com> Cc: Lukasz Majewski <lukma@denx.de> Cc: Sean Anderson <seanga2@gmail.com> Cc: Marek Vasut <marex@denx.de> Cc: Christoph Fritz <chf.fritz@googlemail.com> Cc: Jagan Teki <jagan@amarulasolutions.com> Signed-off-by: Xavier Drudis Ferran <xdrudis@tinet.cat> --- drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c index 55e1dbcfef..2f31350134 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c @@ -7,7 +7,7 @@ */ #include <common.h> -#include <clk.h> +#include <clk-uclass.h> #include <dm.h> #include <asm/global_data.h> #include <dm/device_compat.h> @@ -168,6 +168,9 @@ static struct phy_ops rockchip_usb2phy_ops = { .of_xlate = rockchip_usb2phy_of_xlate, }; +static struct clk_ops rockchip_usb2phy_clk_ops = { +}; + static int rockchip_usb2phy_probe(struct udevice *dev) { struct rockchip_usb2phy *priv = dev_get_priv(dev); @@ -249,6 +252,18 @@ static int rockchip_usb2phy_bind(struct udevice *dev) } } + if (!ret) { + node = dev_ofnode(dev); + name = ofnode_get_name(node); + dev_dbg(dev, "clk for node %s\n", name); + ret = device_bind_driver_to_node(dev, "rockchip_usb2phy_clock", + name, node, &usb2phy_dev); + if (ret) { + dev_err(dev, + "'%s' cannot bind 'rockchip_usb2phy_clock'\n", name); + } + } + return ret; } @@ -366,6 +381,12 @@ U_BOOT_DRIVER(rockchip_usb2phy_port) = { .ops = &rockchip_usb2phy_ops, }; +U_BOOT_DRIVER(rockchip_usb2phy_clock) = { + .name = "rockchip_usb2phy_clock", + .id = UCLASS_CLK, + .ops = &rockchip_usb2phy_clk_ops, +}; + U_BOOT_DRIVER(rockchip_usb2phy) = { .name = "rockchip_usb2phy", .id = UCLASS_PHY, -- 2.20.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v6 1/2] arm: dts: rockchip: rk3399: usb: ehci: Fix EHCI probe in rk3399 to access peripherals by USB 2. 2023-06-04 8:13 ` [PATCH v6 1/2] " Xavier Drudis Ferran @ 2023-06-04 9:31 ` Marek Vasut 2023-06-04 22:12 ` Xavier Drudis Ferran 0 siblings, 1 reply; 9+ messages in thread From: Marek Vasut @ 2023-06-04 9:31 UTC (permalink / raw) To: Xavier Drudis Ferran, u-boot Cc: Simon Glass, Philipp Tomsich, Kever Yang, Lukasz Majewski, Sean Anderson, Christoph Fritz, Jagan Teki On 6/4/23 10:13, Xavier Drudis Ferran wrote: > > arch/arm/dts/rk3399.dtsi has a node > > usb_host0_ehci: usb@fe380000 { > compatible = "generic-ehci"; > > with clocks: > > clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST0_ARB>, > <&u2phy0>; > > The first 2 refer to nodes with class UCLASS_CLK, but &u2phy0 > has class UCLASS_PHY. > > u2phy0: usb2phy@e450 { > compatible = "rockchip,rk3399-usb2phy"; > > Since clk_get_bulk() only looks for devices with UCLASS_CLK, > it fails with -ENODEV and then ehci_usb_probe() aborts. > > The consequence is peripherals connected to a USB 2 port (e.g. in a > Rock Pi 4 the white port, nearer the edge) not being detected. > They're detected if CONFIG_USB_OHCI_GENERIC is selected in Kconfig, > because ohci_usb_probe() does not abort when one clk_get_by_index() > fails, but then they work in USB 1 mode. > > rk3399.dtsi comes from linux and the u2phy0 was added[1] to the clock > list in: > > commit b5d1c57299734f5b54035ef2e61706b83041f20c > Author: William wu <wulf@rock-chips.com> > Date: Wed Dec 21 18:41:05 2016 +0800 > > arm64: dts: rockchip: add u2phy clock for ehci and ohci of rk3399 > > We found that the suspend process was blocked when it run into > ehci/ohci module due to clk-480m of usb2-phy was disabled. > [...] > > Suspend concerns don't apply to U-Boot, and the problem with U-Boot > failing to probe EHCI doesn't apply to linux, because in linux > rockchip_usb2phy_clk480m_register makes u2phy0 a proper clock provider > when called by rockchip_usb2phy_probe(). > > So I can think of a few alternative solutions: > > 1- Change ehci_usb_probe() to make it more similar to > ohci_usb_probe(), and survive failure to get one clock. Looks a > little harder, and I don't know whether it could break something if > it ignored a clock that was important for something else than > suspend. > > 2- Change rk3399.dtsi effectively reverting the linux commit > b5d1c57299734f5b54035ef2e61706b83041f20c. This dealigns the .dtsi > from linux and seems fragile at the next synchronisation. > > 3- Change the clock list in rk3399-u-boot.dtsi or somewhere else. > This survives .dts* sync but may survive "too much" and miss some > change from linux that we might want. > > 4- Enable CONFIG_USB_OHCI_GENERIC and use the ports in USB 1 mode. > This would need to be made for all boards using rk3399. In a > simple test reading one file from USB storage it gave 769.5 KiB/s > instead of 20.5 MiB/s with solution 2. > > 5- Trying to replicate linux and have usb2phy somehow provide a clk, > or have a separate clock device for usb2phy in addition to the phy > device. > > This patch tries to implement option 5 as Marek Vasut requested in > December 5th. Options 1 and 3 didn't get through [2][3]. > > It just registers usb2phy as a clock driver (device_bind_driver() > didn't work but device_bind_driver_to_node() did), without any > specific operations, so that ehci-generic.c finds it and is happy. It > worked in my tests on a Rock Pi 4 B+ (rk3399). > > Link: [1] https://lkml.kernel.org/lkml/1731551.Q6cHK6n5ZM@phil/T/ > [2] https://patchwork.ozlabs.org/project/uboot/patch/20220701185959.GC1700@begut/ > [3] https://patchwork.ozlabs.org/project/uboot/patch/Y44+ayJfUlI08ptM@localhost/ > > Cc: Simon Glass <sjg@chromium.org> > Cc: Philipp Tomsich <philipp.tomsich@vrull.eu> > Cc: Kever Yang <kever.yang@rock-chips.com> > Cc: Lukasz Majewski <lukma@denx.de> > Cc: Sean Anderson <seanga2@gmail.com> > Cc: Marek Vasut <marex@denx.de> > Cc: Christoph Fritz <chf.fritz@googlemail.com> > Cc: Jagan Teki <jagan@amarulasolutions.com> > > Signed-off-by: Xavier Drudis Ferran <xdrudis@tinet.cat> > --- > drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 23 ++++++++++++++++++- > 1 file changed, 22 insertions(+), 1 deletion(-) > > diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c > index 55e1dbcfef..2f31350134 100644 > --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c > +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c > @@ -7,7 +7,7 @@ > */ > > #include <common.h> > -#include <clk.h> > +#include <clk-uclass.h> > #include <dm.h> > #include <asm/global_data.h> > #include <dm/device_compat.h> > @@ -168,6 +168,9 @@ static struct phy_ops rockchip_usb2phy_ops = { > .of_xlate = rockchip_usb2phy_of_xlate, > }; > > +static struct clk_ops rockchip_usb2phy_clk_ops = { > +}; > + > static int rockchip_usb2phy_probe(struct udevice *dev) > { > struct rockchip_usb2phy *priv = dev_get_priv(dev); > @@ -249,6 +252,18 @@ static int rockchip_usb2phy_bind(struct udevice *dev) > } > } > > + if (!ret) { Can $ret ever be != 0 here ? btw. the dev_for_each_subnode() above is missing error handling, in case device_bind_driver_to_node() there returns non-zero, there should be some 'goto err' and 'err: dev_for_each_subnode() device_unbind()' fail path. > + node = dev_ofnode(dev); > + name = ofnode_get_name(node); > + dev_dbg(dev, "clk for node %s\n", name); > + ret = device_bind_driver_to_node(dev, "rockchip_usb2phy_clock", > + name, node, &usb2phy_dev); > + if (ret) { > + dev_err(dev, > + "'%s' cannot bind 'rockchip_usb2phy_clock'\n", name); Use device_unbind() in fail path here too. > + } > + } > + > return ret; > } > > @@ -366,6 +381,12 @@ U_BOOT_DRIVER(rockchip_usb2phy_port) = { > .ops = &rockchip_usb2phy_ops, > }; > > +U_BOOT_DRIVER(rockchip_usb2phy_clock) = { > + .name = "rockchip_usb2phy_clock", > + .id = UCLASS_CLK, > + .ops = &rockchip_usb2phy_clk_ops, > +}; > + > U_BOOT_DRIVER(rockchip_usb2phy) = { > .name = "rockchip_usb2phy", > .id = UCLASS_PHY, ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v6 1/2] arm: dts: rockchip: rk3399: usb: ehci: Fix EHCI probe in rk3399 to access peripherals by USB 2. 2023-06-04 9:31 ` Marek Vasut @ 2023-06-04 22:12 ` Xavier Drudis Ferran 0 siblings, 0 replies; 9+ messages in thread From: Xavier Drudis Ferran @ 2023-06-04 22:12 UTC (permalink / raw) To: Marek Vasut Cc: Xavier Drudis Ferran, u-boot, Simon Glass, Philipp Tomsich, Kever Yang, Lukasz Majewski, Sean Anderson, Christoph Fritz, Jagan Teki Thanks for your feedback. El Sun, Jun 04, 2023 at 11:31:28AM +0200, Marek Vasut deia: > > diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c > > index 55e1dbcfef..2f31350134 100644 > > --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c > > +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c > > @@ -7,7 +7,7 @@ > > */ > > #include <common.h> > > -#include <clk.h> > > +#include <clk-uclass.h> > > #include <dm.h> > > #include <asm/global_data.h> > > #include <dm/device_compat.h> > > @@ -168,6 +168,9 @@ static struct phy_ops rockchip_usb2phy_ops = { > > .of_xlate = rockchip_usb2phy_of_xlate, > > }; > > +static struct clk_ops rockchip_usb2phy_clk_ops = { > > +}; > > + > > static int rockchip_usb2phy_probe(struct udevice *dev) > > { > > struct rockchip_usb2phy *priv = dev_get_priv(dev); > > @@ -249,6 +252,18 @@ static int rockchip_usb2phy_bind(struct udevice *dev) > > } > > } > > + if (!ret) { > > Can $ret ever be != 0 here ? > No, you're right. I can get rid of the if in v7. > btw. the dev_for_each_subnode() above is missing error handling, in case > device_bind_driver_to_node() there returns non-zero, there should be some > 'goto err' and 'err: dev_for_each_subnode() device_unbind()' fail path. > > > + node = dev_ofnode(dev); > > + name = ofnode_get_name(node); > > + dev_dbg(dev, "clk for node %s\n", name); > > + ret = device_bind_driver_to_node(dev, "rockchip_usb2phy_clock", > > + name, node, &usb2phy_dev); > > + if (ret) { > > + dev_err(dev, > > + "'%s' cannot bind 'rockchip_usb2phy_clock'\n", name); > > Use device_unbind() in fail path here too. > Well, dev_for_each_subnode wouldn't give me the dev to pass to device_unbind, but I can simply call device_chld_unbind(dev) on the error path (on the parent device) and that should clean up any bound children. I'll fix it in v7, thanks. ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v6 2/2] arm: rk3399: usb2phy: phy-rockchip-inno-usb2.c: Implement operations for the 480MHz usb2phy clock in rk3399. 2023-06-04 8:12 [PATCH v6 0/2] arm: dts: rockchip: rk3399: usb: ehci: Fix EHCI probe in rk3399 to access peripherals by USB 2 Xavier Drudis Ferran 2023-06-04 8:13 ` [PATCH v6 1/2] " Xavier Drudis Ferran @ 2023-06-04 8:13 ` Xavier Drudis Ferran 2023-06-04 9:33 ` Marek Vasut 2023-06-05 2:41 ` [PATCH v6 0/2] arm: dts: rockchip: rk3399: usb: ehci: Fix EHCI probe in rk3399 to access peripherals by USB 2 Jagan Teki 2 siblings, 1 reply; 9+ messages in thread From: Xavier Drudis Ferran @ 2023-06-04 8:13 UTC (permalink / raw) To: u-boot Cc: Simon Glass, Philipp Tomsich, Kever Yang, Lukasz Majewski, Sean Anderson, Marek Vasut, Christoph Fritz, Jagan Teki This clock doesn't seem needed but appears in a phandle list used by ehci-generic.c to bulk enable it. The phandle list comes from linux, where it is needed for suspend/resume to work [1]. My tests give the same results with or without this patch, but Marek Vasut found it weird to declare an empty clk_ops [2]. So I adapted the code from linux 6.1-rc8 so that it hopefully works if it ever has some user. For now, without real use, it seems to at least not give any errors when called. Link: [1] https://lkml.kernel.org/lkml/1731551.Q6cHK6n5ZM@phil/T/ [2] https://patchwork.ozlabs.org/project/uboot/patch/Y5IWpjYLB4aXMy9o@localhost/ Cc: Simon Glass <sjg@chromium.org> Cc: Philipp Tomsich <philipp.tomsich@vrull.eu> Cc: Kever Yang <kever.yang@rock-chips.com> Cc: Lukasz Majewski <lukma@denx.de> Cc: Sean Anderson <seanga2@gmail.com> Cc: Marek Vasut <marex@denx.de> Cc: Christoph Fritz <chf.fritz@googlemail.com> Cc: Jagan Teki <jagan@amarulasolutions.com> Signed-off-by: Xavier Drudis Ferran <xdrudis@tinet.cat> --- v6: just retested over current next branch and some corrections to message and headers (no changes to code). v5: ignores the return value from property_enable() which is not an error code in U-Boot (unlike in linux). This avoid a false failure of rockchip_usb2phy_clk_disable() that interfered with clock disable and appeared to cause hang or reset. --- drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 78 ++++++++++++++++++- 1 file changed, 76 insertions(+), 2 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c index 2f31350134..451841b025 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c @@ -55,6 +55,7 @@ struct rockchip_usb2phy_port_cfg { struct rockchip_usb2phy_cfg { unsigned int reg; + struct usb2phy_reg clkout_ctl; const struct rockchip_usb2phy_port_cfg port_cfgs[USB2PHY_NUM_PORTS]; }; @@ -76,6 +77,18 @@ static inline int property_enable(void *reg_base, return writel(val, reg_base + reg->offset); } +static inline bool property_enabled(void *reg_base, + const struct usb2phy_reg *reg) +{ + unsigned int tmp, orig; + unsigned int mask = GENMASK(reg->bitend, reg->bitstart); + + orig = readl(reg_base + reg->offset); + + tmp = (orig & mask) >> reg->bitstart; + return tmp != reg->disable; +} + static const struct rockchip_usb2phy_port_cfg *us2phy_get_port(struct phy *phy) { @@ -168,7 +181,63 @@ static struct phy_ops rockchip_usb2phy_ops = { .of_xlate = rockchip_usb2phy_of_xlate, }; +/** + * round_rate() - Adjust a rate to the exact rate a clock can provide. + * @clk: The clock to manipulate. + * @rate: Desidered clock rate in Hz. + * + * Return: rounded rate in Hz, or -ve error code. + */ +ulong rockchip_usb2phy_clk_round_rate(struct clk *clk, ulong rate) +{ + return 480000000; +} + +/** + * enable() - Enable a clock. + * @clk: The clock to manipulate. + * + * Return: zero on success, or -ve error code. + */ +int rockchip_usb2phy_clk_enable(struct clk *clk) +{ + struct udevice *parent = dev_get_parent(clk->dev); + struct rockchip_usb2phy *priv = dev_get_priv(parent); + const struct rockchip_usb2phy_cfg *phy_cfg = priv->phy_cfg; + + /* turn on 480m clk output if it is off */ + if (!property_enabled(priv->reg_base, &phy_cfg->clkout_ctl)) { + property_enable(priv->reg_base, &phy_cfg->clkout_ctl, true); + + /* waiting for the clk become stable */ + usleep_range(1200, 1300); + } + + return 0; +} + +/** + * disable() - Disable a clock. + * @clk: The clock to manipulate. + * + * Return: zero on success, or -ve error code. + */ +int rockchip_usb2phy_clk_disable(struct clk *clk) +{ + struct udevice *parent = dev_get_parent(clk->dev); + struct rockchip_usb2phy *priv = dev_get_priv(parent); + const struct rockchip_usb2phy_cfg *phy_cfg = priv->phy_cfg; + + /* turn off 480m clk output */ + property_enable(priv->reg_base, &phy_cfg->clkout_ctl, false); + + return 0; +} + static struct clk_ops rockchip_usb2phy_clk_ops = { + .enable = rockchip_usb2phy_clk_enable, + .disable = rockchip_usb2phy_clk_disable, + .round_rate = rockchip_usb2phy_clk_round_rate }; static int rockchip_usb2phy_probe(struct udevice *dev) @@ -254,8 +323,11 @@ static int rockchip_usb2phy_bind(struct udevice *dev) if (!ret) { node = dev_ofnode(dev); - name = ofnode_get_name(node); - dev_dbg(dev, "clk for node %s\n", name); + name = "clk_usbphy_480m"; + dev_read_string_index(dev, "clock-output-names", 0, &name); + + dev_dbg(dev, "clk %s for node %s\n", name, ofnode_get_name(node)); + ret = device_bind_driver_to_node(dev, "rockchip_usb2phy_clock", name, node, &usb2phy_dev); if (ret) { @@ -270,6 +342,7 @@ static int rockchip_usb2phy_bind(struct udevice *dev) static const struct rockchip_usb2phy_cfg rk3399_usb2phy_cfgs[] = { { .reg = 0xe450, + .clkout_ctl = { 0xe450, 4, 4, 1, 0 }, .port_cfgs = { [USB2PHY_PORT_OTG] = { .phy_sus = { 0xe454, 1, 0, 2, 1 }, @@ -291,6 +364,7 @@ static const struct rockchip_usb2phy_cfg rk3399_usb2phy_cfgs[] = { }, { .reg = 0xe460, + .clkout_ctl = { 0xe460, 4, 4, 1, 0 }, .port_cfgs = { [USB2PHY_PORT_OTG] = { .phy_sus = { 0xe464, 1, 0, 2, 1 }, -- 2.20.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v6 2/2] arm: rk3399: usb2phy: phy-rockchip-inno-usb2.c: Implement operations for the 480MHz usb2phy clock in rk3399. 2023-06-04 8:13 ` [PATCH v6 2/2] arm: rk3399: usb2phy: phy-rockchip-inno-usb2.c: Implement operations for the 480MHz usb2phy clock in rk3399 Xavier Drudis Ferran @ 2023-06-04 9:33 ` Marek Vasut 2023-06-04 22:30 ` Xavier Drudis Ferran 0 siblings, 1 reply; 9+ messages in thread From: Marek Vasut @ 2023-06-04 9:33 UTC (permalink / raw) To: Xavier Drudis Ferran, u-boot Cc: Simon Glass, Philipp Tomsich, Kever Yang, Lukasz Majewski, Sean Anderson, Christoph Fritz, Jagan Teki On 6/4/23 10:13, Xavier Drudis Ferran wrote: > > This clock doesn't seem needed but appears in a phandle list used by > ehci-generic.c to bulk enable it. The phandle list comes from linux, > where it is needed for suspend/resume to work [1]. > > My tests give the same results with or without this patch, but Marek > Vasut found it weird to declare an empty clk_ops [2]. > > So I adapted the code from linux 6.1-rc8 so that it hopefully works > if it ever has some user. For now, without real use, it seems to > at least not give any errors when called. > > Link: [1] https://lkml.kernel.org/lkml/1731551.Q6cHK6n5ZM@phil/T/ > [2] https://patchwork.ozlabs.org/project/uboot/patch/Y5IWpjYLB4aXMy9o@localhost/ > > Cc: Simon Glass <sjg@chromium.org> > Cc: Philipp Tomsich <philipp.tomsich@vrull.eu> > Cc: Kever Yang <kever.yang@rock-chips.com> > Cc: Lukasz Majewski <lukma@denx.de> > Cc: Sean Anderson <seanga2@gmail.com> > Cc: Marek Vasut <marex@denx.de> > Cc: Christoph Fritz <chf.fritz@googlemail.com> > Cc: Jagan Teki <jagan@amarulasolutions.com> > > Signed-off-by: Xavier Drudis Ferran <xdrudis@tinet.cat> > --- > > v6: just retested over current next branch and some corrections > to message and headers > (no changes to code). > > > v5: ignores the return value from property_enable() which is not > an error code in U-Boot (unlike in linux). This avoid a false > failure of rockchip_usb2phy_clk_disable() that interfered with > clock disable and appeared to cause hang or reset. > > --- > drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 78 ++++++++++++++++++- > 1 file changed, 76 insertions(+), 2 deletions(-) > > diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c > index 2f31350134..451841b025 100644 > --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c > +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c > @@ -55,6 +55,7 @@ struct rockchip_usb2phy_port_cfg { > > struct rockchip_usb2phy_cfg { > unsigned int reg; > + struct usb2phy_reg clkout_ctl; > const struct rockchip_usb2phy_port_cfg port_cfgs[USB2PHY_NUM_PORTS]; > }; > > @@ -76,6 +77,18 @@ static inline int property_enable(void *reg_base, > return writel(val, reg_base + reg->offset); > } > > +static inline bool property_enabled(void *reg_base, > + const struct usb2phy_reg *reg) > +{ > + unsigned int tmp, orig; > + unsigned int mask = GENMASK(reg->bitend, reg->bitstart); > + > + orig = readl(reg_base + reg->offset); > + > + tmp = (orig & mask) >> reg->bitstart; Use FIELD_GET() macro if possible. > + return tmp != reg->disable; > +} > + > static const > struct rockchip_usb2phy_port_cfg *us2phy_get_port(struct phy *phy) > { > @@ -168,7 +181,63 @@ static struct phy_ops rockchip_usb2phy_ops = { > .of_xlate = rockchip_usb2phy_of_xlate, > }; [...] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v6 2/2] arm: rk3399: usb2phy: phy-rockchip-inno-usb2.c: Implement operations for the 480MHz usb2phy clock in rk3399. 2023-06-04 9:33 ` Marek Vasut @ 2023-06-04 22:30 ` Xavier Drudis Ferran 0 siblings, 0 replies; 9+ messages in thread From: Xavier Drudis Ferran @ 2023-06-04 22:30 UTC (permalink / raw) To: Marek Vasut Cc: Xavier Drudis Ferran, u-boot, Simon Glass, Philipp Tomsich, Kever Yang, Lukasz Majewski, Sean Anderson, Christoph Fritz, Jagan Teki Thanks for looking at this. El Sun, Jun 04, 2023 at 11:33:21AM +0200, Marek Vasut deia: > > diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c > > index 2f31350134..451841b025 100644 > > --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c > > +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c > > @@ -55,6 +55,7 @@ struct rockchip_usb2phy_port_cfg { > > struct rockchip_usb2phy_cfg { > > unsigned int reg; > > + struct usb2phy_reg clkout_ctl; > > const struct rockchip_usb2phy_port_cfg port_cfgs[USB2PHY_NUM_PORTS]; > > }; > > @@ -76,6 +77,18 @@ static inline int property_enable(void *reg_base, > > return writel(val, reg_base + reg->offset); > > } > > +static inline bool property_enabled(void *reg_base, > > + const struct usb2phy_reg *reg) > > +{ > > + unsigned int tmp, orig; > > + unsigned int mask = GENMASK(reg->bitend, reg->bitstart); > > + > > + orig = readl(reg_base + reg->offset); > > + > > + tmp = (orig & mask) >> reg->bitstart; > > Use FIELD_GET() macro if possible. > It would be possible, but it seems to require a constant mask. Now the mask is read from a cfg struct, so it's not constant. Currently the mask bitend and bitstart are really always the same value (4 and 4) for all (2) SOCs, so I could change the code to make it a constant and use FIELD_GET(), but I'd see two drawbacks: - It makes code more different than needed from linux drivers/phy/rockchip/phy-rockchip-inno-usb2.c - It will stop working if we ever support rk3366 here, the mask there is bit 15. So I'd rather leave it as it is. But you made me realise I was missing the clkout_ctl struct for rk3568, so I'll copy from linux in v7. I can't test it, though. Thank you. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v6 0/2] arm: dts: rockchip: rk3399: usb: ehci: Fix EHCI probe in rk3399 to access peripherals by USB 2. 2023-06-04 8:12 [PATCH v6 0/2] arm: dts: rockchip: rk3399: usb: ehci: Fix EHCI probe in rk3399 to access peripherals by USB 2 Xavier Drudis Ferran 2023-06-04 8:13 ` [PATCH v6 1/2] " Xavier Drudis Ferran 2023-06-04 8:13 ` [PATCH v6 2/2] arm: rk3399: usb2phy: phy-rockchip-inno-usb2.c: Implement operations for the 480MHz usb2phy clock in rk3399 Xavier Drudis Ferran @ 2023-06-05 2:41 ` Jagan Teki 2023-06-05 15:21 ` Xavier Drudis Ferran 2 siblings, 1 reply; 9+ messages in thread From: Jagan Teki @ 2023-06-05 2:41 UTC (permalink / raw) To: Xavier Drudis Ferran Cc: u-boot, Simon Glass, Philipp Tomsich, Kever Yang, Lukasz Majewski, Sean Anderson, Marek Vasut, Christoph Fritz On Sun, Jun 4, 2023 at 1:42 PM Xavier Drudis Ferran <xdrudis@tinet.cat> wrote: > > EHCI probing in Rock pi 4 currently fails. > > Add a clock driver for usb2phy so that probing EHCI does not fail when > missing one of the clocks in the bundle for usb_host0_ehci, since > usb2phy is UCLASS_PHY but not UCLASS_CLK. > > Xavier Drudis Ferran (2): > arm: dts: rockchip: rk3399: usb: ehci: Fix EHCI probe in rk3399 to > access peripherals by USB 2. > arm: rk3399: usb2phy: phy-rockchip-inno-usb2.c: Implement operations > for the 480MHz usb2phy clock in rk3399. Please note that commit head on both the patches seems improper to me. Commit body looks fine, but the head should start phy: rockchip-inno-usb2: Add usb2phy clock provider of 480MHz clock phy: rockchip-inno-usb2: Implement clock operations for usb2phy clock Thanks, Jagan. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v6 0/2] arm: dts: rockchip: rk3399: usb: ehci: Fix EHCI probe in rk3399 to access peripherals by USB 2. 2023-06-05 2:41 ` [PATCH v6 0/2] arm: dts: rockchip: rk3399: usb: ehci: Fix EHCI probe in rk3399 to access peripherals by USB 2 Jagan Teki @ 2023-06-05 15:21 ` Xavier Drudis Ferran 0 siblings, 0 replies; 9+ messages in thread From: Xavier Drudis Ferran @ 2023-06-05 15:21 UTC (permalink / raw) To: Jagan Teki Cc: Xavier Drudis Ferran, u-boot, Simon Glass, Philipp Tomsich, Kever Yang, Lukasz Majewski, Sean Anderson, Marek Vasut, Christoph Fritz El Mon, Jun 05, 2023 at 08:11:07AM +0530, Jagan Teki deia: > On Sun, Jun 4, 2023 at 1:42 PM Xavier Drudis Ferran <xdrudis@tinet.cat> wrote: > > > > EHCI probing in Rock pi 4 currently fails. > > > > Add a clock driver for usb2phy so that probing EHCI does not fail when > > missing one of the clocks in the bundle for usb_host0_ehci, since > > usb2phy is UCLASS_PHY but not UCLASS_CLK. > > > > Xavier Drudis Ferran (2): > > arm: dts: rockchip: rk3399: usb: ehci: Fix EHCI probe in rk3399 to > > access peripherals by USB 2. > > arm: rk3399: usb2phy: phy-rockchip-inno-usb2.c: Implement operations > > for the 480MHz usb2phy clock in rk3399. > > Please note that commit head on both the patches seems improper to me. > > Commit body looks fine, but the head should start > > phy: rockchip-inno-usb2: Add usb2phy clock provider of 480MHz clock > phy: rockchip-inno-usb2: Implement clock operations for usb2phy clock > > Thanks, > Jagan. Done, thank you. I hope it's right now. ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2023-06-05 15:32 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2023-06-04 8:12 [PATCH v6 0/2] arm: dts: rockchip: rk3399: usb: ehci: Fix EHCI probe in rk3399 to access peripherals by USB 2 Xavier Drudis Ferran 2023-06-04 8:13 ` [PATCH v6 1/2] " Xavier Drudis Ferran 2023-06-04 9:31 ` Marek Vasut 2023-06-04 22:12 ` Xavier Drudis Ferran 2023-06-04 8:13 ` [PATCH v6 2/2] arm: rk3399: usb2phy: phy-rockchip-inno-usb2.c: Implement operations for the 480MHz usb2phy clock in rk3399 Xavier Drudis Ferran 2023-06-04 9:33 ` Marek Vasut 2023-06-04 22:30 ` Xavier Drudis Ferran 2023-06-05 2:41 ` [PATCH v6 0/2] arm: dts: rockchip: rk3399: usb: ehci: Fix EHCI probe in rk3399 to access peripherals by USB 2 Jagan Teki 2023-06-05 15:21 ` Xavier Drudis Ferran
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.