[PATCH 0/4] clk: Add support to enable clocks

Hi,
Add support to enable clocks using clock subsystem ops for zynqmp & versal platforms. Enable rx clock in ethernet driver for versal platform. Add clock enable feature in i2c-cdns driver.
Thanks, Karthik, Michal
T Karthik Reddy (4): clk: zynqmp: Add support to enable clocks i2c: i2c_cdns: Enable i2c clock clk: versal: Add support to enable clocks net: gem: Enable ethernet rx clock for versal
drivers/clk/clk_versal.c | 11 +++++++++ drivers/clk/clk_zynqmp.c | 49 ++++++++++++++++++++++++++++++++++++++++ drivers/i2c/i2c-cdns.c | 7 ++++++ drivers/net/zynq_gem.c | 26 ++++++++++++++++----- 4 files changed, 87 insertions(+), 6 deletions(-)

From: T Karthik Reddy t.karthik.reddy@xilinx.com
Add clock enable functionality in zynqmp clock driver to enable clocks from peripheral drivers using clk_ops.
Signed-off-by: T Karthik Reddy t.karthik.reddy@xilinx.com Signed-off-by: Michal Simek michal.simek@xilinx.com ---
drivers/clk/clk_zynqmp.c | 49 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+)
diff --git a/drivers/clk/clk_zynqmp.c b/drivers/clk/clk_zynqmp.c index e8acca00660d..609d8e3b2fff 100644 --- a/drivers/clk/clk_zynqmp.c +++ b/drivers/clk/clk_zynqmp.c @@ -199,6 +199,8 @@ static u32 zynqmp_clk_get_register(enum zynqmp_clk id) return CRF_APB_DDR_CTRL; case qspi_ref: return CRL_APB_QSPI_REF_CTRL; + case usb3_dual_ref: + return CRL_APB_USB3_DUAL_REF_CTRL; case gem0_ref: return CRL_APB_GEM0_REF_CTRL; case gem1_ref: @@ -207,6 +209,10 @@ static u32 zynqmp_clk_get_register(enum zynqmp_clk id) return CRL_APB_GEM2_REF_CTRL; case gem3_ref: return CRL_APB_GEM3_REF_CTRL; + case usb0_bus_ref: + return CRL_APB_USB0_BUS_REF_CTRL; + case usb1_bus_ref: + return CRL_APB_USB1_BUS_REF_CTRL; case uart0_ref: return CRL_APB_UART0_REF_CTRL; case uart1_ref: @@ -699,9 +705,52 @@ static int zynqmp_clk_probe(struct udevice *dev) return 0; }
+static int zynqmp_clk_enable(struct clk *clk) +{ + enum zynqmp_clk id = clk->id; + u32 reg, clk_ctrl, clkact_shift, mask; + int ret; + + reg = zynqmp_clk_get_register(id); + debug("%s, clk_id:%x, clk_base:0x%x\n", __func__, id, reg); + + switch (id) { + case usb0_bus_ref ... usb1: + clkact_shift = 25; + mask = 0x1; + break; + case gem0_ref ... gem3_ref: + clkact_shift = 25; + mask = 0x3; + break; + case qspi_ref ... can1_ref: + clkact_shift = 24; + mask = 0x1; + break; + default: + return -ENXIO; + } + + ret = zynqmp_mmio_read(reg, &clk_ctrl); + if (ret) { + printf("%s mio read fail\n", __func__); + return -EIO; + } + + clk_ctrl |= (mask << clkact_shift); + ret = zynqmp_mmio_write(reg, mask << clkact_shift, clk_ctrl); + if (ret) { + printf("%s mio write fail\n", __func__); + return -EIO; + } + + return ret; +} + static struct clk_ops zynqmp_clk_ops = { .set_rate = zynqmp_clk_set_rate, .get_rate = zynqmp_clk_get_rate, + .enable = zynqmp_clk_enable, };
static const struct udevice_id zynqmp_clk_ids[] = {

From: T Karthik Reddy t.karthik.reddy@xilinx.com
Enable i2c controller clock from driver probe function by calling clk_enable().
Signed-off-by: T Karthik Reddy t.karthik.reddy@xilinx.com Signed-off-by: Michal Simek michal.simek@xilinx.com ---
drivers/i2c/i2c-cdns.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/i2c/i2c-cdns.c b/drivers/i2c/i2c-cdns.c index db3c04fa6e75..a650dd69b89f 100644 --- a/drivers/i2c/i2c-cdns.c +++ b/drivers/i2c/i2c-cdns.c @@ -15,6 +15,7 @@ #include <linux/types.h> #include <linux/io.h> #include <linux/errno.h> +#include <dm/device_compat.h> #include <dm/root.h> #include <i2c.h> #include <fdtdec.h> @@ -481,6 +482,12 @@ static int cdns_i2c_of_to_plat(struct udevice *dev)
i2c_bus->input_freq = clk_get_rate(&clk);
+ ret = clk_enable(&clk); + if (ret) { + dev_err(dev, "failed to enable clock\n"); + return ret; + } + return 0; }

From: T Karthik Reddy t.karthik.reddy@xilinx.com
Add clock enable functionality in versal clock driver to enable clocks from peripheral drivers using clk_ops.
Signed-off-by: T Karthik Reddy t.karthik.reddy@xilinx.com Signed-off-by: Michal Simek michal.simek@xilinx.com ---
drivers/clk/clk_versal.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/drivers/clk/clk_versal.c b/drivers/clk/clk_versal.c index 908bc7519c42..62523d290999 100644 --- a/drivers/clk/clk_versal.c +++ b/drivers/clk/clk_versal.c @@ -718,9 +718,20 @@ static ulong versal_clk_set_rate(struct clk *clk, ulong rate) return clk_rate; }
+static int versal_clk_enable(struct clk *clk) +{ + struct versal_clk_priv *priv = dev_get_priv(clk->dev); + u32 clk_id; + + clk_id = priv->clk[clk->id].clk_id; + + return xilinx_pm_request(PM_CLOCK_ENABLE, clk_id, 0, 0, 0, NULL); +} + static struct clk_ops versal_clk_ops = { .set_rate = versal_clk_set_rate, .get_rate = versal_clk_get_rate, + .enable = versal_clk_enable, };
static const struct udevice_id versal_clk_ids[] = {

From: T Karthik Reddy t.karthik.reddy@xilinx.com
Enable rx clock along with tx clock for versal platform.
Signed-off-by: T Karthik Reddy t.karthik.reddy@xilinx.com Signed-off-by: Michal Simek michal.simek@xilinx.com ---
drivers/net/zynq_gem.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-)
diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c index 5cb02bb3a7d2..ea080fbacc94 100644 --- a/drivers/net/zynq_gem.c +++ b/drivers/net/zynq_gem.c @@ -205,7 +205,8 @@ struct zynq_gem_priv { struct phy_device *phydev; ofnode phy_of_node; struct mii_dev *bus; - struct clk clk; + struct clk rx_clk; + struct clk tx_clk; u32 max_speed; bool int_pcs; bool dma_64bit; @@ -476,18 +477,25 @@ static int zynq_gem_init(struct udevice *dev) break; }
- ret = clk_set_rate(&priv->clk, clk_rate); + ret = clk_set_rate(&priv->tx_clk, clk_rate); if (IS_ERR_VALUE(ret) && ret != (unsigned long)-ENOSYS) { dev_err(dev, "failed to set tx clock rate\n"); return ret; }
- ret = clk_enable(&priv->clk); - if (ret && ret != -ENOSYS) { + ret = clk_enable(&priv->tx_clk); + if (ret) { dev_err(dev, "failed to enable tx clock\n"); return ret; }
+ if (IS_ENABLED(CONFIG_ARCH_VERSAL)) { + ret = clk_enable(&priv->rx_clk); + if (ret) { + dev_err(dev, "failed to enable rx clock\n"); + return ret; + } + } setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK | ZYNQ_GEM_NWCTRL_TXEN_MASK);
@@ -694,9 +702,15 @@ static int zynq_gem_probe(struct udevice *dev) priv->tx_bd = (struct emac_bd *)bd_space; priv->rx_bd = (struct emac_bd *)((ulong)bd_space + BD_SEPRN_SPACE);
- ret = clk_get_by_name(dev, "tx_clk", &priv->clk); + ret = clk_get_by_name(dev, "tx_clk", &priv->tx_clk); + if (ret < 0) { + dev_err(dev, "failed to get tx_clock\n"); + goto err1; + } + + ret = clk_get_by_name(dev, "rx_clk", &priv->rx_clk); if (ret < 0) { - dev_err(dev, "failed to get clock\n"); + dev_err(dev, "failed to get rx_clock\n"); goto err1; }

On Wed, Feb 3, 2021 at 2:18 PM Michal Simek michal.simek@xilinx.com wrote:
From: T Karthik Reddy t.karthik.reddy@xilinx.com
Enable rx clock along with tx clock for versal platform.
Signed-off-by: T Karthik Reddy t.karthik.reddy@xilinx.com Signed-off-by: Michal Simek michal.simek@xilinx.com
drivers/net/zynq_gem.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-)
diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c index 5cb02bb3a7d2..ea080fbacc94 100644 --- a/drivers/net/zynq_gem.c +++ b/drivers/net/zynq_gem.c @@ -205,7 +205,8 @@ struct zynq_gem_priv { struct phy_device *phydev; ofnode phy_of_node; struct mii_dev *bus;
struct clk clk;
struct clk rx_clk;
struct clk tx_clk; u32 max_speed; bool int_pcs; bool dma_64bit;
@@ -476,18 +477,25 @@ static int zynq_gem_init(struct udevice *dev) break; }
ret = clk_set_rate(&priv->clk, clk_rate);
ret = clk_set_rate(&priv->tx_clk, clk_rate); if (IS_ERR_VALUE(ret) && ret != (unsigned long)-ENOSYS) { dev_err(dev, "failed to set tx clock rate\n"); return ret; }
ret = clk_enable(&priv->clk);
if (ret && ret != -ENOSYS) {
ret = clk_enable(&priv->tx_clk);
if (ret) { dev_err(dev, "failed to enable tx clock\n"); return ret; }
if (IS_ENABLED(CONFIG_ARCH_VERSAL)) {
ret = clk_enable(&priv->rx_clk);
if (ret) {
dev_err(dev, "failed to enable rx clock\n");
return ret;
}
} setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK | ZYNQ_GEM_NWCTRL_TXEN_MASK);
@@ -694,9 +702,15 @@ static int zynq_gem_probe(struct udevice *dev) priv->tx_bd = (struct emac_bd *)bd_space; priv->rx_bd = (struct emac_bd *)((ulong)bd_space + BD_SEPRN_SPACE);
ret = clk_get_by_name(dev, "tx_clk", &priv->clk);
ret = clk_get_by_name(dev, "tx_clk", &priv->tx_clk);
if (ret < 0) {
dev_err(dev, "failed to get tx_clock\n");
goto err1;
}
ret = clk_get_by_name(dev, "rx_clk", &priv->rx_clk); if (ret < 0) {
dev_err(dev, "failed to get clock\n");
dev_err(dev, "failed to get rx_clock\n"); goto err1; }
-- 2.30.0
Reviewed-By: Ramon Fried rfried.dev@gmail.com

st 3. 2. 2021 v 13:18 odesÃlatel Michal Simek michal.simek@xilinx.com napsal:
Hi,
Add support to enable clocks using clock subsystem ops for zynqmp & versal platforms. Enable rx clock in ethernet driver for versal platform. Add clock enable feature in i2c-cdns driver.
Thanks, Karthik, Michal
T Karthik Reddy (4): clk: zynqmp: Add support to enable clocks i2c: i2c_cdns: Enable i2c clock clk: versal: Add support to enable clocks net: gem: Enable ethernet rx clock for versal
drivers/clk/clk_versal.c | 11 +++++++++ drivers/clk/clk_zynqmp.c | 49 ++++++++++++++++++++++++++++++++++++++++ drivers/i2c/i2c-cdns.c | 7 ++++++ drivers/net/zynq_gem.c | 26 ++++++++++++++++----- 4 files changed, 87 insertions(+), 6 deletions(-)
-- 2.30.0
Please ignore this series. It needs to be redone.
Thanks, Michal
participants (3)
-
Michal Simek
-
Michal Simek
-
Ramon Fried