phy: rockchip-inno-usb2: Add support for clkout_ctl_phy
authorJonas Karlman <jonas@kwiboo.se>
Mon, 7 Apr 2025 22:46:59 +0000 (22:46 +0000)
committerKever Yang <kever.yang@rock-chips.com>
Wed, 23 Apr 2025 14:12:04 +0000 (22:12 +0800)
The 480m clk is controlled using regs in the PHY address space and not
in the USB GRF address space on e.g. RK3528 and RK3506.

Add a clkout_ctl_phy usb2phy_reg to handle enable/disable of the 480m
clk on these SoCs.

Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
drivers/phy/rockchip/phy-rockchip-inno-usb2.c

index 43f6e02..f40a86b 100644 (file)
@@ -40,11 +40,13 @@ struct rockchip_usb2phy_port_cfg {
 struct rockchip_usb2phy_cfg {
        unsigned int reg;
        struct usb2phy_reg      clkout_ctl;
+       struct usb2phy_reg      clkout_ctl_phy;
        const struct rockchip_usb2phy_port_cfg port_cfgs[USB2PHY_NUM_PORTS];
 };
 
 struct rockchip_usb2phy {
        struct regmap *reg_base;
+       struct regmap *phy_base;
        struct clk phyclk;
        const struct rockchip_usb2phy_cfg *phy_cfg;
 };
@@ -165,6 +167,22 @@ static struct phy_ops rockchip_usb2phy_ops = {
        .of_xlate = rockchip_usb2phy_of_xlate,
 };
 
+static void rockchip_usb2phy_clkout_ctl(struct clk *clk, struct regmap **base,
+                                       const struct usb2phy_reg **clkout_ctl)
+{
+       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;
+
+       if (priv->phy_cfg->clkout_ctl_phy.enable) {
+               *base = priv->phy_base;
+               *clkout_ctl = &phy_cfg->clkout_ctl_phy;
+       } else {
+               *base = priv->reg_base;
+               *clkout_ctl = &phy_cfg->clkout_ctl;
+       }
+}
+
 /**
  * round_rate() - Adjust a rate to the exact rate a clock can provide.
  * @clk:       The clock to manipulate.
@@ -185,13 +203,14 @@ ulong rockchip_usb2phy_clk_round_rate(struct clk *clk, ulong rate)
  */
 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;
+       const struct usb2phy_reg *clkout_ctl;
+       struct regmap *base;
+
+       rockchip_usb2phy_clkout_ctl(clk, &base, &clkout_ctl);
 
        /* 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);
+       if (!property_enabled(base, clkout_ctl)) {
+               property_enable(base, clkout_ctl, true);
 
                /* waiting for the clk become stable */
                usleep_range(1200, 1300);
@@ -208,12 +227,13 @@ int rockchip_usb2phy_clk_enable(struct clk *clk)
  */
 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;
+       const struct usb2phy_reg *clkout_ctl;
+       struct regmap *base;
+
+       rockchip_usb2phy_clkout_ctl(clk, &base, &clkout_ctl);
 
        /* turn off 480m clk output */
-       property_enable(priv->reg_base, &phy_cfg->clkout_ctl, false);
+       property_enable(base, clkout_ctl, false);
 
        return 0;
 }
@@ -281,7 +301,10 @@ static int rockchip_usb2phy_probe(struct udevice *dev)
                return ret;
        }
 
-       return 0;
+       if (priv->phy_cfg->clkout_ctl_phy.enable)
+               ret = regmap_init_mem_index(dev_ofnode(dev), &priv->phy_base, 0);
+
+       return ret;
 }
 
 static int rockchip_usb2phy_bind(struct udevice *dev)