diff options
author | Tom Rini <trini@konsulko.com> | 2023-06-08 18:23:06 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2023-06-08 18:23:06 -0400 |
commit | addd47379df54a3eb247c6db4f799f14af43e523 (patch) | |
tree | 61701556c3239f03943d95967209fde072a00a6b | |
parent | 681bfd6b46c7e3bb48c486e22906cc5d88be433d (diff) | |
parent | e10f96414934edaca958e4323f82149a030e56a4 (diff) | |
download | u-boot-WIP/08Jun2028.zip u-boot-WIP/08Jun2028.tar.gz u-boot-WIP/08Jun2028.tar.bz2 |
Merge https://source.denx.de/u-boot/custodians/u-boot-usbWIP/08Jun2028
-rw-r--r-- | drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 109 | ||||
-rw-r--r-- | drivers/usb/musb-new/sunxi.c | 4 |
2 files changed, 107 insertions, 6 deletions
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c index 22e2797..e43a5ba 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c @@ -7,10 +7,11 @@ */ #include <common.h> -#include <clk.h> +#include <clk-uclass.h> #include <dm.h> #include <asm/global_data.h> #include <dm/device_compat.h> +#include <dm/device-internal.h> #include <dm/lists.h> #include <generic-phy.h> #include <reset.h> @@ -55,6 +56,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 +78,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,6 +182,65 @@ 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) { struct rockchip_usb2phy *priv = dev_get_priv(dev); @@ -234,7 +307,8 @@ static int rockchip_usb2phy_bind(struct udevice *dev) dev_for_each_subnode(node, dev) { if (!ofnode_valid(node)) { dev_info(dev, "subnode %s not found\n", dev->name); - return -ENXIO; + ret = -ENXIO; + goto bind_fail; } name = ofnode_get_name(node); @@ -245,16 +319,36 @@ static int rockchip_usb2phy_bind(struct udevice *dev) if (ret) { dev_err(dev, "'%s' cannot bind 'rockchip_usb2phy_port'\n", name); - return ret; + goto bind_fail; } } + node = dev_ofnode(dev); + 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) { + dev_err(dev, + "'%s' cannot bind 'rockchip_usb2phy_clock'\n", name); + goto bind_fail; + } + + return 0; + +bind_fail: + device_chld_unbind(dev, NULL); + return ret; } 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 }, @@ -276,6 +370,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 }, @@ -301,6 +396,7 @@ static const struct rockchip_usb2phy_cfg rk3399_usb2phy_cfgs[] = { static const struct rockchip_usb2phy_cfg rk3568_phy_cfgs[] = { { .reg = 0xfe8a0000, + .clkout_ctl = { 0x0008, 4, 4, 1, 0 }, .port_cfgs = { [USB2PHY_PORT_OTG] = { .phy_sus = { 0x0000, 8, 0, 0x052, 0x1d1 }, @@ -326,6 +422,7 @@ static const struct rockchip_usb2phy_cfg rk3568_phy_cfgs[] = { }, { .reg = 0xfe8b0000, + .clkout_ctl = { 0x0008, 4, 4, 1, 0 }, .port_cfgs = { [USB2PHY_PORT_OTG] = { .phy_sus = { 0x0000, 8, 0, 0x1d2, 0x1d1 }, @@ -422,6 +519,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, diff --git a/drivers/usb/musb-new/sunxi.c b/drivers/usb/musb-new/sunxi.c index dc4cfc2..485b9dc 100644 --- a/drivers/usb/musb-new/sunxi.c +++ b/drivers/usb/musb-new/sunxi.c @@ -81,8 +81,6 @@ * From usbc/usbc.c ******************************************************************************/ -#define OFF_SUN6I_AHB_RESET0 0x2c0 - struct sunxi_musb_config { struct musb_hdrc_config *config; }; @@ -486,7 +484,7 @@ static int musb_usb_probe(struct udevice *dev) #else pdata.mode = MUSB_PERIPHERAL; host->host = musb_register(&pdata, &glue->dev, base); - if (!host->host) + if (IS_ERR_OR_NULL(host->host)) return -EIO; printf("Allwinner mUSB OTG (Peripheral)\n"); |