[PATCH v7 2/2] phy: rockchip-inno-usb2: Implement clock operations for usb2phy clock

Kever Yang kever.yang at rock-chips.com
Tue Jun 6 02:54:01 CEST 2023


On 2023/6/5 23:06, 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 at chromium.org>
> Cc: Philipp Tomsich <philipp.tomsich at vrull.eu>
> Cc: Kever Yang <kever.yang at rock-chips.com>
> Cc: Lukasz Majewski <lukma at denx.de>
> Cc: Sean Anderson <seanga2 at gmail.com>
> Cc: Marek Vasut <marex at denx.de>
> Cc: Christoph Fritz <chf.fritz at googlemail.com>
> Cc: Jagan Teki <jagan at amarulasolutions.com>
>
> Signed-off-by: Xavier Drudis Ferran <xdrudis at tinet.cat>
Reviewed-by: Kever Yang <kever.yang at rock-chips.com>

Thanks,
- Kever
> ---
>
>   v7: add clkout_ctl values for rk3568 (from linux).
>       UNTESTED (I don't have the hardware).
>
>   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 | 80 ++++++++++++++++++-
>   1 file changed, 78 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> index 732d37201d..be5f79490c 100644
> --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> @@ -56,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];
>   };
>   
> @@ -77,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)
>   {
> @@ -169,7 +182,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)
> @@ -255,8 +324,11 @@ static int rockchip_usb2phy_bind(struct udevice *dev)
>   	}
>   
>   	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) {
> @@ -276,6 +348,7 @@ bind_fail:
>   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 },
> @@ -297,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 },
> @@ -322,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 },
> @@ -347,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 },


More information about the U-Boot mailing list