phy: rockchip-inno-usb2: Add support for clkout_ctl_phy
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>
This commit is contained in:
committed by
Simon Glass
parent
2be1911f52
commit
d7c449f1db
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user