From: Jonas Karlman Date: Wed, 1 May 2024 16:22:20 +0000 (+0000) Subject: clk: rockchip: rk3399: Improve support for SCLK_PCIEPHY_REF clock X-Git-Url: http://git.dujemihanovic.xyz/?a=commitdiff_plain;h=e801d05bea6d99b2731f3c96edc754b36f75bcdc;p=u-boot.git clk: rockchip: rk3399: Improve support for SCLK_PCIEPHY_REF clock rk3399-nanopi-4.dtsi try to set parent of and set rate to 100 MHz of the SCLK_PCIEPHY_REF clock. The existing enable/disable ops for SCLK_PCIEPHY_REF currently force use of 24 MHz parent and rate. Add improved support for setting parent and rate of the pciephy refclk to driver to better support assign-clock props for pciephy refclk in DT. This limited implementation only support setting 24 or 100 MHz rate, and expect npll and clk_pciephy_ref100m divider to use default values. Signed-off-by: Jonas Karlman Reviewed-by: Kever Yang --- diff --git a/drivers/clk/rockchip/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c index 5934771b40..0b3223611a 100644 --- a/drivers/clk/rockchip/clk_rk3399.c +++ b/drivers/clk/rockchip/clk_rk3399.c @@ -926,6 +926,26 @@ static ulong rk3399_saradc_set_clk(struct rockchip_cru *cru, uint hz) return rk3399_saradc_get_clk(cru); } +static ulong rk3399_pciephy_get_clk(struct rockchip_cru *cru) +{ + if (readl(&cru->clksel_con[18]) & BIT(10)) + return 100 * MHz; + else + return OSC_HZ; +} + +static ulong rk3399_pciephy_set_clk(struct rockchip_cru *cru, uint hz) +{ + if (hz == 100 * MHz) + rk_setreg(&cru->clksel_con[18], BIT(10)); + else if (hz == OSC_HZ) + rk_clrreg(&cru->clksel_con[18], BIT(10)); + else + return -EINVAL; + + return rk3399_pciephy_get_clk(cru); +} + static ulong rk3399_clk_get_rate(struct clk *clk) { struct rk3399_clk_priv *priv = dev_get_priv(clk->dev); @@ -967,6 +987,9 @@ static ulong rk3399_clk_get_rate(struct clk *clk) case SCLK_SARADC: rate = rk3399_saradc_get_clk(priv->cru); break; + case SCLK_PCIEPHY_REF: + rate = rk3399_pciephy_get_clk(priv->cru); + break; case ACLK_VIO: case ACLK_HDCP: case ACLK_GIC_PRE: @@ -1058,6 +1081,9 @@ static ulong rk3399_clk_set_rate(struct clk *clk, ulong rate) case SCLK_SARADC: ret = rk3399_saradc_set_clk(priv->cru, rate); break; + case SCLK_PCIEPHY_REF: + ret = rk3399_pciephy_set_clk(priv->cru, rate); + break; case ACLK_VIO: case ACLK_HDCP: case ACLK_GIC_PRE: @@ -1108,12 +1134,39 @@ static int __maybe_unused rk3399_gmac_set_parent(struct clk *clk, return -EINVAL; } +static int __maybe_unused rk3399_pciephy_set_parent(struct clk *clk, + struct clk *parent) +{ + struct rk3399_clk_priv *priv = dev_get_priv(clk->dev); + const char *clock_output_name; + int ret; + + if (parent->dev == clk->dev && parent->id == SCLK_PCIEPHY_REF100M) { + rk_setreg(&priv->cru->clksel_con[18], BIT(10)); + return 0; + } + + ret = dev_read_string_index(parent->dev, "clock-output-names", + parent->id, &clock_output_name); + if (ret < 0) + return -ENODATA; + + if (!strcmp(clock_output_name, "xin24m")) { + rk_clrreg(&priv->cru->clksel_con[18], BIT(10)); + return 0; + } + + return -EINVAL; +} + static int __maybe_unused rk3399_clk_set_parent(struct clk *clk, struct clk *parent) { switch (clk->id) { case SCLK_RMII_SRC: return rk3399_gmac_set_parent(clk, parent); + case SCLK_PCIEPHY_REF: + return rk3399_pciephy_set_parent(clk, parent); } debug("%s: unsupported clk %ld\n", __func__, clk->id); @@ -1204,7 +1257,8 @@ static int rk3399_clk_enable(struct clk *clk) rk_clrreg(&priv->cru->clkgate_con[13], BIT(7)); break; case SCLK_PCIEPHY_REF: - rk_clrreg(&priv->cru->clksel_con[18], BIT(10)); + if (readl(&priv->cru->clksel_con[18]) & BIT(10)) + rk_clrreg(&priv->cru->clkgate_con[12], BIT(6)); break; default: debug("%s: unsupported clk %ld\n", __func__, clk->id); @@ -1298,7 +1352,8 @@ static int rk3399_clk_disable(struct clk *clk) rk_setreg(&priv->cru->clkgate_con[13], BIT(7)); break; case SCLK_PCIEPHY_REF: - rk_clrreg(&priv->cru->clksel_con[18], BIT(10)); + if (readl(&priv->cru->clksel_con[18]) & BIT(10)) + rk_setreg(&priv->cru->clkgate_con[12], BIT(6)); break; default: debug("%s: unsupported clk %ld\n", __func__, clk->id);